xref: /aoo41x/main/basic/source/basmgr/vbahelper.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_basic.hxx"
30 
31 #include <basic/vbahelper.hxx>
32 
33 #include <map>
34 #include <vector>
35 #include <com/sun/star/container/XEnumeration.hpp>
36 #include <com/sun/star/frame/XDesktop.hpp>
37 #include <com/sun/star/frame/XModel2.hpp>
38 #include <com/sun/star/frame/XModuleManager.hpp>
39 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
40 #include <comphelper/processfactory.hxx>
41 #include <cppuhelper/implbase1.hxx>
42 #include <rtl/instance.hxx>
43 
44 namespace basic {
45 namespace vba {
46 
47 using namespace ::com::sun::star;
48 
49 // ============================================================================
50 
51 namespace {
52 
53 /** Create an instance of a module manager.
54  */
55 uno::Reference< frame::XModuleManager > lclCreateModuleManager()
56 {
57     uno::Reference< frame::XModuleManager > xModuleManager;
58     try
59     {
60         uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
61         xModuleManager.set( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.ModuleManager" ) ) ), uno::UNO_QUERY );
62     }
63     catch( uno::Exception& )
64     {
65     }
66     return xModuleManager;
67 }
68 
69 // ----------------------------------------------------------------------------
70 
71 /** Implementation of an enumeration of all open documents of the same type.
72  */
73 class DocumentsEnumeration : public ::cppu::WeakImplHelper1< container::XEnumeration >
74 {
75 public:
76     DocumentsEnumeration( const uno::Reference< frame::XModel >& rxModel );
77     virtual sal_Bool SAL_CALL hasMoreElements() throw (uno::RuntimeException);
78     virtual uno::Any SAL_CALL nextElement() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException);
79 private:
80     typedef ::std::vector< uno::Reference< frame::XModel > > ModelVector;
81     ModelVector maModels;
82     ModelVector::iterator maModelIt;
83 };
84 
85 DocumentsEnumeration::DocumentsEnumeration( const uno::Reference< frame::XModel >& rxModel )
86 {
87     try
88     {
89         uno::Reference< frame::XModuleManager > xModuleManager( lclCreateModuleManager(), uno::UNO_SET_THROW );
90         ::rtl::OUString aIdentifier = xModuleManager->identify( rxModel );
91         uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
92         uno::Reference< frame::XDesktop > xDesktop( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ) ) ), uno::UNO_QUERY_THROW );
93         uno::Reference< container::XEnumerationAccess > xComponentsEA( xDesktop->getComponents(), uno::UNO_SET_THROW );
94         uno::Reference< container::XEnumeration > xEnumeration( xComponentsEA->createEnumeration(), uno::UNO_SET_THROW );
95         while( xEnumeration->hasMoreElements() )
96         {
97             uno::Reference< frame::XModel > xCurrModel( xEnumeration->nextElement(), uno::UNO_QUERY_THROW );
98             if( xModuleManager->identify( xCurrModel ) == aIdentifier )
99                 maModels.push_back( xCurrModel );
100         }
101     }
102     catch( uno::Exception& )
103     {
104     }
105     maModelIt = maModels.begin();
106 }
107 
108 sal_Bool SAL_CALL DocumentsEnumeration::hasMoreElements() throw (uno::RuntimeException)
109 {
110     return maModelIt != maModels.end();
111 }
112 
113 uno::Any SAL_CALL DocumentsEnumeration::nextElement() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
114 {
115     if( maModelIt == maModels.end() )
116         throw container::NoSuchElementException();
117     return uno::Any( *maModelIt++ );
118 }
119 
120 // ----------------------------------------------------------------------------
121 
122 /** Locks or unlocks the controllers of the specified document model.
123  */
124 void lclLockControllers( const uno::Reference< frame::XModel >& rxModel, sal_Bool bLockControllers )
125 {
126     if( rxModel.is() ) try
127     {
128         if( bLockControllers )
129             rxModel->lockControllers();
130         else
131             rxModel->unlockControllers();
132     }
133     catch( uno::Exception& )
134     {
135     }
136 }
137 
138 // ----------------------------------------------------------------------------
139 
140 /** Enables or disables the container windows of all controllers of the
141     specified document model.
142  */
143 void lclEnableContainerWindows( const uno::Reference< frame::XModel >& rxModel, sal_Bool bEnableWindows )
144 {
145     try
146     {
147         uno::Reference< frame::XModel2 > xModel2( rxModel, uno::UNO_QUERY_THROW );
148         uno::Reference< container::XEnumeration > xControllersEnum( xModel2->getControllers(), uno::UNO_SET_THROW );
149         // iterate over all controllers
150         while( xControllersEnum->hasMoreElements() )
151         {
152             try
153             {
154                 uno::Reference< frame::XController > xController( xControllersEnum->nextElement(), uno::UNO_QUERY_THROW );
155                 uno::Reference< frame::XFrame > xFrame( xController->getFrame(), uno::UNO_SET_THROW );
156                 uno::Reference< awt::XWindow > xWindow( xFrame->getContainerWindow(), uno::UNO_SET_THROW );
157                 xWindow->setEnable( bEnableWindows );
158             }
159             catch( uno::Exception& )
160             {
161             }
162         }
163     }
164     catch( uno::Exception& )
165     {
166     }
167 }
168 
169 // ----------------------------------------------------------------------------
170 
171 typedef void (*ModifyDocumentFunc)( const uno::Reference< frame::XModel >&, sal_Bool );
172 
173 /** Implementation iterating over all documents that have the same type as the
174     specified model, and calling the passed functor.
175  */
176 void lclIterateDocuments( ModifyDocumentFunc pModifyDocumentFunc, const uno::Reference< frame::XModel >& rxModel, sal_Bool bModificator )
177 {
178     uno::Reference< container::XEnumeration > xDocumentsEnum( new DocumentsEnumeration( rxModel ) );
179     // iterate over all open documents
180     while( xDocumentsEnum->hasMoreElements() ) try
181     {
182         uno::Reference< frame::XModel > xCurrModel( xDocumentsEnum->nextElement(), uno::UNO_QUERY_THROW );
183         pModifyDocumentFunc( xCurrModel, bModificator );
184     }
185     catch( uno::Exception& )
186     {
187     }
188 }
189 
190 // ----------------------------------------------------------------------------
191 
192 struct CurrDirPool
193 {
194     ::osl::Mutex maMutex;
195     ::std::map< ::rtl::OUString, ::rtl::OUString > maCurrDirs;
196 };
197 
198 struct StaticCurrDirPool : public ::rtl::Static< CurrDirPool, StaticCurrDirPool > {};
199 
200 } // namespace
201 
202 // ============================================================================
203 
204 uno::Reference< container::XEnumeration > createDocumentsEnumeration( const uno::Reference< frame::XModel >& rxModel )
205 {
206     return new DocumentsEnumeration( rxModel );
207 }
208 
209 // ============================================================================
210 
211 void lockControllersOfAllDocuments( const uno::Reference< frame::XModel >& rxModel, sal_Bool bLockControllers )
212 {
213     lclIterateDocuments( &lclLockControllers, rxModel, bLockControllers );
214 }
215 
216 // ============================================================================
217 
218 void enableContainerWindowsOfAllDocuments( const uno::Reference< frame::XModel >& rxModel, sal_Bool bEnableWindows )
219 {
220     lclIterateDocuments( &lclEnableContainerWindows, rxModel, bEnableWindows );
221 }
222 
223 // ============================================================================
224 
225 void registerCurrentDirectory( const uno::Reference< frame::XModel >& rxModel, const ::rtl::OUString& rPath )
226 {
227     if( rPath.getLength() > 0 )
228     {
229         CurrDirPool& rPool = StaticCurrDirPool::get();
230         ::osl::MutexGuard aGuard( rPool.maMutex );
231         try
232         {
233             uno::Reference< frame::XModuleManager > xModuleManager( lclCreateModuleManager(), uno::UNO_SET_THROW );
234             ::rtl::OUString aIdentifier = xModuleManager->identify( rxModel );
235             if( aIdentifier.getLength() > 0 )
236                 rPool.maCurrDirs[ aIdentifier ] = rPath;
237         }
238         catch( uno::Exception& )
239         {
240         }
241     }
242 }
243 
244 // ============================================================================
245 
246 ::rtl::OUString getCurrentDirectory( const uno::Reference< frame::XModel >& rxModel )
247 {
248     ::rtl::OUString aPath;
249     CurrDirPool& rPool = StaticCurrDirPool::get();
250     ::osl::MutexGuard aGuard( rPool.maMutex );
251     try
252     {
253         uno::Reference< frame::XModuleManager > xModuleManager( lclCreateModuleManager(), uno::UNO_SET_THROW );
254         ::rtl::OUString aIdentifier = xModuleManager->identify( rxModel );
255         aPath = rPool.maCurrDirs[ aIdentifier ];
256     }
257     catch( uno::Exception& )
258     {
259     }
260     return aPath;
261 }
262 
263 // ============================================================================
264 
265 } // namespace vba
266 } // namespace basic
267