1*34dd1e25SAndrew Rist /**************************************************************
2*34dd1e25SAndrew Rist  *
3*34dd1e25SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*34dd1e25SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*34dd1e25SAndrew Rist  * distributed with this work for additional information
6*34dd1e25SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*34dd1e25SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*34dd1e25SAndrew Rist  * "License"); you may not use this file except in compliance
9*34dd1e25SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*34dd1e25SAndrew Rist  *
11*34dd1e25SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*34dd1e25SAndrew Rist  *
13*34dd1e25SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*34dd1e25SAndrew Rist  * software distributed under the License is distributed on an
15*34dd1e25SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*34dd1e25SAndrew Rist  * KIND, either express or implied.  See the License for the
17*34dd1e25SAndrew Rist  * specific language governing permissions and limitations
18*34dd1e25SAndrew Rist  * under the License.
19*34dd1e25SAndrew Rist  *
20*34dd1e25SAndrew Rist  *************************************************************/
21*34dd1e25SAndrew Rist 
22*34dd1e25SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // __________ Imports __________
25cdf0e10cSrcweir 
26cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime;
27cdf0e10cSrcweir import com.sun.star.uno.AnyConverter;
28cdf0e10cSrcweir 
29cdf0e10cSrcweir import java.lang.*;
30cdf0e10cSrcweir import java.awt.*;
31cdf0e10cSrcweir import javax.swing.*;
32cdf0e10cSrcweir import java.io.*;
33cdf0e10cSrcweir import java.net.*;
34cdf0e10cSrcweir 
35cdf0e10cSrcweir // __________ Implementation __________
36cdf0e10cSrcweir 
37cdf0e10cSrcweir /**
38cdf0e10cSrcweir  * Is a collection of basic features.
39cdf0e10cSrcweir  * This helper shows different functionality of framework api
40cdf0e10cSrcweir  * in an example manner. You can use the follow ones:
41cdf0e10cSrcweir  *      (1) parse URL's
42cdf0e10cSrcweir  *      (2) create frames (inside/outside a java application)
43cdf0e10cSrcweir  *      (3) dispatches (with[out] notifications)
44cdf0e10cSrcweir  *      (4) loading/saving documents
45cdf0e10cSrcweir  *      (5) convert documents to HTML (if possible)
46cdf0e10cSrcweir  *      (6) close documents (and her frames) correctly
47cdf0e10cSrcweir  *
48cdf0e10cSrcweir  * There exist some other helper functionality too, which
49cdf0e10cSrcweir  * doesn't use or demonstrate the office api:
50cdf0e10cSrcweir  *      (a) getting file names by using a file chosser
51cdf0e10cSrcweir  *
52cdf0e10cSrcweir  * @author     Andreas Schlüns
53cdf0e10cSrcweir  * @created    28.02.2002 15:31
54cdf0e10cSrcweir  */
55cdf0e10cSrcweir public class FunctionHelper
56cdf0e10cSrcweir {
57cdf0e10cSrcweir     // ____________________
58cdf0e10cSrcweir 
59cdf0e10cSrcweir     /**
60cdf0e10cSrcweir      * This convert an URL (formated as a string) to a struct com.sun.star.util.URL.
61cdf0e10cSrcweir      * It use a special service to do that: the URLTransformer.
62cdf0e10cSrcweir      * Because some API calls need it and it's not allowed to set "Complete"
63cdf0e10cSrcweir      * part of the util struct only. The URL must be parsed.
64cdf0e10cSrcweir      *
65cdf0e10cSrcweir      * @param sURL
66cdf0e10cSrcweir      *          URL for parsing in string notation
67cdf0e10cSrcweir      *
68cdf0e10cSrcweir      * @return [com.sun.star.util.URL]
69cdf0e10cSrcweir      *              URL in UNO struct notation
70cdf0e10cSrcweir      */
parseURL(String sURL)71cdf0e10cSrcweir     public static com.sun.star.util.URL parseURL(String sURL)
72cdf0e10cSrcweir     {
73cdf0e10cSrcweir         com.sun.star.util.URL aURL = null;
74cdf0e10cSrcweir 
75cdf0e10cSrcweir         if (sURL==null || sURL.equals(""))
76cdf0e10cSrcweir         {
77cdf0e10cSrcweir             System.out.println("wrong using of URL parser");
78cdf0e10cSrcweir             return null;
79cdf0e10cSrcweir         }
80cdf0e10cSrcweir 
81cdf0e10cSrcweir         try
82cdf0e10cSrcweir         {
83cdf0e10cSrcweir             com.sun.star.uno.XComponentContext xOfficeCtx =
84cdf0e10cSrcweir                 OfficeConnect.getOfficeContext();
85cdf0e10cSrcweir 
86cdf0e10cSrcweir             // Create special service for parsing of given URL.
87cdf0e10cSrcweir             com.sun.star.util.XURLTransformer xParser =
88cdf0e10cSrcweir                 (com.sun.star.util.XURLTransformer)UnoRuntime.queryInterface(
89cdf0e10cSrcweir                     com.sun.star.util.XURLTransformer.class,
90cdf0e10cSrcweir                     xOfficeCtx.getServiceManager().createInstanceWithContext(
91cdf0e10cSrcweir                         "com.sun.star.util.URLTransformer", xOfficeCtx));
92cdf0e10cSrcweir 
93cdf0e10cSrcweir             // Because it's an in/out parameter we must use an array of URL objects.
94cdf0e10cSrcweir             com.sun.star.util.URL[] aParseURL = new com.sun.star.util.URL[1];
95cdf0e10cSrcweir             aParseURL[0] = new com.sun.star.util.URL();
96cdf0e10cSrcweir             aParseURL[0].Complete = sURL;
97cdf0e10cSrcweir 
98cdf0e10cSrcweir             // Parse the URL
99cdf0e10cSrcweir             xParser.parseStrict(aParseURL);
100cdf0e10cSrcweir 
101cdf0e10cSrcweir             aURL = aParseURL[0];
102cdf0e10cSrcweir         }
103cdf0e10cSrcweir         catch(com.sun.star.uno.RuntimeException exRuntime)
104cdf0e10cSrcweir         {
105cdf0e10cSrcweir             // Any UNO method of this scope can throw this exception.
106cdf0e10cSrcweir             // Reset the return value only.
107cdf0e10cSrcweir             aURL = null;
108cdf0e10cSrcweir         }
109cdf0e10cSrcweir         catch(com.sun.star.uno.Exception exUno)
110cdf0e10cSrcweir         {
111cdf0e10cSrcweir             // "createInstance()" method of used service manager can throw it.
112cdf0e10cSrcweir             // Then it wasn't possible to get the URL transformer.
113cdf0e10cSrcweir             // Return default instead of realy parsed URL.
114cdf0e10cSrcweir             aURL = null;
115cdf0e10cSrcweir         }
116cdf0e10cSrcweir 
117cdf0e10cSrcweir         return aURL;
118cdf0e10cSrcweir     }
119cdf0e10cSrcweir 
120cdf0e10cSrcweir     // ____________________
121cdf0e10cSrcweir 
122cdf0e10cSrcweir     /**
123cdf0e10cSrcweir      * create a new empty target frame
124cdf0e10cSrcweir      * Attention: Currently we must use special service com.sun.star.frame.Task instead of Frame.
125cdf0e10cSrcweir      * Because desktop environment accept this special frame type only as direct children.
126cdf0e10cSrcweir      * Note - This service will be deprecated and must be replaces by com.sun.star.frame.Frame in
127cdf0e10cSrcweir      * further versions. To feature prove we use both service names. If for new versions
128cdf0e10cSrcweir      * the deprecated one not exist we get an empty frame, we can try to use the new service.
129cdf0e10cSrcweir      *
130cdf0e10cSrcweir      * @param xSMGR
131cdf0e10cSrcweir      *          we nee the remote service manager to create this task/frame service
132cdf0e10cSrcweir      *
133cdf0e10cSrcweir      * @return [com.sun.star.frame.XFrame]
134cdf0e10cSrcweir      *          the new created frame reference in case of success or null otherwhise
135cdf0e10cSrcweir      */
impl_createEmptyFrame( com.sun.star.uno.XComponentContext xCtx )136cdf0e10cSrcweir     private static com.sun.star.frame.XFrame impl_createEmptyFrame(
137cdf0e10cSrcweir         com.sun.star.uno.XComponentContext xCtx )
138cdf0e10cSrcweir     {
139cdf0e10cSrcweir         com.sun.star.frame.XFrame xFrame = null;
140cdf0e10cSrcweir 
141cdf0e10cSrcweir         try{
142cdf0e10cSrcweir             xFrame = (com.sun.star.frame.XFrame)UnoRuntime.queryInterface(
143cdf0e10cSrcweir                 com.sun.star.frame.XFrame.class,
144cdf0e10cSrcweir                 xCtx.getServiceManager().createInstanceWithContext(
145cdf0e10cSrcweir                     "com.sun.star.frame.Task", xCtx));
146cdf0e10cSrcweir         } catch(com.sun.star.uno.Exception ex1) {}
147cdf0e10cSrcweir 
148cdf0e10cSrcweir         if (xFrame==null)
149cdf0e10cSrcweir         {
150cdf0e10cSrcweir             try{
151cdf0e10cSrcweir                 xFrame = (com.sun.star.frame.XFrame)UnoRuntime.queryInterface(
152cdf0e10cSrcweir                     com.sun.star.frame.XFrame.class,
153cdf0e10cSrcweir                     xCtx.getServiceManager().createInstanceWithContext(
154cdf0e10cSrcweir                         "com.sun.star.frame.Frame", xCtx));
155cdf0e10cSrcweir             } catch(com.sun.star.uno.Exception ex2) {}
156cdf0e10cSrcweir         }
157cdf0e10cSrcweir 
158cdf0e10cSrcweir         return xFrame;
159cdf0e10cSrcweir     }
160cdf0e10cSrcweir 
161cdf0e10cSrcweir     // ____________________
162cdf0e10cSrcweir 
163cdf0e10cSrcweir     /**
164cdf0e10cSrcweir      * create a new window which can be used as container window of an office frame
165cdf0e10cSrcweir      * We know two modes for creation:
166cdf0e10cSrcweir      *   - the office window will be a child of one of our java windows
167cdf0e10cSrcweir      *   - the office will be a normal system window outside this java application
168cdf0e10cSrcweir      * This behaviour will be regulated by the second parameter of this operation.
169cdf0e10cSrcweir      * If a parentview is given the first mode will be activated - otherwhise
170cdf0e10cSrcweir      * the second one.
171cdf0e10cSrcweir      *
172cdf0e10cSrcweir      * Note: First mode (creation of a child window) can be reached by two different
173cdf0e10cSrcweir      *       ways.
174cdf0e10cSrcweir      *   - pack the required window handle of our java window inside an UNO object
175cdf0e10cSrcweir      *     to transport it to the remote office toolkit and get a child office
176cdf0e10cSrcweir      *     window.
177cdf0e10cSrcweir      *     This is the old way. It's better to use the second one - but to be
178cdf0e10cSrcweir      *     future prove this old one should be tried too.
179cdf0e10cSrcweir      *   - it's possible to pass the native window handle directly to the toolkit.
180cdf0e10cSrcweir      *     A special interface method was enabled to accept that.
181cdf0e10cSrcweir      *
182cdf0e10cSrcweir      *   The right way to create an office window should be then:
183cdf0e10cSrcweir      *   - try to use second creation mode (directly using of the window handle)
184cdf0e10cSrcweir      *   - if it failed ... use the old way by packing the handle inside an object
185cdf0e10cSrcweir      *
186cdf0e10cSrcweir      * @param xSMGR
187cdf0e10cSrcweir      *          we need a service manager to be able to create remote office
188cdf0e10cSrcweir      *          services
189cdf0e10cSrcweir      *
190cdf0e10cSrcweir      * @param aParentView
191cdf0e10cSrcweir      *          the java window as parent for the office window if an inplace office
192cdf0e10cSrcweir      *          is required. If it is set to null the created office window will be
193cdf0e10cSrcweir      *          a normal system window outside of our java application.
194cdf0e10cSrcweir      *
195cdf0e10cSrcweir      * @return [com.sun.star.awt.XWindow]
196cdf0e10cSrcweir      *          The new created office window which can be used to set it as
197cdf0e10cSrcweir      *          a ContainerWindow on an empty office frame.
198cdf0e10cSrcweir      */
impl_createWindow( com.sun.star.uno.XComponentContext xCtx, NativeView aParentView )199cdf0e10cSrcweir     private static com.sun.star.awt.XWindow impl_createWindow(
200cdf0e10cSrcweir         com.sun.star.uno.XComponentContext xCtx, NativeView aParentView )
201cdf0e10cSrcweir     {
202cdf0e10cSrcweir         com.sun.star.awt.XWindow     xWindow  = null;
203cdf0e10cSrcweir         com.sun.star.awt.XWindowPeer xPeer    = null;
204cdf0e10cSrcweir         com.sun.star.awt.XToolkit    xToolkit = null;
205cdf0e10cSrcweir 
206cdf0e10cSrcweir         // get access to toolkit of remote office to create the container window of
207cdf0e10cSrcweir         // new target frame
208cdf0e10cSrcweir         try{
209cdf0e10cSrcweir             xToolkit = (com.sun.star.awt.XToolkit)UnoRuntime.queryInterface(
210cdf0e10cSrcweir                 com.sun.star.awt.XToolkit.class,
211cdf0e10cSrcweir                 xCtx.getServiceManager().createInstanceWithContext(
212cdf0e10cSrcweir                     "com.sun.star.awt.Toolkit", xCtx));
213cdf0e10cSrcweir         }
214cdf0e10cSrcweir         catch(com.sun.star.uno.Exception ex)
215cdf0e10cSrcweir         {
216cdf0e10cSrcweir             return null;
217cdf0e10cSrcweir         }
218cdf0e10cSrcweir 
219cdf0e10cSrcweir         // mode 1) create an external system window
220cdf0e10cSrcweir         if (aParentView==null)
221cdf0e10cSrcweir         {
222cdf0e10cSrcweir             // Describe the properties of the container window.
223cdf0e10cSrcweir             com.sun.star.awt.WindowDescriptor aDescriptor =
224cdf0e10cSrcweir                 new com.sun.star.awt.WindowDescriptor();
225cdf0e10cSrcweir             aDescriptor.Type =   com.sun.star.awt.WindowClass.TOP;
226cdf0e10cSrcweir             aDescriptor.WindowServiceName = "window";
227cdf0e10cSrcweir             aDescriptor.ParentIndex = -1;
228cdf0e10cSrcweir             aDescriptor.Parent = null;
229cdf0e10cSrcweir             aDescriptor.Bounds = new com.sun.star.awt.Rectangle(0,0,0,0);
230cdf0e10cSrcweir             aDescriptor.WindowAttributes = com.sun.star.awt.WindowAttribute.BORDER |
231cdf0e10cSrcweir                 com.sun.star.awt.WindowAttribute.MOVEABLE |
232cdf0e10cSrcweir                 com.sun.star.awt.WindowAttribute.SIZEABLE |
233cdf0e10cSrcweir                 com.sun.star.awt.WindowAttribute.CLOSEABLE;
234cdf0e10cSrcweir 
235cdf0e10cSrcweir             try{
236cdf0e10cSrcweir                 xPeer = xToolkit.createWindow( aDescriptor );
237cdf0e10cSrcweir             } catch(com.sun.star.lang.IllegalArgumentException exIllegal) {}
238cdf0e10cSrcweir         }
239cdf0e10cSrcweir         // mode 2) create an internal office window as child of our given java
240cdf0e10cSrcweir         // parent window
241cdf0e10cSrcweir         else
242cdf0e10cSrcweir         {
243cdf0e10cSrcweir             // try new version of creation first: directly using of the window
244cdf0e10cSrcweir             // handle. The old implementation of the corresponding toolkit method
245cdf0e10cSrcweir             // requires a process ID. If this id isn't the right one a null object
246cdf0e10cSrcweir             // is returned. But normaly nobody outside the office knows this id.
247cdf0e10cSrcweir             // New version of this method ignore the id parameter and creation will
248cdf0e10cSrcweir             // work.
249cdf0e10cSrcweir             // Note: You must be shure if your window handle can be realy used by
250cdf0e10cSrcweir             // the remote office. Means if this java client and the remote office
251cdf0e10cSrcweir             // use the same display!
252cdf0e10cSrcweir             com.sun.star.awt.XSystemChildFactory xChildFactory =
253cdf0e10cSrcweir                 (com.sun.star.awt.XSystemChildFactory)UnoRuntime.queryInterface(
254cdf0e10cSrcweir                     com.sun.star.awt.XSystemChildFactory.class, xToolkit);
255cdf0e10cSrcweir 
256cdf0e10cSrcweir             try
257cdf0e10cSrcweir             {
258cdf0e10cSrcweir                 Integer nHandle = aParentView.getHWND();
259cdf0e10cSrcweir                 short   nSystem = (short)aParentView.getNativeWindowSystemType();
260cdf0e10cSrcweir                 byte[]  lProcID = new byte[0];
261cdf0e10cSrcweir 
262cdf0e10cSrcweir                 xPeer = xChildFactory.createSystemChild((Object)nHandle,
263cdf0e10cSrcweir                                                         lProcID, nSystem);
264cdf0e10cSrcweir 
265cdf0e10cSrcweir                 if (xPeer==null)
266cdf0e10cSrcweir                 {
267cdf0e10cSrcweir                     // mode 3) OK - new version doesn't work. It requires the
268cdf0e10cSrcweir                     // process id which we doesn't have.
269cdf0e10cSrcweir                     // So we must use the old way to get the right window peer.
270cdf0e10cSrcweir                     // Pack the handle inside a wrapper object.
271cdf0e10cSrcweir                     JavaWindowPeerFake aWrapper = new
272cdf0e10cSrcweir                         JavaWindowPeerFake(aParentView);
273cdf0e10cSrcweir 
274cdf0e10cSrcweir                     com.sun.star.awt.XWindowPeer xParentPeer =
275cdf0e10cSrcweir                         (com.sun.star.awt.XWindowPeer)UnoRuntime.queryInterface(
276cdf0e10cSrcweir                             com.sun.star.awt.XWindowPeer.class, aWrapper);
277cdf0e10cSrcweir 
278cdf0e10cSrcweir                     com.sun.star.awt.WindowDescriptor aDescriptor =
279cdf0e10cSrcweir                         new com.sun.star.awt.WindowDescriptor();
280cdf0e10cSrcweir                     aDescriptor.Type = com.sun.star.awt.WindowClass.TOP;
281cdf0e10cSrcweir                     aDescriptor.WindowServiceName = "workwindow";
282cdf0e10cSrcweir                     aDescriptor.ParentIndex = 1;
283cdf0e10cSrcweir                     aDescriptor.Parent = xParentPeer;
284cdf0e10cSrcweir                     aDescriptor.Bounds = new com.sun.star.awt.Rectangle(0,0,0,0);
285cdf0e10cSrcweir                     if (nSystem == com.sun.star.lang.SystemDependent.SYSTEM_WIN32)
286cdf0e10cSrcweir                         aDescriptor.WindowAttributes =
287cdf0e10cSrcweir                             com.sun.star.awt.WindowAttribute.SHOW;
288cdf0e10cSrcweir                     else
289cdf0e10cSrcweir                         aDescriptor.WindowAttributes =
290cdf0e10cSrcweir                             com.sun.star.awt.WindowAttribute.SYSTEMDEPENDENT;
291cdf0e10cSrcweir 
292cdf0e10cSrcweir                     try{
293cdf0e10cSrcweir                         xPeer = xToolkit.createWindow( aDescriptor );
294cdf0e10cSrcweir                     } catch(com.sun.star.lang.IllegalArgumentException exIllegal) {}
295cdf0e10cSrcweir                 }
296cdf0e10cSrcweir             }
297cdf0e10cSrcweir             catch(java.lang.RuntimeException exJRun)
298cdf0e10cSrcweir             {
299cdf0e10cSrcweir                 // This exception is thrown by the native JNI code if it try to get
300cdf0e10cSrcweir                 // the systemw window handle. A possible reason can be an invisible
301cdf0e10cSrcweir                 // java window. In this case it should be enough to set return
302cdf0e10cSrcweir                 // values to null. All other ressources (which was created before)
303cdf0e10cSrcweir                 // will be freed automaticly if scope wil be leaved.
304cdf0e10cSrcweir                 System.out.println("May be the NativeView object wasn't realy visible at calling time of getNativeWindow()?");
305cdf0e10cSrcweir                 xPeer   = null;
306cdf0e10cSrcweir                 xWindow = null;
307cdf0e10cSrcweir             }
308cdf0e10cSrcweir         }
309cdf0e10cSrcweir 
310cdf0e10cSrcweir         // It doesn't matter which way was used to get the window peer.
311cdf0e10cSrcweir         // Cast it to the right return interface and return it.
312cdf0e10cSrcweir         xWindow = (com.sun.star.awt.XWindow)UnoRuntime.queryInterface(
313cdf0e10cSrcweir             com.sun.star.awt.XWindow.class,
314cdf0e10cSrcweir             xPeer);
315cdf0e10cSrcweir 
316cdf0e10cSrcweir         return xWindow;
317cdf0e10cSrcweir     }
318cdf0e10cSrcweir 
319cdf0e10cSrcweir     // ____________________
320cdf0e10cSrcweir 
321cdf0e10cSrcweir     /**
322cdf0e10cSrcweir      * This method create a new empty child frame on desktop instance of remote office.
323cdf0e10cSrcweir      * It use a special JNI functionality to pass the office XWindow over a java window.
324cdf0e10cSrcweir      * This java window can be inserted into another java window container for complex layouting.
325cdf0e10cSrcweir      * If this parent java window isn't used, a top level system window will be created.
326cdf0e10cSrcweir      * The the resulting office frame isn't plugged into this java application.
327cdf0e10cSrcweir      *
328cdf0e10cSrcweir      * @param sName
329cdf0e10cSrcweir      *          name to set it on the new created frame
330cdf0e10cSrcweir      *
331cdf0e10cSrcweir      * @param aParentView
332cdf0e10cSrcweir      *          java window which should be used as parent window of new created office frame window
333cdf0e10cSrcweir      *          May be set to null.
334cdf0e10cSrcweir      *
335cdf0e10cSrcweir      * @return [com.sun.star.frame.XFrame]
336cdf0e10cSrcweir      *          reference to the new created frame for success or null if it failed
337cdf0e10cSrcweir      */
createViewFrame(String sName, NativeView aParentView)338cdf0e10cSrcweir     public static com.sun.star.frame.XFrame createViewFrame(String sName, NativeView aParentView)
339cdf0e10cSrcweir     {
340cdf0e10cSrcweir         com.sun.star.frame.XFrame xFrame = null;
341cdf0e10cSrcweir 
342cdf0e10cSrcweir         try
343cdf0e10cSrcweir         {
344cdf0e10cSrcweir             com.sun.star.uno.XComponentContext xCtx =
345cdf0e10cSrcweir                 OfficeConnect.getOfficeContext();
346cdf0e10cSrcweir 
347cdf0e10cSrcweir             // create an empty office frame first
348cdf0e10cSrcweir             xFrame = impl_createEmptyFrame(xCtx);
349cdf0e10cSrcweir 
350cdf0e10cSrcweir             // create an office window then
351cdf0e10cSrcweir             // Depending from the given parameter aParentView it will be a child or a top level
352cdf0e10cSrcweir             // system window. (see impl method for further informations)
353cdf0e10cSrcweir             // But before we call this helper - prepare the possible parent window: show it.
354cdf0e10cSrcweir             // JNI calls to get system window handle of java window can't work without that!
355cdf0e10cSrcweir             if (aParentView!=null)
356cdf0e10cSrcweir                 aParentView.setVisible(true);
357cdf0e10cSrcweir             com.sun.star.awt.XWindow xWindow = impl_createWindow(xCtx, aParentView);
358cdf0e10cSrcweir 
359cdf0e10cSrcweir             // pass the window the frame as his new container window.
360cdf0e10cSrcweir             // It's neccessary to do it first  - before you call anything else there.
361cdf0e10cSrcweir             // Otherwhise the frame throws some exceptions for "uninitialized state".
362cdf0e10cSrcweir             xFrame.initialize( xWindow );
363cdf0e10cSrcweir 
364cdf0e10cSrcweir             // Insert the new frame in desktop hierarchy.
365cdf0e10cSrcweir             // Use XFrames interface to do so. It provides access to the child frame container of that instance.
366cdf0e10cSrcweir             com.sun.star.frame.XFramesSupplier xTreeRoot = (com.sun.star.frame.XFramesSupplier)UnoRuntime.queryInterface(
367cdf0e10cSrcweir                 com.sun.star.frame.XFramesSupplier.class,
368cdf0e10cSrcweir                 xCtx.getServiceManager().createInstanceWithContext(
369cdf0e10cSrcweir                     "com.sun.star.frame.Desktop", xCtx));
370cdf0e10cSrcweir             com.sun.star.frame.XFrames xChildContainer = xTreeRoot.getFrames();
371cdf0e10cSrcweir             xChildContainer.append(xFrame);
372cdf0e10cSrcweir 
373cdf0e10cSrcweir             // Make some further initializations on frame and window.
374cdf0e10cSrcweir             xWindow.setVisible(true);
375cdf0e10cSrcweir             xFrame.setName(sName);
376cdf0e10cSrcweir         }
377cdf0e10cSrcweir         catch(com.sun.star.uno.RuntimeException exRuntime)
378cdf0e10cSrcweir         {
379cdf0e10cSrcweir             // Any UNO method of this scope can throw this exception.
380cdf0e10cSrcweir             // So the frame can be already created and he must be freed
381cdf0e10cSrcweir             // correctly. May be he was inserted into the desktop tree too ...
382cdf0e10cSrcweir             if(xFrame!=null)
383cdf0e10cSrcweir             {
384cdf0e10cSrcweir                 // Try to dispose the frame. He should deregister himself at the desktop object
385cdf0e10cSrcweir                 // and free all internal used ressources (e.g. the container window) automaticly.
386cdf0e10cSrcweir                 // It's possible to do that here - because frame has no component inside yet.
387cdf0e10cSrcweir                 // So nobody can disagree with that.
388cdf0e10cSrcweir                 // After the dispose() call forget all references to this frame and let him die.
389cdf0e10cSrcweir                 // If a new exception will occure ... no generell solution exist then.
390cdf0e10cSrcweir                 // Nobody can guarantee if next call will work or not.
391cdf0e10cSrcweir                 com.sun.star.lang.XComponent xComponent = (com.sun.star.lang.XComponent)UnoRuntime.queryInterface(
392cdf0e10cSrcweir                     com.sun.star.lang.XComponent.class,
393cdf0e10cSrcweir                     xFrame);
394cdf0e10cSrcweir                 xComponent.dispose();
395cdf0e10cSrcweir                 xComponent = null;
396cdf0e10cSrcweir                 xFrame     = null;
397cdf0e10cSrcweir             }
398cdf0e10cSrcweir         }
399cdf0e10cSrcweir         catch(com.sun.star.uno.Exception exUno)
400cdf0e10cSrcweir         {
401cdf0e10cSrcweir             // "createInstance()" method of used service manager can throw it.
402cdf0e10cSrcweir             // If it occured during creation of desktop service the frame already was created.
403cdf0e10cSrcweir             // Free it by decresing his refcount. Changes on the desktop tree couldn't exist.
404cdf0e10cSrcweir             // Without the desktop service that wasn't possible. So no further rollbacks must follow.
405cdf0e10cSrcweir             if(xFrame!=null)
406cdf0e10cSrcweir             {
407cdf0e10cSrcweir                 com.sun.star.lang.XComponent xComponent = (com.sun.star.lang.XComponent)UnoRuntime.queryInterface(
408cdf0e10cSrcweir                     com.sun.star.lang.XComponent.class,
409cdf0e10cSrcweir                     xFrame);
410cdf0e10cSrcweir                 xComponent.dispose();
411cdf0e10cSrcweir                 xComponent = null;
412cdf0e10cSrcweir                 xFrame     = null;
413cdf0e10cSrcweir             }
414cdf0e10cSrcweir         }
415cdf0e10cSrcweir 
416cdf0e10cSrcweir         return xFrame;
417cdf0e10cSrcweir     }
418cdf0e10cSrcweir 
419cdf0e10cSrcweir     // ____________________
420cdf0e10cSrcweir 
421cdf0e10cSrcweir     /**
422cdf0e10cSrcweir      * Dispatch an URL to given frame.
423cdf0e10cSrcweir      * Caller can register himself for following status events for dispatched
424cdf0e10cSrcweir      * URL too. But nobody guarantee that such notifications will occure.
425cdf0e10cSrcweir      * (see dispatchWithNotification() if you interest on that)
426cdf0e10cSrcweir      * The returned dispatch object should be hold alive by caller
427cdf0e10cSrcweir      * till he deosn't need it any longer. Otherwise the dispatcher can(!)
428cdf0e10cSrcweir      * die by decreasing his refcount.
429cdf0e10cSrcweir      *
430cdf0e10cSrcweir      * @param   xFrame      frame wich should be the target of this dispatch
431cdf0e10cSrcweir      * @param   aURL        full parsed and converted office URL for dispatch
432cdf0e10cSrcweir      * @param   lProperties optional arguments for dispatch
433cdf0e10cSrcweir      * @param   xListener   optional listener which is registered automaticly for status events
434cdf0e10cSrcweir      *                      (Note: Deregistration is part of this listener himself!)
435cdf0e10cSrcweir      *
436cdf0e10cSrcweir      * @return  [XDispatch] It's the used dispatch object and can be used for deregistration of an optional listener.
437cdf0e10cSrcweir      *                      Otherwhise caller can ignore it.
438cdf0e10cSrcweir      */
execute(com.sun.star.frame.XFrame xFrame , com.sun.star.util.URL aURL , com.sun.star.beans.PropertyValue[] lProperties, com.sun.star.frame.XStatusListener xListener )439cdf0e10cSrcweir     public static com.sun.star.frame.XDispatch execute(com.sun.star.frame.XFrame          xFrame     ,
440cdf0e10cSrcweir                                                        com.sun.star.util.URL              aURL       ,
441cdf0e10cSrcweir                                                        com.sun.star.beans.PropertyValue[] lProperties,
442cdf0e10cSrcweir                                                        com.sun.star.frame.XStatusListener xListener  )
443cdf0e10cSrcweir     {
444cdf0e10cSrcweir         com.sun.star.frame.XDispatch xDispatcher = null;
445cdf0e10cSrcweir 
446cdf0e10cSrcweir         try
447cdf0e10cSrcweir         {
448cdf0e10cSrcweir             // Query the frame for right interface which provides access to all available dispatch objects.
449cdf0e10cSrcweir             com.sun.star.frame.XDispatchProvider xProvider = (com.sun.star.frame.XDispatchProvider)UnoRuntime.queryInterface(
450cdf0e10cSrcweir                 com.sun.star.frame.XDispatchProvider.class,
451cdf0e10cSrcweir                 xFrame);
452cdf0e10cSrcweir 
453cdf0e10cSrcweir             // Ask himn for right dispatch object for given URL.
454cdf0e10cSrcweir             // Force given frame as target for following dispatch by using "".
455cdf0e10cSrcweir             // It means the same like "_self".
456cdf0e10cSrcweir             xDispatcher = xProvider.queryDispatch(aURL,"",0);
457cdf0e10cSrcweir 
458cdf0e10cSrcweir             // Dispatch the URL into the frame.
459cdf0e10cSrcweir             if(xDispatcher!=null)
460cdf0e10cSrcweir             {
461cdf0e10cSrcweir                 if(xListener!=null)
462cdf0e10cSrcweir                     xDispatcher.addStatusListener(xListener,aURL);
463cdf0e10cSrcweir 
464cdf0e10cSrcweir                 xDispatcher.dispatch(aURL,lProperties);
465cdf0e10cSrcweir             }
466cdf0e10cSrcweir         }
467cdf0e10cSrcweir         catch(com.sun.star.uno.RuntimeException exUno)
468cdf0e10cSrcweir         {
469cdf0e10cSrcweir             // Any UNO method of this scope can throw this exception.
470cdf0e10cSrcweir             // But there will be nothing to do then - because
471cdf0e10cSrcweir             // we haven't changed anything inside the remote objects
472cdf0e10cSrcweir             // except method "addStatusListener().
473cdf0e10cSrcweir             // But in this case the source of this exception has to
474cdf0e10cSrcweir             // rollback all his operations. There is no chance to
475cdf0e10cSrcweir             // make anything right then.
476cdf0e10cSrcweir             // Reset the return value to a default - that's it.
477cdf0e10cSrcweir             exUno.printStackTrace();
478cdf0e10cSrcweir             xDispatcher = null;
479cdf0e10cSrcweir         }
480cdf0e10cSrcweir 
481cdf0e10cSrcweir         return xDispatcher;
482cdf0e10cSrcweir     }
483cdf0e10cSrcweir 
484cdf0e10cSrcweir     // ____________________
485cdf0e10cSrcweir 
486cdf0e10cSrcweir     /**
487cdf0e10cSrcweir      * Dispatch an URL to given frame.
488cdf0e10cSrcweir      * Caller can register himself for following result events for dispatched
489cdf0e10cSrcweir      * URL too. Notifications are guaranteed (instead of dispatch())
490cdf0e10cSrcweir      * Returning of the dispatch object isn't neccessary.
491cdf0e10cSrcweir      * Nobody must hold it alive longer the dispatch needs.
492cdf0e10cSrcweir      *
493cdf0e10cSrcweir      * @param   xFrame      frame wich should be the target of this dispatch
494cdf0e10cSrcweir      * @param   aURL        full parsed and converted office URL for dispatch
495cdf0e10cSrcweir      * @param   lProperties optional arguments for dispatch
496cdf0e10cSrcweir      * @param   xListener   optional listener which is registered automaticly for status events
497cdf0e10cSrcweir      *                      (Note: Deregistration is not supported. Dispatcher does it automaticly.)
498cdf0e10cSrcweir      */
executeWithNotification(com.sun.star.frame.XFrame xFrame , com.sun.star.util.URL aURL , com.sun.star.beans.PropertyValue[] lProperties, com.sun.star.frame.XDispatchResultListener xListener )499cdf0e10cSrcweir     public static void executeWithNotification(com.sun.star.frame.XFrame                  xFrame     ,
500cdf0e10cSrcweir                                                com.sun.star.util.URL                      aURL       ,
501cdf0e10cSrcweir                                                com.sun.star.beans.PropertyValue[]         lProperties,
502cdf0e10cSrcweir                                                com.sun.star.frame.XDispatchResultListener xListener  )
503cdf0e10cSrcweir     {
504cdf0e10cSrcweir         try
505cdf0e10cSrcweir         {
506cdf0e10cSrcweir             // Query the frame for right interface which provides access to all available dispatch objects.
507cdf0e10cSrcweir             com.sun.star.frame.XDispatchProvider xProvider = (com.sun.star.frame.XDispatchProvider)UnoRuntime.queryInterface(
508cdf0e10cSrcweir                 com.sun.star.frame.XDispatchProvider.class,
509cdf0e10cSrcweir                 xFrame);
510cdf0e10cSrcweir 
511cdf0e10cSrcweir             // Ask himn for right dispatch object for given URL.
512cdf0e10cSrcweir             // Force THIS frame as target for following dispatch.
513cdf0e10cSrcweir             // Attention: The interface XNotifyingDispatch is an optional one!
514cdf0e10cSrcweir             com.sun.star.frame.XDispatch xDispatcher = xProvider.queryDispatch(aURL,"",0);
515cdf0e10cSrcweir             com.sun.star.frame.XNotifyingDispatch xNotifyingDispatcher = (com.sun.star.frame.XNotifyingDispatch)UnoRuntime.queryInterface(
516cdf0e10cSrcweir                 com.sun.star.frame.XNotifyingDispatch.class,
517cdf0e10cSrcweir                 xDispatcher);
518cdf0e10cSrcweir 
519cdf0e10cSrcweir             // Dispatch the URL.
520cdf0e10cSrcweir             if(xNotifyingDispatcher!=null)
521cdf0e10cSrcweir                 xNotifyingDispatcher.dispatchWithNotification(aURL,lProperties,xListener);
522cdf0e10cSrcweir         }
523cdf0e10cSrcweir         catch(com.sun.star.uno.RuntimeException exUno)
524cdf0e10cSrcweir         {
525cdf0e10cSrcweir             // Any UNO method of this scope can throw this exception.
526cdf0e10cSrcweir             // But there is nothing we can do then.
527cdf0e10cSrcweir             exUno.printStackTrace();
528cdf0e10cSrcweir         }
529cdf0e10cSrcweir     }
530cdf0e10cSrcweir 
531cdf0e10cSrcweir     // ____________________
532cdf0e10cSrcweir 
533cdf0e10cSrcweir     /**
534cdf0e10cSrcweir      * Load document specified by an URL into given frame synchronously.
535cdf0e10cSrcweir      * The result of this operation will be the loaded document for success
536cdf0e10cSrcweir      * or null if loading failed.
537cdf0e10cSrcweir      *
538cdf0e10cSrcweir      * @param   xFrame          frame wich should be the target of this load call
539cdf0e10cSrcweir      * @param   sURL            unparsed URL for loading
540cdf0e10cSrcweir      * @param   lProperties     optional arguments
541cdf0e10cSrcweir      *
542cdf0e10cSrcweir      * @return  [XComponent]    the loaded document for success or null if it's failed
543cdf0e10cSrcweir      */
loadDocument( com.sun.star.frame.XFrame xFrame, String sURL, com.sun.star.beans.PropertyValue[] lProperties)544cdf0e10cSrcweir     public static com.sun.star.lang.XComponent loadDocument(
545cdf0e10cSrcweir         com.sun.star.frame.XFrame xFrame, String sURL,
546cdf0e10cSrcweir         com.sun.star.beans.PropertyValue[] lProperties)
547cdf0e10cSrcweir     {
548cdf0e10cSrcweir         com.sun.star.lang.XComponent xDocument = null;
549cdf0e10cSrcweir         String                       sOldName  = null;
550cdf0e10cSrcweir 
551cdf0e10cSrcweir         try
552cdf0e10cSrcweir         {
553cdf0e10cSrcweir             com.sun.star.uno.XComponentContext xCtx =
554cdf0e10cSrcweir                 OfficeConnect.getOfficeContext();
555cdf0e10cSrcweir 
556cdf0e10cSrcweir             // First prepare frame for loading
557cdf0e10cSrcweir             // We must adress it inside the frame tree without any complications.
558cdf0e10cSrcweir             // So we set an unambigous (we hope it) name and use it later.
559cdf0e10cSrcweir             // Don't forget to reset original name after that.
560cdf0e10cSrcweir                    sOldName = xFrame.getName();
561cdf0e10cSrcweir             String sTarget  = "odk_officedev_desk";
562cdf0e10cSrcweir             xFrame.setName(sTarget);
563cdf0e10cSrcweir 
564cdf0e10cSrcweir             // Get access to the global component loader of the office
565cdf0e10cSrcweir             // for synchronous loading the document.
566cdf0e10cSrcweir             com.sun.star.frame.XComponentLoader xLoader =
567cdf0e10cSrcweir                 (com.sun.star.frame.XComponentLoader)UnoRuntime.queryInterface(
568cdf0e10cSrcweir                     com.sun.star.frame.XComponentLoader.class,
569cdf0e10cSrcweir                     xCtx.getServiceManager().createInstanceWithContext(
570cdf0e10cSrcweir                         "com.sun.star.frame.Desktop", xCtx));
571cdf0e10cSrcweir 
572cdf0e10cSrcweir             // Load the document into the target frame by using his name and
573cdf0e10cSrcweir             // special search flags.
574cdf0e10cSrcweir             xDocument = xLoader.loadComponentFromURL(
575cdf0e10cSrcweir                 sURL,
576cdf0e10cSrcweir                 sTarget,
577cdf0e10cSrcweir                 com.sun.star.frame.FrameSearchFlag.CHILDREN,
578cdf0e10cSrcweir                 lProperties);
579cdf0e10cSrcweir 
580cdf0e10cSrcweir             // dont forget to restore old frame name ...
581cdf0e10cSrcweir             xFrame.setName(sOldName);
582cdf0e10cSrcweir         }
583cdf0e10cSrcweir         catch(com.sun.star.io.IOException exIO)
584cdf0e10cSrcweir         {
585cdf0e10cSrcweir             // Can be thrown by "loadComponentFromURL()" call.
586cdf0e10cSrcweir             // The only thing we should do then is to reset changed frame name!
587cdf0e10cSrcweir             exIO.printStackTrace();
588cdf0e10cSrcweir             xDocument = null;
589cdf0e10cSrcweir             if(sOldName!=null)
590cdf0e10cSrcweir                 xFrame.setName(sOldName);
591cdf0e10cSrcweir         }
592cdf0e10cSrcweir         catch(com.sun.star.lang.IllegalArgumentException exIllegal)
593cdf0e10cSrcweir         {
594cdf0e10cSrcweir             // Can be thrown by "loadComponentFromURL()" call.
595cdf0e10cSrcweir             // The only thing we should do then is to reset changed frame name!
596cdf0e10cSrcweir             exIllegal.printStackTrace();
597cdf0e10cSrcweir             xDocument = null;
598cdf0e10cSrcweir             if(sOldName!=null)
599cdf0e10cSrcweir                 xFrame.setName(sOldName);
600cdf0e10cSrcweir         }
601cdf0e10cSrcweir         catch(com.sun.star.uno.RuntimeException exRuntime)
602cdf0e10cSrcweir         {
603cdf0e10cSrcweir             // Any UNO method of this scope can throw this exception.
604cdf0e10cSrcweir             // The only thing we can try(!) is to reset changed frame name.
605cdf0e10cSrcweir             exRuntime.printStackTrace();
606cdf0e10cSrcweir             xDocument = null;
607cdf0e10cSrcweir             if(sOldName!=null)
608cdf0e10cSrcweir                 xFrame.setName(sOldName);
609cdf0e10cSrcweir         }
610cdf0e10cSrcweir         catch(com.sun.star.uno.Exception exUno)
611cdf0e10cSrcweir         {
612cdf0e10cSrcweir             // "createInstance()" method of used service manager can throw it.
613cdf0e10cSrcweir             // The only thing we should do then is to reset changed frame name!
614cdf0e10cSrcweir             exUno.printStackTrace();
615cdf0e10cSrcweir             xDocument = null;
616cdf0e10cSrcweir             if(sOldName!=null)
617cdf0e10cSrcweir                 xFrame.setName(sOldName);
618cdf0e10cSrcweir         }
619cdf0e10cSrcweir 
620cdf0e10cSrcweir         return xDocument;
621cdf0e10cSrcweir     }
622cdf0e10cSrcweir 
623cdf0e10cSrcweir     // ____________________
624cdf0e10cSrcweir 
625cdf0e10cSrcweir     /**
626cdf0e10cSrcweir      * Save currently loaded document of given frame.
627cdf0e10cSrcweir      *
628cdf0e10cSrcweir      * @param   xDocument   document for saving changes
629cdf0e10cSrcweir      */
saveDocument(com.sun.star.lang.XComponent xDocument)630cdf0e10cSrcweir     public static void saveDocument(com.sun.star.lang.XComponent xDocument)
631cdf0e10cSrcweir     {
632cdf0e10cSrcweir         try
633cdf0e10cSrcweir         {
634cdf0e10cSrcweir             // Check for supported model functionality.
635cdf0e10cSrcweir             // Normaly the application documents (text, spreadsheet ...) do so
636cdf0e10cSrcweir             // but some other ones (e.g. db components) doesn't do that.
637cdf0e10cSrcweir             // They can't be save then.
638cdf0e10cSrcweir             com.sun.star.frame.XModel xModel = (com.sun.star.frame.XModel)UnoRuntime.queryInterface(
639cdf0e10cSrcweir                 com.sun.star.frame.XModel.class,
640cdf0e10cSrcweir                 xDocument);
641cdf0e10cSrcweir             if(xModel!=null)
642cdf0e10cSrcweir             {
643cdf0e10cSrcweir                 // Check for modifications => break save process if there is nothing to do.
644cdf0e10cSrcweir                 com.sun.star.util.XModifiable xModified = (com.sun.star.util.XModifiable)UnoRuntime.queryInterface(
645cdf0e10cSrcweir                     com.sun.star.util.XModifiable.class,
646cdf0e10cSrcweir                     xModel);
647cdf0e10cSrcweir                 if(xModified.isModified()==true)
648cdf0e10cSrcweir                 {
649cdf0e10cSrcweir                     com.sun.star.frame.XStorable xStore = (com.sun.star.frame.XStorable)UnoRuntime.queryInterface(
650cdf0e10cSrcweir                         com.sun.star.frame.XStorable.class,
651cdf0e10cSrcweir                         xModel);
652cdf0e10cSrcweir 
653cdf0e10cSrcweir                     xStore.store();
654cdf0e10cSrcweir                 }
655cdf0e10cSrcweir             }
656cdf0e10cSrcweir         }
657cdf0e10cSrcweir         catch(com.sun.star.io.IOException exIO)
658cdf0e10cSrcweir         {
659cdf0e10cSrcweir             // Can be thrown by "store()" call.
660cdf0e10cSrcweir             // But there is nothing we can do then.
661cdf0e10cSrcweir             exIO.printStackTrace();
662cdf0e10cSrcweir         }
663cdf0e10cSrcweir         catch(com.sun.star.uno.RuntimeException exUno)
664cdf0e10cSrcweir         {
665cdf0e10cSrcweir             // Any UNO method of this scope can throw this exception.
666cdf0e10cSrcweir             // But there is nothing we can do then.
667cdf0e10cSrcweir             exUno.printStackTrace();
668cdf0e10cSrcweir         }
669cdf0e10cSrcweir     }
670cdf0e10cSrcweir 
671cdf0e10cSrcweir     // ____________________
672cdf0e10cSrcweir 
673cdf0e10cSrcweir     /**
674cdf0e10cSrcweir      * It try to export given document in HTML format.
675cdf0e10cSrcweir      * Current document will be converted to HTML and moved to new place on disk.
676cdf0e10cSrcweir      * A "new" file will be created by given URL (may be overwritten
677cdf0e10cSrcweir      * if it already exist). Right filter will be used automaticly if factory of
678cdf0e10cSrcweir      * this document support it. If no valid filter can be found for export,
679cdf0e10cSrcweir      * nothing will be done here.
680cdf0e10cSrcweir      *
681cdf0e10cSrcweir      * @param   xDocument   document which should be exported
682cdf0e10cSrcweir      * @param   sURL        target URL for converted document
683cdf0e10cSrcweir      */
saveAsHTML(com.sun.star.lang.XComponent xDocument, String sURL )684cdf0e10cSrcweir     public static void saveAsHTML(com.sun.star.lang.XComponent xDocument,
685cdf0e10cSrcweir                                   String                       sURL     )
686cdf0e10cSrcweir     {
687cdf0e10cSrcweir         try
688cdf0e10cSrcweir         {
689cdf0e10cSrcweir             // First detect factory of this document.
690cdf0e10cSrcweir             // Ask for the supported service name of this document.
691cdf0e10cSrcweir             // If information is available it can be used to find out wich
692cdf0e10cSrcweir             // filter exist for HTML export. Normaly this filter should be searched
693cdf0e10cSrcweir             // inside the filter configuration but this little demo doesn't do so.
694cdf0e10cSrcweir             // (see service com.sun.star.document.FilterFactory for further
695cdf0e10cSrcweir             // informations too)
696cdf0e10cSrcweir             // Well known filter names are used directly. They must exist in current
697cdf0e10cSrcweir             // office installation. Otherwise this code will fail. But to prevent
698cdf0e10cSrcweir             // this code against missing filters it check for existing state of it.
699cdf0e10cSrcweir             com.sun.star.lang.XServiceInfo xInfo = (com.sun.star.lang.XServiceInfo)
700cdf0e10cSrcweir                 UnoRuntime.queryInterface(com.sun.star.lang.XServiceInfo.class,
701cdf0e10cSrcweir                                           xDocument);
702cdf0e10cSrcweir 
703cdf0e10cSrcweir             if(xInfo!=null)
704cdf0e10cSrcweir             {
705cdf0e10cSrcweir                 // Find out possible filter name.
706cdf0e10cSrcweir                 String sFilter = null;
707cdf0e10cSrcweir                 if(xInfo.supportsService("com.sun.star.text.TextDocument")==true)
708cdf0e10cSrcweir                     sFilter = new String("HTML (StarWriter)");
709cdf0e10cSrcweir                 else
710cdf0e10cSrcweir                 if(xInfo.supportsService("com.sun.star.text.WebDocument")==true)
711cdf0e10cSrcweir                     sFilter = new String("HTML");
712cdf0e10cSrcweir                 else
713cdf0e10cSrcweir                 if(xInfo.supportsService("com.sun.star.sheet.SpreadsheetDocument")==true)
714cdf0e10cSrcweir                     sFilter = new String("HTML (StarCalc)");
715cdf0e10cSrcweir 
716cdf0e10cSrcweir                 // Check for existing state of this filter.
717cdf0e10cSrcweir                 if(sFilter!=null)
718cdf0e10cSrcweir                 {
719cdf0e10cSrcweir                     com.sun.star.uno.XComponentContext xCtx =
720cdf0e10cSrcweir                         OfficeConnect.getOfficeContext();
721cdf0e10cSrcweir 
722cdf0e10cSrcweir                     com.sun.star.container.XNameAccess xFilterContainer =
723cdf0e10cSrcweir                         (com.sun.star.container.XNameAccess)
724cdf0e10cSrcweir                         UnoRuntime.queryInterface(
725cdf0e10cSrcweir                             com.sun.star.container.XNameAccess.class,
726cdf0e10cSrcweir                             xCtx.getServiceManager().createInstanceWithContext(
727cdf0e10cSrcweir                                 "com.sun.star.document.FilterFactory", xCtx));
728cdf0e10cSrcweir 
729cdf0e10cSrcweir                     if(xFilterContainer.hasByName(sFilter)==false)
730cdf0e10cSrcweir                         sFilter=null;
731cdf0e10cSrcweir                 }
732cdf0e10cSrcweir 
733cdf0e10cSrcweir                 // Use this filter for export.
734cdf0e10cSrcweir                 if(sFilter!=null)
735cdf0e10cSrcweir                 {
736cdf0e10cSrcweir                     // Export can be forced by saving the document and using a
737cdf0e10cSrcweir                     // special filter name which can write needed format. Build
738cdf0e10cSrcweir                     // neccessary argument list now.
739cdf0e10cSrcweir                     // Use special flag "Overwrite" too, to prevent operation
740cdf0e10cSrcweir                     // against possible exceptions, if file already exist.
741cdf0e10cSrcweir                     com.sun.star.beans.PropertyValue[] lProperties =
742cdf0e10cSrcweir                         new com.sun.star.beans.PropertyValue[2];
743cdf0e10cSrcweir                     lProperties[0] = new com.sun.star.beans.PropertyValue();
744cdf0e10cSrcweir                     lProperties[0].Name = "FilterName";
745cdf0e10cSrcweir                     lProperties[0].Value = sFilter;
746cdf0e10cSrcweir                     lProperties[1] = new com.sun.star.beans.PropertyValue();
747cdf0e10cSrcweir                     lProperties[1].Name = "Overwrite";
748cdf0e10cSrcweir                     lProperties[1].Value = Boolean.TRUE;
749cdf0e10cSrcweir 
750cdf0e10cSrcweir                     com.sun.star.frame.XStorable xStore =
751cdf0e10cSrcweir                         (com.sun.star.frame.XStorable)UnoRuntime.queryInterface(
752cdf0e10cSrcweir                             com.sun.star.frame.XStorable.class, xDocument);
753cdf0e10cSrcweir 
754cdf0e10cSrcweir                     xStore.storeAsURL(sURL,lProperties);
755cdf0e10cSrcweir                 }
756cdf0e10cSrcweir             }
757cdf0e10cSrcweir         }
758cdf0e10cSrcweir         catch(com.sun.star.io.IOException exIO)
759cdf0e10cSrcweir         {
760cdf0e10cSrcweir             // Can be thrown by "store()" call.
761cdf0e10cSrcweir             // Do nothing then. Saving failed - that's it.
762cdf0e10cSrcweir             exIO.printStackTrace();
763cdf0e10cSrcweir         }
764cdf0e10cSrcweir         catch(com.sun.star.uno.RuntimeException exRuntime)
765cdf0e10cSrcweir         {
766cdf0e10cSrcweir             // Can be thrown by any uno call.
767cdf0e10cSrcweir             // Do nothing here. Saving failed - that's it.
768cdf0e10cSrcweir             exRuntime.printStackTrace();
769cdf0e10cSrcweir         }
770cdf0e10cSrcweir         catch(com.sun.star.uno.Exception exUno)
771cdf0e10cSrcweir         {
772cdf0e10cSrcweir             // Can be thrown by "createInstance()" call of service manager.
773cdf0e10cSrcweir             // Do nothing here. Saving failed - that's it.
774cdf0e10cSrcweir             exUno.printStackTrace();
775cdf0e10cSrcweir         }
776cdf0e10cSrcweir     }
777cdf0e10cSrcweir 
778cdf0e10cSrcweir     // ____________________
779cdf0e10cSrcweir 
780cdf0e10cSrcweir     /**
781cdf0e10cSrcweir      * Try to close the document without any saving of modifications.
782cdf0e10cSrcweir      * We can try it only! Controller and/or model of this document
783cdf0e10cSrcweir      * can disagree with that. But mostly they doesn't do so.
784cdf0e10cSrcweir      *
785cdf0e10cSrcweir      * @param   xDocument   document which should be clcosed
786cdf0e10cSrcweir      */
closeDocument(com.sun.star.lang.XComponent xDocument)787cdf0e10cSrcweir     public static void closeDocument(com.sun.star.lang.XComponent xDocument)
788cdf0e10cSrcweir     {
789cdf0e10cSrcweir         try
790cdf0e10cSrcweir         {
791cdf0e10cSrcweir             // Check supported functionality of the document (model or controller).
792cdf0e10cSrcweir             com.sun.star.frame.XModel xModel =
793cdf0e10cSrcweir                 (com.sun.star.frame.XModel)UnoRuntime.queryInterface(
794cdf0e10cSrcweir                     com.sun.star.frame.XModel.class, xDocument);
795cdf0e10cSrcweir 
796cdf0e10cSrcweir             if(xModel!=null)
797cdf0e10cSrcweir             {
798cdf0e10cSrcweir                 // It's a full featured office document.
799cdf0e10cSrcweir                 // Reset the modify state of it and close it.
800cdf0e10cSrcweir                 // Note: Model can disgree by throwing a veto exception.
801cdf0e10cSrcweir                 com.sun.star.util.XModifiable xModify =
802cdf0e10cSrcweir                     (com.sun.star.util.XModifiable)UnoRuntime.queryInterface(
803cdf0e10cSrcweir                         com.sun.star.util.XModifiable.class, xModel);
804cdf0e10cSrcweir 
805cdf0e10cSrcweir                 xModify.setModified(false);
806cdf0e10cSrcweir                 xDocument.dispose();
807cdf0e10cSrcweir             }
808cdf0e10cSrcweir             else
809cdf0e10cSrcweir             {
810cdf0e10cSrcweir                 // It's a document which supports a controller .. or may by a pure
811cdf0e10cSrcweir                 // window only. If it's at least a controller - we can try to
812cdf0e10cSrcweir                 // suspend him. But - he can disagree with that!
813cdf0e10cSrcweir                 com.sun.star.frame.XController xController =
814cdf0e10cSrcweir                     (com.sun.star.frame.XController)UnoRuntime.queryInterface(
815cdf0e10cSrcweir                         com.sun.star.frame.XController.class, xDocument);
816cdf0e10cSrcweir 
817cdf0e10cSrcweir                 if(xController!=null)
818cdf0e10cSrcweir                 {
819cdf0e10cSrcweir                     if(xController.suspend(true)==true)
820cdf0e10cSrcweir                     {
821cdf0e10cSrcweir                         // Note: Don't dispose the controller - destroy the frame
822cdf0e10cSrcweir                         // to make it right!
823cdf0e10cSrcweir                         com.sun.star.frame.XFrame xFrame = xController.getFrame();
824cdf0e10cSrcweir                         xFrame.dispose();
825cdf0e10cSrcweir                     }
826cdf0e10cSrcweir                 }
827cdf0e10cSrcweir             }
828cdf0e10cSrcweir         }
829cdf0e10cSrcweir         catch(com.sun.star.beans.PropertyVetoException exVeto)
830cdf0e10cSrcweir         {
831cdf0e10cSrcweir             // Can be thrown by "setModified()" call on model.
832cdf0e10cSrcweir             // He disagree with our request.
833cdf0e10cSrcweir             // But there is nothing to do then. Following "dispose()" call wasn't
834cdf0e10cSrcweir             // never called (because we catch it before). Closing failed -that's it.
835cdf0e10cSrcweir             exVeto.printStackTrace();
836cdf0e10cSrcweir         }
837cdf0e10cSrcweir         catch(com.sun.star.lang.DisposedException exDisposed)
838cdf0e10cSrcweir         {
839cdf0e10cSrcweir             // If an UNO object was already disposed before - he throw this special
840cdf0e10cSrcweir             // runtime exception. Of course every UNO call must be look for that -
841cdf0e10cSrcweir             // but it's a question of error handling.
842cdf0e10cSrcweir             // For demonstration this exception is handled here.
843cdf0e10cSrcweir             exDisposed.printStackTrace();
844cdf0e10cSrcweir         }
845cdf0e10cSrcweir         catch(com.sun.star.uno.RuntimeException exRuntime)
846cdf0e10cSrcweir         {
847cdf0e10cSrcweir             // Every uno call can throw that.
848cdf0e10cSrcweir             // Do nothing - closing failed - that's it.
849cdf0e10cSrcweir             exRuntime.printStackTrace();
850cdf0e10cSrcweir         }
851cdf0e10cSrcweir     }
852cdf0e10cSrcweir 
853cdf0e10cSrcweir     // ____________________
854cdf0e10cSrcweir 
855cdf0e10cSrcweir     /**
856cdf0e10cSrcweir      * Try to close the frame instead of the document.
857cdf0e10cSrcweir      * It shows the possible interface to do so.
858cdf0e10cSrcweir      *
859cdf0e10cSrcweir      * @param xFrame
860cdf0e10cSrcweir      *          frame which should be clcosed
861cdf0e10cSrcweir      *
862cdf0e10cSrcweir      * @return  <TRUE/> in case frame could be closed
863cdf0e10cSrcweir      *          <FALSE/> otherwise
864cdf0e10cSrcweir      */
closeFrame(com.sun.star.frame.XFrame xFrame)865cdf0e10cSrcweir     public static boolean closeFrame(com.sun.star.frame.XFrame xFrame)
866cdf0e10cSrcweir     {
867cdf0e10cSrcweir         boolean bClosed = false;
868cdf0e10cSrcweir 
869cdf0e10cSrcweir         try
870cdf0e10cSrcweir         {
871cdf0e10cSrcweir             // first try the new way: use new interface XCloseable
872cdf0e10cSrcweir             // It replace the deprecated XTask::close() and should be preferred ...
873cdf0e10cSrcweir             // if it can be queried.
874cdf0e10cSrcweir             com.sun.star.util.XCloseable xCloseable =
875cdf0e10cSrcweir                 (com.sun.star.util.XCloseable)UnoRuntime.queryInterface(
876cdf0e10cSrcweir                     com.sun.star.util.XCloseable.class, xFrame);
877cdf0e10cSrcweir             if (xCloseable!=null)
878cdf0e10cSrcweir             {
879cdf0e10cSrcweir                 // We deliver the owner ship of this frame not to the (possible)
880cdf0e10cSrcweir                 // source which throw a CloseVetoException. We whishto have it
881cdf0e10cSrcweir                 // under our own control.
882cdf0e10cSrcweir                 try
883cdf0e10cSrcweir                 {
884cdf0e10cSrcweir                     xCloseable.close(false);
885cdf0e10cSrcweir                     bClosed = true;
886cdf0e10cSrcweir                 }
887cdf0e10cSrcweir                 catch( com.sun.star.util.CloseVetoException exVeto )
888cdf0e10cSrcweir                 {
889cdf0e10cSrcweir                     bClosed = false;
890cdf0e10cSrcweir                 }
891cdf0e10cSrcweir             }
892cdf0e10cSrcweir             else
893cdf0e10cSrcweir             {
894cdf0e10cSrcweir                 // OK: the new way isn't possible. Try the old one.
895cdf0e10cSrcweir                 com.sun.star.frame.XTask xTask = (com.sun.star.frame.XTask)
896cdf0e10cSrcweir                     UnoRuntime.queryInterface(com.sun.star.frame.XTask.class,
897cdf0e10cSrcweir                                               xFrame);
898cdf0e10cSrcweir                 if (xTask!=null)
899cdf0e10cSrcweir                 {
900cdf0e10cSrcweir                     // return value doesn't interest here. Because
901cdf0e10cSrcweir                     // we forget this task ...
902cdf0e10cSrcweir                     bClosed = xTask.close();
903cdf0e10cSrcweir                 }
904cdf0e10cSrcweir             }
905cdf0e10cSrcweir         }
906cdf0e10cSrcweir         catch (com.sun.star.lang.DisposedException exDisposed)
907cdf0e10cSrcweir         {
908cdf0e10cSrcweir             // Of course - this task can be already dead - means disposed.
909cdf0e10cSrcweir             // But for us it's not important. Because we tried to close it too.
910cdf0e10cSrcweir             // And "already disposed" or "closed" should be the same ...
911cdf0e10cSrcweir             bClosed = true;
912cdf0e10cSrcweir         }
913cdf0e10cSrcweir 
914cdf0e10cSrcweir         return bClosed;
915cdf0e10cSrcweir     }
916cdf0e10cSrcweir 
917cdf0e10cSrcweir     // ____________________
918cdf0e10cSrcweir 
919cdf0e10cSrcweir     /**
920cdf0e10cSrcweir      * Try to find an unique frame name, which isn't currently used inside
921cdf0e10cSrcweir      * remote office instance. Because we create top level frames
922cdf0e10cSrcweir      * only, it's enough to check the names of existing child frames on the
923cdf0e10cSrcweir      * desktop only.
924cdf0e10cSrcweir      *
925cdf0e10cSrcweir      * @return [String]
926cdf0e10cSrcweir      *          should represent an unique frame name, which currently isn't
927cdf0e10cSrcweir      *          used inside the remote office frame tree
928cdf0e10cSrcweir      *          (Couldn't guaranteed for a real multithreaded environment.
929cdf0e10cSrcweir      *           But we try it ...)
930cdf0e10cSrcweir      */
931cdf0e10cSrcweir     private static final String BASEFRAMENAME = "Desk View ";
932cdf0e10cSrcweir 
getUniqueFrameName()933cdf0e10cSrcweir     public static String getUniqueFrameName()
934cdf0e10cSrcweir     {
935cdf0e10cSrcweir         String sName = null;
936cdf0e10cSrcweir 
937cdf0e10cSrcweir         com.sun.star.uno.XComponentContext xCtx = OfficeConnect.getOfficeContext();
938cdf0e10cSrcweir 
939cdf0e10cSrcweir         try
940cdf0e10cSrcweir         {
941cdf0e10cSrcweir             com.sun.star.frame.XFramesSupplier xSupplier =
942cdf0e10cSrcweir                 (com.sun.star.frame.XFramesSupplier)UnoRuntime.queryInterface(
943cdf0e10cSrcweir                     com.sun.star.frame.XFramesSupplier.class,
944cdf0e10cSrcweir                     xCtx.getServiceManager().createInstanceWithContext(
945cdf0e10cSrcweir                         "com.sun.star.frame.Desktop", xCtx));
946cdf0e10cSrcweir 
947cdf0e10cSrcweir             com.sun.star.container.XIndexAccess xContainer =
948cdf0e10cSrcweir                 (com.sun.star.container.XIndexAccess)UnoRuntime.queryInterface(
949cdf0e10cSrcweir                     com.sun.star.container.XIndexAccess.class,
950cdf0e10cSrcweir                     xSupplier.getFrames());
951cdf0e10cSrcweir 
952cdf0e10cSrcweir             int nCount = xContainer.getCount();
953cdf0e10cSrcweir             for (int i=0; i<nCount; ++i )
954cdf0e10cSrcweir             {
955cdf0e10cSrcweir                 com.sun.star.frame.XFrame xFrame = (com.sun.star.frame.XFrame)AnyConverter.toObject(new com.sun.star.uno.Type(com.sun.star.frame.XFrame.class), xContainer.getByIndex(i));
956cdf0e10cSrcweir                                         sName  = new String(BASEFRAMENAME+mnViewCount);
957cdf0e10cSrcweir                 while(sName.compareTo(xFrame.getName())==0)
958cdf0e10cSrcweir                 {
959cdf0e10cSrcweir                     ++mnViewCount;
960cdf0e10cSrcweir                     sName = new String(BASEFRAMENAME+mnViewCount);
961cdf0e10cSrcweir                 }
962cdf0e10cSrcweir             }
963cdf0e10cSrcweir         }
964cdf0e10cSrcweir         catch(com.sun.star.uno.Exception exCreateFailed)
965cdf0e10cSrcweir         {
966cdf0e10cSrcweir             sName = new String(BASEFRAMENAME);
967cdf0e10cSrcweir         }
968cdf0e10cSrcweir 
969cdf0e10cSrcweir         if (sName==null)
970cdf0e10cSrcweir         {
971cdf0e10cSrcweir             System.out.println("invalid name!");
972cdf0e10cSrcweir             sName = new String(BASEFRAMENAME);
973cdf0e10cSrcweir         }
974cdf0e10cSrcweir 
975cdf0e10cSrcweir         return sName;
976cdf0e10cSrcweir     }
977cdf0e10cSrcweir 
978cdf0e10cSrcweir     // ____________________
979cdf0e10cSrcweir 
980cdf0e10cSrcweir     /**
981cdf0e10cSrcweir      * helper to get a file URL selected by user
982cdf0e10cSrcweir      * This method doesn't show any API concepts ...
983cdf0e10cSrcweir      * but is neccessary rof this demo application.
984cdf0e10cSrcweir      *
985cdf0e10cSrcweir      * @param   aParent parent window of this dialog
986cdf0e10cSrcweir      * @param   bOpen   If it is set to true =>
987cdf0e10cSrcweir      *                  dialog is opend in "file open" mode -
988cdf0e10cSrcweir      *                  otherwise in "file save" mode.
989cdf0e10cSrcweir      */
askUserForFileURL(Component aParent,boolean bOpen)990cdf0e10cSrcweir     public static String askUserForFileURL(Component aParent,boolean bOpen)
991cdf0e10cSrcweir     {
992cdf0e10cSrcweir         String        sFileURL  = null;
993cdf0e10cSrcweir         int           nDecision = JFileChooser.CANCEL_OPTION;
994cdf0e10cSrcweir         JFileChooser  aChooser  = null;
995cdf0e10cSrcweir 
996cdf0e10cSrcweir         // set last visited directory on new file chosser
997cdf0e10cSrcweir         // (if this information is available)
998cdf0e10cSrcweir         if( maLastDir==null )
999cdf0e10cSrcweir             aChooser = new JFileChooser();
1000cdf0e10cSrcweir         else
1001cdf0e10cSrcweir             aChooser = new JFileChooser(maLastDir);
1002cdf0e10cSrcweir 
1003cdf0e10cSrcweir         // decide between file open/save dialog
1004cdf0e10cSrcweir         if( bOpen==true )
1005cdf0e10cSrcweir             nDecision = aChooser.showOpenDialog(aParent);
1006cdf0e10cSrcweir         else
1007cdf0e10cSrcweir             nDecision = aChooser.showSaveDialog(aParent);
1008cdf0e10cSrcweir 
1009cdf0e10cSrcweir         // react for "OK" result only
1010cdf0e10cSrcweir         if(nDecision == JFileChooser.APPROVE_OPTION)
1011cdf0e10cSrcweir         {
1012cdf0e10cSrcweir             // save current directory as last visited one
1013cdf0e10cSrcweir             maLastDir = aChooser.getCurrentDirectory();
1014cdf0e10cSrcweir             // get file URL from the dialog
1015cdf0e10cSrcweir             try
1016cdf0e10cSrcweir             {
1017cdf0e10cSrcweir                 sFileURL = aChooser.getSelectedFile().toURL().toExternalForm();
1018cdf0e10cSrcweir             }
1019cdf0e10cSrcweir             catch( MalformedURLException ex )
1020cdf0e10cSrcweir             {
1021cdf0e10cSrcweir                 ex.printStackTrace();
1022cdf0e10cSrcweir                 sFileURL = null;
1023cdf0e10cSrcweir             }
1024cdf0e10cSrcweir             // problem of java: file URL's are coded with 1 slash instead of 3 ones!
1025cdf0e10cSrcweir             // => correct this problem first, otherwise office can't use these URL's
1026cdf0e10cSrcweir             if(
1027cdf0e10cSrcweir                 ( sFileURL                      !=null  ) &&
1028cdf0e10cSrcweir                 ( sFileURL.startsWith("file:/") ==true  ) &&
1029cdf0e10cSrcweir                 ( sFileURL.startsWith("file://")==false )
1030cdf0e10cSrcweir               )
1031cdf0e10cSrcweir             {
1032cdf0e10cSrcweir                 StringBuffer sWorkBuffer = new StringBuffer(sFileURL);
1033cdf0e10cSrcweir                 sWorkBuffer.insert(6,"//");
1034cdf0e10cSrcweir                 sFileURL = sWorkBuffer.toString();
1035cdf0e10cSrcweir             }
1036cdf0e10cSrcweir         }
1037cdf0e10cSrcweir 
1038cdf0e10cSrcweir         return sFileURL;
1039cdf0e10cSrcweir     }
1040cdf0e10cSrcweir 
1041cdf0e10cSrcweir     // ____________________
1042cdf0e10cSrcweir 
1043cdf0e10cSrcweir     /**
1044cdf0e10cSrcweir      * @member  maLastDir   save the last visited directory of used file open/save dialog
1045cdf0e10cSrcweir      * @member  mnViewCount we try to set unique names on every frame we create (that's why we must count it)
1046cdf0e10cSrcweir      */
1047cdf0e10cSrcweir     private static File maLastDir   = null;
1048cdf0e10cSrcweir     private static int  mnViewCount = 0   ;
1049cdf0e10cSrcweir }
1050