xref: /aoo41x/main/basic/source/basmgr/vbahelper.cxx (revision e1f63238)
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_basic.hxx"
26 
27 #include <basic/vbahelper.hxx>
28 
29 #include <map>
30 #include <vector>
31 #include <com/sun/star/container/XEnumeration.hpp>
32 #include <com/sun/star/frame/XDesktop.hpp>
33 #include <com/sun/star/frame/XModel2.hpp>
34 #include <com/sun/star/frame/XModuleManager.hpp>
35 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
36 #include <comphelper/processfactory.hxx>
37 #include <cppuhelper/implbase1.hxx>
38 #include <rtl/instance.hxx>
39 
40 namespace basic {
41 namespace vba {
42 
43 using namespace ::com::sun::star;
44 
45 // ============================================================================
46 
47 namespace {
48 
49 /** Create an instance of a module manager.
50  */
51 uno::Reference< frame::XModuleManager > lclCreateModuleManager()
52 {
53     uno::Reference< frame::XModuleManager > xModuleManager;
54     try
55     {
56         uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
57         xModuleManager.set( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.ModuleManager" ) ) ), uno::UNO_QUERY );
58     }
59     catch( uno::Exception& )
60     {
61     }
62     return xModuleManager;
63 }
64 
65 // ----------------------------------------------------------------------------
66 
67 /** Implementation of an enumeration of all open documents of the same type.
68  */
69 class DocumentsEnumeration : public ::cppu::WeakImplHelper1< container::XEnumeration >
70 {
71 public:
72     DocumentsEnumeration( const uno::Reference< frame::XModel >& rxModel );
73     virtual sal_Bool SAL_CALL hasMoreElements() throw (uno::RuntimeException);
74     virtual uno::Any SAL_CALL nextElement() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException);
75 private:
76     typedef ::std::vector< uno::Reference< frame::XModel > > ModelVector;
77     ModelVector maModels;
78     ModelVector::iterator maModelIt;
79 };
80 
81 DocumentsEnumeration::DocumentsEnumeration( const uno::Reference< frame::XModel >& rxModel )
82 {
83     try
84     {
85         uno::Reference< frame::XModuleManager > xModuleManager( lclCreateModuleManager(), uno::UNO_SET_THROW );
86         ::rtl::OUString aIdentifier = xModuleManager->identify( rxModel );
87         uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
88         uno::Reference< frame::XDesktop > xDesktop( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ) ) ), uno::UNO_QUERY_THROW );
89         uno::Reference< container::XEnumerationAccess > xComponentsEA( xDesktop->getComponents(), uno::UNO_SET_THROW );
90         uno::Reference< container::XEnumeration > xEnumeration( xComponentsEA->createEnumeration(), uno::UNO_SET_THROW );
91         while( xEnumeration->hasMoreElements() )
92         {
93             uno::Reference< frame::XModel > xCurrModel( xEnumeration->nextElement(), uno::UNO_QUERY_THROW );
94             if( xModuleManager->identify( xCurrModel ) == aIdentifier )
95                 maModels.push_back( xCurrModel );
96         }
97     }
98     catch( uno::Exception& )
99     {
100     }
101     maModelIt = maModels.begin();
102 }
103 
104 sal_Bool SAL_CALL DocumentsEnumeration::hasMoreElements() throw (uno::RuntimeException)
105 {
106     return maModelIt != maModels.end();
107 }
108 
109 uno::Any SAL_CALL DocumentsEnumeration::nextElement() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
110 {
111     if( maModelIt == maModels.end() )
112         throw container::NoSuchElementException();
113     return uno::Any( *maModelIt++ );
114 }
115 
116 // ----------------------------------------------------------------------------
117 
118 /** Locks or unlocks the controllers of the specified document model.
119  */
120 void lclLockControllers( const uno::Reference< frame::XModel >& rxModel, sal_Bool bLockControllers )
121 {
122     if( rxModel.is() ) try
123     {
124         if( bLockControllers )
125             rxModel->lockControllers();
126         else
127             rxModel->unlockControllers();
128     }
129     catch( uno::Exception& )
130     {
131     }
132 }
133 
134 // ----------------------------------------------------------------------------
135 
136 /** Enables or disables the container windows of all controllers of the
137     specified document model.
138  */
139 void lclEnableContainerWindows( const uno::Reference< frame::XModel >& rxModel, sal_Bool bEnableWindows )
140 {
141     try
142     {
143         uno::Reference< frame::XModel2 > xModel2( rxModel, uno::UNO_QUERY_THROW );
144         uno::Reference< container::XEnumeration > xControllersEnum( xModel2->getControllers(), uno::UNO_SET_THROW );
145         // iterate over all controllers
146         while( xControllersEnum->hasMoreElements() )
147         {
148             try
149             {
150                 uno::Reference< frame::XController > xController( xControllersEnum->nextElement(), uno::UNO_QUERY_THROW );
151                 uno::Reference< frame::XFrame > xFrame( xController->getFrame(), uno::UNO_SET_THROW );
152                 uno::Reference< awt::XWindow > xWindow( xFrame->getContainerWindow(), uno::UNO_SET_THROW );
153                 xWindow->setEnable( bEnableWindows );
154             }
155             catch( uno::Exception& )
156             {
157             }
158         }
159     }
160     catch( uno::Exception& )
161     {
162     }
163 }
164 
165 // ----------------------------------------------------------------------------
166 
167 typedef void (*ModifyDocumentFunc)( const uno::Reference< frame::XModel >&, sal_Bool );
168 
169 /** Implementation iterating over all documents that have the same type as the
170     specified model, and calling the passed functor.
171  */
172 void lclIterateDocuments( ModifyDocumentFunc pModifyDocumentFunc, const uno::Reference< frame::XModel >& rxModel, sal_Bool bModificator )
173 {
174     uno::Reference< container::XEnumeration > xDocumentsEnum( new DocumentsEnumeration( rxModel ) );
175     // iterate over all open documents
176     while( xDocumentsEnum->hasMoreElements() ) try
177     {
178         uno::Reference< frame::XModel > xCurrModel( xDocumentsEnum->nextElement(), uno::UNO_QUERY_THROW );
179         pModifyDocumentFunc( xCurrModel, bModificator );
180     }
181     catch( uno::Exception& )
182     {
183     }
184 }
185 
186 // ----------------------------------------------------------------------------
187 
188 struct CurrDirPool
189 {
190     ::osl::Mutex maMutex;
191     ::std::map< ::rtl::OUString, ::rtl::OUString > maCurrDirs;
192 };
193 
194 struct StaticCurrDirPool : public ::rtl::Static< CurrDirPool, StaticCurrDirPool > {};
195 
196 } // namespace
197 
198 // ============================================================================
199 
200 uno::Reference< container::XEnumeration > createDocumentsEnumeration( const uno::Reference< frame::XModel >& rxModel )
201 {
202     return new DocumentsEnumeration( rxModel );
203 }
204 
205 // ============================================================================
206 
207 void lockControllersOfAllDocuments( const uno::Reference< frame::XModel >& rxModel, sal_Bool bLockControllers )
208 {
209     lclIterateDocuments( &lclLockControllers, rxModel, bLockControllers );
210 }
211 
212 // ============================================================================
213 
214 void enableContainerWindowsOfAllDocuments( const uno::Reference< frame::XModel >& rxModel, sal_Bool bEnableWindows )
215 {
216     lclIterateDocuments( &lclEnableContainerWindows, rxModel, bEnableWindows );
217 }
218 
219 // ============================================================================
220 
221 void registerCurrentDirectory( const uno::Reference< frame::XModel >& rxModel, const ::rtl::OUString& rPath )
222 {
223     if( rPath.getLength() > 0 )
224     {
225         CurrDirPool& rPool = StaticCurrDirPool::get();
226         ::osl::MutexGuard aGuard( rPool.maMutex );
227         try
228         {
229             uno::Reference< frame::XModuleManager > xModuleManager( lclCreateModuleManager(), uno::UNO_SET_THROW );
230             ::rtl::OUString aIdentifier = xModuleManager->identify( rxModel );
231             if( aIdentifier.getLength() > 0 )
232                 rPool.maCurrDirs[ aIdentifier ] = rPath;
233         }
234         catch( uno::Exception& )
235         {
236         }
237     }
238 }
239 
240 // ============================================================================
241 
242 ::rtl::OUString getCurrentDirectory( const uno::Reference< frame::XModel >& rxModel )
243 {
244     ::rtl::OUString aPath;
245     CurrDirPool& rPool = StaticCurrDirPool::get();
246     ::osl::MutexGuard aGuard( rPool.maMutex );
247     try
248     {
249         uno::Reference< frame::XModuleManager > xModuleManager( lclCreateModuleManager(), uno::UNO_SET_THROW );
250         ::rtl::OUString aIdentifier = xModuleManager->identify( rxModel );
251         aPath = rPool.maCurrDirs[ aIdentifier ];
252     }
253     catch( uno::Exception& )
254     {
255     }
256     return aPath;
257 }
258 
259 // ============================================================================
260 
261 } // namespace vba
262 } // namespace basic
263