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 
24 #ifndef SCRIPTDOCUMENT_HXX
25 #define SCRIPTDOCUMENT_HXX
26 
27 /** === begin UNO includes === **/
28 #include <com/sun/star/script/XLibraryContainer.hpp>
29 #include <com/sun/star/frame/XModel.hpp>
30 #include <com/sun/star/task/XStatusIndicator.hpp>
31 #include <com/sun/star/io/XInputStreamProvider.hpp>
32 /** === end UNO includes === **/
33 
34 #include <boost/shared_ptr.hpp>
35 #include <vector>
36 
37 class BasicManager;
38 class SfxListener;
39 
40 //........................................................................
41 namespace basctl
42 {
43 //........................................................................
44 
45     //====================================================================
46     //= LibraryContainerType
47     //====================================================================
48     enum LibraryContainerType
49     {
50         E_SCRIPTS,
51         E_DIALOGS
52     };
53 
54     enum LibraryLocation
55     {
56         LIBRARY_LOCATION_UNKNOWN,
57         LIBRARY_LOCATION_USER,
58         LIBRARY_LOCATION_SHARE,
59         LIBRARY_LOCATION_DOCUMENT
60     };
61 
62     enum LibraryType
63     {
64         LIBRARY_TYPE_UNKNOWN,
65         LIBRARY_TYPE_MODULE,
66         LIBRARY_TYPE_DIALOG,
67         LIBRARY_TYPE_ALL
68     };
69 
70     //====================================================================
71 	//= ScriptDocument
72 	//====================================================================
73     class ScriptDocument_Impl;
74 
75     class ScriptDocument;
76     typedef ::std::vector< ScriptDocument >  ScriptDocuments;
77 
78     /** encapsulates a document which contains Basic scripts and dialogs
79     */
80     class ScriptDocument
81 	{
82     private:
83         ::boost::shared_ptr< ScriptDocument_Impl > m_pImpl;
84 
85     private:
86         /** creates a ScriptDocument instance which operates on the application-wide
87             scripts and dialogs
88         */
89                     ScriptDocument();
90 
91     public:
92         enum SpecialDocument { NoDocument };
93         /** creates a ScriptDocument instance which does refers to neither the application-wide,
94             nor a specific real document's scripts.
95 
96             This constructor might come handy when you need some kind of uninitialized
97             ScriptDocument, which you do not want to operate on (yet), but initialize later
98             by assignment.
99 
100             <member>isValid</member> will return <FALSE/> for a ScriptDocument constructed
101             this way.
102         */
103         explicit    ScriptDocument( SpecialDocument _eType );
104 
105         /** creates a ScriptDocument instance which refers to a document given as
106             XModel
107 
108             @param _rxDocument
109                 the document. Must not be <NULL/>.
110         */
111         explicit    ScriptDocument( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& _rxDocument );
112 
113         /// copy constructor
114                     ScriptDocument( const ScriptDocument& _rSource );
115 
116         /// destructor
117                     ~ScriptDocument();
118 
119         /** returns a reference to a shared ScriptDocument instance which
120             operates on the application-wide scripts and dialogs
121         */
122         static const ScriptDocument&
123                     getApplicationScriptDocument();
124 
125         /** returns a (newly created) ScriptDocument instance for the document to
126             which a given BasicManager belongs
127 
128             If the basic manager is the application's basic manager, then the (shared)
129             ScriptDocument instance which is responsible for the application is returned.
130 
131             @see getApplicationScriptDocument
132         */
133         static ScriptDocument
134                     getDocumentForBasicManager( const BasicManager* _pManager );
135 
136         /** returns a (newly created) ScriptDocument instance for the document
137             with a given caption or URL
138 
139             If there is no document with the given caption, then the (shared)
140             ScriptDocument instance which is responsible for the application is returned.
141 
142             @see getApplicationScriptDocument
143         */
144         static ScriptDocument
145                     getDocumentWithURLOrCaption( const ::rtl::OUString& _rUrlOrCaption );
146 
147         /** operation mode for getAllScriptDocuments
148         */
149         enum ScriptDocumentList
150         {
151             /** all ScriptDocuments, including the dedicated one which represents
152                 the application-wide scripts/dialogs.
153             */
154             AllWithApplication,
155             /** real documents only
156             */
157             DocumentsOnly,
158             /** real documents only, sorted lexicographically by their title (using the sys locale's default
159                 collator)
160             */
161             DocumentsSorted
162         };
163 
164         /** returns the set of ScriptDocument instances, one for each open document which
165             contains Basic/Dialog containers; plus an additional instance for
166             the application, if desired
167 
168             Documents which are not visible - i.e. do not have a visible frame.
169 
170             @param _bIncludingApplication
171                 <TRUE/> if the application-wide scripts/dialogs should also be represented
172                 by a ScriptDocument
173         */
174         static ScriptDocuments
175                     getAllScriptDocuments( ScriptDocumentList _eListType );
176 
177         // comparison
178                 bool operator==( const ScriptDocument& _rhs ) const;
179         inline  bool operator!=( const ScriptDocument& _rhs ) const { return !( *this == _rhs ); }
180 
181         /// retrieves a (pretty simple) hash code for the document
182         sal_Int32   hashCode() const;
183 
184         /** determines whether the document is actually able to contain Basic/Dialog libraries
185 
186             Note that validity does not automatically imply the document can be used for active
187             work. Instead, it is possible the document is closed already (or being closed currently).
188             In this case, isValid will return <TRUE/>, but isAlive will return <FALSE/>.
189 
190             @return
191                 <TRUE/> if the instance refers to a document which contains Basic/Dialog libraries,
192                 or the application as a whole, <FALSE/> otherwise.
193 
194             @see isAlive
195         */
196         bool        isValid() const;
197 
198         /** determines whether the document instance is alive
199 
200             If the instance is not valid, <FALSE/> is returned.
201 
202             If the instance refers to a real document, which is already closed, or just being closed,
203             the method returns <FALSE/>.
204 
205             If the instance refers to the application, <TRUE/> is returned.
206 
207             @see isValid
208         */
209         bool        isAlive() const;
210 
211         bool        isInVBAMode() const;
212         /// returns the BasicManager associated with this instance
213         BasicManager*
214                     getBasicManager() const;
215 
216         /** returns the UNO component representing the document which the instance operates on
217 
218             Must not be used when the instance operates on the application-wide
219             Basic/Dialog libraries.
220         */
221         ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >
222                     getDocument() const;
223 
224         /** returns the UNO component representing the document which the instance operates on
225 
226             May be used when the instance operates on the application-wide
227             Basic/Dialog libraries, in this case it returns <NULL/>.
228         */
229         ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >
230                     getDocumentOrNull() const;
231 
232         /** returns the Basic or Dialog library container of the document
233 
234             If the document is not valid, <NULL/> is returned.
235         */
236         ::com::sun::star::uno::Reference< ::com::sun::star::script::XLibraryContainer >
237                     getLibraryContainer( LibraryContainerType _eType ) const;
238 
239         /** determines whether there exists a library of the given type, with the given name
240         */
241         bool        hasLibrary( LibraryContainerType _eType, const ::rtl::OUString& _rLibName ) const;
242 
243         /** returns a script or dialog library given by name
244 
245             @param _eType
246                 the type of library to load
247             @param _rLibName
248                 the name of the script library
249             @param _bLoadLibrary
250                 <TRUE/> if and only if the library should be loaded.
251 
252             @throws NoSuchElementException
253                 if there is no script library with the given name
254         */
255 	    ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >
256                     getLibrary( LibraryContainerType _eType, const ::rtl::OUString& _rLibName, bool _bLoadLibrary ) const
257                         SAL_THROW((::com::sun::star::container::NoSuchElementException));
258 
259         /** creates a script or dialog library in the document, or returns an existing one
260 
261             If <code>_rLibName</code> denotes an existing library which does not need to be created,
262             then this library will automatically be loaded, and then returned.
263         */
264         ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >
265                     getOrCreateLibrary( LibraryContainerType _eType, const ::rtl::OUString& _rLibName ) const;
266 
267         /** returns the names of the modules in a given script or dialog library of the document
268         */
269 	    ::com::sun::star::uno::Sequence< ::rtl::OUString >
270                     getObjectNames( LibraryContainerType _eType, const ::rtl::OUString& _rLibName ) const;
271 
272         /** retrieves a name for a newly to be created module or dialog
273         */
274         ::rtl::OUString
275                     createObjectName( LibraryContainerType _eType, const ::rtl::OUString& _rLibName ) const;
276 
277         /** loads a script or dialog library given by name, if there is such a library
278         */
279         void        loadLibraryIfExists( LibraryContainerType _eType, const ::rtl::OUString& _rLibrary );
280 
281         /// retrieves the (combined) names of all script and dialog libraries
282         ::com::sun::star::uno::Sequence< ::rtl::OUString >
283                     getLibraryNames() const;
284 
285         /** removes a given script module from the document
286 
287             @return
288                 <TRUE/> if and only if the removal was successful. When <FALSE/> is returned,
289                 this will reported as assertion in a non-product build.
290         */
291         bool        removeModule( const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rModuleName ) const;
292 
293         /** creates a module with the given name in the given library
294             @param  _rLibName
295                 the library name
296             @param  _rModName
297                 the name of the to-be-created module
298             @param  _bCreateMain
299                 determines whether or not a function Main should be created
300             @param  _out_rNewModuleCode
301                 the source code of the newly created module
302             @return
303                 <TRUE/> if and only if the creation was successful
304         */
305         bool        createModule( const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rModName, bool _bCreateMain, ::rtl::OUString& _out_rNewModuleCode ) const;
306 
307         /** inserts a given piece as code as module
308             @param  _rLibName
309                 the name of the library to insert the module into. If a library with this name does
310                 not yet exist, it will be created.
311             @param  _rModName
312                 the name of the module to insert the code as. Must denote a name which is not yet
313                 used in the module library.
314             @param  _rModuleCode
315                 the code of the new module
316             @return
317                 <TRUE/> if and only if the insertion was successful.
318         */
319         bool        insertModule( const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rModName, const ::rtl::OUString& _rModuleCode ) const;
320 
321         /** updates a given module with new code
322             @param  _rLibName
323                 the name of the library the modules lives in. Must denote an existing module library.
324             @param  _rModName
325                 the name of the module to update. Must denote an existing module in the given library.
326             @param  _rModuleCode
327                 the new module code.
328             @return
329                 <TRUE/> if and only if the insertion was successful.
330         */
331         bool        updateModule( const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rModName, const ::rtl::OUString& _rModuleCode ) const;
332 
333         /// determines whether a module with the given name exists in the given library
334         bool        hasModule( const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rModName ) const;
335 
336         /** retrieves a module's source
337             @param  _rLibName
338                 the library name where the module is located
339             @param  _rModName
340                 the module name
341             @param  _out_rModuleSource
342                 takes the module's source upon successful return
343             @return
344                 <TRUE/> if and only if the code could be successfully retrieved, <FALSE/> otherwise
345         */
346         bool        getModule( const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rModName, ::rtl::OUString& _rModuleSource ) const;
347 
348         /** renames a module
349             @param  _rLibName
350                 the library where the module lives in. Must denote an existing library.
351             @param  _rOldName
352                 the old module name. Must denote an existing module.
353             @param  _rNewName
354                 the new module name
355             @return
356                 <TRUE/> if and only if renaming was successful.
357         */
358         bool        renameModule( const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rOldName, const ::rtl::OUString& _rNewName ) const;
359 
360         /** removes a given dialog from the document
361 
362             @return
363                 <TRUE/> if and only if the removal was successful. When <FALSE/> is returned,
364                 this will reported as assertion in a non-product build.
365         */
366         bool        removeDialog( const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rDialogName ) const;
367 
368         /// determines whether a dialog with the given name exists in the given library
369         bool        hasDialog( const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rDialogName ) const;
370 
371         /** retrieves a dialog
372             @param  _rLibName
373                 the library name where the module is located
374             @param  _rDialogName
375                 the dialog's name
376             @param  _out_rDialogSource
377                 takes the provider for the dialog's desription, upon successful return
378             @return
379                 <TRUE/> if and only if the dialog could be successfully retrieved, <FALSE/> otherwise
380         */
381         bool        getDialog(
382                         const ::rtl::OUString& _rLibName,
383                         const ::rtl::OUString& _rDialogName,
384                         ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStreamProvider >& _out_rDialogProvider
385                     ) const;
386 
387         /** renames a dialog
388             @param  _rLibName
389                 the library where the dialog lives in. Must denote an existing library.
390             @param  _rOldName
391                 the old dialog name. Must denote an existing dialog.
392             @param  _rNewName
393                 the new dialog name
394             @param _rxExistingDialogModel
395                 the existing model of the dialog, if already loaded in the IDE
396             @return
397                 <TRUE/> if and only if renaming was successful.
398         */
399         bool        renameDialog(
400                         const ::rtl::OUString& _rLibName,
401                         const ::rtl::OUString& _rOldName,
402                         const ::rtl::OUString& _rNewName,
403                         const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& _rxExistingDialogModel
404                     ) const;
405 
406         /** create a dialog
407             @param  _rLibName
408                 the library name where the module is located
409             @param  _rDialogName
410                 the dialog's name
411             @param  _out_rDialogSource
412                 takes the provider for the dialog's desription, upon successful return
413             @return
414                 <TRUE/> if and only if the dialog could be successfully retrieved, <FALSE/> otherwise
415         */
416         bool        createDialog(
417                         const ::rtl::OUString& _rLibName,
418                         const ::rtl::OUString& _rDialogName,
419                         ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStreamProvider >& _out_rDialogProvider
420                     ) const;
421 
422         /** inserts a given dialog into a given library
423 
424             @param  _rLibName
425                 the name of the library to insert the dialog into. If a library with this name does
426                 not yet exist, it will be created.
427             @param  _rModName
428                 the name of the dialog to insert. Must denote a name which is not yet
429                 used in the dialog library.
430             @param  _rDialogProvider
431                 the provider of the dialog's description
432             @return
433                 <TRUE/> if and only if the insertion was successful.
434         */
435         bool        insertDialog(
436                         const ::rtl::OUString& _rLibName,
437                         const ::rtl::OUString& _rDialogName,
438                         const ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStreamProvider >& _rDialogProvider
439                     ) const;
440 
441         /** determines whether the document is read-only
442 
443             cannot be called if the document operates on the application-wide scripts
444         */
445         bool        isReadOnly() const;
446 
447         /** determines whether the ScriptDocument instance operates on the whole application,
448             as opposed to a real document
449         */
450         bool        isApplication() const;
451 
452         /** determines whether the ScriptDocument instance operates on a real document,
453             as opposed to the whole application
454         */
455         bool        isDocument() const { return isValid() && !isApplication(); }
456 
457         /** marks the document as modified
458             @precond
459                 the instance operates on a real document, not on the application
460             @see isDocument
461         */
462         void        setDocumentModified() const;
463 
464         /** determines whether the document is modified
465             @precond
466                 the instance operates on a real document, not on the application
467             @see isDocument
468         */
469         bool        isDocumentModified() const;
470 
471         /** saves the document, if the instance refers to a real document
472             @precond
473                 <code>isApplication</code> returns <FALSE/>
474         */
475         bool        saveDocument(
476                         const ::com::sun::star::uno::Reference< ::com::sun::star::task::XStatusIndicator >& _rxStatusIndicator
477                     ) const;
478 
479         /// returns the location of a library given by name
480         LibraryLocation
481                     getLibraryLocation( const ::rtl::OUString& _rLibName ) const;
482 
483         /// returns the title for the document
484         ::rtl::OUString
485                     getTitle( LibraryLocation _eLocation, LibraryType _eType = LIBRARY_TYPE_ALL ) const;
486 
487         /** returns the title of the document
488 
489             to be used for valid documents only
490         */
491         ::rtl::OUString
492                     getTitle() const;
493 
494         /** returns the URL of the document
495 
496             to be used for valid documents only
497         */
498         ::rtl::OUString
499                     getURL() const;
500 
501         /** determines whether the document is currently the one-and-only application-wide active document
502         */
503         bool        isActive() const;
504 
505         /** determines whether macro execution for this document is allowed
506 
507             only to be called for real documents (->isDocument)
508         */
509         bool    allowMacros() const;
510 	};
511 
512 //........................................................................
513 } // namespace basctl
514 //........................................................................
515 
516 // convenience ... better would be all classes in the project are in
517 // the same namespace ...
518 using ::basctl::ScriptDocument;
519 using ::basctl::ScriptDocuments;
520 using ::basctl::E_SCRIPTS;
521 using ::basctl::E_DIALOGS;
522 using ::basctl::LibraryLocation;
523 using ::basctl::LIBRARY_LOCATION_UNKNOWN;
524 using ::basctl::LIBRARY_LOCATION_USER;
525 using ::basctl::LIBRARY_LOCATION_SHARE;
526 using ::basctl::LIBRARY_LOCATION_DOCUMENT;
527 using ::basctl::LibraryType;
528 using ::basctl::LIBRARY_TYPE_UNKNOWN;
529 using ::basctl::LIBRARY_TYPE_MODULE;
530 using ::basctl::LIBRARY_TYPE_DIALOG;
531 using ::basctl::LIBRARY_TYPE_ALL;
532 
533 #endif // SCRIPTDOCUMENT_HXX
534