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