1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 package integration.forms; 24 25 import com.sun.star.beans.PropertyState; 26 import com.sun.star.beans.PropertyValue; 27 import com.sun.star.beans.XPropertySet; 28 import com.sun.star.container.XChild; 29 import com.sun.star.container.XIndexContainer; 30 import com.sun.star.container.XNameContainer; 31 import com.sun.star.document.MacroExecMode; 32 import com.sun.star.drawing.XDrawPage; 33 import com.sun.star.drawing.XDrawPageSupplier; 34 import com.sun.star.drawing.XDrawPages; 35 import com.sun.star.drawing.XDrawPagesSupplier; 36 import com.sun.star.form.XFormsSupplier; 37 import com.sun.star.frame.XComponentLoader; 38 import com.sun.star.frame.XController; 39 import com.sun.star.frame.XFrame; 40 import com.sun.star.frame.XModel; 41 import com.sun.star.lang.XComponent; 42 import com.sun.star.lang.XMultiServiceFactory; 43 import com.sun.star.lang.XServiceInfo; 44 import com.sun.star.uno.UnoRuntime; 45 import com.sun.star.uno.XInterface; 46 import com.sun.star.util.XModifiable; 47 48 /**************************************************************************/ 49 50 /**************************************************************************/ 51 /** provides a small wrapper around a document 52 */ 53 public class DocumentHelper 54 { 55 private XMultiServiceFactory m_orb; 56 private XComponent m_documentComponent; 57 58 /* ================================================================== */ 59 /* ------------------------------------------------------------------ */ DocumentHelper( XMultiServiceFactory orb, XComponent document )60 public DocumentHelper( XMultiServiceFactory orb, XComponent document ) 61 { 62 m_orb = orb; 63 m_documentComponent = document; 64 } 65 66 /* ------------------------------------------------------------------ */ implLoadAsComponent( XMultiServiceFactory orb, String documentOrFactoryURL )67 protected static XComponent implLoadAsComponent( XMultiServiceFactory orb, String documentOrFactoryURL ) throws com.sun.star.uno.Exception 68 { 69 return implLoadAsComponent( orb, documentOrFactoryURL, new PropertyValue[0] ); 70 } 71 72 /* ------------------------------------------------------------------ */ implLoadAsComponent( XMultiServiceFactory orb, String documentOrFactoryURL, final PropertyValue[] i_args )73 protected static XComponent implLoadAsComponent( XMultiServiceFactory orb, String documentOrFactoryURL, final PropertyValue[] i_args ) throws com.sun.star.uno.Exception 74 { 75 XComponentLoader aLoader = (XComponentLoader)UnoRuntime.queryInterface( 76 XComponentLoader.class, 77 orb.createInstance( "com.sun.star.frame.Desktop" ) 78 ); 79 80 XComponent document = dbfTools.queryComponent( 81 aLoader.loadComponentFromURL( documentOrFactoryURL, "_blank", 0, i_args ) 82 ); 83 return document; 84 } 85 86 /* ------------------------------------------------------------------ */ implLoadDocument( XMultiServiceFactory orb, String documentOrFactoryURL )87 private static DocumentHelper implLoadDocument( XMultiServiceFactory orb, String documentOrFactoryURL ) throws com.sun.star.uno.Exception 88 { 89 return implLoadDocument( orb, documentOrFactoryURL, new PropertyValue[0] ); 90 } 91 92 /* ------------------------------------------------------------------ */ implLoadDocument( XMultiServiceFactory orb, String documentOrFactoryURL, final PropertyValue[] i_args )93 private static DocumentHelper implLoadDocument( XMultiServiceFactory orb, String documentOrFactoryURL, final PropertyValue[] i_args ) throws com.sun.star.uno.Exception 94 { 95 XComponent document = implLoadAsComponent( orb, documentOrFactoryURL, i_args ); 96 97 XServiceInfo xSI = (XServiceInfo)UnoRuntime.queryInterface( XServiceInfo.class, 98 document ); 99 if ( xSI.supportsService( "com.sun.star.sheet.SpreadsheetDocument" ) ) 100 return new SpreadsheetDocument( orb, document ); 101 return new DocumentHelper( orb, document ); 102 } 103 104 /* ------------------------------------------------------------------ */ loadDocument( XMultiServiceFactory orb, String documentURL )105 public static DocumentHelper loadDocument( XMultiServiceFactory orb, String documentURL ) throws com.sun.star.uno.Exception 106 { 107 return implLoadDocument( orb, documentURL ); 108 } 109 110 /* ------------------------------------------------------------------ */ blankTextDocument( XMultiServiceFactory orb )111 public static DocumentHelper blankTextDocument( XMultiServiceFactory orb ) throws com.sun.star.uno.Exception 112 { 113 return blankDocument( orb, DocumentType.WRITER ); 114 } 115 116 /* ------------------------------------------------------------------ */ blankXMLForm( XMultiServiceFactory orb )117 public static DocumentHelper blankXMLForm( XMultiServiceFactory orb ) throws com.sun.star.uno.Exception 118 { 119 return blankDocument( orb, DocumentType.XMLFORM ); 120 } 121 122 /* ------------------------------------------------------------------ */ blankDocument( XMultiServiceFactory orb, DocumentType eType )123 public static DocumentHelper blankDocument( XMultiServiceFactory orb, DocumentType eType ) throws com.sun.star.uno.Exception 124 { 125 final PropertyValue[] args = new PropertyValue[] { 126 new PropertyValue( "MacroExecutionMode", -1, MacroExecMode.ALWAYS_EXECUTE, PropertyState.DIRECT_VALUE ) 127 }; 128 return implLoadDocument( orb, getDocumentFactoryURL( eType ), args ); 129 } 130 131 /* ================================================================== */ 132 /* ------------------------------------------------------------------ */ getDocument( )133 public XComponent getDocument( ) 134 { 135 return m_documentComponent; 136 } 137 138 /* ------------------------------------------------------------------ */ isModified()139 public boolean isModified() 140 { 141 XModifiable modify = (XModifiable)query( XModifiable.class ); 142 return modify.isModified(); 143 } 144 145 /* ------------------------------------------------------------------ */ query( Class aInterfaceClass )146 public Object query( Class aInterfaceClass ) 147 { 148 return UnoRuntime.queryInterface( aInterfaceClass, m_documentComponent ); 149 } 150 151 /* ------------------------------------------------------------------ */ getOrb( )152 public XMultiServiceFactory getOrb( ) 153 { 154 return m_orb; 155 } 156 157 /* ------------------------------------------------------------------ */ 158 /** retrieves the current view of the document 159 @return 160 the view component, queried for the interface described by aInterfaceClass 161 */ getCurrentView( )162 public DocumentViewHelper getCurrentView( ) 163 { 164 // get the model interface for the document 165 XModel xDocModel = (XModel)UnoRuntime.queryInterface(XModel.class, m_documentComponent ); 166 // get the current controller for the document - as a controller is tied to a view, 167 // this gives us the currently active view for the document. 168 XController xController = xDocModel.getCurrentController(); 169 170 if ( classify() == DocumentType.CALC ) 171 return new SpreadsheetView( m_orb, this, xController ); 172 173 return new DocumentViewHelper( m_orb, this, xController ); 174 } 175 176 /* ------------------------------------------------------------------ */ 177 /** reloads the document 178 * 179 * The reload is done by dispatching the respective URL at a frame of the document. 180 * As a consequence, if you have references to a view of the document, or any interface 181 * of the document, they will become invalid. 182 * The Model instance itself, at which you called reload, will still be valid, it will 183 * automatically update its internal state after the reload. 184 * 185 * Another consequence is that if the document does not have a view at all, it cannot 186 * be reloaded. 187 */ reload()188 public void reload() throws Exception 189 { 190 DocumentViewHelper view = getCurrentView(); 191 XFrame frame = view.getController().getFrame(); 192 XModel oldModel = frame.getController().getModel(); 193 194 getCurrentView().dispatch( ".uno:Reload" ); 195 196 m_documentComponent = (XComponent)UnoRuntime.queryInterface( XComponent.class, 197 frame.getController().getModel() ); 198 199 XModel newModel = getCurrentView().getController().getModel(); 200 if ( UnoRuntime.areSame( oldModel, newModel ) ) 201 throw new java.lang.IllegalStateException( "reload failed" ); 202 } 203 204 /* ------------------------------------------------------------------ */ 205 /** creates a new form which is a child of the given form components container 206 207 @param xParentContainer 208 The parent container for the new form 209 @param sInitialName 210 The initial name of the form. May be null, in this case the default (which 211 is an implementation detail) applies. 212 */ createSubForm( XIndexContainer xParentContainer, String sInitialName )213 protected XIndexContainer createSubForm( XIndexContainer xParentContainer, String sInitialName ) 214 throws com.sun.star.uno.Exception 215 { 216 // create a new form 217 Object xNewForm = m_orb.createInstance( "com.sun.star.form.component.DataForm" ); 218 219 // insert 220 xParentContainer.insertByIndex( xParentContainer.getCount(), xNewForm ); 221 222 // set the name if necessary 223 if ( null != sInitialName ) 224 { 225 XPropertySet xFormProps = dbfTools.queryPropertySet( xNewForm ); 226 xFormProps.setPropertyValue( "Name", sInitialName ); 227 } 228 229 // outta here 230 return (XIndexContainer)UnoRuntime.queryInterface( XIndexContainer.class, xNewForm ); 231 } 232 233 /* ------------------------------------------------------------------ */ 234 /** creates a new form which is a child of the given form components container 235 236 @param aParentContainer 237 The parent container for the new form 238 @param sInitialName 239 The initial name of the form. May be null, in this case the default (which 240 is an implementation detail) applies. 241 */ createSubForm( Object aParentContainer, String sInitialName )242 public XIndexContainer createSubForm( Object aParentContainer, String sInitialName ) 243 throws com.sun.star.uno.Exception 244 { 245 XIndexContainer xParentContainer = (XIndexContainer)UnoRuntime.queryInterface( 246 XIndexContainer.class, aParentContainer ); 247 return createSubForm( xParentContainer, sInitialName ); 248 } 249 250 /* ------------------------------------------------------------------ */ 251 /** creates a form which is a sibling of the given form 252 @param aForm 253 A sinbling of the to be created form. 254 255 @param sInitialName 256 The initial name of the form. May be null, in this case the default (which 257 is an implementation detail) applies. 258 */ createSiblingForm( Object aForm, String sInitialName )259 public XIndexContainer createSiblingForm( Object aForm, String sInitialName ) throws com.sun.star.uno.Exception 260 { 261 // get the parent 262 XIndexContainer xContainer = (XIndexContainer)dbfTools.getParent( 263 aForm, XIndexContainer.class ); 264 // append a new form to this parent container 265 return createSubForm( xContainer, sInitialName ); 266 } 267 268 /* ------------------------------------------------------------------ */ 269 /** retrieves the document model which a given form component belongs to 270 */ getDocumentForComponent( Object aFormComponent, XMultiServiceFactory orb )271 static public DocumentHelper getDocumentForComponent( Object aFormComponent, XMultiServiceFactory orb ) 272 { 273 XChild xChild = (XChild)UnoRuntime.queryInterface( XChild.class, aFormComponent ); 274 XModel xModel = null; 275 while ( ( null != xChild ) && ( null == xModel ) ) 276 { 277 XInterface xParent = (XInterface)xChild.getParent(); 278 xModel = (XModel)UnoRuntime.queryInterface( XModel.class, xParent ); 279 xChild = (XChild)UnoRuntime.queryInterface( XChild.class, xParent ); 280 } 281 282 return new DocumentHelper( orb, xModel ); 283 } 284 285 /* ------------------------------------------------------------------ */ 286 /** returns a URL which can be used to create a document of a certain type 287 */ getDocumentFactoryURL( DocumentType eType )288 public static String getDocumentFactoryURL( DocumentType eType ) 289 { 290 if ( eType == DocumentType.WRITER ) 291 return "private:factory/swriter"; 292 if ( eType == DocumentType.CALC ) 293 return "private:factory/scalc"; 294 if ( eType == DocumentType.DRAWING ) 295 return "private:factory/sdraw"; 296 if ( eType == DocumentType.XMLFORM ) 297 return "private:factory/swriter?slot=21053"; 298 return "private:factory/swriter"; 299 } 300 301 /* ------------------------------------------------------------------ */ 302 /** classifies a document 303 */ classify( )304 public DocumentType classify( ) 305 { 306 XServiceInfo xSI = (XServiceInfo)UnoRuntime.queryInterface( 307 XServiceInfo.class, m_documentComponent ); 308 309 if ( xSI.supportsService( "com.sun.star.text.TextDocument" ) ) 310 return DocumentType.WRITER; 311 else if ( xSI.supportsService( "com.sun.star.sheet.SpreadsheetDocument" ) ) 312 return DocumentType.CALC; 313 else if ( xSI.supportsService( "com.sun.star.drawing.DrawingDocument" ) ) 314 return DocumentType.DRAWING; 315 316 return DocumentType.UNKNOWN; 317 } 318 319 /* ------------------------------------------------------------------ */ 320 /** retrieves a com.sun.star.drawing.DrawPage of the document, denoted by index 321 * @param index 322 * the index of the draw page 323 * @throws 324 * com.sun.star.lang.IndexOutOfBoundsException 325 * com.sun.star.lang.WrappedTargetException 326 */ getDrawPage( int index )327 protected XDrawPage getDrawPage( int index ) throws com.sun.star.lang.IndexOutOfBoundsException, com.sun.star.lang.WrappedTargetException 328 { 329 XDrawPagesSupplier xSuppPages = (XDrawPagesSupplier)UnoRuntime.queryInterface( 330 XDrawPagesSupplier.class, getDocument() ); 331 XDrawPages xPages = xSuppPages.getDrawPages(); 332 333 return (XDrawPage)UnoRuntime.queryInterface( XDrawPage.class, xPages.getByIndex( index ) ); 334 } 335 336 /* ------------------------------------------------------------------ */ 337 /** retrieves the <type scope="com.sun.star.drawing">DrawPage</type> of the document 338 */ getMainDrawPage( )339 protected XDrawPage getMainDrawPage( ) throws com.sun.star.uno.Exception 340 { 341 XDrawPage xReturn; 342 343 // in case of a Writer document, this is rather easy: simply ask the XDrawPageSupplier 344 XDrawPageSupplier xSuppPage = (XDrawPageSupplier)UnoRuntime.queryInterface( 345 XDrawPageSupplier.class, getDocument() ); 346 if ( null != xSuppPage ) 347 xReturn = xSuppPage.getDrawPage(); 348 else 349 { // the model itself is no draw page supplier - okay, it may be a Writer or Calc document 350 // (or any other multi-page document) 351 XDrawPagesSupplier xSuppPages = (XDrawPagesSupplier)UnoRuntime.queryInterface( 352 XDrawPagesSupplier.class, getDocument() ); 353 XDrawPages xPages = xSuppPages.getDrawPages(); 354 355 xReturn = (XDrawPage)UnoRuntime.queryInterface( XDrawPage.class, xPages.getByIndex( 0 ) ); 356 357 // Note that this is no really error-proof code: If the document model does not support the 358 // XDrawPagesSupplier interface, or if the pages collection returned is empty, this will break. 359 } 360 361 return xReturn; 362 } 363 364 /* ------------------------------------------------------------------ */ 365 /** retrieves the root of the hierarchy of form components 366 */ getFormComponentTreeRoot( )367 protected XNameContainer getFormComponentTreeRoot( ) throws com.sun.star.uno.Exception 368 { 369 XFormsSupplier xSuppForms = (XFormsSupplier)UnoRuntime.queryInterface( 370 XFormsSupplier.class, getMainDrawPage( ) ); 371 372 XNameContainer xFormsCollection = null; 373 if ( null != xSuppForms ) 374 { 375 xFormsCollection = xSuppForms.getForms(); 376 } 377 return xFormsCollection; 378 } 379 380 /* ------------------------------------------------------------------ */ 381 /** creates a component at the service factory provided by the document 382 */ createInstance( String serviceSpecifier )383 public XInterface createInstance( String serviceSpecifier ) throws com.sun.star.uno.Exception 384 { 385 XMultiServiceFactory xORB = (XMultiServiceFactory)UnoRuntime.queryInterface( XMultiServiceFactory.class, 386 m_documentComponent ); 387 return (XInterface)xORB.createInstance( serviceSpecifier ); 388 } 389 390 /* ------------------------------------------------------------------ */ 391 /** creates a component at the service factory provided by the document 392 */ createInstanceWithArguments( String serviceSpecifier, Object[] arguments )393 public XInterface createInstanceWithArguments( String serviceSpecifier, Object[] arguments ) throws com.sun.star.uno.Exception 394 { 395 XMultiServiceFactory xORB = (XMultiServiceFactory)UnoRuntime.queryInterface( XMultiServiceFactory.class, 396 m_documentComponent ); 397 return (XInterface) xORB.createInstanceWithArguments( serviceSpecifier, arguments ); 398 } 399 }; 400 401