1 /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * The Contents of this file are made available subject to the terms of
7 * Copyright 2000, 2010 Oracle and/or its affiliates.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of Sun Microsystems, Inc. nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
29 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
31 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
32 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 *************************************************************************/
36 // __________ Imports __________
38 import com
.sun
.star
.uno
.UnoRuntime
;
39 import com
.sun
.star
.uno
.AnyConverter
;
46 // __________ Implementation __________
49 * Is a collection of basic features.
50 * This helper shows different functionality of framework api
51 * in an example manner. You can use the follow ones:
53 * (2) create frames (inside/outside a java application)
54 * (3) dispatches (with[out] notifications)
55 * (4) loading/saving documents
56 * (5) convert documents to HTML (if possible)
57 * (6) close documents (and her frames) correctly
59 * There exist some other helper functionality too, which
60 * doesn't use or demonstrate the office api:
61 * (a) getting file names by using a file chosser
63 public class FunctionHelper
68 * This convert a URL (formatted as a string) to a struct com.sun.star.util.URL.
69 * It use a special service to do that: the URLTransformer.
70 * Because some API calls need it and it's not allowed to set "Complete"
71 * part of the util struct only. The URL must be parsed.
74 * URL for parsing in string notation
76 * @return [com.sun.star.util.URL]
77 * URL in UNO struct notation
79 public static com
.sun
.star
.util
.URL
parseURL(String sURL
)
81 com
.sun
.star
.util
.URL aURL
= null;
83 if (sURL
==null || sURL
.equals(""))
85 System
.out
.println("wrong using of URL parser");
91 com
.sun
.star
.uno
.XComponentContext xOfficeCtx
=
92 OfficeConnect
.getOfficeContext();
94 // Create special service for parsing of given URL.
95 com
.sun
.star
.util
.XURLTransformer xParser
=
96 UnoRuntime
.queryInterface(
97 com
.sun
.star
.util
.XURLTransformer
.class,
98 xOfficeCtx
.getServiceManager().createInstanceWithContext(
99 "com.sun.star.util.URLTransformer", xOfficeCtx
));
101 // Because it's an in/out parameter we must use an array of URL objects.
102 com
.sun
.star
.util
.URL
[] aParseURL
= new com
.sun
.star
.util
.URL
[1];
103 aParseURL
[0] = new com
.sun
.star
.util
.URL();
104 aParseURL
[0].Complete
= sURL
;
107 xParser
.parseStrict(aParseURL
);
111 catch(com
.sun
.star
.uno
.RuntimeException exRuntime
)
113 // Any UNO method of this scope can throw this exception.
114 // Reset the return value only.
116 catch(com
.sun
.star
.uno
.Exception exUno
)
118 // "createInstance()" method of used service manager can throw it.
119 // Then it wasn't possible to get the URL transformer.
120 // Return default instead of really parsed URL.
129 * create a new empty target frame
130 * Attention: Currently we must use special service com.sun.star.frame.Task instead of Frame.
131 * Because desktop environment accept this special frame type only as direct children.
132 * Note - This service will be deprecated and must be replaces by com.sun.star.frame.Frame in
133 * further versions. To feature prove we use both service names. If for new versions
134 * the deprecated one not exist we get an empty frame, we can try to use the new service.
137 * we need the remote service manager to create this task/frame service
139 * @return [com.sun.star.frame.XFrame]
140 * the new created frame reference in case of success or null otherwise
142 private static com
.sun
.star
.frame
.XFrame
impl_createEmptyFrame(
143 com
.sun
.star
.uno
.XComponentContext xCtx
)
145 com
.sun
.star
.frame
.XFrame xFrame
= null;
148 xFrame
= UnoRuntime
.queryInterface(
149 com
.sun
.star
.frame
.XFrame
.class,
150 xCtx
.getServiceManager().createInstanceWithContext(
151 "com.sun.star.frame.Task", xCtx
));
152 } catch(com
.sun
.star
.uno
.Exception ex1
) {}
157 xFrame
= UnoRuntime
.queryInterface(
158 com
.sun
.star
.frame
.XFrame
.class,
159 xCtx
.getServiceManager().createInstanceWithContext(
160 "com.sun.star.frame.Frame", xCtx
));
161 } catch(com
.sun
.star
.uno
.Exception ex2
) {}
170 * create a new window which can be used as container window of an office frame
171 * We know two modes for creation:
172 * - the office window will be a child of one of our java windows
173 * - the office will be a normal system window outside this java application
174 * This behaviour will be regulated by the second parameter of this operation.
175 * If a parentview is given the first mode will be activated - otherwise
178 * Note: First mode (creation of a child window) can be reached by two different
180 * - pack the required window handle of our java window inside a UNO object
181 * to transport it to the remote office toolkit and get a child office
183 * This is the old way. It's better to use the second one - but to be
184 * future prove this old one should be tried too.
185 * - it's possible to pass the native window handle directly to the toolkit.
186 * A special interface method was enabled to accept that.
188 * The right way to create an office window should be then:
189 * - try to use second creation mode (directly using of the window handle)
190 * - if it failed ... use the old way by packing the handle inside an object
193 * we need a service manager to be able to create remote office
197 * the java window as parent for the office window if an inplace office
198 * is required. If it is set to null the created office window will be
199 * a normal system window outside of our java application.
201 * @return [com.sun.star.awt.XWindow]
202 * The new created office window which can be used to set it as
203 * a ContainerWindow on an empty office frame.
205 private static com
.sun
.star
.awt
.XWindow
impl_createWindow(
206 com
.sun
.star
.uno
.XComponentContext xCtx
, NativeView aParentView
)
208 com
.sun
.star
.awt
.XWindow xWindow
= null;
209 com
.sun
.star
.awt
.XWindowPeer xPeer
= null;
210 com
.sun
.star
.awt
.XToolkit xToolkit
= null;
212 // get access to toolkit of remote office to create the container window of
215 xToolkit
= UnoRuntime
.queryInterface(
216 com
.sun
.star
.awt
.XToolkit
.class,
217 xCtx
.getServiceManager().createInstanceWithContext(
218 "com.sun.star.awt.Toolkit", xCtx
));
220 catch(com
.sun
.star
.uno
.Exception ex
)
225 // mode 1) create an external system window
226 if (aParentView
==null)
228 // Describe the properties of the container window.
229 com
.sun
.star
.awt
.WindowDescriptor aDescriptor
=
230 new com
.sun
.star
.awt
.WindowDescriptor();
231 aDescriptor
.Type
= com
.sun
.star
.awt
.WindowClass
.TOP
;
232 aDescriptor
.WindowServiceName
= "window";
233 aDescriptor
.ParentIndex
= -1;
234 aDescriptor
.Parent
= null;
235 aDescriptor
.Bounds
= new com
.sun
.star
.awt
.Rectangle(0,0,0,0);
236 aDescriptor
.WindowAttributes
= com
.sun
.star
.awt
.WindowAttribute
.BORDER
|
237 com
.sun
.star
.awt
.WindowAttribute
.MOVEABLE
|
238 com
.sun
.star
.awt
.WindowAttribute
.SIZEABLE
|
239 com
.sun
.star
.awt
.WindowAttribute
.CLOSEABLE
;
242 xPeer
= xToolkit
.createWindow( aDescriptor
);
243 } catch(com
.sun
.star
.lang
.IllegalArgumentException exIllegal
) {}
245 // mode 2) create an internal office window as child of our given java
249 // try new version of creation first: directly using of the window
250 // handle. The old implementation of the corresponding toolkit method
251 // requires a process ID. If this id isn't the right one a null object
252 // is returned. But normally nobody outside the office knows this id.
253 // New version of this method ignore the id parameter and creation will
255 // Note: You must be sure if your window handle can be really used by
256 // the remote office. Means if this java client and the remote office
257 // use the same display!
258 com
.sun
.star
.awt
.XSystemChildFactory xChildFactory
=
259 UnoRuntime
.queryInterface(
260 com
.sun
.star
.awt
.XSystemChildFactory
.class, xToolkit
);
264 Integer nHandle
= aParentView
.getHWND();
265 short nSystem
= (short)aParentView
.getNativeWindowSystemType();
266 byte[] lProcID
= new byte[0];
268 xPeer
= xChildFactory
.createSystemChild(nHandle
,
273 // mode 3) OK - new version doesn't work. It requires the
274 // process id which we don't have.
275 // So we must use the old way to get the right window peer.
276 // Pack the handle inside a wrapper object.
277 JavaWindowPeerFake aWrapper
= new
278 JavaWindowPeerFake(aParentView
);
280 com
.sun
.star
.awt
.XWindowPeer xParentPeer
=
281 UnoRuntime
.queryInterface(
282 com
.sun
.star
.awt
.XWindowPeer
.class, aWrapper
);
284 com
.sun
.star
.awt
.WindowDescriptor aDescriptor
=
285 new com
.sun
.star
.awt
.WindowDescriptor();
286 aDescriptor
.Type
= com
.sun
.star
.awt
.WindowClass
.TOP
;
287 aDescriptor
.WindowServiceName
= "workwindow";
288 aDescriptor
.ParentIndex
= 1;
289 aDescriptor
.Parent
= xParentPeer
;
290 aDescriptor
.Bounds
= new com
.sun
.star
.awt
.Rectangle(0,0,0,0);
291 if (nSystem
== com
.sun
.star
.lang
.SystemDependent
.SYSTEM_WIN32
)
292 aDescriptor
.WindowAttributes
=
293 com
.sun
.star
.awt
.WindowAttribute
.SHOW
;
295 aDescriptor
.WindowAttributes
=
296 com
.sun
.star
.awt
.WindowAttribute
.SYSTEMDEPENDENT
;
299 xPeer
= xToolkit
.createWindow( aDescriptor
);
300 } catch(com
.sun
.star
.lang
.IllegalArgumentException exIllegal
) {}
303 catch(java
.lang
.RuntimeException exJRun
)
305 // This exception is thrown by the native JNI code if it try to get
306 // the systemw window handle. A possible reason can be an invisible
307 // java window. In this case it should be enough to set return
308 // values to null. All other resources (which was created before)
309 // will be freed automatically if scope will be leaved.
310 System
.out
.println("May be the NativeView object wasn't really visible at calling time of getNativeWindow()?");
316 // It doesn't matter which way was used to get the window peer.
317 // Cast it to the right return interface and return it.
318 xWindow
= UnoRuntime
.queryInterface(
319 com
.sun
.star
.awt
.XWindow
.class,
328 * This method create a new empty child frame on desktop instance of remote office.
329 * It use a special JNI functionality to pass the office XWindow over a java window.
330 * This java window can be inserted into another java window container for complex layouting.
331 * If this parent java window isn't used, a top level system window will be created.
332 * The resulting office frame isn't plugged into this java application.
335 * name to set it on the new created frame
338 * java window which should be used as parent window of new created office frame window
339 * May be set to null.
341 * @return [com.sun.star.frame.XFrame]
342 * reference to the new created frame for success or null if it failed
344 public static com
.sun
.star
.frame
.XFrame
createViewFrame(String sName
, NativeView aParentView
)
346 com
.sun
.star
.frame
.XFrame xFrame
= null;
350 com
.sun
.star
.uno
.XComponentContext xCtx
=
351 OfficeConnect
.getOfficeContext();
353 // create an empty office frame first
354 xFrame
= impl_createEmptyFrame(xCtx
);
356 // create an office window then
357 // Depending from the given parameter aParentView it will be a child or a top level
358 // system window. (see impl method for further information)
359 // But before we call this helper - prepare the possible parent window: show it.
360 // JNI calls to get system window handle of java window can't work without that!
361 if (aParentView
!=null)
362 aParentView
.setVisible(true);
363 com
.sun
.star
.awt
.XWindow xWindow
= impl_createWindow(xCtx
, aParentView
);
365 // pass the window the frame as his new container window.
366 // It's necessary to do it first - before you call anything else there.
367 // Otherwise the frame throws some exceptions for "uninitialized state".
368 xFrame
.initialize( xWindow
);
370 // Insert the new frame in desktop hierarchy.
371 // Use XFrames interface to do so. It provides access to the child frame container of that instance.
372 com
.sun
.star
.frame
.XFramesSupplier xTreeRoot
= UnoRuntime
.queryInterface(
373 com
.sun
.star
.frame
.XFramesSupplier
.class,
374 xCtx
.getServiceManager().createInstanceWithContext(
375 "com.sun.star.frame.Desktop", xCtx
));
376 com
.sun
.star
.frame
.XFrames xChildContainer
= xTreeRoot
.getFrames();
377 xChildContainer
.append(xFrame
);
379 // Make some further initializations on frame and window.
380 xWindow
.setVisible(true);
381 xFrame
.setName(sName
);
383 catch(com
.sun
.star
.uno
.RuntimeException exRuntime
)
385 // Any UNO method of this scope can throw this exception.
386 // So the frame can be already created and he must be freed
387 // correctly. May be he was inserted into the desktop tree too ...
390 // Try to dispose the frame. He should deregister himself at the desktop object
391 // and free all internal used resources (e.g. the container window) automatically.
392 // It's possible to do that here - because frame has no component inside yet.
393 // So nobody can disagree with that.
394 // After the dispose() call forget all references to this frame and let him die.
395 // If a new exception will occur ... no general solution exist then.
396 // Nobody can guarantee if next call will work or not.
397 com
.sun
.star
.lang
.XComponent xComponent
= UnoRuntime
.queryInterface(
398 com
.sun
.star
.lang
.XComponent
.class,
400 xComponent
.dispose();
405 catch(com
.sun
.star
.uno
.Exception exUno
)
407 // "createInstance()" method of used service manager can throw it.
408 // If it occurred during creation of desktop service the frame already was created.
409 // Free it by decreasing his refcount. Changes on the desktop tree couldn't exist.
410 // Without the desktop service that wasn't possible. So no further rollbacks must follow.
413 com
.sun
.star
.lang
.XComponent xComponent
= UnoRuntime
.queryInterface(
414 com
.sun
.star
.lang
.XComponent
.class,
416 xComponent
.dispose();
428 * Dispatch a URL to given frame.
429 * Caller can register himself for following status events for dispatched
430 * URL too. But nobody guarantee that such notifications will occur.
431 * (see dispatchWithNotification() if you interest on that)
432 * The returned dispatch object should be hold alive by caller
433 * till he doesn't need it any longer. Otherwise the dispatcher can(!)
434 * die by decreasing his refcount.
436 * @param xFrame frame which should be the target of this dispatch
437 * @param aURL full parsed and converted office URL for dispatch
438 * @param lProperties optional arguments for dispatch
439 * @param xListener optional listener which is registered automatically for status events
440 * (Note: Deregistration is part of this listener himself!)
442 * @return [XDispatch] It's the used dispatch object and can be used for deregistration of an optional listener.
443 * Otherwise caller can ignore it.
445 public static com
.sun
.star
.frame
.XDispatch
execute(com
.sun
.star
.frame
.XFrame xFrame
,
446 com
.sun
.star
.util
.URL aURL
,
447 com
.sun
.star
.beans
.PropertyValue
[] lProperties
,
448 com
.sun
.star
.frame
.XStatusListener xListener
)
450 com
.sun
.star
.frame
.XDispatch xDispatcher
= null;
454 // Query the frame for right interface which provides access to all available dispatch objects.
455 com
.sun
.star
.frame
.XDispatchProvider xProvider
= UnoRuntime
.queryInterface(
456 com
.sun
.star
.frame
.XDispatchProvider
.class,
459 // Ask him for right dispatch object for given URL.
460 // Force given frame as target for following dispatch by using "".
461 // It means the same like "_self".
462 xDispatcher
= xProvider
.queryDispatch(aURL
,"",0);
464 // Dispatch the URL into the frame.
465 if(xDispatcher
!=null)
468 xDispatcher
.addStatusListener(xListener
,aURL
);
470 xDispatcher
.dispatch(aURL
,lProperties
);
473 catch(com
.sun
.star
.uno
.RuntimeException exUno
)
475 // Any UNO method of this scope can throw this exception.
476 // But there will be nothing to do then - because
477 // we haven't changed anything inside the remote objects
478 // except method "addStatusListener().
479 // But in this case the source of this exception has to
480 // rollback all his operations. There is no chance to
481 // make anything right then.
482 // Reset the return value to a default - that's it.
483 exUno
.printStackTrace();
497 * Load document specified by a URL into given frame synchronously.
498 * The result of this operation will be the loaded document for success
499 * or null if loading failed.
501 * @param xFrame frame which should be the target of this load call
502 * @param sURL unparsed URL for loading
503 * @param lProperties optional arguments
505 * @return [XComponent] the loaded document for success or null if it's failed
507 public static com
.sun
.star
.lang
.XComponent
loadDocument(
508 com
.sun
.star
.frame
.XFrame xFrame
, String sURL
,
509 com
.sun
.star
.beans
.PropertyValue
[] lProperties
)
511 com
.sun
.star
.lang
.XComponent xDocument
= null;
512 String sOldName
= null;
516 com
.sun
.star
.uno
.XComponentContext xCtx
=
517 OfficeConnect
.getOfficeContext();
519 // First prepare frame for loading
520 // We must address it inside the frame tree without any complications.
521 // So we set an unambiguous (we hope it) name and use it later.
522 // Don't forget to reset original name after that.
523 sOldName
= xFrame
.getName();
524 String sTarget
= "odk_officedev_desk";
525 xFrame
.setName(sTarget
);
527 // Get access to the global component loader of the office
528 // for synchronous loading the document.
529 com
.sun
.star
.frame
.XComponentLoader xLoader
=
530 UnoRuntime
.queryInterface(
531 com
.sun
.star
.frame
.XComponentLoader
.class,
532 xCtx
.getServiceManager().createInstanceWithContext(
533 "com.sun.star.frame.Desktop", xCtx
));
535 // Load the document into the target frame by using his name and
536 // special search flags.
537 xDocument
= xLoader
.loadComponentFromURL(
540 com
.sun
.star
.frame
.FrameSearchFlag
.CHILDREN
,
543 // don't forget to restore old frame name...
544 xFrame
.setName(sOldName
);
546 catch(com
.sun
.star
.io
.IOException exIO
)
548 // Can be thrown by "loadComponentFromURL()" call.
549 // The only thing we should do then is to reset changed frame name!
550 exIO
.printStackTrace();
553 xFrame
.setName(sOldName
);
555 catch(com
.sun
.star
.lang
.IllegalArgumentException exIllegal
)
557 // Can be thrown by "loadComponentFromURL()" call.
558 // The only thing we should do then is to reset changed frame name!
559 exIllegal
.printStackTrace();
562 xFrame
.setName(sOldName
);
564 catch(com
.sun
.star
.uno
.RuntimeException exRuntime
)
566 // Any UNO method of this scope can throw this exception.
567 // The only thing we can try(!) is to reset changed frame name.
568 exRuntime
.printStackTrace();
571 xFrame
.setName(sOldName
);
573 catch(com
.sun
.star
.uno
.Exception exUno
)
575 // "createInstance()" method of used service manager can throw it.
576 // The only thing we should do then is to reset changed frame name!
577 exUno
.printStackTrace();
580 xFrame
.setName(sOldName
);
589 * Save currently loaded document of given frame.
591 * @param xDocument document for saving changes
593 public static void saveDocument(com
.sun
.star
.lang
.XComponent xDocument
)
597 // Check for supported model functionality.
598 // Normally the application documents (text, spreadsheet ...) do so
599 // but some other ones (e.g. db components) doesn't do that.
600 // They can't be save then.
601 com
.sun
.star
.frame
.XModel xModel
= UnoRuntime
.queryInterface(
602 com
.sun
.star
.frame
.XModel
.class,
606 // Check for modifications => break save process if there is nothing to do.
607 com
.sun
.star
.util
.XModifiable xModified
= UnoRuntime
.queryInterface(
608 com
.sun
.star
.util
.XModifiable
.class,
610 if(xModified
.isModified())
612 com
.sun
.star
.frame
.XStorable xStore
= UnoRuntime
.queryInterface(
613 com
.sun
.star
.frame
.XStorable
.class,
620 catch(com
.sun
.star
.io
.IOException exIO
)
622 // Can be thrown by "store()" call.
623 // But there is nothing we can do then.
624 exIO
.printStackTrace();
626 catch(com
.sun
.star
.uno
.RuntimeException exUno
)
628 // Any UNO method of this scope can throw this exception.
629 // But there is nothing we can do then.
630 exUno
.printStackTrace();
637 * It try to export given document in HTML format.
638 * Current document will be converted to HTML and moved to new place on disk.
639 * A "new" file will be created by given URL (may be overwritten
640 * if it already exist). Right filter will be used automatically if factory of
641 * this document support it. If no valid filter can be found for export,
642 * nothing will be done here.
644 * @param xDocument document which should be exported
645 * @param sURL target URL for converted document
647 public static void saveAsHTML(com
.sun
.star
.lang
.XComponent xDocument
,
652 // First detect factory of this document.
653 // Ask for the supported service name of this document.
654 // If information is available it can be used to find out which
655 // filter exist for HTML export. Normally this filter should be searched
656 // inside the filter configuration but this little demo doesn't do so.
657 // (see service com.sun.star.document.FilterFactory for further
659 // Well known filter names are used directly. They must exist in current
660 // office installation. Otherwise this code will fail. But to prevent
661 // this code against missing filters it check for existing state of it.
662 com
.sun
.star
.lang
.XServiceInfo xInfo
= UnoRuntime
.queryInterface(com
.sun
.star
.lang
.XServiceInfo
.class,
667 // Find out possible filter name.
668 String sFilter
= null;
669 if(xInfo
.supportsService("com.sun.star.text.TextDocument"))
670 sFilter
= "HTML (StarWriter)";
672 if(xInfo
.supportsService("com.sun.star.text.WebDocument"))
675 if(xInfo
.supportsService("com.sun.star.sheet.SpreadsheetDocument"))
676 sFilter
= "HTML (StarCalc)";
678 // Check for existing state of this filter.
681 com
.sun
.star
.uno
.XComponentContext xCtx
=
682 OfficeConnect
.getOfficeContext();
684 com
.sun
.star
.container
.XNameAccess xFilterContainer
=
685 UnoRuntime
.queryInterface(
686 com
.sun
.star
.container
.XNameAccess
.class,
687 xCtx
.getServiceManager().createInstanceWithContext(
688 "com.sun.star.document.FilterFactory", xCtx
));
690 if(!xFilterContainer
.hasByName(sFilter
))
694 // Use this filter for export.
697 // Export can be forced by saving the document and using a
698 // special filter name which can write needed format. Build
699 // necessary argument list now.
700 // Use special flag "Overwrite" too, to prevent operation
701 // against possible exceptions, if file already exist.
702 com
.sun
.star
.beans
.PropertyValue
[] lProperties
=
703 new com
.sun
.star
.beans
.PropertyValue
[2];
704 lProperties
[0] = new com
.sun
.star
.beans
.PropertyValue();
705 lProperties
[0].Name
= "FilterName";
706 lProperties
[0].Value
= sFilter
;
707 lProperties
[1] = new com
.sun
.star
.beans
.PropertyValue();
708 lProperties
[1].Name
= "Overwrite";
709 lProperties
[1].Value
= Boolean
.TRUE
;
711 com
.sun
.star
.frame
.XStorable xStore
=
712 UnoRuntime
.queryInterface(
713 com
.sun
.star
.frame
.XStorable
.class, xDocument
);
715 xStore
.storeAsURL(sURL
,lProperties
);
719 catch(com
.sun
.star
.io
.IOException exIO
)
721 // Can be thrown by "store()" call.
722 // Do nothing then. Saving failed - that's it.
723 exIO
.printStackTrace();
725 catch(com
.sun
.star
.uno
.RuntimeException exRuntime
)
727 // Can be thrown by any uno call.
728 // Do nothing here. Saving failed - that's it.
729 exRuntime
.printStackTrace();
731 catch(com
.sun
.star
.uno
.Exception exUno
)
733 // Can be thrown by "createInstance()" call of service manager.
734 // Do nothing here. Saving failed - that's it.
735 exUno
.printStackTrace();
746 * Try to close the frame instead of the document.
747 * It shows the possible interface to do so.
750 * frame which should be closed
752 * @return <TRUE/> in case frame could be closed
755 public static boolean closeFrame(com
.sun
.star
.frame
.XFrame xFrame
)
757 boolean bClosed
= false;
761 // first try the new way: use new interface XCloseable
762 // It replace the deprecated XTask::close() and should be preferred ...
763 // if it can be queried.
764 com
.sun
.star
.util
.XCloseable xCloseable
=
765 UnoRuntime
.queryInterface(
766 com
.sun
.star
.util
.XCloseable
.class, xFrame
);
767 if (xCloseable
!=null)
769 // We deliver the ownership of this frame not to the (possible)
770 // source which throw a CloseVetoException. We wish to have it
771 // under our own control.
774 xCloseable
.close(false);
777 catch( com
.sun
.star
.util
.CloseVetoException exVeto
)
784 // OK: the new way isn't possible. Try the old one.
785 com
.sun
.star
.frame
.XTask xTask
= UnoRuntime
.queryInterface(com
.sun
.star
.frame
.XTask
.class,
789 // return value doesn't interest here. Because
790 // we forget this task ...
791 bClosed
= xTask
.close();
795 catch (com
.sun
.star
.lang
.DisposedException exDisposed
)
797 // Of course - this task can be already dead - means disposed.
798 // But for us it's not important. Because we tried to close it too.
799 // And "already disposed" or "closed" should be the same ...
809 * Try to find a unique frame name, which isn't currently used inside
810 * remote office instance. Because we create top level frames
811 * only, it's enough to check the names of existing child frames on the
814 * should represent a unique frame name, which currently isn't
815 * used inside the remote office frame tree
816 * (Couldn't guaranteed for a real multithreaded environment.
819 private static final String BASEFRAMENAME
= "Desk View ";
821 public static String
getUniqueFrameName()
825 com
.sun
.star
.uno
.XComponentContext xCtx
= OfficeConnect
.getOfficeContext();
829 com
.sun
.star
.frame
.XFramesSupplier xSupplier
=
830 UnoRuntime
.queryInterface(
831 com
.sun
.star
.frame
.XFramesSupplier
.class,
832 xCtx
.getServiceManager().createInstanceWithContext(
833 "com.sun.star.frame.Desktop", xCtx
));
835 com
.sun
.star
.container
.XIndexAccess xContainer
=
836 UnoRuntime
.queryInterface(
837 com
.sun
.star
.container
.XIndexAccess
.class,
838 xSupplier
.getFrames());
840 int nCount
= xContainer
.getCount();
841 for (int i
=0; i
<nCount
; ++i
)
843 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
));
844 sName
= BASEFRAMENAME
+mnViewCount
;
845 while(sName
.equals(xFrame
.getName()))
848 sName
= BASEFRAMENAME
+mnViewCount
;
852 catch(com
.sun
.star
.uno
.Exception exCreateFailed
)
854 sName
= BASEFRAMENAME
;
859 System
.out
.println("invalid name!");
860 sName
= BASEFRAMENAME
;
869 * helper to get a file URL selected by user
870 * This method doesn't show any API concepts...
871 * but is necessary for this demo application.
873 * @param aParent parent window of this dialog
874 * @param bOpen If it is set to true =>
875 * dialog is opened in "file open" mode -
876 * otherwise in "file save" mode.
878 public static String
askUserForFileURL(Component aParent
,boolean bOpen
)
880 String sFileURL
= null;
881 int nDecision
= JFileChooser
.CANCEL_OPTION
;
882 JFileChooser aChooser
= null;
884 // set last visited directory on new file chosser
885 // (if this information is available)
886 if( maLastDir
==null )
887 aChooser
= new JFileChooser();
889 aChooser
= new JFileChooser(maLastDir
);
891 // decide between file open/save dialog
893 nDecision
= aChooser
.showOpenDialog(aParent
);
895 nDecision
= aChooser
.showSaveDialog(aParent
);
897 // react for "OK" result only
898 if(nDecision
== JFileChooser
.APPROVE_OPTION
)
900 // save current directory as last visited one
901 maLastDir
= aChooser
.getCurrentDirectory();
902 // get file URL from the dialog
905 sFileURL
= aChooser
.getSelectedFile().toURI().toURL().toExternalForm();
907 catch( MalformedURLException ex
)
909 ex
.printStackTrace();
912 // problem of java: file URL's are coded with 1 slash instead of 3 ones!
913 // => correct this problem first, otherwise office can't use these URL's
915 ( sFileURL
!=null ) &&
916 ( sFileURL
.startsWith("file:/") ) &&
917 ( !sFileURL
.startsWith("file://") )
920 StringBuffer sWorkBuffer
= new StringBuffer(sFileURL
);
921 sWorkBuffer
.insert(6,"//");
922 sFileURL
= sWorkBuffer
.toString();
932 * @member maLastDir save the last visited directory of used file open/save dialog
933 * @member mnViewCount we try to set unique names on every frame we create (that's why we must count it)
935 private static File maLastDir
= null;
936 private static int mnViewCount
= 0 ;
939 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */