1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 package util;
28 
29 import com.sun.star.awt.Rectangle;
30 import com.sun.star.awt.WindowDescriptor;
31 import com.sun.star.awt.XToolkit;
32 import com.sun.star.awt.XWindowPeer;
33 import com.sun.star.awt.XTopWindow;
34 import com.sun.star.beans.PropertyValue;
35 import com.sun.star.beans.XPropertySet;
36 import com.sun.star.container.XEnumeration;
37 import com.sun.star.container.XNameReplace;
38 import com.sun.star.frame.XComponentLoader;
39 import com.sun.star.frame.XDesktop;
40 import com.sun.star.frame.XFrame;
41 import com.sun.star.frame.XModel;
42 import com.sun.star.lang.XComponent;
43 import com.sun.star.lang.XMultiServiceFactory;
44 import com.sun.star.lang.XServiceInfo;
45 import com.sun.star.uno.UnoRuntime;
46 
47 // access the implementations via names
48 import com.sun.star.uno.XInterface;
49 import com.sun.star.util.XCloseable;
50 import com.sun.star.util.XModifiable;
51 import com.sun.star.view.XViewSettingsSupplier;
52 import helper.ConfigHelper;
53 import java.util.Vector;
54 import lib.StatusException;
55 
56 /**
57  * contains helper methods for the Desktop
58  */
59 public class DesktopTools
60 {
61 
62     /**
63      * Queries the XComponentLoader
64      *
65      * @param xMSF the MultiServiceFactory
66      * @return the gained XComponentLoader
67      */
68     public static XComponentLoader getCLoader(XMultiServiceFactory xMSF)
69     {
70         XDesktop oDesktop = (XDesktop) UnoRuntime.queryInterface(
71                 XDesktop.class, createDesktop(xMSF));
72 
73         XComponentLoader oCLoader = (XComponentLoader) UnoRuntime.queryInterface(
74                 XComponentLoader.class, oDesktop);
75 
76         return oCLoader;
77     } // finish getCLoader
78 
79     /**
80      * Creates an Instance of the Desktop service
81      *
82      * @param xMSF the MultiServiceFactory
83      * @return the gained Object
84      */
85     public static Object createDesktop(XMultiServiceFactory xMSF)
86     {
87         Object oInterface;
88 
89         try
90         {
91             oInterface = xMSF.createInstance("com.sun.star.comp.framework.Desktop");
92         }
93         catch (com.sun.star.uno.Exception e)
94         {
95             throw new IllegalArgumentException("Desktop Service not available");
96         }
97 
98         return oInterface;
99     } //finish createDesktop
100 
101     /**
102      * returns a XEnumeration containing all components containing on the desktop
103      * @param xMSF the XMultiServiceFactory
104      * @return XEnumeration of all components on the desktop
105      */
106     public static XEnumeration getAllComponents(XMultiServiceFactory xMSF)
107     {
108         XDesktop xDesktop = (XDesktop) UnoRuntime.queryInterface(
109                 XDesktop.class, createDesktop(xMSF));
110         return xDesktop.getComponents().createEnumeration();
111     }
112 
113     /**
114      * returns the current component on the desktop
115      * @param xMSF the XMultiServiceFactory
116      * @return XComponent of the current component on the desktop
117      */
118     public static XComponent getCurrentComponent(XMultiServiceFactory xMSF)
119     {
120         XDesktop xDesktop = (XDesktop) UnoRuntime.queryInterface(
121                 XDesktop.class, createDesktop(xMSF));
122         return xDesktop.getCurrentComponent();
123     }
124 
125     /**
126      * returns the current component on the desktop
127      * @param xMSF the XMultiServiceFactory
128      * @return XComponent of the current component on the desktop
129      */
130     public static XFrame getCurrentFrame(XMultiServiceFactory xMSF)
131     {
132         XDesktop xDesktop = (XDesktop) UnoRuntime.queryInterface(
133                 XDesktop.class, createDesktop(xMSF));
134         return xDesktop.getCurrentFrame();
135     }
136 
137     /**
138      * returns an object arrary of all open documents
139      * @param xMSF the MultiServiceFactory
140      * @return returns an Array of document kinds like ["swriter"]
141      */
142     /**
143      * returns an array of all open documents
144      * @param xMSF the XMultiSerivceFactory
145      * @return returns an array of all open documents
146      */
147     public static Object[] getAllOpenDocuments(XMultiServiceFactory xMSF)
148     {
149         Vector components = new Vector();
150         XDesktop xDesktop = (XDesktop) UnoRuntime.queryInterface(
151                 XDesktop.class, createDesktop(xMSF));
152 
153         XEnumeration allComp = getAllComponents(xMSF);
154 
155         while (allComp.hasMoreElements())
156         {
157             try
158             {
159                 XComponent xComponent = (XComponent) UnoRuntime.queryInterface(
160                         XComponent.class, allComp.nextElement());
161 
162                 if (getDocumentType(xComponent) != null)
163                 {
164                     components.add(xComponent);
165                 }
166 
167             }
168             catch (com.sun.star.container.NoSuchElementException e)
169             {
170             }
171             catch (com.sun.star.lang.WrappedTargetException e)
172             {
173             }
174         }
175         return components.toArray();
176     }
177 
178     /**
179      * Returns the document type for the given XComponent of an document
180      * @param xComponent the document to query for its type
181      * @return possible:
182      * <ul>
183      * <li>swriter</li>
184      * <li>scalc</li>
185      * <li>sdraw</li>
186      * <li>smath</li>
187      * </ul>
188      * or <CODE>null</CODE>
189      */
190     public static String getDocumentType(XComponent xComponent)
191     {
192         XServiceInfo sInfo = (XServiceInfo) UnoRuntime.queryInterface(
193                 XServiceInfo.class, xComponent);
194 
195         if (sInfo == null)
196         {
197             return "";
198         }
199         else if (sInfo.supportsService("com.sun.star.sheet.SpreadsheetDocument"))
200         {
201             return "scalc";
202         }
203         else if (sInfo.supportsService("com.sun.star.text.TextDocument"))
204         {
205             return "swriter";
206         }
207         else if (sInfo.supportsService("com.sun.star.drawing.DrawingDocument"))
208         {
209             return "sdraw";
210         }
211         else if (sInfo.supportsService("com.sun.star.presentation.PresentationDocument"))
212         {
213             return "simpress";
214         }
215         else if (sInfo.supportsService("com.sun.star.formula.FormulaProperties"))
216         {
217             return "smath";
218         }
219         else
220         {
221             return null;
222         }
223     }
224 
225     /**
226      * Opens a new document of a given kind
227      * with arguments
228      * @return the XComponent Interface of the document
229      * @param kind the kind of document to load.<br>
230      * possible:
231      * <ul>
232      * <li>swriter</li>
233      * <li>scalc</li>
234      * <li>sdaw</li>
235      * <li>smath</li>
236      * </ul>
237      * @param Args arguments which passed to the document to load
238      * @param xMSF the MultiServiceFactory
239      */
240     public static XComponent openNewDoc(XMultiServiceFactory xMSF, String kind,
241             PropertyValue[] Args)
242     {
243         XComponent oDoc = null;
244 
245         try
246         {
247             oDoc = getCLoader(xMSF).loadComponentFromURL("private:factory/" + kind,
248                     "_blank", 0, Args);
249         }
250         catch (com.sun.star.uno.Exception e)
251         {
252             throw new IllegalArgumentException("Document could not be opened");
253         }
254 
255         return oDoc;
256     } //finish openNewDoc
257 
258     /**
259      * loads a document of from a given url
260      * with arguments
261      * @return the XComponent Interface of the document
262      * @param url the URL of the document to load.
263      * @param Args arguments which passed to the document to load
264      * @param xMSF the MultiServiceFactory
265      */
266     public static XComponent loadDoc(XMultiServiceFactory xMSF, String url,
267             PropertyValue[] Args)
268     {
269         XComponent oDoc = null;
270         if (Args == null)
271         {
272             Args = new PropertyValue[0];
273         }
274         try
275         {
276             oDoc = getCLoader(xMSF).loadComponentFromURL(url, "_blank", 0, Args);
277         }
278         catch (com.sun.star.uno.Exception e)
279         {
280             throw new IllegalArgumentException("Document could not be loaded");
281         }
282 
283         bringWindowToFront(oDoc);
284         return oDoc;
285     } //finish openNewDoc
286 
287     /**
288      * closes a given document
289      * @param DocumentToClose the document to close
290      */
291     public static void closeDoc(XInterface DocumentToClose)
292     {
293         if (DocumentToClose == null)
294         {
295             return;
296         }
297 
298         String kd = System.getProperty("KeepDocument");
299         if (kd != null)
300         {
301             System.out.println("The property 'KeepDocument' is set and so the document won't be disposed");
302             return;
303         }
304         XModifiable modified = (XModifiable) UnoRuntime.queryInterface(XModifiable.class, DocumentToClose);
305         XCloseable closer = (XCloseable) UnoRuntime.queryInterface(XCloseable.class, DocumentToClose);
306 
307         try
308         {
309             if (modified != null)
310             {
311                 modified.setModified(false);
312             }
313             closer.close(true);
314         }
315         catch (com.sun.star.util.CloseVetoException e)
316         {
317             // e.printStackTrace();
318             System.out.println("Couldn't close document");
319         }
320         catch (com.sun.star.lang.DisposedException e)
321         {
322             // e.printStackTrace();
323             System.out.println("Couldn't close document");
324         }
325         catch (java.lang.NullPointerException e)
326         {
327             // e.printStackTrace();
328             System.out.println("Couldn't close document");
329         }
330         catch (com.sun.star.beans.PropertyVetoException e)
331         {
332             // e.printStackTrace();
333             System.out.println("Couldn't close document");
334         }
335     }
336 
337     /**
338      * Creates a floating XWindow with the size of X=500 Y=100 width=400 height=600
339      * @param xMSF the MultiServiceFactory
340      * @throws lib.StatusException if it is not possible to create a floating window a lib.StatusException was thrown
341      * @return a floating XWindow
342      */
343     public static XWindowPeer createFloatingWindow(XMultiServiceFactory xMSF)
344             throws StatusException
345     {
346         return createFloatingWindow(xMSF, 500, 100, 400, 600);
347     }
348 
349     /**
350      * Creates a floating XWindow on the given position and size.
351      * @return a floating XWindow
352      * @param X the X-Postion of the floating XWindow
353      * @param Y the Y-Postion of the floating XWindow
354      * @param width the width of the floating XWindow
355      * @param height the height of the floating XWindow
356      * @param xMSF the MultiServiceFactory
357      * @throws lib.StatusException if it is not possible to create a floating window a lib.StatusException was thrown
358      */
359     public static XWindowPeer createFloatingWindow(XMultiServiceFactory xMSF, int X, int Y, int width, int height)
360             throws StatusException
361     {
362 
363         XInterface oObj = null;
364 
365         try
366         {
367             oObj = (XInterface) xMSF.createInstance("com.sun.star.awt.Toolkit");
368         }
369         catch (com.sun.star.uno.Exception e)
370         {
371             throw new StatusException("Couldn't get toolkit", e);
372         }
373 
374         XToolkit tk = (XToolkit) UnoRuntime.queryInterface(
375                 XToolkit.class, oObj);
376 
377         WindowDescriptor descriptor = new com.sun.star.awt.WindowDescriptor();
378 
379         descriptor.Type = com.sun.star.awt.WindowClass.TOP;
380         descriptor.WindowServiceName = "modelessdialog";
381         descriptor.ParentIndex = -1;
382 
383         Rectangle bounds = new com.sun.star.awt.Rectangle();
384         bounds.X = X;
385         bounds.Y = Y;
386         bounds.Width = width;
387         bounds.Height = height;
388 
389         descriptor.Bounds = bounds;
390         descriptor.WindowAttributes = (com.sun.star.awt.WindowAttribute.BORDER +
391                 com.sun.star.awt.WindowAttribute.MOVEABLE +
392                 com.sun.star.awt.WindowAttribute.SIZEABLE +
393                 com.sun.star.awt.WindowAttribute.CLOSEABLE +
394                 com.sun.star.awt.VclWindowPeerAttribute.CLIPCHILDREN);
395 
396         XWindowPeer xWindow = null;
397 
398         try
399         {
400             xWindow = tk.createWindow(descriptor);
401         }
402         catch (com.sun.star.lang.IllegalArgumentException e)
403         {
404             throw new StatusException("Could not create window", e);
405         }
406 
407         return xWindow;
408 
409     }
410 
411     /**
412      * zoom to have a view over the hole page
413      * @param xDoc the document to zoom
414      */
415     public static void zoomToEntirePage(XInterface xDoc)
416     {
417         try
418         {
419             XModel xMod = (XModel) UnoRuntime.queryInterface(XModel.class, xDoc);
420             XInterface oCont = xMod.getCurrentController();
421             XViewSettingsSupplier oVSSupp = (XViewSettingsSupplier) UnoRuntime.queryInterface(XViewSettingsSupplier.class, oCont);
422 
423             XInterface oViewSettings = oVSSupp.getViewSettings();
424             XPropertySet oViewProp = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, oViewSettings);
425             oViewProp.setPropertyValue("ZoomType",
426                     new Short(com.sun.star.view.DocumentZoomType.ENTIRE_PAGE));
427 
428             utils.shortWait(5000);
429         }
430         catch (Exception e)
431         {
432             System.out.println("Could not zoom to entire page: " + e.toString());
433         }
434 
435     }
436 
437     /**
438      * This function docks the Stylist onto the right side of the window.</p>
439      * Note:<P>
440      * Since the svt.viewoptions cache the view configuration at start up
441      * the chage of the docking will be effective at a restart.
442      * @param xMSF the XMultiServiceFactory
443      */
444     public static void dockStylist(XMultiServiceFactory xMSF)
445     {
446         // prepare Window-Settings
447         try
448         {
449             ConfigHelper aConfig = new ConfigHelper(xMSF,
450                     "org.openoffice.Office.Views", false);
451 
452             // Is node "5539" (slot-id for navigator) available? If not, insert it
453             XNameReplace x5539 = aConfig.getOrInsertGroup("Windows", "5539");
454 
455             aConfig.updateGroupProperty(
456                     "Windows", "5539", "WindowState", "952,180,244,349;1;0,0,0,0;");
457 
458             aConfig.insertOrUpdateExtensibleGroupProperty(
459                     "Windows", "5539", "UserData", "Data", "V2,V,0,AL:(5,16,0/0/244/349,244;610)");
460 
461             // Is node "SplitWindow2" available? If not, instert it.
462             aConfig.getOrInsertGroup("Windows", "SplitWindow2");
463 
464             aConfig.insertOrUpdateExtensibleGroupProperty(
465                     "Windows", "SplitWindow2", "UserData", "UserItem", "V1,2,1,0,5539");
466 
467             aConfig.flush();
468             aConfig = null;
469 
470         }
471         catch (com.sun.star.uno.Exception e)
472         {
473             e.printStackTrace();
474         }
475     }
476 
477     /**
478      * Due to typo deprecated
479      * @param xModel
480      * @deprecated
481      */
482     @Deprecated
483     public static void bringWindowToFromt(XModel xModel)
484     {
485         bringWindowToFront(xModel);
486     }
487 
488     /**
489      * This function brings a document to the front.<P>
490      * NOTE: it is not possible to change the window order of your Window-Manager!!
491      * Only the order of Office documents are changeable.
492      * @param xModel the XModel of the document to bring to top
493      */
494     public static void bringWindowToFront(XModel xModel)
495     {
496         // System.out.println("DEBUG: bring to front xModel");
497 
498         XTopWindow xTopWindow =
499                 (XTopWindow) UnoRuntime.queryInterface(
500                 XTopWindow.class,
501                 xModel.getCurrentController().getFrame().getContainerWindow());
502 
503         xTopWindow.toFront();
504     }
505 
506     public static void bringWindowToFront(XComponent xComponent)
507     {
508         // System.out.println("DEBUG: bring to front xComponent");
509         XModel xModel = (XModel) UnoRuntime.queryInterface(XModel.class, xComponent);
510         if (xModel != null)
511         {
512             bringWindowToFront(xModel);
513         }
514     }
515 }
516