xref: /trunk/main/basctl/source/basicide/scriptdocument.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_basctl.hxx"
26 
27 #include "scriptdocument.hxx"
28 #include "basobj.hxx"
29 #include "basidesh.hrc"
30 #include "iderid.hxx"
31 #include "dlgeddef.hxx"
32 #include "localizationmgr.hxx"
33 #include "doceventnotifier.hxx"
34 #include "documentenumeration.hxx"
35 
36 /** === begin UNO includes === **/
37 #include <com/sun/star/beans/XPropertySet.hpp>
38 #include <com/sun/star/script/XLibraryContainer2.hpp>
39 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
40 #include <com/sun/star/uri/XUriReferenceFactory.hpp>
41 #include <com/sun/star/util/XMacroExpander.hpp>
42 #include <com/sun/star/document/MacroExecMode.hpp>
43 #include <com/sun/star/document/XEventBroadcaster.hpp>
44 #include <com/sun/star/frame/XStorable.hpp>
45 #include <com/sun/star/util/XModifiable.hpp>
46 #include <com/sun/star/frame/XDispatchProvider.hpp>
47 #include <com/sun/star/frame/FrameSearchFlag.hpp>
48 #include <com/sun/star/frame/XDesktop.hpp>
49 #include <com/sun/star/frame/XModel2.hpp>
50 #include <com/sun/star/awt/XWindow2.hpp>
51 #include <com/sun/star/document/XEmbeddedScripts.hpp>
52 #include <com/sun/star/script/vba/XVBACompatibility.hpp>
53 #include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
54 /** === end UNO includes === **/
55 
56 #include <sfx2/objsh.hxx>
57 #include <sfx2/app.hxx>
58 #include <sfx2/viewfrm.hxx>
59 #include <sfx2/bindings.hxx>
60 #include <sfx2/docfile.hxx>
61 
62 #include <vcl/svapp.hxx>
63 
64 #include <basic/basicmanagerrepository.hxx>
65 
66 #include <xmlscript/xmldlg_imexp.hxx>
67 
68 #include <unotools/syslocale.hxx>
69 
70 #include <unotools/collatorwrapper.hxx>
71 
72 #include <tools/diagnose_ex.h>
73 #include <tools/urlobj.hxx>
74 
75 #include <comphelper/processfactory.hxx>
76 #include <comphelper/documentinfo.hxx>
77 #include <comphelper/componentcontext.hxx>
78 
79 #include <vos/mutex.hxx>
80 
81 #include <cppuhelper/implbase1.hxx>
82 
83 #include <rtl/uri.hxx>
84 #include <rtl/bootstrap.hxx>
85 
86 #include <osl/process.h>
87 #include <osl/file.hxx>
88 
89 #include <algorithm>
90 #include <functional>
91 #include <set>
92 #include <iterator>
93 
94 //........................................................................
95 namespace basctl
96 {
97 //........................................................................
98 
99     /** === begin UNO using === **/
100     using ::com::sun::star::uno::Sequence;
101     using ::com::sun::star::uno::Reference;
102     using ::com::sun::star::frame::XModel;
103     using ::com::sun::star::beans::XPropertySet;
104     using ::com::sun::star::script::XLibraryContainer;
105     using ::com::sun::star::uno::UNO_QUERY_THROW;
106     using ::com::sun::star::uno::UNO_SET_THROW;
107     using ::com::sun::star::beans::XPropertySetInfo;
108     using ::com::sun::star::uno::Exception;
109     using ::com::sun::star::container::XNameContainer;
110     using ::com::sun::star::container::NoSuchElementException;
111     using ::com::sun::star::uno::UNO_QUERY;
112     using ::com::sun::star::task::XStatusIndicator;
113     using ::com::sun::star::uno::makeAny;
114     using ::com::sun::star::script::XLibraryContainer2;
115     using ::com::sun::star::lang::XMultiServiceFactory;
116     using ::com::sun::star::uri::XUriReferenceFactory;
117     using ::com::sun::star::uri::XUriReference;
118     using ::com::sun::star::uno::XComponentContext;
119     using ::com::sun::star::util::XMacroExpander;
120     using ::com::sun::star::io::XInputStreamProvider;
121     using ::com::sun::star::uno::Any;
122     using ::com::sun::star::io::XInputStream;
123     using ::com::sun::star::frame::XStorable;
124     using ::com::sun::star::util::XModifiable;
125     using ::com::sun::star::frame::XController;
126     using ::com::sun::star::frame::XFrame;
127     using ::com::sun::star::util::URL;
128     using ::com::sun::star::frame::XDispatchProvider;
129     using ::com::sun::star::frame::XDispatch;
130     using ::com::sun::star::beans::PropertyValue;
131     using ::com::sun::star::frame::XDesktop;
132     using ::com::sun::star::container::XEnumerationAccess;
133     using ::com::sun::star::container::XEnumeration;
134     using ::com::sun::star::frame::XModel2;
135     using ::com::sun::star::awt::XWindow2;
136     using ::com::sun::star::document::XEventListener;
137     using ::com::sun::star::lang::EventObject;
138     using ::com::sun::star::uno::RuntimeException;
139     using ::com::sun::star::document::XEventBroadcaster;
140     using ::com::sun::star::document::XEmbeddedScripts;
141     using ::com::sun::star::script::ModuleInfo;
142     using ::com::sun::star::script::vba::XVBACompatibility;
143     using ::com::sun::star::script::vba::XVBAModuleInfo;
144     /** === end UNO using === **/
145     namespace MacroExecMode = ::com::sun::star::document::MacroExecMode;
146     namespace FrameSearchFlag = ::com::sun::star::frame::FrameSearchFlag;
147 
148     //====================================================================
149     //= helper
150     //====================================================================
151     namespace
152     {
153         //................................................................
StringCompareLessThan(const String & lhs,const String & rhs)154         static bool StringCompareLessThan( const String& lhs, const String& rhs )
155         {
156             return ( lhs.CompareIgnoreCaseToAscii( rhs ) == COMPARE_LESS );
157         }
158 
159         //................................................................
160         class FilterDocuments : public docs::IDocumentDescriptorFilter
161         {
162         public:
FilterDocuments(bool _bFilterInvisible)163             FilterDocuments( bool _bFilterInvisible ) : m_bFilterInvisible( _bFilterInvisible ) { }
164 
165             virtual bool    includeDocument( const docs::DocumentDescriptor& _rDocument ) const;
166 
167         private:
168             bool    impl_isDocumentVisible_nothrow( const docs::DocumentDescriptor& _rDocument ) const;
169 
170         private:
171             bool    m_bFilterInvisible;
172         };
173 
174         //................................................................
impl_isDocumentVisible_nothrow(const docs::DocumentDescriptor & _rDocument) const175         bool FilterDocuments::impl_isDocumentVisible_nothrow( const docs::DocumentDescriptor& _rDocument ) const
176         {
177             try
178             {
179                 for (   docs::Controllers::const_iterator controller = _rDocument.aControllers.begin();
180                         controller != _rDocument.aControllers.end();
181                         ++controller
182                     )
183                 {
184                     Reference< XFrame > xFrame( (*controller)->getFrame(), UNO_SET_THROW );
185                     Reference< XWindow2 > xContainer( xFrame->getContainerWindow(), UNO_QUERY_THROW );
186                     if ( xContainer->isVisible() )
187                         return true;
188                 }
189             }
190             catch( const Exception& )
191             {
192                 DBG_UNHANDLED_EXCEPTION();
193             }
194             return false;
195         }
196 
197         //................................................................
includeDocument(const docs::DocumentDescriptor & _rDocument) const198         bool FilterDocuments::includeDocument( const docs::DocumentDescriptor& _rDocument ) const
199         {
200             Reference< XEmbeddedScripts > xScripts( _rDocument.xModel, UNO_QUERY );
201             if ( !xScripts.is() )
202                 return false;
203             if ( !m_bFilterInvisible || impl_isDocumentVisible_nothrow( _rDocument ) )
204                 return true;
205             return false;
206         }
207 
208         //................................................................
lcl_getAllModels_throw(docs::Documents & _out_rModels,bool _bVisibleOnly)209         void lcl_getAllModels_throw( docs::Documents& _out_rModels, bool _bVisibleOnly )
210         {
211             _out_rModels.clear();
212 
213             ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
214             FilterDocuments aFilter( _bVisibleOnly );
215             docs::DocumentEnumeration aEnum( aContext, &aFilter );
216 
217             aEnum.getDocuments( _out_rModels );
218         }
219     }
220 
221     //====================================================================
222     //= ScriptDocument_Impl - declaration
223     //====================================================================
224     class ScriptDocument_Impl : public DocumentEventListener
225     {
226     private:
227         bool                            m_bIsApplication;
228         bool                            m_bValid;
229         bool                            m_bDocumentClosed;
230         Reference< XModel >             m_xDocument;
231         Reference< XModifiable >        m_xDocModify;
232         Reference< XEmbeddedScripts >   m_xScriptAccess;
233         ::std::auto_ptr< DocumentEventNotifier >
234                                         m_pDocListener;
235 
236     public:
237         ScriptDocument_Impl( );
238         ScriptDocument_Impl( const Reference< XModel >& _rxDocument );
239         ~ScriptDocument_Impl();
240 
241         /** determines whether the instance refers to a valid "document" with script and
242             dialog libraries
243         */
isValid() const244         inline  bool    isValid()       const   { return m_bValid; }
245         /** determines whether the instance refers to a non-closed document
246         */
isAlive() const247         inline  bool    isAlive()       const   { return m_bValid ? ( m_bIsApplication ? true : !m_bDocumentClosed ) : false; }
248         /// determines whether the "document" refers to the application in real
isApplication() const249         inline  bool    isApplication() const   { return m_bValid && m_bIsApplication; }
250         /// determines whether the document refers to a real document (instead of the application)
isDocument() const251         inline  bool    isDocument()    const   { return m_bValid && !m_bIsApplication; }
252 
253         /** invalidates the instance
254         */
255         void    invalidate();
256 
257         const Reference< XModel >&
getDocumentRef() const258                         getDocumentRef() const { return m_xDocument; }
259 
260         /// returns a library container belonging to the document
261         Reference< XLibraryContainer >
262                     getLibraryContainer( LibraryContainerType _eType ) const;
263 
264         /// determines whether a given library is part of the shared installation
265         bool        isLibraryShared( const ::rtl::OUString& _rLibName, LibraryContainerType _eType );
266 
267         /** returns the current frame of the document
268 
269             To be called for documents only, not for the application.
270 
271             If <FALSE/> is returned, an assertion will be raised in non-product builds.
272         */
273         bool        getCurrentFrame( Reference< XFrame >& _out_rxFrame ) const;
274 
275         // versions with the same signature/semantics as in ScriptDocument itself
276         bool        isReadOnly() const;
277         bool        isInVBAMode() const;
278         BasicManager*
279                     getBasicManager() const;
280         Reference< XModel >
281                     getDocument() const;
282         void        setDocumentModified() const;
283         bool        isDocumentModified() const;
284         bool        saveDocument( const Reference< XStatusIndicator >& _rxStatusIndicator ) const;
285 
286         ::rtl::OUString
287                     getTitle() const;
288         ::rtl::OUString
289                     getURL() const;
290 
291         bool        allowMacros() const;
292 
293         Reference< XNameContainer >
294                     getLibrary( LibraryContainerType _eType, const ::rtl::OUString& _rLibName, bool _bLoadLibrary ) const;
295         bool        hasLibrary( LibraryContainerType _eType, const ::rtl::OUString& _rLibName ) const;
296         Reference< XNameContainer >
297                     getOrCreateLibrary( LibraryContainerType _eType, const ::rtl::OUString& _rLibName ) const;
298 
299         void        loadLibraryIfExists( LibraryContainerType _eType, const ::rtl::OUString& _rLibrary );
300 
301         bool        removeModuleOrDialog( LibraryContainerType _eType, const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rModuleName );
302         bool        hasModuleOrDialog( LibraryContainerType _eType, const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rModName ) const;
303         bool        getModuleOrDialog( LibraryContainerType _eType, const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rObjectName, Any& _out_rModuleOrDialog );
304         bool        renameModuleOrDialog( LibraryContainerType _eType, const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rOldName, const ::rtl::OUString& _rNewName, const Reference< XNameContainer >& _rxExistingDialogModel );
305         bool        createModule( const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rModName, bool _bCreateMain, ::rtl::OUString& _out_rNewModuleCode ) const;
306         bool        insertModuleOrDialog( LibraryContainerType _eType, const ::rtl::OUString& _rObjectName, const ::rtl::OUString& _rModName, const Any& _rElement ) const;
307         bool        updateModule( const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rModName, const ::rtl::OUString& _rModuleCode ) const;
308         bool        createDialog( const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rDialogName, Reference< XInputStreamProvider >& _out_rDialogProvider ) const;
309 
310     protected:
311         // DocumentEventListener
312         virtual void onDocumentCreated( const ScriptDocument& _rDocument );
313         virtual void onDocumentOpened( const ScriptDocument& _rDocument );
314         virtual void onDocumentSave( const ScriptDocument& _rDocument );
315         virtual void onDocumentSaveDone( const ScriptDocument& _rDocument );
316         virtual void onDocumentSaveAs( const ScriptDocument& _rDocument );
317         virtual void onDocumentSaveAsDone( const ScriptDocument& _rDocument );
318         virtual void onDocumentClosed( const ScriptDocument& _rDocument );
319         virtual void onDocumentTitleChanged( const ScriptDocument& _rDocument );
320         virtual void onDocumentModeChanged( const ScriptDocument& _rDocument );
321 
322     private:
323         bool        impl_initDocument_nothrow( const Reference< XModel >& _rxModel );
324     };
325 
326     //====================================================================
327     //= ScriptDocument_Impl - implementation
328     //====================================================================
329     //--------------------------------------------------------------------
ScriptDocument_Impl()330     ScriptDocument_Impl::ScriptDocument_Impl()
331         :m_bIsApplication( true )
332         ,m_bValid( true )
333         ,m_bDocumentClosed( false )
334     {
335     }
336 
337     //--------------------------------------------------------------------
ScriptDocument_Impl(const Reference<XModel> & _rxDocument)338     ScriptDocument_Impl::ScriptDocument_Impl( const Reference< XModel >& _rxDocument )
339         :m_bIsApplication( false )
340         ,m_bValid( false )
341         ,m_bDocumentClosed( false )
342     {
343         if ( _rxDocument.is() )
344         {
345             if ( impl_initDocument_nothrow( _rxDocument ) )
346             {
347             }
348         }
349     }
350 
351     //--------------------------------------------------------------------
~ScriptDocument_Impl()352     ScriptDocument_Impl::~ScriptDocument_Impl()
353     {
354         invalidate();
355     }
356 
357     //--------------------------------------------------------------------
invalidate()358     void ScriptDocument_Impl::invalidate()
359     {
360         m_bIsApplication = false;
361         m_bValid = false;
362         m_bDocumentClosed = false;
363 
364         m_xDocument.clear();
365         m_xDocModify.clear();
366         m_xScriptAccess.clear();
367 
368         if ( m_pDocListener.get() )
369             m_pDocListener->dispose();
370     }
371 
372     //--------------------------------------------------------------------
impl_initDocument_nothrow(const Reference<XModel> & _rxModel)373     bool ScriptDocument_Impl::impl_initDocument_nothrow( const Reference< XModel >& _rxModel )
374     {
375         try
376         {
377             m_xDocument.set     ( _rxModel, UNO_SET_THROW );
378             m_xDocModify.set    ( _rxModel, UNO_QUERY_THROW );
379             m_xScriptAccess.set ( _rxModel, UNO_QUERY );
380 
381             m_bValid = m_xScriptAccess.is();
382 
383             if ( m_bValid )
384                 m_pDocListener.reset( new DocumentEventNotifier( *this, _rxModel ) );
385         }
386         catch( const Exception& )
387         {
388             DBG_UNHANDLED_EXCEPTION();
389             m_bValid = false;
390         }
391 
392         if ( !m_bValid )
393         {
394             invalidate();
395         }
396 
397         return m_bValid;
398     }
399     //--------------------------------------------------------------------
getLibraryContainer(LibraryContainerType _eType) const400     Reference< XLibraryContainer > ScriptDocument_Impl::getLibraryContainer( LibraryContainerType _eType ) const
401     {
402         OSL_ENSURE( isValid(), "ScriptDocument_Impl::getLibraryContainer: invalid!" );
403 
404         Reference< XLibraryContainer > xContainer;
405         if ( !isValid() )
406             return xContainer;
407 
408         try
409         {
410             if ( isApplication() )
411                 xContainer.set( _eType == E_SCRIPTS ? SFX_APP()->GetBasicContainer() : SFX_APP()->GetDialogContainer(), UNO_QUERY_THROW );
412             else
413             {
414                 xContainer.set(
415                     _eType == E_SCRIPTS ? m_xScriptAccess->getBasicLibraries() : m_xScriptAccess->getDialogLibraries(),
416                     UNO_QUERY_THROW );
417             }
418         }
419         catch( const Exception& )
420         {
421             DBG_UNHANDLED_EXCEPTION();
422         }
423         return xContainer;
424     }
425 
426     //--------------------------------------------------------------------
isReadOnly() const427     bool ScriptDocument_Impl::isReadOnly() const
428     {
429         OSL_ENSURE( isValid(), "ScriptDocument_Impl::isReadOnly: invalid state!" );
430         OSL_ENSURE( !isApplication(), "ScriptDocument_Impl::isReadOnly: not allowed to be called for the application!" );
431 
432         bool bIsReadOnly = true;
433         if ( isValid() && !isApplication() )
434         {
435             try
436             {
437                 // note that XStorable is required by the OfficeDocument service
438                 Reference< XStorable > xDocStorable( m_xDocument, UNO_QUERY_THROW );
439                 bIsReadOnly = xDocStorable->isReadonly();
440             }
441             catch( const Exception& )
442             {
443                 DBG_UNHANDLED_EXCEPTION();
444             }
445         }
446         return bIsReadOnly;
447     }
448 
isInVBAMode() const449     bool ScriptDocument_Impl::isInVBAMode() const
450     {
451         bool bResult = false;
452 #ifdef FUTURE_VBA_CWS
453         if ( !isApplication() )
454         {
455             Reference< XVBACompatibility > xVBACompat( getLibraryContainer( E_SCRIPTS ), UNO_QUERY );
456             if ( xVBACompat.is() )
457                 bResult = xVBACompat->getVBACompatibilityMode();
458         }
459 #endif
460         return bResult;
461     }
462 
463     //--------------------------------------------------------------------
getBasicManager() const464     BasicManager* ScriptDocument_Impl::getBasicManager() const
465     {
466         OSL_ENSURE( isValid(), "ScriptDocument_Impl::getBasicManager: invalid state!" );
467         if ( !isValid() )
468             return NULL;
469 
470         if ( isApplication() )
471             return SFX_APP()->GetBasicManager();
472 
473         return ::basic::BasicManagerRepository::getDocumentBasicManager( m_xDocument );
474     }
475 
476     //--------------------------------------------------------------------
getDocument() const477     Reference< XModel > ScriptDocument_Impl::getDocument() const
478     {
479         OSL_ENSURE( isValid(), "ScriptDocument_Impl::getDocument: invalid state!" );
480         OSL_ENSURE( isDocument(), "ScriptDocument_Impl::getDocument: for documents only!" );
481         if ( !isValid() || !isDocument() )
482             return NULL;
483 
484         return m_xDocument;
485     }
486 
487     //--------------------------------------------------------------------
getLibrary(LibraryContainerType _eType,const::rtl::OUString & _rLibName,bool _bLoadLibrary) const488     Reference< XNameContainer > ScriptDocument_Impl::getLibrary( LibraryContainerType _eType, const ::rtl::OUString& _rLibName, bool _bLoadLibrary ) const
489     {
490         OSL_ENSURE( isValid(), "ScriptDocument_Impl::getLibrary: invalid state!" );
491 
492         Reference< XNameContainer > xContainer;
493         try
494         {
495             Reference< XLibraryContainer > xLibContainer = getLibraryContainer( _eType );
496             if ( isValid() )
497             {
498                 if ( xLibContainer.is() )
499                     xContainer.set( xLibContainer->getByName( _rLibName ), UNO_QUERY_THROW );
500             }
501 
502             if ( !xContainer.is() )
503                 throw NoSuchElementException();
504 
505             // load library
506             if ( _bLoadLibrary && !xLibContainer->isLibraryLoaded( _rLibName ) )
507                 xLibContainer->loadLibrary( _rLibName );
508         }
509         catch( const NoSuchElementException& )
510         {
511             throw;  // allowed to leave
512         }
513         catch( const Exception& )
514         {
515             DBG_UNHANDLED_EXCEPTION();
516         }
517 
518         return xContainer;
519     }
520 
521     //--------------------------------------------------------------------
hasLibrary(LibraryContainerType _eType,const::rtl::OUString & _rLibName) const522     bool ScriptDocument_Impl::hasLibrary( LibraryContainerType _eType, const ::rtl::OUString& _rLibName ) const
523     {
524         bool bHas = false;
525         try
526         {
527             Reference< XLibraryContainer > xLibContainer = getLibraryContainer( _eType );
528             bHas = xLibContainer.is() && xLibContainer->hasByName( _rLibName );
529         }
530         catch( const Exception& )
531         {
532             DBG_UNHANDLED_EXCEPTION();
533         }
534         return bHas;
535     }
536 
537     //--------------------------------------------------------------------
getOrCreateLibrary(LibraryContainerType _eType,const::rtl::OUString & _rLibName) const538     Reference< XNameContainer > ScriptDocument_Impl::getOrCreateLibrary( LibraryContainerType _eType, const ::rtl::OUString& _rLibName ) const
539     {
540         Reference< XNameContainer > xLibrary;
541         try
542         {
543             Reference< XLibraryContainer > xLibContainer( getLibraryContainer( _eType ), UNO_QUERY_THROW );
544             if ( xLibContainer->hasByName( _rLibName ) )
545                 xLibrary.set( xLibContainer->getByName( _rLibName ), UNO_QUERY_THROW );
546             else
547                 xLibrary.set( xLibContainer->createLibrary( _rLibName ), UNO_QUERY_THROW );
548 
549             if ( !xLibContainer->isLibraryLoaded( _rLibName ) )
550                 xLibContainer->loadLibrary( _rLibName );
551         }
552         catch( const Exception& )
553         {
554             DBG_UNHANDLED_EXCEPTION();
555         }
556         return xLibrary;
557     }
558 
559     //--------------------------------------------------------------------
loadLibraryIfExists(LibraryContainerType _eType,const::rtl::OUString & _rLibrary)560     void ScriptDocument_Impl::loadLibraryIfExists( LibraryContainerType _eType, const ::rtl::OUString& _rLibrary )
561     {
562         try
563         {
564             Reference< XLibraryContainer > xLibContainer( getLibraryContainer( _eType ) );
565             if ( xLibContainer.is() && xLibContainer->hasByName( _rLibrary ) && !xLibContainer->isLibraryLoaded( _rLibrary ) )
566                 xLibContainer->loadLibrary( _rLibrary );
567         }
568         catch( const Exception& )
569         {
570             DBG_UNHANDLED_EXCEPTION();
571         }
572     }
573 
574     //--------------------------------------------------------------------
removeModuleOrDialog(LibraryContainerType _eType,const::rtl::OUString & _rLibName,const::rtl::OUString & _rModuleName)575     bool ScriptDocument_Impl::removeModuleOrDialog( LibraryContainerType _eType, const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rModuleName )
576     {
577         OSL_ENSURE( isValid(), "ScriptDocument_Impl::removeModuleOrDialog: invalid!" );
578         if ( isValid() )
579         {
580             try
581             {
582                 Reference< XNameContainer > xLib( getLibrary( _eType, _rLibName, sal_True ) );
583                 if ( xLib.is() )
584                 {
585                     xLib->removeByName( _rModuleName );
586                     return true;
587                 }
588             }
589             catch( const Exception& )
590             {
591                 DBG_UNHANDLED_EXCEPTION();
592             }
593         }
594         return false;
595     }
596 
597     //--------------------------------------------------------------------
hasModuleOrDialog(LibraryContainerType _eType,const::rtl::OUString & _rLibName,const::rtl::OUString & _rModName) const598     bool ScriptDocument_Impl::hasModuleOrDialog( LibraryContainerType _eType, const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rModName ) const
599     {
600         OSL_ENSURE( isValid(), "ScriptDocument_Impl::hasModuleOrDialog: invalid!" );
601         if ( !isValid() )
602             return false;
603 
604         try
605         {
606             Reference< XNameContainer > xLib( getLibrary( _eType, _rLibName, sal_True ) );
607             if ( xLib.is() )
608                 return xLib->hasByName( _rModName );
609         }
610         catch( const Exception& )
611         {
612             DBG_UNHANDLED_EXCEPTION();
613         }
614         return false;
615     }
616 
617     //--------------------------------------------------------------------
getModuleOrDialog(LibraryContainerType _eType,const::rtl::OUString & _rLibName,const::rtl::OUString & _rObjectName,Any & _out_rModuleOrDialog)618     bool ScriptDocument_Impl::getModuleOrDialog( LibraryContainerType _eType, const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rObjectName, Any& _out_rModuleOrDialog )
619     {
620         OSL_ENSURE( isValid(), "ScriptDocument_Impl::getModuleOrDialog: invalid!" );
621         if ( !isValid() )
622             return false;
623 
624         _out_rModuleOrDialog.clear();
625         try
626         {
627             Reference< XNameContainer > xLib( getLibrary( _eType, _rLibName, sal_True ), UNO_QUERY_THROW );
628             if ( xLib->hasByName( _rObjectName ) )
629             {
630                 _out_rModuleOrDialog = xLib->getByName( _rObjectName );
631                 return true;
632             }
633         }
634         catch( const Exception& )
635         {
636             DBG_UNHANDLED_EXCEPTION();
637         }
638         return false;
639     }
640 
641     //--------------------------------------------------------------------
renameModuleOrDialog(LibraryContainerType _eType,const::rtl::OUString & _rLibName,const::rtl::OUString & _rOldName,const::rtl::OUString & _rNewName,const Reference<XNameContainer> & _rxExistingDialogModel)642     bool ScriptDocument_Impl::renameModuleOrDialog( LibraryContainerType _eType, const ::rtl::OUString& _rLibName,
643         const ::rtl::OUString& _rOldName, const ::rtl::OUString& _rNewName, const Reference< XNameContainer >& _rxExistingDialogModel )
644     {
645         OSL_ENSURE( isValid(), "ScriptDocument_Impl::renameModuleOrDialog: invalid!" );
646         if ( !isValid() )
647             return false;
648 
649         try
650         {
651             Reference< XNameContainer > xLib( getLibrary( _eType, _rLibName, sal_True ), UNO_QUERY_THROW );
652 
653             // get element
654             Any aElement( xLib->getByName( _rOldName ) );
655 
656             // remove element from container
657             xLib->removeByName( _rOldName );
658 
659             // if it's a dialog, import and export, to reflect the new name
660             if ( _eType == E_DIALOGS )
661             {
662                 // create dialog model
663                 ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
664                 Reference< XNameContainer > xDialogModel;
665                 if ( _rxExistingDialogModel.is() )
666                     xDialogModel = _rxExistingDialogModel;
667                 else
668                     if ( !aContext.createComponent( "com.sun.star.awt.UnoControlDialogModel", xDialogModel ) )
669                         return false;
670 
671                 // import dialog model
672                 Reference< XInputStreamProvider > xISP( aElement, UNO_QUERY_THROW );
673                 if ( !_rxExistingDialogModel.is() )
674                 {
675                     Reference< XInputStream > xInput( xISP->createInputStream(), UNO_QUERY_THROW );
676                     ::xmlscript::importDialogModel( xInput, xDialogModel, aContext.getUNOContext() );
677                 }
678 
679                 // set new name as property
680                 Reference< XPropertySet > xDlgPSet( xDialogModel, UNO_QUERY_THROW );
681                 xDlgPSet->setPropertyValue( DLGED_PROP_NAME, makeAny( _rNewName ) );
682 
683                 // export dialog model
684                 xISP = ::xmlscript::exportDialogModel( xDialogModel, aContext.getUNOContext() );
685                 aElement <<= xISP;
686             }
687 
688             // insert element by new name in container
689             else if ( _eType == E_SCRIPTS )
690             {
691                 Reference< XVBAModuleInfo > xVBAModuleInfo( xLib, UNO_QUERY );
692                 if ( xVBAModuleInfo->hasModuleInfo( _rOldName ) )
693                 {
694                     ModuleInfo sModuleInfo = xVBAModuleInfo->getModuleInfo( _rOldName );
695                     xVBAModuleInfo->removeModuleInfo( _rOldName );
696                     xVBAModuleInfo->insertModuleInfo( _rNewName, sModuleInfo );
697                 }
698             }
699             xLib->insertByName( _rNewName, aElement );
700             return true;
701         }
702         catch( const Exception& )
703         {
704             DBG_UNHANDLED_EXCEPTION();
705         }
706         return false;
707     }
708 
709     //--------------------------------------------------------------------
createModule(const::rtl::OUString & _rLibName,const::rtl::OUString & _rModName,bool _bCreateMain,::rtl::OUString & _out_rNewModuleCode) const710     bool ScriptDocument_Impl::createModule( const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rModName, bool _bCreateMain, ::rtl::OUString& _out_rNewModuleCode ) const
711     {
712         _out_rNewModuleCode = ::rtl::OUString();
713         try
714         {
715             Reference< XNameContainer > xLib( getLibrary( E_SCRIPTS, _rLibName, sal_True ) );
716             if ( !xLib.is() || xLib->hasByName( _rModName ) )
717                 return false;
718 
719             // create new module
720             _out_rNewModuleCode = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "REM  *****  BASIC  *****\n\n" ) );
721             if ( _bCreateMain )
722                 _out_rNewModuleCode += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Sub Main\n\nEnd Sub\n" ) );
723 
724             // insert module into library
725             xLib->insertByName( _rModName, makeAny( _out_rNewModuleCode ) );
726         }
727         catch( const Exception& )
728         {
729             DBG_UNHANDLED_EXCEPTION();
730             return false;
731         }
732 
733         return true;
734     }
735 
736     //--------------------------------------------------------------------
insertModuleOrDialog(LibraryContainerType _eType,const::rtl::OUString & _rLibName,const::rtl::OUString & _rObjectName,const Any & _rElement) const737     bool ScriptDocument_Impl::insertModuleOrDialog( LibraryContainerType _eType, const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rObjectName, const Any& _rElement ) const
738     {
739         try
740         {
741             Reference< XNameContainer > xLib( getOrCreateLibrary( _eType, _rLibName ), UNO_QUERY_THROW );
742             if ( xLib->hasByName( _rObjectName ) )
743                 return false;
744 
745             xLib->insertByName( _rObjectName, _rElement );
746             return true;
747         }
748         catch( const Exception& )
749         {
750             DBG_UNHANDLED_EXCEPTION();
751         }
752         return false;
753     }
754 
755     //--------------------------------------------------------------------
updateModule(const::rtl::OUString & _rLibName,const::rtl::OUString & _rModName,const::rtl::OUString & _rModuleCode) const756     bool ScriptDocument_Impl::updateModule( const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rModName, const ::rtl::OUString& _rModuleCode ) const
757     {
758         try
759         {
760             Reference< XNameContainer > xLib( getOrCreateLibrary( E_SCRIPTS, _rLibName ), UNO_QUERY_THROW );
761             if ( !xLib->hasByName( _rModName ) )
762                 return false;
763             xLib->replaceByName( _rModName, makeAny( _rModuleCode ) );
764             return true;
765         }
766         catch( const Exception& )
767         {
768             DBG_UNHANDLED_EXCEPTION();
769         }
770         return false;
771     }
772 
773     //--------------------------------------------------------------------
createDialog(const::rtl::OUString & _rLibName,const::rtl::OUString & _rDialogName,Reference<XInputStreamProvider> & _out_rDialogProvider) const774     bool ScriptDocument_Impl::createDialog( const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rDialogName, Reference< XInputStreamProvider >& _out_rDialogProvider ) const
775     {
776         try
777         {
778             Reference< XNameContainer > xLib( getLibrary( E_DIALOGS, _rLibName, sal_True ), UNO_QUERY_THROW );
779 
780             // create dialog
781             _out_rDialogProvider.clear();
782             if ( xLib->hasByName( _rDialogName ) )
783                 return false;
784 
785             // create new dialog model
786             ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
787             Reference< XNameContainer > xDialogModel;
788             if ( !aContext.createComponent( "com.sun.star.awt.UnoControlDialogModel", xDialogModel ) )
789                 return false;
790 
791             // set name property
792             Reference< XPropertySet > xDlgPSet( xDialogModel, UNO_QUERY_THROW );
793             xDlgPSet->setPropertyValue( DLGED_PROP_NAME, makeAny( _rDialogName ) );
794 
795             // export dialog model
796             _out_rDialogProvider = ::xmlscript::exportDialogModel( xDialogModel, aContext.getUNOContext() );
797 
798             // insert dialog into library
799             xLib->insertByName( _rDialogName, makeAny( _out_rDialogProvider ) );
800         }
801         catch( const Exception& )
802         {
803             DBG_UNHANDLED_EXCEPTION();
804         }
805 
806         return _out_rDialogProvider.is();
807     }
808 
809     //--------------------------------------------------------------------
setDocumentModified() const810     void ScriptDocument_Impl::setDocumentModified() const
811     {
812         OSL_ENSURE( isValid() && isDocument(), "ScriptDocument_Impl::setDocumentModified: only to be called for real documents!" );
813         if ( isValid() && isDocument() )
814         {
815             try
816             {
817                 m_xDocModify->setModified( sal_True );
818             }
819             catch( const Exception& )
820             {
821                 DBG_UNHANDLED_EXCEPTION();
822             }
823         }
824     }
825 
826     //--------------------------------------------------------------------
isDocumentModified() const827     bool ScriptDocument_Impl::isDocumentModified() const
828     {
829         OSL_ENSURE( isValid() && isDocument(), "ScriptDocument_Impl::isDocumentModified: only to be called for real documents!" );
830         bool bIsModified = false;
831         if ( isValid() && isDocument() )
832         {
833             try
834             {
835                 bIsModified = m_xDocModify->isModified();
836             }
837             catch( const Exception& )
838             {
839                 DBG_UNHANDLED_EXCEPTION();
840             }
841         }
842         return bIsModified;
843     }
844 
845     //--------------------------------------------------------------------
saveDocument(const Reference<XStatusIndicator> & _rxStatusIndicator) const846     bool ScriptDocument_Impl::saveDocument( const Reference< XStatusIndicator >& _rxStatusIndicator ) const
847     {
848         Reference< XFrame > xFrame;
849         if ( !getCurrentFrame( xFrame ) )
850             return false;
851 
852         Sequence< PropertyValue > aArgs;
853         if ( _rxStatusIndicator.is() )
854         {
855             aArgs.realloc(1);
856             aArgs[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StatusIndicator" ) );
857             aArgs[0].Value <<= _rxStatusIndicator;
858         }
859 
860         try
861         {
862             URL aURL;
863             aURL.Complete = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:Save" ) );
864             aURL.Main = aURL.Complete;
865             aURL.Protocol = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:" ) );
866             aURL.Path = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Save" ) );
867 
868             Reference< XDispatchProvider > xDispProv( xFrame, UNO_QUERY_THROW );
869             Reference< XDispatch > xDispatch(
870                 xDispProv->queryDispatch( aURL, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_self" ) ), FrameSearchFlag::AUTO ),
871                 UNO_SET_THROW );
872 
873             xDispatch->dispatch( aURL, aArgs );
874         }
875         catch( const Exception& )
876         {
877             DBG_UNHANDLED_EXCEPTION();
878             return false;
879         }
880 
881         return true;
882     }
883 
884     //--------------------------------------------------------------------
getTitle() const885     ::rtl::OUString ScriptDocument_Impl::getTitle() const
886     {
887         OSL_PRECOND( isValid() && isDocument(), "ScriptDocument_Impl::getTitle: for documents only!" );
888 
889         ::rtl::OUString sTitle;
890         if ( isValid() && isDocument() )
891         {
892             sTitle = ::comphelper::DocumentInfo::getDocumentTitle( m_xDocument );
893         }
894         return sTitle;
895     }
896 
897     //--------------------------------------------------------------------
getURL() const898     ::rtl::OUString ScriptDocument_Impl::getURL() const
899     {
900         OSL_PRECOND( isValid() && isDocument(), "ScriptDocument_Impl::getURL: for documents only!" );
901 
902         ::rtl::OUString sURL;
903         if ( isValid() && isDocument() )
904         {
905             try
906             {
907                 sURL = m_xDocument->getURL();
908             }
909             catch( const Exception& )
910             {
911                 DBG_UNHANDLED_EXCEPTION();
912             }
913         }
914         return sURL;
915     }
916 
917     //--------------------------------------------------------------------
allowMacros() const918     bool ScriptDocument_Impl::allowMacros() const
919     {
920         OSL_ENSURE( isValid() && isDocument(), "ScriptDocument_Impl::allowMacros: for documents only!" );
921         bool bAllow = false;
922         if ( isValid() && isDocument() )
923         {
924             try
925             {
926                 bAllow = m_xScriptAccess->getAllowMacroExecution();
927             }
928             catch( const Exception& )
929             {
930                 DBG_UNHANDLED_EXCEPTION();
931             }
932         }
933         return bAllow;
934     }
935 
936     //--------------------------------------------------------------------
getCurrentFrame(Reference<XFrame> & _out_rxFrame) const937     bool ScriptDocument_Impl::getCurrentFrame( Reference< XFrame >& _out_rxFrame ) const
938     {
939         _out_rxFrame.clear();
940         OSL_PRECOND( isValid() && isDocument(), "ScriptDocument_Impl::getCurrentFrame: documents only!" );
941         if ( !isValid() || !isDocument() )
942             return false;
943 
944         try
945         {
946             Reference< XModel > xDocument( m_xDocument, UNO_SET_THROW );
947             Reference< XController > xController( xDocument->getCurrentController(), UNO_SET_THROW );
948             _out_rxFrame.set( xController->getFrame(), UNO_SET_THROW );
949         }
950         catch( const Exception& )
951         {
952             DBG_UNHANDLED_EXCEPTION();
953         }
954 
955         return _out_rxFrame.is();
956     }
957 
958     //--------------------------------------------------------------------
isLibraryShared(const::rtl::OUString & _rLibName,LibraryContainerType _eType)959     bool ScriptDocument_Impl::isLibraryShared( const ::rtl::OUString& _rLibName, LibraryContainerType _eType )
960     {
961         bool bIsShared = false;
962         try
963         {
964             Reference< XLibraryContainer2 > xLibContainer( getLibraryContainer( _eType ), UNO_QUERY_THROW );
965 
966             if ( !xLibContainer->hasByName( _rLibName ) || !xLibContainer->isLibraryLink( _rLibName ) )
967                 return false;
968             ::rtl::OUString aFileURL;
969             Reference< XMultiServiceFactory > xMSF( ::comphelper::getProcessServiceFactory() );
970             Reference< XUriReferenceFactory > xUriFac;
971             if ( xMSF.is() )
972             {
973                 xUriFac.set(
974                     xMSF->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.uri.UriReferenceFactory" ) ) ),
975                     UNO_QUERY_THROW );
976             }
977 
978             ::rtl::OUString aLinkURL( xLibContainer->getLibraryLinkURL( _rLibName ) );
979             Reference< XUriReference > xUriRef( xUriFac->parse( aLinkURL ), UNO_QUERY_THROW );
980 
981             ::rtl::OUString aScheme = xUriRef->getScheme();
982             if ( aScheme.equalsIgnoreAsciiCaseAscii( "file" ) )
983             {
984                 aFileURL = aLinkURL;
985             }
986             else if ( aScheme.equalsIgnoreAsciiCaseAscii( "vnd.sun.star.pkg" ) )
987             {
988                 ::rtl::OUString aAuthority = xUriRef->getAuthority();
989                 if ( aAuthority.matchIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.expand:" ) ) )
990                 {
991                     ::rtl::OUString aDecodedURL( aAuthority.copy( sizeof ( "vnd.sun.star.expand:" ) - 1 ) );
992                     aDecodedURL = ::rtl::Uri::decode( aDecodedURL, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 );
993                     Reference< XComponentContext > xContext;
994                     Reference< XPropertySet > xProps( xMSF, UNO_QUERY_THROW );
995                     xContext.set( xProps->getPropertyValue( ::rtl::OUString::createFromAscii( "DefaultContext" ) ), UNO_QUERY_THROW );
996                     Reference< XMacroExpander > xMacroExpander(
997                         xContext->getValueByName(
998                         ::rtl::OUString::createFromAscii( "/singletons/com.sun.star.util.theMacroExpander" ) ),
999                         UNO_QUERY_THROW );
1000                     aFileURL = xMacroExpander->expandMacros( aDecodedURL );
1001                 }
1002             }
1003 
1004             if ( !aFileURL.isEmpty() )
1005             {
1006                 ::osl::DirectoryItem aFileItem;
1007                 ::osl::FileStatus aFileStatus( FileStatusMask_FileURL );
1008                 OSL_VERIFY( ::osl::DirectoryItem::get( aFileURL, aFileItem ) == ::osl::FileBase::E_None );
1009                 OSL_VERIFY( aFileItem.getFileStatus( aFileStatus ) == ::osl::FileBase::E_None );
1010                 ::rtl::OUString aCanonicalFileURL( aFileStatus.getFileURL() );
1011 
1012                 ::rtl::OUString aSearchURL1( RTL_CONSTASCII_USTRINGPARAM( "share/basic" ) );
1013                 ::rtl::OUString aSearchURL2( RTL_CONSTASCII_USTRINGPARAM( "share/uno_packages" ) );
1014                 ::rtl::OUString aSearchURL3( RTL_CONSTASCII_USTRINGPARAM( "share/extensions" ) );
1015                 if( aCanonicalFileURL.indexOf( aSearchURL1 ) != -1 ||
1016                     aCanonicalFileURL.indexOf( aSearchURL2 ) != -1 ||
1017                     aCanonicalFileURL.indexOf( aSearchURL3 ) != -1 )
1018                         bIsShared = true;
1019             }
1020         }
1021         catch( const Exception& )
1022         {
1023             DBG_UNHANDLED_EXCEPTION();
1024         }
1025 
1026         return bIsShared;
1027     }
1028 
1029     //--------------------------------------------------------------------
onDocumentCreated(const ScriptDocument &)1030     void ScriptDocument_Impl::onDocumentCreated( const ScriptDocument& /*_rDocument*/ )
1031     {
1032         // not interested in
1033     }
1034 
1035     //--------------------------------------------------------------------
onDocumentOpened(const ScriptDocument &)1036     void ScriptDocument_Impl::onDocumentOpened( const ScriptDocument& /*_rDocument*/ )
1037     {
1038         // not interested in
1039     }
1040 
1041     //--------------------------------------------------------------------
onDocumentSave(const ScriptDocument &)1042     void ScriptDocument_Impl::onDocumentSave( const ScriptDocument& /*_rDocument*/ )
1043     {
1044         // not interested in
1045     }
1046 
1047     //--------------------------------------------------------------------
onDocumentSaveDone(const ScriptDocument &)1048     void ScriptDocument_Impl::onDocumentSaveDone( const ScriptDocument& /*_rDocument*/ )
1049     {
1050         // not interested in
1051     }
1052 
1053     //--------------------------------------------------------------------
onDocumentSaveAs(const ScriptDocument &)1054     void ScriptDocument_Impl::onDocumentSaveAs( const ScriptDocument& /*_rDocument*/ )
1055     {
1056         // not interested in
1057     }
1058 
1059     //--------------------------------------------------------------------
onDocumentSaveAsDone(const ScriptDocument &)1060     void ScriptDocument_Impl::onDocumentSaveAsDone( const ScriptDocument& /*_rDocument*/ )
1061     {
1062         // not interested in
1063     }
1064 
1065     //--------------------------------------------------------------------
onDocumentClosed(const ScriptDocument & _rDocument)1066     void ScriptDocument_Impl::onDocumentClosed( const ScriptDocument& _rDocument )
1067     {
1068         DBG_TESTSOLARMUTEX();
1069         OSL_PRECOND( isValid(), "ScriptDocument_Impl::onDocumentClosed: should not be listening if I'm not valid!" );
1070 
1071         bool bMyDocument = m_xDocument == _rDocument.getDocument();
1072         OSL_PRECOND( bMyDocument, "ScriptDocument_Impl::onDocumentClosed: didn't want to know *this*!" );
1073         if ( bMyDocument )
1074         {
1075             m_bDocumentClosed = true;
1076         }
1077     }
1078 
1079     //--------------------------------------------------------------------
onDocumentTitleChanged(const ScriptDocument &)1080     void ScriptDocument_Impl::onDocumentTitleChanged( const ScriptDocument& /*_rDocument*/ )
1081     {
1082         // not interested in
1083     }
1084 
1085     //--------------------------------------------------------------------
onDocumentModeChanged(const ScriptDocument &)1086     void ScriptDocument_Impl::onDocumentModeChanged( const ScriptDocument& /*_rDocument*/ )
1087     {
1088         // not interested in
1089     }
1090 
1091     //====================================================================
1092     //= ScriptDocument
1093     //====================================================================
1094     //--------------------------------------------------------------------
ScriptDocument()1095     ScriptDocument::ScriptDocument()
1096         :m_pImpl( new ScriptDocument_Impl() )
1097     {
1098     }
1099 
1100     //--------------------------------------------------------------------
ScriptDocument(ScriptDocument::SpecialDocument _eType)1101     ScriptDocument::ScriptDocument( ScriptDocument::SpecialDocument _eType )
1102         :m_pImpl( new ScriptDocument_Impl( Reference< XModel >() ) )
1103     {
1104         OSL_ENSURE( _eType == NoDocument, "ScriptDocument::ScriptDocument: unknown SpecialDocument type!" );
1105         (void)_eType;
1106     }
1107 
1108     //--------------------------------------------------------------------
ScriptDocument(const Reference<XModel> & _rxDocument)1109     ScriptDocument::ScriptDocument( const Reference< XModel >& _rxDocument )
1110         :m_pImpl( new ScriptDocument_Impl( _rxDocument ) )
1111     {
1112         OSL_ENSURE( _rxDocument.is(), "ScriptDocument::ScriptDocument: document must not be NULL!" );
1113             // a NULL document results in an uninitialized instance, and for this
1114             // purpose, there is a dedicated constructor
1115     }
1116 
1117     //--------------------------------------------------------------------
ScriptDocument(const ScriptDocument & _rSource)1118     ScriptDocument::ScriptDocument( const ScriptDocument& _rSource )
1119         :m_pImpl( _rSource.m_pImpl )
1120     {
1121     }
1122 
1123     //--------------------------------------------------------------------
~ScriptDocument()1124     ScriptDocument::~ScriptDocument()
1125     {
1126     }
1127 
1128     //--------------------------------------------------------------------
getApplicationScriptDocument()1129     const ScriptDocument& ScriptDocument::getApplicationScriptDocument()
1130     {
1131         static ScriptDocument s_aApplicationScripts;
1132         return s_aApplicationScripts;
1133     }
1134 
1135     //--------------------------------------------------------------------
getDocumentForBasicManager(const BasicManager * _pManager)1136     ScriptDocument ScriptDocument::getDocumentForBasicManager( const BasicManager* _pManager )
1137     {
1138         if ( _pManager == SFX_APP()->GetBasicManager() )
1139             return getApplicationScriptDocument();
1140 
1141         docs::Documents aDocuments;
1142         lcl_getAllModels_throw( aDocuments, false );
1143 
1144         for (   docs::Documents::const_iterator doc = aDocuments.begin();
1145                 doc != aDocuments.end();
1146                 ++doc
1147             )
1148         {
1149             const BasicManager* pDocBasicManager = ::basic::BasicManagerRepository::getDocumentBasicManager( doc->xModel );
1150             if  (   ( pDocBasicManager != SFX_APP()->GetBasicManager() )
1151                 &&  ( pDocBasicManager == _pManager )
1152                 )
1153             {
1154                 return ScriptDocument( doc->xModel );
1155             }
1156         }
1157 
1158         OSL_ENSURE( false, "ScriptDocument::getDocumentForBasicManager: did not find a document for this manager!" );
1159         return ScriptDocument( NoDocument );
1160     }
1161 
1162     //--------------------------------------------------------------------
getDocumentWithURLOrCaption(const::rtl::OUString & _rUrlOrCaption)1163     ScriptDocument ScriptDocument::getDocumentWithURLOrCaption( const ::rtl::OUString& _rUrlOrCaption )
1164     {
1165         ScriptDocument aDocument( getApplicationScriptDocument() );
1166         if ( _rUrlOrCaption.isEmpty() )
1167             return aDocument;
1168 
1169         docs::Documents aDocuments;
1170         lcl_getAllModels_throw( aDocuments, false );
1171 
1172         for (   docs::Documents::const_iterator doc = aDocuments.begin();
1173                 doc != aDocuments.end();
1174                 ++doc
1175             )
1176         {
1177             const ScriptDocument aCheck = ScriptDocument( doc->xModel );
1178             if  (   _rUrlOrCaption == aCheck.getTitle()
1179                 ||  _rUrlOrCaption == aCheck.getURL()
1180                 )
1181             {
1182                 aDocument = aCheck;
1183                 break;
1184             }
1185         }
1186 
1187         return aDocument;
1188     }
1189 
1190     //--------------------------------------------------------------------
1191     namespace
1192     {
1193         struct DocumentTitleLess : public ::std::binary_function< ScriptDocument, ScriptDocument, bool >
1194         {
DocumentTitleLessbasctl::__anon09005bf60211::DocumentTitleLess1195             DocumentTitleLess( const CollatorWrapper& _rCollator )
1196                 :m_aCollator( _rCollator )
1197             {
1198             }
1199 
operator ()basctl::__anon09005bf60211::DocumentTitleLess1200             bool operator()( const ScriptDocument& _lhs, const ScriptDocument& _rhs ) const
1201             {
1202                 return m_aCollator.compareString( _lhs.getTitle(), _rhs.getTitle() ) < 0;
1203             }
1204         private:
1205             const CollatorWrapper   m_aCollator;
1206         };
1207     }
1208 
1209     //--------------------------------------------------------------------
getAllScriptDocuments(ScriptDocument::ScriptDocumentList _eListType)1210     ScriptDocuments ScriptDocument::getAllScriptDocuments( ScriptDocument::ScriptDocumentList _eListType )
1211     {
1212         ScriptDocuments aScriptDocs;
1213 
1214         // include application?
1215         if ( _eListType == AllWithApplication )
1216             aScriptDocs.push_back( getApplicationScriptDocument() );
1217 
1218         // obtain documents
1219         try
1220         {
1221             docs::Documents aDocuments;
1222             lcl_getAllModels_throw( aDocuments, true /* exclude invisible */ );
1223 
1224             for (   docs::Documents::const_iterator doc = aDocuments.begin();
1225                     doc != aDocuments.end();
1226                     ++doc
1227                 )
1228             {
1229                 // exclude documents without script/library containers
1230                 ScriptDocument aDoc( doc->xModel );
1231                 if ( !aDoc.isValid() )
1232                     continue;
1233 
1234                 aScriptDocs.push_back( aDoc );
1235             }
1236         }
1237         catch( const Exception& )
1238         {
1239             DBG_UNHANDLED_EXCEPTION();
1240         }
1241 
1242         // sort document list by doc title?
1243         if ( _eListType == DocumentsSorted )
1244         {
1245             CollatorWrapper aCollator( ::comphelper::getProcessServiceFactory() );
1246             aCollator.loadDefaultCollator( SvtSysLocale().GetLocaleData().getLocale(), 0 );
1247             ::std::sort( aScriptDocs.begin(), aScriptDocs.end(), DocumentTitleLess( aCollator ) );
1248         }
1249 
1250         return aScriptDocs;
1251     }
1252 
1253     //--------------------------------------------------------------------
operator ==(const ScriptDocument & _rhs) const1254     bool ScriptDocument::operator==( const ScriptDocument& _rhs ) const
1255     {
1256         return m_pImpl->getDocumentRef() == _rhs.m_pImpl->getDocumentRef();
1257     }
1258 
1259     //--------------------------------------------------------------------
hashCode() const1260     sal_Int32 ScriptDocument::hashCode() const
1261     {
1262         return sal::static_int_cast<sal_Int32>(reinterpret_cast< sal_IntPtr >( m_pImpl->getDocumentRef().get() ));
1263     }
1264 
1265     //--------------------------------------------------------------------
isValid() const1266     bool ScriptDocument::isValid() const
1267     {
1268         return m_pImpl->isValid();
1269     }
1270 
1271     //--------------------------------------------------------------------
isAlive() const1272     bool ScriptDocument::isAlive() const
1273     {
1274         return m_pImpl->isAlive();
1275     }
1276 
1277     //--------------------------------------------------------------------
getLibraryContainer(LibraryContainerType _eType) const1278     Reference< XLibraryContainer > ScriptDocument::getLibraryContainer( LibraryContainerType _eType ) const
1279     {
1280         return m_pImpl->getLibraryContainer( _eType );
1281     }
1282 
1283     //--------------------------------------------------------------------
getLibrary(LibraryContainerType _eType,const::rtl::OUString & _rLibName,bool _bLoadLibrary) const1284     Reference< XNameContainer > ScriptDocument::getLibrary( LibraryContainerType _eType, const ::rtl::OUString& _rLibName, bool _bLoadLibrary ) const
1285     {
1286         return m_pImpl->getLibrary( _eType, _rLibName, _bLoadLibrary );
1287     }
1288 
1289     //--------------------------------------------------------------------
hasLibrary(LibraryContainerType _eType,const::rtl::OUString & _rLibName) const1290     bool ScriptDocument::hasLibrary( LibraryContainerType _eType, const ::rtl::OUString& _rLibName ) const
1291     {
1292         return m_pImpl->hasLibrary( _eType, _rLibName );
1293     }
1294 
1295     //--------------------------------------------------------------------
getOrCreateLibrary(LibraryContainerType _eType,const::rtl::OUString & _rLibName) const1296     Reference< XNameContainer > ScriptDocument::getOrCreateLibrary( LibraryContainerType _eType, const ::rtl::OUString& _rLibName ) const
1297     {
1298         return m_pImpl->getOrCreateLibrary( _eType, _rLibName );
1299     }
1300 
1301     //--------------------------------------------------------------------
loadLibraryIfExists(LibraryContainerType _eType,const::rtl::OUString & _rLibrary)1302     void ScriptDocument::loadLibraryIfExists( LibraryContainerType _eType, const ::rtl::OUString& _rLibrary )
1303     {
1304         m_pImpl->loadLibraryIfExists( _eType, _rLibrary );
1305     }
1306 
1307     //--------------------------------------------------------------------
getObjectNames(LibraryContainerType _eType,const::rtl::OUString & _rLibName) const1308     Sequence< ::rtl::OUString > ScriptDocument::getObjectNames( LibraryContainerType _eType, const ::rtl::OUString& _rLibName ) const
1309     {
1310         Sequence< ::rtl::OUString > aModuleNames;
1311 
1312         try
1313         {
1314             if ( hasLibrary( _eType, _rLibName ) )
1315             {
1316                 Reference< XNameContainer > xLib( getLibrary( _eType, _rLibName, false ) );
1317                 if ( xLib.is() )
1318                     aModuleNames = xLib->getElementNames();
1319             }
1320         }
1321         catch( const Exception& )
1322         {
1323             DBG_UNHANDLED_EXCEPTION();
1324         }
1325 
1326         // sort
1327         ::std::sort( aModuleNames.getArray() , aModuleNames.getArray() + aModuleNames.getLength() , StringCompareLessThan );
1328 
1329         return aModuleNames;
1330     }
1331 
1332     //--------------------------------------------------------------------
createObjectName(LibraryContainerType _eType,const::rtl::OUString & _rLibName) const1333     ::rtl::OUString ScriptDocument::createObjectName( LibraryContainerType _eType, const ::rtl::OUString& _rLibName ) const
1334     {
1335         ::rtl::OUString aObjectName;
1336 
1337         ::rtl::OUString aBaseName = _eType == E_SCRIPTS
1338             ?   ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Module" ) )
1339             :   ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Dialog" ) );
1340 
1341         Sequence< ::rtl::OUString > aUsedNames( getObjectNames( _eType, _rLibName ) );
1342         ::std::set< ::rtl::OUString > aUsedNamesCheck;
1343         ::std::copy( aUsedNames.getConstArray(), aUsedNames.getConstArray() + aUsedNames.getLength(),
1344             ::std::insert_iterator< ::std::set< ::rtl::OUString > >( aUsedNamesCheck, aUsedNamesCheck.begin() ) );
1345 
1346         bool bValid = false;
1347         sal_uInt16 i = 1;
1348         while ( !bValid )
1349         {
1350             aObjectName = aBaseName;
1351             aObjectName += String::CreateFromInt32( i );
1352 
1353             if ( aUsedNamesCheck.find( aObjectName ) == aUsedNamesCheck.end() )
1354                 bValid = sal_True;
1355 
1356             ++i;
1357         }
1358 
1359         return aObjectName;
1360     }
1361 
1362     //--------------------------------------------------------------------
getLibraryNames() const1363     Sequence< ::rtl::OUString > ScriptDocument::getLibraryNames() const
1364     {
1365         return BasicIDE::GetMergedLibraryNames( getLibraryContainer( E_SCRIPTS ), getLibraryContainer( E_DIALOGS ) );
1366     }
1367 
1368     //--------------------------------------------------------------------
isReadOnly() const1369     bool ScriptDocument::isReadOnly() const
1370     {
1371         return m_pImpl->isReadOnly();
1372     }
1373 
1374     //--------------------------------------------------------------------
isApplication() const1375     bool ScriptDocument::isApplication() const
1376     {
1377         return m_pImpl->isApplication();
1378     }
1379 
isInVBAMode() const1380     bool ScriptDocument::isInVBAMode() const
1381     {
1382         return m_pImpl->isInVBAMode();
1383     }
1384 
1385     //--------------------------------------------------------------------
getBasicManager() const1386     BasicManager* ScriptDocument::getBasicManager() const
1387     {
1388         return m_pImpl->getBasicManager();
1389     }
1390 
1391     //--------------------------------------------------------------------
getDocument() const1392     Reference< XModel > ScriptDocument::getDocument() const
1393     {
1394         return m_pImpl->getDocument();
1395     }
1396 
1397     //--------------------------------------------------------------------
getDocumentOrNull() const1398     Reference< XModel > ScriptDocument::getDocumentOrNull() const
1399     {
1400         if ( isDocument() )
1401             return m_pImpl->getDocument();
1402         return NULL;
1403     }
1404 
1405     //--------------------------------------------------------------------
removeModule(const::rtl::OUString & _rLibName,const::rtl::OUString & _rModuleName) const1406     bool ScriptDocument::removeModule( const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rModuleName ) const
1407     {
1408         return m_pImpl->removeModuleOrDialog( E_SCRIPTS, _rLibName, _rModuleName );
1409     }
1410 
1411     //--------------------------------------------------------------------
hasModule(const::rtl::OUString & _rLibName,const::rtl::OUString & _rModuleName) const1412     bool ScriptDocument::hasModule( const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rModuleName ) const
1413     {
1414         return m_pImpl->hasModuleOrDialog( E_SCRIPTS, _rLibName, _rModuleName );
1415     }
1416 
1417     //--------------------------------------------------------------------
getModule(const::rtl::OUString & _rLibName,const::rtl::OUString & _rModName,::rtl::OUString & _out_rModuleSource) const1418     bool ScriptDocument::getModule( const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rModName, ::rtl::OUString& _out_rModuleSource ) const
1419     {
1420         Any aCode;
1421         if ( !m_pImpl->getModuleOrDialog( E_SCRIPTS, _rLibName, _rModName, aCode ) )
1422             return false;
1423         OSL_VERIFY( aCode >>= _out_rModuleSource );
1424         return true;
1425     }
1426 
1427     //--------------------------------------------------------------------
renameModule(const::rtl::OUString & _rLibName,const::rtl::OUString & _rOldName,const::rtl::OUString & _rNewName) const1428     bool ScriptDocument::renameModule( const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rOldName, const ::rtl::OUString& _rNewName ) const
1429     {
1430         return m_pImpl->renameModuleOrDialog( E_SCRIPTS, _rLibName, _rOldName, _rNewName, NULL );
1431     }
1432 
1433     //--------------------------------------------------------------------
createModule(const::rtl::OUString & _rLibName,const::rtl::OUString & _rModName,bool _bCreateMain,::rtl::OUString & _out_rNewModuleCode) const1434     bool ScriptDocument::createModule( const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rModName, bool _bCreateMain, ::rtl::OUString& _out_rNewModuleCode ) const
1435     {
1436         if ( !m_pImpl->createModule( _rLibName, _rModName, _bCreateMain, _out_rNewModuleCode ) )
1437             return false;
1438 
1439         // doc shell modified
1440         BasicIDE::MarkDocumentModified( *const_cast< ScriptDocument* >( this ) );    // here?
1441         return true;
1442     }
1443 
1444     //--------------------------------------------------------------------
insertModule(const::rtl::OUString & _rLibName,const::rtl::OUString & _rModName,const::rtl::OUString & _rModuleCode) const1445     bool ScriptDocument::insertModule( const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rModName, const ::rtl::OUString& _rModuleCode ) const
1446     {
1447         return m_pImpl->insertModuleOrDialog( E_SCRIPTS, _rLibName, _rModName, makeAny( _rModuleCode ) );
1448     }
1449 
1450     //--------------------------------------------------------------------
updateModule(const::rtl::OUString & _rLibName,const::rtl::OUString & _rModName,const::rtl::OUString & _rModuleCode) const1451     bool ScriptDocument::updateModule( const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rModName, const ::rtl::OUString& _rModuleCode ) const
1452     {
1453         return m_pImpl->updateModule( _rLibName, _rModName, _rModuleCode );
1454     }
1455 
1456     //--------------------------------------------------------------------
removeDialog(const::rtl::OUString & _rLibName,const::rtl::OUString & _rDialogName) const1457     bool ScriptDocument::removeDialog( const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rDialogName ) const
1458     {
1459         return m_pImpl->removeModuleOrDialog( E_DIALOGS, _rLibName, _rDialogName );
1460     }
1461 
1462     //--------------------------------------------------------------------
hasDialog(const::rtl::OUString & _rLibName,const::rtl::OUString & _rDialogName) const1463     bool ScriptDocument::hasDialog( const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rDialogName ) const
1464     {
1465         return m_pImpl->hasModuleOrDialog( E_DIALOGS, _rLibName, _rDialogName );
1466     }
1467 
1468     //--------------------------------------------------------------------
getDialog(const::rtl::OUString & _rLibName,const::rtl::OUString & _rDialogName,Reference<XInputStreamProvider> & _out_rDialogProvider) const1469     bool ScriptDocument::getDialog( const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rDialogName, Reference< XInputStreamProvider >& _out_rDialogProvider ) const
1470     {
1471         Any aCode;
1472         if ( !m_pImpl->getModuleOrDialog( E_DIALOGS, _rLibName, _rDialogName, aCode ) )
1473             return false;
1474         OSL_VERIFY( aCode >>= _out_rDialogProvider );
1475         return _out_rDialogProvider.is();
1476     }
1477 
1478     //--------------------------------------------------------------------
renameDialog(const::rtl::OUString & _rLibName,const::rtl::OUString & _rOldName,const::rtl::OUString & _rNewName,const Reference<XNameContainer> & _rxExistingDialogModel) const1479     bool ScriptDocument::renameDialog( const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rOldName, const ::rtl::OUString& _rNewName, const Reference< XNameContainer >& _rxExistingDialogModel ) const
1480     {
1481         return m_pImpl->renameModuleOrDialog( E_DIALOGS, _rLibName, _rOldName, _rNewName, _rxExistingDialogModel );
1482     }
1483 
1484     //--------------------------------------------------------------------
createDialog(const::rtl::OUString & _rLibName,const::rtl::OUString & _rDialogName,Reference<XInputStreamProvider> & _out_rDialogProvider) const1485     bool ScriptDocument::createDialog( const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rDialogName, Reference< XInputStreamProvider >& _out_rDialogProvider ) const
1486     {
1487         if ( !m_pImpl->createDialog( _rLibName, _rDialogName, _out_rDialogProvider ) )
1488             return false;
1489 
1490         BasicIDE::MarkDocumentModified( *const_cast< ScriptDocument* >( this ) );    // here?
1491         return true;
1492     }
1493 
1494     //--------------------------------------------------------------------
insertDialog(const::rtl::OUString & _rLibName,const::rtl::OUString & _rDialogName,const Reference<XInputStreamProvider> & _rxDialogProvider) const1495     bool ScriptDocument::insertDialog( const ::rtl::OUString& _rLibName, const ::rtl::OUString& _rDialogName, const Reference< XInputStreamProvider >& _rxDialogProvider ) const
1496     {
1497         return m_pImpl->insertModuleOrDialog( E_DIALOGS, _rLibName, _rDialogName, makeAny( _rxDialogProvider ) );
1498     }
1499 
1500     //--------------------------------------------------------------------
setDocumentModified() const1501     void ScriptDocument::setDocumentModified() const
1502     {
1503         m_pImpl->setDocumentModified();
1504     }
1505 
1506     //--------------------------------------------------------------------
isDocumentModified() const1507     bool ScriptDocument::isDocumentModified() const
1508     {
1509         return m_pImpl->isDocumentModified();
1510     }
1511 
1512     //--------------------------------------------------------------------
saveDocument(const Reference<XStatusIndicator> & _rxStatusIndicator) const1513     bool ScriptDocument::saveDocument( const Reference< XStatusIndicator >& _rxStatusIndicator ) const
1514     {
1515         return m_pImpl->saveDocument( _rxStatusIndicator );
1516     }
1517 
1518     //--------------------------------------------------------------------
getLibraryLocation(const::rtl::OUString & _rLibName) const1519     LibraryLocation ScriptDocument::getLibraryLocation( const ::rtl::OUString& _rLibName ) const
1520     {
1521         LibraryLocation eLocation = LIBRARY_LOCATION_UNKNOWN;
1522         if ( !_rLibName.isEmpty() )
1523         {
1524             if ( isDocument() )
1525             {
1526                 eLocation = LIBRARY_LOCATION_DOCUMENT;
1527             }
1528             else
1529             {
1530                 if  (  ( hasLibrary( E_SCRIPTS, _rLibName ) && !m_pImpl->isLibraryShared( _rLibName, E_SCRIPTS ) )
1531                     || ( hasLibrary( E_DIALOGS, _rLibName ) && !m_pImpl->isLibraryShared( _rLibName, E_DIALOGS ) )
1532                     )
1533                 {
1534                     eLocation = LIBRARY_LOCATION_USER;
1535                 }
1536                 else
1537                 {
1538                     eLocation = LIBRARY_LOCATION_SHARE;
1539                 }
1540             }
1541         }
1542 
1543         return eLocation;
1544     }
1545 
1546     //--------------------------------------------------------------------
getTitle(LibraryLocation _eLocation,LibraryType _eType) const1547     ::rtl::OUString ScriptDocument::getTitle( LibraryLocation _eLocation, LibraryType _eType ) const
1548     {
1549         ::rtl::OUString aTitle;
1550 
1551         switch ( _eLocation )
1552         {
1553             case LIBRARY_LOCATION_USER:
1554             {
1555                 switch ( _eType )
1556                 {
1557                 case LIBRARY_TYPE_MODULE:   aTitle = String( IDEResId( RID_STR_USERMACROS ) ); break;
1558                 case LIBRARY_TYPE_DIALOG:   aTitle = String( IDEResId( RID_STR_USERDIALOGS ) ); break;
1559                 case LIBRARY_TYPE_ALL:      aTitle = String( IDEResId( RID_STR_USERMACROSDIALOGS ) ); break;
1560                 default:
1561                     break;
1562             }
1563             break;
1564             case LIBRARY_LOCATION_SHARE:
1565             {
1566                 switch ( _eType )
1567                 {
1568                 case LIBRARY_TYPE_MODULE:   aTitle = String( IDEResId( RID_STR_SHAREMACROS ) ); break;
1569                 case LIBRARY_TYPE_DIALOG:   aTitle = String( IDEResId( RID_STR_SHAREDIALOGS ) ); break;
1570                 case LIBRARY_TYPE_ALL:      aTitle = String( IDEResId( RID_STR_SHAREMACROSDIALOGS ) ); break;
1571                 default:
1572                     break;
1573                 }
1574             }
1575             break;
1576             case LIBRARY_LOCATION_DOCUMENT:
1577                 aTitle = getTitle();
1578                 break;
1579             default:
1580                 break;
1581             }
1582         }
1583 
1584         return aTitle;
1585     }
1586 
1587     //--------------------------------------------------------------------
getTitle() const1588     ::rtl::OUString ScriptDocument::getTitle() const
1589     {
1590         return m_pImpl->getTitle();
1591     }
1592 
1593     //--------------------------------------------------------------------
getURL() const1594     ::rtl::OUString ScriptDocument::getURL() const
1595     {
1596         return m_pImpl->getURL();
1597     }
1598 
1599     //--------------------------------------------------------------------
isActive() const1600     bool ScriptDocument::isActive() const
1601     {
1602         bool bIsActive( false );
1603         try
1604         {
1605             Reference< XFrame > xFrame;
1606             if ( m_pImpl->getCurrentFrame( xFrame ) )
1607                 bIsActive = xFrame->isActive();
1608         }
1609         catch( const Exception& )
1610         {
1611             DBG_UNHANDLED_EXCEPTION();
1612         }
1613         return bIsActive;
1614     }
1615 
1616     //--------------------------------------------------------------------
allowMacros() const1617     bool ScriptDocument::allowMacros() const
1618     {
1619         return m_pImpl->allowMacros();
1620     }
1621 
1622 //........................................................................
1623 } // namespace basctl
1624 //........................................................................
1625