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