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