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 
28 /**************************************************************************/
29 import com.sun.star.uno.*;
30 import com.sun.star.lang.*;
31 import com.sun.star.util.*;
32 import com.sun.star.awt.*;
33 import com.sun.star.drawing.*;
34 import com.sun.star.frame.*;
35 import com.sun.star.form.*;
36 import com.sun.star.beans.*;
37 import com.sun.star.container.*;
38 import com.sun.star.container.*;
39 
40 /**************************************************************************/
41 /** provides a small wrapper around a document
42 */
43 public class DocumentHelper
44 {
45     /// the remote office context
46     protected XComponentContext         m_remoteContext;
47     /// the remote service manager
48     protected XMultiServiceFactory      m_orb;
49     protected XComponent                m_documentComponent;
50 
51     /* ------------------------------------------------------------------ */
52     public XComponent getDocument( )
53     {
54         return m_documentComponent;
55     }
56 
57     /* ------------------------------------------------------------------ */
58     public XComponentContext getContext( )
59     {
60         return m_remoteContext;
61     }
62 
63     /* ------------------------------------------------------------------ */
64     public XMultiServiceFactory getOrb( )
65     {
66         return m_orb;
67     }
68 
69     /* ------------------------------------------------------------------ */
70     public DocumentHelper( XComponentContext xContext, XComponent document )
71     {
72         m_remoteContext = xContext;
73         m_orb = (XMultiServiceFactory)UnoRuntime.queryInterface(
74             XMultiServiceFactory.class, m_remoteContext.getServiceManager());
75         m_documentComponent = document;
76     }
77 
78     /* ------------------------------------------------------------------ */
79     protected static XComponent implCreateBlankDocument( XComponentContext xCtx, String factoryURL ) throws com.sun.star.uno.Exception
80     {
81         XComponentLoader aLoader = (XComponentLoader)UnoRuntime.queryInterface(
82             XComponentLoader.class,
83             xCtx.getServiceManager().createInstanceWithContext(
84                 "com.sun.star.frame.Desktop", xCtx ));
85 
86         return UNO.queryComponent(
87             aLoader.loadComponentFromURL( factoryURL, "_blank", 0, new PropertyValue[ 0 ] )
88         );
89     }
90 
91     /* ------------------------------------------------------------------ */
92     public static DocumentHelper blankTextDocument( XComponentContext xCtx ) throws com.sun.star.uno.Exception
93     {
94         return blankDocument( xCtx, DocumentType.WRITER );
95     }
96 
97     /* ------------------------------------------------------------------ */
98     public static DocumentHelper blankDocument( XComponentContext xCtx, DocumentType eType ) throws com.sun.star.uno.Exception
99     {
100         XComponent document = implCreateBlankDocument( xCtx, getDocumentFactoryURL( eType ) );
101         if ( eType == DocumentType.CALC )
102             return new SpreadsheetDocument( xCtx, document );
103 
104         return new DocumentHelper( xCtx, document );
105     }
106 
107     /* ------------------------------------------------------------------ */
108     /** retrieves the current view of the document
109         @return
110             the view component, queried for the interface described by aInterfaceClass
111     */
112     public DocumentViewHelper getCurrentView( )
113     {
114         // get the model interface for the document
115         XModel xDocModel = (XModel)UnoRuntime.queryInterface(XModel.class, m_documentComponent );
116         // get the current controller for the document - as a controller is tied to a view,
117         // this gives us the currently active view for the document.
118         XController xController = xDocModel.getCurrentController();
119 
120         if ( classify() == DocumentType.CALC )
121             return new SpreadsheetView( m_orb, this, xController );
122 
123         return new DocumentViewHelper( m_orb, this, xController );
124     }
125 
126     /* ------------------------------------------------------------------ */
127     /** creates a new form which is a child of the given form components container
128 
129         @param xParentContainer
130             The parent container for the new form
131         @param sInitialName
132             The initial name of the form. May be null, in this case the default (which
133             is an implementation detail) applies.
134     */
135     protected XIndexContainer createSubForm( XIndexContainer xParentContainer, String sInitialName )
136             throws com.sun.star.uno.Exception
137     {
138         // create a new form
139         Object xNewForm = m_orb.createInstance( "com.sun.star.form.component.DataForm" );
140 
141         // insert
142         xParentContainer.insertByIndex( xParentContainer.getCount(), xNewForm );
143 
144         // set the name if necessary
145         if ( null != sInitialName )
146         {
147             XPropertySet xFormProps = UNO.queryPropertySet( xNewForm );
148             xFormProps.setPropertyValue( "Name", sInitialName );
149         }
150 
151         // outta here
152         return (XIndexContainer)UnoRuntime.queryInterface( XIndexContainer.class, xNewForm );
153     }
154 
155     /* ------------------------------------------------------------------ */
156     /** creates a new form which is a child of the given form components container
157 
158         @param aParentContainer
159             The parent container for the new form
160         @param sInitialName
161             The initial name of the form. May be null, in this case the default (which
162             is an implementation detail) applies.
163     */
164     public XIndexContainer createSubForm( Object aParentContainer, String sInitialName )
165         throws com.sun.star.uno.Exception
166     {
167         XIndexContainer xParentContainer = (XIndexContainer)UnoRuntime.queryInterface(
168             XIndexContainer.class, aParentContainer );
169         return createSubForm( xParentContainer, sInitialName );
170     }
171 
172     /* ------------------------------------------------------------------ */
173     /** creates a form which is a sibling of the given form
174         @param aForm
175             A sinbling of the to be created form.
176 
177         @param sInitialName
178             The initial name of the form. May be null, in this case the default (which
179             is an implementation detail) applies.
180     */
181     public XIndexContainer createSiblingForm( Object aForm, String sInitialName ) throws com.sun.star.uno.Exception
182     {
183         // get the parent
184         XChild xAsChild = (XChild)UnoRuntime.queryInterface( XChild.class, aForm );
185         XIndexContainer xContainer = (XIndexContainer)UnoRuntime.queryInterface(
186             XIndexContainer.class, xAsChild.getParent() );;
187         // append a new form to this parent container
188         return createSubForm( xContainer, sInitialName );
189     }
190 
191     /* ------------------------------------------------------------------ */
192     /** retrieves the document model which a given form component belongs to
193     */
194     static public DocumentHelper getDocumentForComponent( Object aFormComponent, XComponentContext xCtx )
195     {
196         XChild xChild = (XChild)UnoRuntime.queryInterface( XChild.class, aFormComponent );
197         XModel xModel = null;
198         while ( ( null != xChild ) && ( null == xModel ) )
199         {
200             XInterface xParent = (XInterface)xChild.getParent();
201             xModel = (XModel)UnoRuntime.queryInterface( XModel.class, xParent );
202             xChild = (XChild)UnoRuntime.queryInterface( XChild.class, xParent );
203         }
204 
205         return new DocumentHelper( xCtx, xModel );
206     }
207 
208     /* ------------------------------------------------------------------ */
209     /** returns a URL which can be used to create a document of a certain type
210     */
211     public static String getDocumentFactoryURL( DocumentType eType )
212     {
213         if ( eType == DocumentType.WRITER )
214             return "private:factory/swriter";
215         if ( eType == DocumentType.CALC )
216             return "private:factory/scalc";
217         if ( eType == DocumentType.DRAWING )
218             return "private:factory/sdraw";
219         return "private:factory/swriter";
220     }
221 
222     /* ------------------------------------------------------------------ */
223     /** classifies a document
224     */
225     public DocumentType classify( )
226     {
227         XServiceInfo xSI = (XServiceInfo)UnoRuntime.queryInterface(
228             XServiceInfo.class, m_documentComponent );
229 
230         if ( xSI.supportsService( "com.sun.star.text.TextDocument" ) )
231             return DocumentType.WRITER;
232         else if ( xSI.supportsService( "com.sun.star.sheet.SpreadsheetDocument" ) )
233             return DocumentType.CALC;
234         else if ( xSI.supportsService( "com.sun.star.drawing.DrawingDocument" ) )
235             return DocumentType.DRAWING;
236 
237         return DocumentType.UNKNOWN;
238     }
239     /* ------------------------------------------------------------------ */
240     /** retrieves a com.sun.star.drawing.DrawPage of the document, denoted by index
241      *  @param index
242      *      the index of the draw page<br/>
243      *  @throws
244      *      com.sun.star.lang.IndexOutOfBoundsException
245      *      com.sun.star.lang.WrappedTargetException
246      */
247     protected XDrawPage getDrawPage( int index ) throws com.sun.star.lang.IndexOutOfBoundsException, com.sun.star.lang.WrappedTargetException
248     {
249         XDrawPagesSupplier xSuppPages = (XDrawPagesSupplier)UnoRuntime.queryInterface(
250             XDrawPagesSupplier.class, getDocument() );
251         XDrawPages xPages = xSuppPages.getDrawPages();
252 
253         return (XDrawPage)UnoRuntime.queryInterface( XDrawPage.class, xPages.getByIndex( index ) );
254     }
255 
256     /* ------------------------------------------------------------------ */
257     /** retrieves the <type scope="com.sun.star.drawing">DrawPage</type> of the document
258     */
259     protected XDrawPage getMainDrawPage( ) throws com.sun.star.uno.Exception
260     {
261         XDrawPage xReturn;
262 
263         // in case of a Writer document, this is rather easy: simply ask the XDrawPageSupplier
264         XDrawPageSupplier xSuppPage = (XDrawPageSupplier)UnoRuntime.queryInterface(
265             XDrawPageSupplier.class, getDocument() );
266         if ( null != xSuppPage )
267             xReturn = xSuppPage.getDrawPage();
268         else
269         {   // the model itself is no draw page supplier - okay, it may be a Writer or Calc document
270             // (or any other multi-page document)
271             XDrawPagesSupplier xSuppPages = (XDrawPagesSupplier)UnoRuntime.queryInterface(
272                 XDrawPagesSupplier.class, getDocument() );
273             XDrawPages xPages = xSuppPages.getDrawPages();
274 
275             xReturn = (XDrawPage)UnoRuntime.queryInterface( XDrawPage.class, xPages.getByIndex( 0 ) );
276 
277             // Note that this is no really error-proof code: If the document model does not support the
278             // XDrawPagesSupplier interface, or if the pages collection returned is empty, this will break.
279         }
280 
281         return xReturn;
282     }
283 
284     /* ------------------------------------------------------------------ */
285     /** retrieves the root of the hierarchy of form components
286     */
287     protected XNameContainer getFormComponentTreeRoot( ) throws com.sun.star.uno.Exception
288     {
289         XFormsSupplier xSuppForms = (XFormsSupplier)UnoRuntime.queryInterface(
290             XFormsSupplier.class, getMainDrawPage( ) );
291 
292         XNameContainer xFormsCollection = null;
293         if ( null != xSuppForms )
294         {
295             xFormsCollection = xSuppForms.getForms();
296         }
297         return xFormsCollection;
298     }
299 
300     /* ------------------------------------------------------------------ */
301     /** creates a component at the service factory provided by the document
302     */
303     public XInterface createInstance( String serviceSpecifier ) throws com.sun.star.uno.Exception
304     {
305         XMultiServiceFactory xORB = (XMultiServiceFactory)UnoRuntime.queryInterface( XMultiServiceFactory.class,
306             m_documentComponent );
307         return (XInterface)xORB.createInstance( serviceSpecifier );
308     }
309 
310     /* ------------------------------------------------------------------ */
311     /** creates a component at the service factory provided by the document
312     */
313     public XInterface createInstanceWithArguments( String serviceSpecifier, Object[] arguments ) throws com.sun.star.uno.Exception
314     {
315         XMultiServiceFactory xORB = (XMultiServiceFactory)UnoRuntime.queryInterface( XMultiServiceFactory.class,
316             m_documentComponent );
317         return (XInterface) xORB.createInstanceWithArguments( serviceSpecifier, arguments );
318     }
319 };
320 
321