1 /*************************************************************************
3 * $RCSfile: FunctionHelper.java,v $
7 * last change: $Author: kz $ $Date: 2005-03-01 12:09:15 $
9 * The Contents of this file are made available subject to the terms of
12 * Copyright (c) 2003 by Sun Microsystems, Inc.
13 * All rights reserved.
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 * 3. Neither the name of Sun Microsystems, Inc. nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
30 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
31 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
32 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
33 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
34 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
35 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
36 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
37 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *************************************************************************/
41 // __________ Imports __________
43 import com
.sun
.star
.uno
.UnoRuntime
;
44 import com
.sun
.star
.uno
.AnyConverter
;
52 // __________ Implementation __________
55 * Is a collection of basic features.
56 * This helper shows different functionality of framework api
57 * in an example manner. You can use the follow ones:
59 * (2) create frames (inside/outside a java application)
60 * (3) dispatches (with[out] notifications)
61 * (4) loading/saving documents
62 * (5) convert documents to HTML (if possible)
63 * (6) close documents (and her frames) correctly
65 * There exist some other helper functionality too, which
66 * doesn't use or demonstrate the office api:
67 * (a) getting file names by using a file chosser
69 * @author Andreas Schlüns
70 * @created 28.02.2002 15:31
72 public class FunctionHelper
74 // ____________________
77 * This convert an URL (formated as a string) to a struct com.sun.star.util.URL.
78 * It use a special service to do that: the URLTransformer.
79 * Because some API calls need it and it's not allowed to set "Complete"
80 * part of the util struct only. The URL must be parsed.
83 * URL for parsing in string notation
85 * @return [com.sun.star.util.URL]
86 * URL in UNO struct notation
88 public static com
.sun
.star
.util
.URL
parseURL(String sURL
)
90 com
.sun
.star
.util
.URL aURL
= null;
92 if (sURL
==null || sURL
.equals(""))
94 System
.out
.println("wrong using of URL parser");
100 com
.sun
.star
.uno
.XComponentContext xOfficeCtx
=
101 OfficeConnect
.getOfficeContext();
103 // Create special service for parsing of given URL.
104 com
.sun
.star
.util
.XURLTransformer xParser
=
105 (com
.sun
.star
.util
.XURLTransformer
)UnoRuntime
.queryInterface(
106 com
.sun
.star
.util
.XURLTransformer
.class,
107 xOfficeCtx
.getServiceManager().createInstanceWithContext(
108 "com.sun.star.util.URLTransformer", xOfficeCtx
));
110 // Because it's an in/out parameter we must use an array of URL objects.
111 com
.sun
.star
.util
.URL
[] aParseURL
= new com
.sun
.star
.util
.URL
[1];
112 aParseURL
[0] = new com
.sun
.star
.util
.URL();
113 aParseURL
[0].Complete
= sURL
;
116 xParser
.parseStrict(aParseURL
);
120 catch(com
.sun
.star
.uno
.RuntimeException exRuntime
)
122 // Any UNO method of this scope can throw this exception.
123 // Reset the return value only.
126 catch(com
.sun
.star
.uno
.Exception exUno
)
128 // "createInstance()" method of used service manager can throw it.
129 // Then it wasn't possible to get the URL transformer.
130 // Return default instead of realy parsed URL.
137 // ____________________
140 * create a new empty target frame
141 * Attention: Currently we must use special service com.sun.star.frame.Task instead of Frame.
142 * Because desktop environment accept this special frame type only as direct children.
143 * Note - This service will be deprecated and must be replaces by com.sun.star.frame.Frame in
144 * further versions. To feature prove we use both service names. If for new versions
145 * the deprecated one not exist we get an empty frame, we can try to use the new service.
148 * we nee the remote service manager to create this task/frame service
150 * @return [com.sun.star.frame.XFrame]
151 * the new created frame reference in case of success or null otherwhise
153 private static com
.sun
.star
.frame
.XFrame
impl_createEmptyFrame(
154 com
.sun
.star
.uno
.XComponentContext xCtx
)
156 com
.sun
.star
.frame
.XFrame xFrame
= null;
159 xFrame
= (com
.sun
.star
.frame
.XFrame
)UnoRuntime
.queryInterface(
160 com
.sun
.star
.frame
.XFrame
.class,
161 xCtx
.getServiceManager().createInstanceWithContext(
162 "com.sun.star.frame.Task", xCtx
));
163 } catch(com
.sun
.star
.uno
.Exception ex1
) {}
168 xFrame
= (com
.sun
.star
.frame
.XFrame
)UnoRuntime
.queryInterface(
169 com
.sun
.star
.frame
.XFrame
.class,
170 xCtx
.getServiceManager().createInstanceWithContext(
171 "com.sun.star.frame.Frame", xCtx
));
172 } catch(com
.sun
.star
.uno
.Exception ex2
) {}
178 // ____________________
181 * create a new window which can be used as container window of an office frame
182 * We know two modes for creation:
183 * - the office window will be a child of one of our java windows
184 * - the office will be a normal system window outside this java application
185 * This behaviour will be regulated by the second parameter of this operation.
186 * If a parentview is given the first mode will be activated - otherwhise
189 * Note: First mode (creation of a child window) can be reached by two different
191 * - pack the required window handle of our java window inside an UNO object
192 * to transport it to the remote office toolkit and get a child office
194 * This is the old way. It's better to use the second one - but to be
195 * future prove this old one should be tried too.
196 * - it's possible to pass the native window handle directly to the toolkit.
197 * A special interface method was enabled to accept that.
199 * The right way to create an office window should be then:
200 * - try to use second creation mode (directly using of the window handle)
201 * - if it failed ... use the old way by packing the handle inside an object
204 * we need a service manager to be able to create remote office
208 * the java window as parent for the office window if an inplace office
209 * is required. If it is set to null the created office window will be
210 * a normal system window outside of our java application.
212 * @return [com.sun.star.awt.XWindow]
213 * The new created office window which can be used to set it as
214 * a ContainerWindow on an empty office frame.
216 private static com
.sun
.star
.awt
.XWindow
impl_createWindow(
217 com
.sun
.star
.uno
.XComponentContext xCtx
, NativeView aParentView
)
219 com
.sun
.star
.awt
.XWindow xWindow
= null;
220 com
.sun
.star
.awt
.XWindowPeer xPeer
= null;
221 com
.sun
.star
.awt
.XToolkit xToolkit
= null;
223 // get access to toolkit of remote office to create the container window of
226 xToolkit
= (com
.sun
.star
.awt
.XToolkit
)UnoRuntime
.queryInterface(
227 com
.sun
.star
.awt
.XToolkit
.class,
228 xCtx
.getServiceManager().createInstanceWithContext(
229 "com.sun.star.awt.Toolkit", xCtx
));
231 catch(com
.sun
.star
.uno
.Exception ex
)
236 // mode 1) create an external system window
237 if (aParentView
==null)
239 // Describe the properties of the container window.
240 com
.sun
.star
.awt
.WindowDescriptor aDescriptor
=
241 new com
.sun
.star
.awt
.WindowDescriptor();
242 aDescriptor
.Type
= com
.sun
.star
.awt
.WindowClass
.TOP
;
243 aDescriptor
.WindowServiceName
= "window";
244 aDescriptor
.ParentIndex
= -1;
245 aDescriptor
.Parent
= null;
246 aDescriptor
.Bounds
= new com
.sun
.star
.awt
.Rectangle(0,0,0,0);
247 aDescriptor
.WindowAttributes
= com
.sun
.star
.awt
.WindowAttribute
.BORDER
|
248 com
.sun
.star
.awt
.WindowAttribute
.MOVEABLE
|
249 com
.sun
.star
.awt
.WindowAttribute
.SIZEABLE
|
250 com
.sun
.star
.awt
.WindowAttribute
.CLOSEABLE
;
253 xPeer
= xToolkit
.createWindow( aDescriptor
);
254 } catch(com
.sun
.star
.lang
.IllegalArgumentException exIllegal
) {}
256 // mode 2) create an internal office window as child of our given java
260 // try new version of creation first: directly using of the window
261 // handle. The old implementation of the corresponding toolkit method
262 // requires a process ID. If this id isn't the right one a null object
263 // is returned. But normaly nobody outside the office knows this id.
264 // New version of this method ignore the id parameter and creation will
266 // Note: You must be shure if your window handle can be realy used by
267 // the remote office. Means if this java client and the remote office
268 // use the same display!
269 com
.sun
.star
.awt
.XSystemChildFactory xChildFactory
=
270 (com
.sun
.star
.awt
.XSystemChildFactory
)UnoRuntime
.queryInterface(
271 com
.sun
.star
.awt
.XSystemChildFactory
.class, xToolkit
);
275 Integer nHandle
= aParentView
.getHWND();
276 short nSystem
= (short)aParentView
.getNativeWindowSystemType();
277 byte[] lProcID
= new byte[0];
279 xPeer
= xChildFactory
.createSystemChild((Object
)nHandle
,
284 // mode 3) OK - new version doesn't work. It requires the
285 // process id which we doesn't have.
286 // So we must use the old way to get the right window peer.
287 // Pack the handle inside a wrapper object.
288 JavaWindowPeerFake aWrapper
= new
289 JavaWindowPeerFake(aParentView
);
291 com
.sun
.star
.awt
.XWindowPeer xParentPeer
=
292 (com
.sun
.star
.awt
.XWindowPeer
)UnoRuntime
.queryInterface(
293 com
.sun
.star
.awt
.XWindowPeer
.class, aWrapper
);
295 com
.sun
.star
.awt
.WindowDescriptor aDescriptor
=
296 new com
.sun
.star
.awt
.WindowDescriptor();
297 aDescriptor
.Type
= com
.sun
.star
.awt
.WindowClass
.TOP
;
298 aDescriptor
.WindowServiceName
= "workwindow";
299 aDescriptor
.ParentIndex
= 1;
300 aDescriptor
.Parent
= xParentPeer
;
301 aDescriptor
.Bounds
= new com
.sun
.star
.awt
.Rectangle(0,0,0,0);
302 if (nSystem
== com
.sun
.star
.lang
.SystemDependent
.SYSTEM_WIN32
)
303 aDescriptor
.WindowAttributes
=
304 com
.sun
.star
.awt
.WindowAttribute
.SHOW
;
306 aDescriptor
.WindowAttributes
=
307 com
.sun
.star
.awt
.WindowAttribute
.SYSTEMDEPENDENT
;
310 xPeer
= xToolkit
.createWindow( aDescriptor
);
311 } catch(com
.sun
.star
.lang
.IllegalArgumentException exIllegal
) {}
314 catch(java
.lang
.RuntimeException exJRun
)
316 // This exception is thrown by the native JNI code if it try to get
317 // the systemw window handle. A possible reason can be an invisible
318 // java window. In this case it should be enough to set return
319 // values to null. All other ressources (which was created before)
320 // will be freed automaticly if scope wil be leaved.
321 System
.out
.println("May be the NativeView object wasn't realy visible at calling time of getNativeWindow()?");
327 // It doesn't matter which way was used to get the window peer.
328 // Cast it to the right return interface and return it.
329 xWindow
= (com
.sun
.star
.awt
.XWindow
)UnoRuntime
.queryInterface(
330 com
.sun
.star
.awt
.XWindow
.class,
336 // ____________________
339 * This method create a new empty child frame on desktop instance of remote office.
340 * It use a special JNI functionality to pass the office XWindow over a java window.
341 * This java window can be inserted into another java window container for complex layouting.
342 * If this parent java window isn't used, a top level system window will be created.
343 * The the resulting office frame isn't plugged into this java application.
346 * name to set it on the new created frame
349 * java window which should be used as parent window of new created office frame window
350 * May be set to null.
352 * @return [com.sun.star.frame.XFrame]
353 * reference to the new created frame for success or null if it failed
355 public static com
.sun
.star
.frame
.XFrame
createViewFrame(String sName
, NativeView aParentView
)
357 com
.sun
.star
.frame
.XFrame xFrame
= null;
361 com
.sun
.star
.uno
.XComponentContext xCtx
=
362 OfficeConnect
.getOfficeContext();
364 // create an empty office frame first
365 xFrame
= impl_createEmptyFrame(xCtx
);
367 // create an office window then
368 // Depending from the given parameter aParentView it will be a child or a top level
369 // system window. (see impl method for further informations)
370 // But before we call this helper - prepare the possible parent window: show it.
371 // JNI calls to get system window handle of java window can't work without that!
372 if (aParentView
!=null)
373 aParentView
.setVisible(true);
374 com
.sun
.star
.awt
.XWindow xWindow
= impl_createWindow(xCtx
, aParentView
);
376 // pass the window the frame as his new container window.
377 // It's neccessary to do it first - before you call anything else there.
378 // Otherwhise the frame throws some exceptions for "uninitialized state".
379 xFrame
.initialize( xWindow
);
381 // Insert the new frame in desktop hierarchy.
382 // Use XFrames interface to do so. It provides access to the child frame container of that instance.
383 com
.sun
.star
.frame
.XFramesSupplier xTreeRoot
= (com
.sun
.star
.frame
.XFramesSupplier
)UnoRuntime
.queryInterface(
384 com
.sun
.star
.frame
.XFramesSupplier
.class,
385 xCtx
.getServiceManager().createInstanceWithContext(
386 "com.sun.star.frame.Desktop", xCtx
));
387 com
.sun
.star
.frame
.XFrames xChildContainer
= xTreeRoot
.getFrames();
388 xChildContainer
.append(xFrame
);
390 // Make some further initializations on frame and window.
391 xWindow
.setVisible(true);
392 xFrame
.setName(sName
);
394 catch(com
.sun
.star
.uno
.RuntimeException exRuntime
)
396 // Any UNO method of this scope can throw this exception.
397 // So the frame can be already created and he must be freed
398 // correctly. May be he was inserted into the desktop tree too ...
401 // Try to dispose the frame. He should deregister himself at the desktop object
402 // and free all internal used ressources (e.g. the container window) automaticly.
403 // It's possible to do that here - because frame has no component inside yet.
404 // So nobody can disagree with that.
405 // After the dispose() call forget all references to this frame and let him die.
406 // If a new exception will occure ... no generell solution exist then.
407 // Nobody can guarantee if next call will work or not.
408 com
.sun
.star
.lang
.XComponent xComponent
= (com
.sun
.star
.lang
.XComponent
)UnoRuntime
.queryInterface(
409 com
.sun
.star
.lang
.XComponent
.class,
411 xComponent
.dispose();
416 catch(com
.sun
.star
.uno
.Exception exUno
)
418 // "createInstance()" method of used service manager can throw it.
419 // If it occured during creation of desktop service the frame already was created.
420 // Free it by decresing his refcount. Changes on the desktop tree couldn't exist.
421 // Without the desktop service that wasn't possible. So no further rollbacks must follow.
424 com
.sun
.star
.lang
.XComponent xComponent
= (com
.sun
.star
.lang
.XComponent
)UnoRuntime
.queryInterface(
425 com
.sun
.star
.lang
.XComponent
.class,
427 xComponent
.dispose();
436 // ____________________
439 * Dispatch an URL to given frame.
440 * Caller can register himself for following status events for dispatched
441 * URL too. But nobody guarantee that such notifications will occure.
442 * (see dispatchWithNotification() if you interest on that)
443 * The returned dispatch object should be hold alive by caller
444 * till he deosn't need it any longer. Otherwise the dispatcher can(!)
445 * die by decreasing his refcount.
447 * @param xFrame frame wich should be the target of this dispatch
448 * @param aURL full parsed and converted office URL for dispatch
449 * @param lProperties optional arguments for dispatch
450 * @param xListener optional listener which is registered automaticly for status events
451 * (Note: Deregistration is part of this listener himself!)
453 * @return [XDispatch] It's the used dispatch object and can be used for deregistration of an optional listener.
454 * Otherwhise caller can ignore it.
456 public static com
.sun
.star
.frame
.XDispatch
execute(com
.sun
.star
.frame
.XFrame xFrame
,
457 com
.sun
.star
.util
.URL aURL
,
458 com
.sun
.star
.beans
.PropertyValue
[] lProperties
,
459 com
.sun
.star
.frame
.XStatusListener xListener
)
461 com
.sun
.star
.frame
.XDispatch xDispatcher
= null;
465 // Query the frame for right interface which provides access to all available dispatch objects.
466 com
.sun
.star
.frame
.XDispatchProvider xProvider
= (com
.sun
.star
.frame
.XDispatchProvider
)UnoRuntime
.queryInterface(
467 com
.sun
.star
.frame
.XDispatchProvider
.class,
470 // Ask himn for right dispatch object for given URL.
471 // Force given frame as target for following dispatch by using "".
472 // It means the same like "_self".
473 xDispatcher
= xProvider
.queryDispatch(aURL
,"",0);
475 // Dispatch the URL into the frame.
476 if(xDispatcher
!=null)
479 xDispatcher
.addStatusListener(xListener
,aURL
);
481 xDispatcher
.dispatch(aURL
,lProperties
);
484 catch(com
.sun
.star
.uno
.RuntimeException exUno
)
486 // Any UNO method of this scope can throw this exception.
487 // But there will be nothing to do then - because
488 // we haven't changed anything inside the remote objects
489 // except method "addStatusListener().
490 // But in this case the source of this exception has to
491 // rollback all his operations. There is no chance to
492 // make anything right then.
493 // Reset the return value to a default - that's it.
494 exUno
.printStackTrace();
501 // ____________________
504 * Dispatch an URL to given frame.
505 * Caller can register himself for following result events for dispatched
506 * URL too. Notifications are guaranteed (instead of dispatch())
507 * Returning of the dispatch object isn't neccessary.
508 * Nobody must hold it alive longer the dispatch needs.
510 * @param xFrame frame wich should be the target of this dispatch
511 * @param aURL full parsed and converted office URL for dispatch
512 * @param lProperties optional arguments for dispatch
513 * @param xListener optional listener which is registered automaticly for status events
514 * (Note: Deregistration is not supported. Dispatcher does it automaticly.)
516 public static void executeWithNotification(com
.sun
.star
.frame
.XFrame xFrame
,
517 com
.sun
.star
.util
.URL aURL
,
518 com
.sun
.star
.beans
.PropertyValue
[] lProperties
,
519 com
.sun
.star
.frame
.XDispatchResultListener xListener
)
523 // Query the frame for right interface which provides access to all available dispatch objects.
524 com
.sun
.star
.frame
.XDispatchProvider xProvider
= (com
.sun
.star
.frame
.XDispatchProvider
)UnoRuntime
.queryInterface(
525 com
.sun
.star
.frame
.XDispatchProvider
.class,
528 // Ask himn for right dispatch object for given URL.
529 // Force THIS frame as target for following dispatch.
530 // Attention: The interface XNotifyingDispatch is an optional one!
531 com
.sun
.star
.frame
.XDispatch xDispatcher
= xProvider
.queryDispatch(aURL
,"",0);
532 com
.sun
.star
.frame
.XNotifyingDispatch xNotifyingDispatcher
= (com
.sun
.star
.frame
.XNotifyingDispatch
)UnoRuntime
.queryInterface(
533 com
.sun
.star
.frame
.XNotifyingDispatch
.class,
537 if(xNotifyingDispatcher
!=null)
538 xNotifyingDispatcher
.dispatchWithNotification(aURL
,lProperties
,xListener
);
540 catch(com
.sun
.star
.uno
.RuntimeException exUno
)
542 // Any UNO method of this scope can throw this exception.
543 // But there is nothing we can do then.
544 exUno
.printStackTrace();
548 // ____________________
551 * Load document specified by an URL into given frame synchronously.
552 * The result of this operation will be the loaded document for success
553 * or null if loading failed.
555 * @param xFrame frame wich should be the target of this load call
556 * @param sURL unparsed URL for loading
557 * @param lProperties optional arguments
559 * @return [XComponent] the loaded document for success or null if it's failed
561 public static com
.sun
.star
.lang
.XComponent
loadDocument(
562 com
.sun
.star
.frame
.XFrame xFrame
, String sURL
,
563 com
.sun
.star
.beans
.PropertyValue
[] lProperties
)
565 com
.sun
.star
.lang
.XComponent xDocument
= null;
566 String sOldName
= null;
570 com
.sun
.star
.uno
.XComponentContext xCtx
=
571 OfficeConnect
.getOfficeContext();
573 // First prepare frame for loading
574 // We must adress it inside the frame tree without any complications.
575 // So we set an unambigous (we hope it) name and use it later.
576 // Don't forget to reset original name after that.
577 sOldName
= xFrame
.getName();
578 String sTarget
= "odk_officedev_desk";
579 xFrame
.setName(sTarget
);
581 // Get access to the global component loader of the office
582 // for synchronous loading the document.
583 com
.sun
.star
.frame
.XComponentLoader xLoader
=
584 (com
.sun
.star
.frame
.XComponentLoader
)UnoRuntime
.queryInterface(
585 com
.sun
.star
.frame
.XComponentLoader
.class,
586 xCtx
.getServiceManager().createInstanceWithContext(
587 "com.sun.star.frame.Desktop", xCtx
));
589 // Load the document into the target frame by using his name and
590 // special search flags.
591 xDocument
= xLoader
.loadComponentFromURL(
594 com
.sun
.star
.frame
.FrameSearchFlag
.CHILDREN
,
597 // dont forget to restore old frame name ...
598 xFrame
.setName(sOldName
);
600 catch(com
.sun
.star
.io
.IOException exIO
)
602 // Can be thrown by "loadComponentFromURL()" call.
603 // The only thing we should do then is to reset changed frame name!
604 exIO
.printStackTrace();
607 xFrame
.setName(sOldName
);
609 catch(com
.sun
.star
.lang
.IllegalArgumentException exIllegal
)
611 // Can be thrown by "loadComponentFromURL()" call.
612 // The only thing we should do then is to reset changed frame name!
613 exIllegal
.printStackTrace();
616 xFrame
.setName(sOldName
);
618 catch(com
.sun
.star
.uno
.RuntimeException exRuntime
)
620 // Any UNO method of this scope can throw this exception.
621 // The only thing we can try(!) is to reset changed frame name.
622 exRuntime
.printStackTrace();
625 xFrame
.setName(sOldName
);
627 catch(com
.sun
.star
.uno
.Exception exUno
)
629 // "createInstance()" method of used service manager can throw it.
630 // The only thing we should do then is to reset changed frame name!
631 exUno
.printStackTrace();
634 xFrame
.setName(sOldName
);
640 // ____________________
643 * Save currently loaded document of given frame.
645 * @param xDocument document for saving changes
647 public static void saveDocument(com
.sun
.star
.lang
.XComponent xDocument
)
651 // Check for supported model functionality.
652 // Normaly the application documents (text, spreadsheet ...) do so
653 // but some other ones (e.g. db components) doesn't do that.
654 // They can't be save then.
655 com
.sun
.star
.frame
.XModel xModel
= (com
.sun
.star
.frame
.XModel
)UnoRuntime
.queryInterface(
656 com
.sun
.star
.frame
.XModel
.class,
660 // Check for modifications => break save process if there is nothing to do.
661 com
.sun
.star
.util
.XModifiable xModified
= (com
.sun
.star
.util
.XModifiable
)UnoRuntime
.queryInterface(
662 com
.sun
.star
.util
.XModifiable
.class,
664 if(xModified
.isModified()==true)
666 com
.sun
.star
.frame
.XStorable xStore
= (com
.sun
.star
.frame
.XStorable
)UnoRuntime
.queryInterface(
667 com
.sun
.star
.frame
.XStorable
.class,
674 catch(com
.sun
.star
.io
.IOException exIO
)
676 // Can be thrown by "store()" call.
677 // But there is nothing we can do then.
678 exIO
.printStackTrace();
680 catch(com
.sun
.star
.uno
.RuntimeException exUno
)
682 // Any UNO method of this scope can throw this exception.
683 // But there is nothing we can do then.
684 exUno
.printStackTrace();
688 // ____________________
691 * It try to export given document in HTML format.
692 * Current document will be converted to HTML and moved to new place on disk.
693 * A "new" file will be created by given URL (may be overwritten
694 * if it already exist). Right filter will be used automaticly if factory of
695 * this document support it. If no valid filter can be found for export,
696 * nothing will be done here.
698 * @param xDocument document which should be exported
699 * @param sURL target URL for converted document
701 public static void saveAsHTML(com
.sun
.star
.lang
.XComponent xDocument
,
706 // First detect factory of this document.
707 // Ask for the supported service name of this document.
708 // If information is available it can be used to find out wich
709 // filter exist for HTML export. Normaly this filter should be searched
710 // inside the filter configuration but this little demo doesn't do so.
711 // (see service com.sun.star.document.FilterFactory for further
713 // Well known filter names are used directly. They must exist in current
714 // office installation. Otherwise this code will fail. But to prevent
715 // this code against missing filters it check for existing state of it.
716 com
.sun
.star
.lang
.XServiceInfo xInfo
= (com
.sun
.star
.lang
.XServiceInfo
)
717 UnoRuntime
.queryInterface(com
.sun
.star
.lang
.XServiceInfo
.class,
722 // Find out possible filter name.
723 String sFilter
= null;
724 if(xInfo
.supportsService("com.sun.star.text.TextDocument")==true)
725 sFilter
= new String("HTML (StarWriter)");
727 if(xInfo
.supportsService("com.sun.star.text.WebDocument")==true)
728 sFilter
= new String("HTML");
730 if(xInfo
.supportsService("com.sun.star.sheet.SpreadsheetDocument")==true)
731 sFilter
= new String("HTML (StarCalc)");
733 // Check for existing state of this filter.
736 com
.sun
.star
.uno
.XComponentContext xCtx
=
737 OfficeConnect
.getOfficeContext();
739 com
.sun
.star
.container
.XNameAccess xFilterContainer
=
740 (com
.sun
.star
.container
.XNameAccess
)
741 UnoRuntime
.queryInterface(
742 com
.sun
.star
.container
.XNameAccess
.class,
743 xCtx
.getServiceManager().createInstanceWithContext(
744 "com.sun.star.document.FilterFactory", xCtx
));
746 if(xFilterContainer
.hasByName(sFilter
)==false)
750 // Use this filter for export.
753 // Export can be forced by saving the document and using a
754 // special filter name which can write needed format. Build
755 // neccessary argument list now.
756 // Use special flag "Overwrite" too, to prevent operation
757 // against possible exceptions, if file already exist.
758 com
.sun
.star
.beans
.PropertyValue
[] lProperties
=
759 new com
.sun
.star
.beans
.PropertyValue
[2];
760 lProperties
[0] = new com
.sun
.star
.beans
.PropertyValue();
761 lProperties
[0].Name
= "FilterName";
762 lProperties
[0].Value
= sFilter
;
763 lProperties
[1] = new com
.sun
.star
.beans
.PropertyValue();
764 lProperties
[1].Name
= "Overwrite";
765 lProperties
[1].Value
= Boolean
.TRUE
;
767 com
.sun
.star
.frame
.XStorable xStore
=
768 (com
.sun
.star
.frame
.XStorable
)UnoRuntime
.queryInterface(
769 com
.sun
.star
.frame
.XStorable
.class, xDocument
);
771 xStore
.storeAsURL(sURL
,lProperties
);
775 catch(com
.sun
.star
.io
.IOException exIO
)
777 // Can be thrown by "store()" call.
778 // Do nothing then. Saving failed - that's it.
779 exIO
.printStackTrace();
781 catch(com
.sun
.star
.uno
.RuntimeException exRuntime
)
783 // Can be thrown by any uno call.
784 // Do nothing here. Saving failed - that's it.
785 exRuntime
.printStackTrace();
787 catch(com
.sun
.star
.uno
.Exception exUno
)
789 // Can be thrown by "createInstance()" call of service manager.
790 // Do nothing here. Saving failed - that's it.
791 exUno
.printStackTrace();
795 // ____________________
798 * Try to close the document without any saving of modifications.
799 * We can try it only! Controller and/or model of this document
800 * can disagree with that. But mostly they doesn't do so.
802 * @param xDocument document which should be clcosed
804 public static void closeDocument(com
.sun
.star
.lang
.XComponent xDocument
)
808 // Check supported functionality of the document (model or controller).
809 com
.sun
.star
.frame
.XModel xModel
=
810 (com
.sun
.star
.frame
.XModel
)UnoRuntime
.queryInterface(
811 com
.sun
.star
.frame
.XModel
.class, xDocument
);
815 // It's a full featured office document.
816 // Reset the modify state of it and close it.
817 // Note: Model can disgree by throwing a veto exception.
818 com
.sun
.star
.util
.XModifiable xModify
=
819 (com
.sun
.star
.util
.XModifiable
)UnoRuntime
.queryInterface(
820 com
.sun
.star
.util
.XModifiable
.class, xModel
);
822 xModify
.setModified(false);
827 // It's a document which supports a controller .. or may by a pure
828 // window only. If it's at least a controller - we can try to
829 // suspend him. But - he can disagree with that!
830 com
.sun
.star
.frame
.XController xController
=
831 (com
.sun
.star
.frame
.XController
)UnoRuntime
.queryInterface(
832 com
.sun
.star
.frame
.XController
.class, xDocument
);
834 if(xController
!=null)
836 if(xController
.suspend(true)==true)
838 // Note: Don't dispose the controller - destroy the frame
840 com
.sun
.star
.frame
.XFrame xFrame
= xController
.getFrame();
846 catch(com
.sun
.star
.beans
.PropertyVetoException exVeto
)
848 // Can be thrown by "setModified()" call on model.
849 // He disagree with our request.
850 // But there is nothing to do then. Following "dispose()" call wasn't
851 // never called (because we catch it before). Closing failed -that's it.
852 exVeto
.printStackTrace();
854 catch(com
.sun
.star
.lang
.DisposedException exDisposed
)
856 // If an UNO object was already disposed before - he throw this special
857 // runtime exception. Of course every UNO call must be look for that -
858 // but it's a question of error handling.
859 // For demonstration this exception is handled here.
860 exDisposed
.printStackTrace();
862 catch(com
.sun
.star
.uno
.RuntimeException exRuntime
)
864 // Every uno call can throw that.
865 // Do nothing - closing failed - that's it.
866 exRuntime
.printStackTrace();
870 // ____________________
873 * Try to close the frame instead of the document.
874 * It shows the possible interface to do so.
877 * frame which should be clcosed
879 * @return <TRUE/> in case frame could be closed
882 public static boolean closeFrame(com
.sun
.star
.frame
.XFrame xFrame
)
884 boolean bClosed
= false;
888 // first try the new way: use new interface XCloseable
889 // It replace the deprecated XTask::close() and should be preferred ...
890 // if it can be queried.
891 com
.sun
.star
.util
.XCloseable xCloseable
=
892 (com
.sun
.star
.util
.XCloseable
)UnoRuntime
.queryInterface(
893 com
.sun
.star
.util
.XCloseable
.class, xFrame
);
894 if (xCloseable
!=null)
896 // We deliver the owner ship of this frame not to the (possible)
897 // source which throw a CloseVetoException. We whishto have it
898 // under our own control.
901 xCloseable
.close(false);
904 catch( com
.sun
.star
.util
.CloseVetoException exVeto
)
911 // OK: the new way isn't possible. Try the old one.
912 com
.sun
.star
.frame
.XTask xTask
= (com
.sun
.star
.frame
.XTask
)
913 UnoRuntime
.queryInterface(com
.sun
.star
.frame
.XTask
.class,
917 // return value doesn't interest here. Because
918 // we forget this task ...
919 bClosed
= xTask
.close();
923 catch (com
.sun
.star
.lang
.DisposedException exDisposed
)
925 // Of course - this task can be already dead - means disposed.
926 // But for us it's not important. Because we tried to close it too.
927 // And "already disposed" or "closed" should be the same ...
934 // ____________________
937 * Try to find an unique frame name, which isn't currently used inside
938 * remote office instance. Because we create top level frames
939 * only, it's enough to check the names of existing child frames on the
943 * should represent an unique frame name, which currently isn't
944 * used inside the remote office frame tree
945 * (Couldn't guaranteed for a real multithreaded environment.
948 private static final String BASEFRAMENAME
= "Desk View ";
950 public static String
getUniqueFrameName()
954 com
.sun
.star
.uno
.XComponentContext xCtx
= OfficeConnect
.getOfficeContext();
958 com
.sun
.star
.frame
.XFramesSupplier xSupplier
=
959 (com
.sun
.star
.frame
.XFramesSupplier
)UnoRuntime
.queryInterface(
960 com
.sun
.star
.frame
.XFramesSupplier
.class,
961 xCtx
.getServiceManager().createInstanceWithContext(
962 "com.sun.star.frame.Desktop", xCtx
));
964 com
.sun
.star
.container
.XIndexAccess xContainer
=
965 (com
.sun
.star
.container
.XIndexAccess
)UnoRuntime
.queryInterface(
966 com
.sun
.star
.container
.XIndexAccess
.class,
967 xSupplier
.getFrames());
969 int nCount
= xContainer
.getCount();
970 for (int i
=0; i
<nCount
; ++i
)
972 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
));
973 sName
= new String(BASEFRAMENAME
+mnViewCount
);
974 while(sName
.compareTo(xFrame
.getName())==0)
977 sName
= new String(BASEFRAMENAME
+mnViewCount
);
981 catch(com
.sun
.star
.uno
.Exception exCreateFailed
)
983 sName
= new String(BASEFRAMENAME
);
988 System
.out
.println("invalid name!");
989 sName
= new String(BASEFRAMENAME
);
995 // ____________________
998 * helper to get a file URL selected by user
999 * This method doesn't show any API concepts ...
1000 * but is neccessary rof this demo application.
1002 * @param aParent parent window of this dialog
1003 * @param bOpen If it is set to true =>
1004 * dialog is opend in "file open" mode -
1005 * otherwise in "file save" mode.
1007 public static String
askUserForFileURL(Component aParent
,boolean bOpen
)
1009 String sFileURL
= null;
1010 int nDecision
= JFileChooser
.CANCEL_OPTION
;
1011 JFileChooser aChooser
= null;
1013 // set last visited directory on new file chosser
1014 // (if this information is available)
1015 if( maLastDir
==null )
1016 aChooser
= new JFileChooser();
1018 aChooser
= new JFileChooser(maLastDir
);
1020 // decide between file open/save dialog
1022 nDecision
= aChooser
.showOpenDialog(aParent
);
1024 nDecision
= aChooser
.showSaveDialog(aParent
);
1026 // react for "OK" result only
1027 if(nDecision
== JFileChooser
.APPROVE_OPTION
)
1029 // save current directory as last visited one
1030 maLastDir
= aChooser
.getCurrentDirectory();
1031 // get file URL from the dialog
1034 sFileURL
= aChooser
.getSelectedFile().toURL().toExternalForm();
1036 catch( MalformedURLException ex
)
1038 ex
.printStackTrace();
1041 // problem of java: file URL's are coded with 1 slash instead of 3 ones!
1042 // => correct this problem first, otherwise office can't use these URL's
1044 ( sFileURL
!=null ) &&
1045 ( sFileURL
.startsWith("file:/") ==true ) &&
1046 ( sFileURL
.startsWith("file://")==false )
1049 StringBuffer sWorkBuffer
= new StringBuffer(sFileURL
);
1050 sWorkBuffer
.insert(6,"//");
1051 sFileURL
= sWorkBuffer
.toString();
1058 // ____________________
1061 * @member maLastDir save the last visited directory of used file open/save dialog
1062 * @member mnViewCount we try to set unique names on every frame we create (that's why we must count it)
1064 private static File maLastDir
= null;
1065 private static int mnViewCount
= 0 ;