1 /************************************************************************* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * Copyright 2000, 2010 Oracle and/or its affiliates. 5 * 6 * OpenOffice.org - a multi-platform office productivity suite 7 * 8 * This file is part of OpenOffice.org. 9 * 10 * OpenOffice.org is free software: you can redistribute it and/or modify 11 * it under the terms of the GNU Lesser General Public License version 3 12 * only, as published by the Free Software Foundation. 13 * 14 * OpenOffice.org is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU Lesser General Public License version 3 for more details 18 * (a copy is included in the LICENSE file that accompanied this code). 19 * 20 * You should have received a copy of the GNU Lesser General Public License 21 * version 3 along with OpenOffice.org. If not, see 22 * <http://www.openoffice.org/license.html> 23 * for a copy of the LGPLv3 License. 24 * 25 ************************************************************************/ 26 27 #include "precompiled_dbaccess.hxx" 28 29 #include "dbaundomanager.hxx" 30 31 /** === begin UNO includes === **/ 32 #include <com/sun/star/lang/DisposedException.hpp> 33 /** === end UNO includes === **/ 34 35 #include <svl/undo.hxx> 36 #include <vcl/svapp.hxx> 37 #include <vos/mutex.hxx> 38 #include <framework/undomanagerhelper.hxx> 39 40 //...................................................................................................................... 41 namespace dbaui 42 { 43 //...................................................................................................................... 44 45 /** === begin UNO using === **/ 46 using ::com::sun::star::uno::Reference; 47 using ::com::sun::star::uno::XInterface; 48 using ::com::sun::star::uno::UNO_QUERY; 49 using ::com::sun::star::uno::UNO_QUERY_THROW; 50 using ::com::sun::star::uno::UNO_SET_THROW; 51 using ::com::sun::star::uno::Exception; 52 using ::com::sun::star::uno::RuntimeException; 53 using ::com::sun::star::uno::Any; 54 using ::com::sun::star::uno::makeAny; 55 using ::com::sun::star::uno::Sequence; 56 using ::com::sun::star::uno::Type; 57 using ::com::sun::star::document::XUndoManager; 58 using ::com::sun::star::lang::DisposedException; 59 using ::com::sun::star::document::UndoContextNotClosedException; 60 using ::com::sun::star::document::UndoFailedException; 61 using ::com::sun::star::document::EmptyUndoStackException; 62 using ::com::sun::star::util::InvalidStateException; 63 using ::com::sun::star::document::XUndoAction; 64 using ::com::sun::star::lang::IllegalArgumentException; 65 using ::com::sun::star::document::XUndoManagerListener; 66 using ::com::sun::star::util::NotLockedException; 67 using ::com::sun::star::lang::NoSupportException; 68 /** === end UNO using === **/ 69 70 //================================================================================================================== 71 //= UndoManager_Impl 72 //================================================================================================================== 73 struct UndoManager_Impl : public ::framework::IUndoManagerImplementation 74 { 75 UndoManager_Impl( UndoManager& i_antiImpl, ::cppu::OWeakObject& i_parent, ::osl::Mutex& i_mutex ) 76 :rAntiImpl( i_antiImpl ) 77 ,rParent( i_parent ) 78 ,rMutex( i_mutex ) 79 ,bDisposed( false ) 80 ,aUndoManager() 81 ,aUndoHelper( *this ) 82 { 83 } 84 85 virtual ~UndoManager_Impl() 86 { 87 } 88 89 UndoManager& rAntiImpl; 90 ::cppu::OWeakObject& rParent; 91 ::osl::Mutex& rMutex; 92 bool bDisposed; 93 SfxUndoManager aUndoManager; 94 ::framework::UndoManagerHelper aUndoHelper; 95 96 // IUndoManagerImplementation 97 virtual ::svl::IUndoManager& getImplUndoManager(); 98 virtual Reference< XUndoManager > getThis(); 99 }; 100 101 //------------------------------------------------------------------------------------------------------------------ 102 ::svl::IUndoManager& UndoManager_Impl::getImplUndoManager() 103 { 104 return aUndoManager; 105 } 106 107 //------------------------------------------------------------------------------------------------------------------ 108 Reference< XUndoManager > UndoManager_Impl::getThis() 109 { 110 return static_cast< XUndoManager* >( &rAntiImpl ); 111 } 112 113 //============================================================================================================== 114 //= OslMutexFacade 115 //============================================================================================================== 116 class OslMutexFacade : public ::framework::IMutex 117 { 118 public: 119 OslMutexFacade( ::osl::Mutex& i_mutex ) 120 :m_rMutex( i_mutex ) 121 { 122 } 123 124 virtual void acquire(); 125 virtual void release(); 126 127 private: 128 ::osl::Mutex& m_rMutex; 129 }; 130 131 //-------------------------------------------------------------------------------------------------------------- 132 void OslMutexFacade::acquire() 133 { 134 m_rMutex.acquire(); 135 } 136 137 //-------------------------------------------------------------------------------------------------------------- 138 void OslMutexFacade::release() 139 { 140 m_rMutex.release(); 141 } 142 143 //============================================================================================================== 144 //= UndoManagerMethodGuard 145 //============================================================================================================== 146 /** guard for public UNO methods of the UndoManager 147 */ 148 class UndoManagerMethodGuard : public ::framework::IMutexGuard 149 { 150 public: 151 UndoManagerMethodGuard( UndoManager_Impl& i_impl ) 152 :m_aGuard( i_impl.rMutex ) 153 ,m_aMutexFacade( i_impl.rMutex ) 154 { 155 // throw if the instance is already disposed 156 if ( i_impl.bDisposed ) 157 throw DisposedException( ::rtl::OUString(), i_impl.getThis() ); 158 } 159 virtual ~UndoManagerMethodGuard() 160 { 161 } 162 163 // IMutexGuard 164 virtual ::framework::IMutex& getGuardedMutex(); 165 166 // IGuard 167 virtual void clear(); 168 virtual void reset(); 169 170 private: 171 ::osl::ResettableMutexGuard m_aGuard; 172 OslMutexFacade m_aMutexFacade; 173 }; 174 175 //-------------------------------------------------------------------------------------------------------------- 176 ::framework::IMutex& UndoManagerMethodGuard::getGuardedMutex() 177 { 178 return m_aMutexFacade; 179 } 180 181 //-------------------------------------------------------------------------------------------------------------- 182 void UndoManagerMethodGuard::clear() 183 { 184 m_aGuard.clear(); 185 } 186 187 //-------------------------------------------------------------------------------------------------------------- 188 void UndoManagerMethodGuard::reset() 189 { 190 m_aGuard.reset(); 191 } 192 193 //================================================================================================================== 194 //= UndoManager 195 //================================================================================================================== 196 //------------------------------------------------------------------------------------------------------------------ 197 UndoManager::UndoManager( ::cppu::OWeakObject& i_parent, ::osl::Mutex& i_mutex ) 198 :m_pImpl( new UndoManager_Impl( *this, i_parent, i_mutex ) ) 199 { 200 } 201 202 //------------------------------------------------------------------------------------------------------------------ 203 UndoManager::~UndoManager() 204 { 205 } 206 207 //------------------------------------------------------------------------------------------------------------------ 208 SfxUndoManager& UndoManager::GetSfxUndoManager() const 209 { 210 return m_pImpl->aUndoManager; 211 } 212 213 //------------------------------------------------------------------------------------------------------------------ 214 void SAL_CALL UndoManager::acquire( ) throw () 215 { 216 m_pImpl->rParent.acquire(); 217 } 218 219 //------------------------------------------------------------------------------------------------------------------ 220 void SAL_CALL UndoManager::release( ) throw () 221 { 222 m_pImpl->rParent.release(); 223 } 224 225 //------------------------------------------------------------------------------------------------------------------ 226 void UndoManager::disposing() 227 { 228 { 229 ::osl::MutexGuard aGuard( m_pImpl->rMutex ); 230 m_pImpl->bDisposed = true; 231 } 232 m_pImpl->aUndoHelper.disposing(); 233 } 234 235 //------------------------------------------------------------------------------------------------------------------ 236 void SAL_CALL UndoManager::enterUndoContext( const ::rtl::OUString& i_title ) throw (RuntimeException) 237 { 238 UndoManagerMethodGuard aGuard( *m_pImpl ); 239 m_pImpl->aUndoHelper.enterUndoContext( i_title, aGuard ); 240 } 241 242 //------------------------------------------------------------------------------------------------------------------ 243 void SAL_CALL UndoManager::enterHiddenUndoContext( ) throw (EmptyUndoStackException, RuntimeException) 244 { 245 UndoManagerMethodGuard aGuard( *m_pImpl ); 246 m_pImpl->aUndoHelper.enterHiddenUndoContext( aGuard ); 247 } 248 249 //------------------------------------------------------------------------------------------------------------------ 250 void SAL_CALL UndoManager::leaveUndoContext( ) throw (InvalidStateException, RuntimeException) 251 { 252 UndoManagerMethodGuard aGuard( *m_pImpl ); 253 m_pImpl->aUndoHelper.leaveUndoContext( aGuard ); 254 } 255 256 //------------------------------------------------------------------------------------------------------------------ 257 void SAL_CALL UndoManager::addUndoAction( const Reference< XUndoAction >& i_action ) throw (IllegalArgumentException, RuntimeException) 258 { 259 UndoManagerMethodGuard aGuard( *m_pImpl ); 260 m_pImpl->aUndoHelper.addUndoAction( i_action, aGuard ); 261 } 262 263 //------------------------------------------------------------------------------------------------------------------ 264 void SAL_CALL UndoManager::undo( ) throw (EmptyUndoStackException, UndoContextNotClosedException, UndoFailedException, RuntimeException) 265 { 266 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 267 // (all our UndoActions work directly on VCL code, usually, so ...) 268 UndoManagerMethodGuard aGuard( *m_pImpl ); 269 m_pImpl->aUndoHelper.undo( aGuard ); 270 } 271 272 //------------------------------------------------------------------------------------------------------------------ 273 void SAL_CALL UndoManager::redo( ) throw (EmptyUndoStackException, UndoContextNotClosedException, UndoFailedException, RuntimeException) 274 { 275 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 276 // (all our UndoActions work directly on VCL code, usually, so ...) 277 UndoManagerMethodGuard aGuard( *m_pImpl ); 278 m_pImpl->aUndoHelper.redo( aGuard ); 279 } 280 281 //------------------------------------------------------------------------------------------------------------------ 282 ::sal_Bool SAL_CALL UndoManager::isUndoPossible( ) throw (RuntimeException) 283 { 284 UndoManagerMethodGuard aGuard( *m_pImpl ); 285 return m_pImpl->aUndoHelper.isUndoPossible(); 286 } 287 288 //------------------------------------------------------------------------------------------------------------------ 289 ::sal_Bool SAL_CALL UndoManager::isRedoPossible( ) throw (RuntimeException) 290 { 291 UndoManagerMethodGuard aGuard( *m_pImpl ); 292 return m_pImpl->aUndoHelper.isRedoPossible(); 293 } 294 295 //------------------------------------------------------------------------------------------------------------------ 296 ::rtl::OUString SAL_CALL UndoManager::getCurrentUndoActionTitle( ) throw (EmptyUndoStackException, RuntimeException) 297 { 298 UndoManagerMethodGuard aGuard( *m_pImpl ); 299 return m_pImpl->aUndoHelper.getCurrentUndoActionTitle(); 300 } 301 302 //------------------------------------------------------------------------------------------------------------------ 303 ::rtl::OUString SAL_CALL UndoManager::getCurrentRedoActionTitle( ) throw (EmptyUndoStackException, RuntimeException) 304 { 305 UndoManagerMethodGuard aGuard( *m_pImpl ); 306 return m_pImpl->aUndoHelper.getCurrentRedoActionTitle(); 307 } 308 309 //------------------------------------------------------------------------------------------------------------------ 310 Sequence< ::rtl::OUString > SAL_CALL UndoManager::getAllUndoActionTitles( ) throw (RuntimeException) 311 { 312 UndoManagerMethodGuard aGuard( *m_pImpl ); 313 return m_pImpl->aUndoHelper.getAllUndoActionTitles(); 314 } 315 316 //------------------------------------------------------------------------------------------------------------------ 317 Sequence< ::rtl::OUString > SAL_CALL UndoManager::getAllRedoActionTitles( ) throw (RuntimeException) 318 { 319 UndoManagerMethodGuard aGuard( *m_pImpl ); 320 return m_pImpl->aUndoHelper.getAllRedoActionTitles(); 321 } 322 323 //------------------------------------------------------------------------------------------------------------------ 324 void SAL_CALL UndoManager::clear( ) throw (UndoContextNotClosedException, RuntimeException) 325 { 326 UndoManagerMethodGuard aGuard( *m_pImpl ); 327 m_pImpl->aUndoHelper.clear( aGuard ); 328 } 329 330 //------------------------------------------------------------------------------------------------------------------ 331 void SAL_CALL UndoManager::clearRedo( ) throw (UndoContextNotClosedException, RuntimeException) 332 { 333 UndoManagerMethodGuard aGuard( *m_pImpl ); 334 m_pImpl->aUndoHelper.clearRedo( aGuard ); 335 } 336 337 //------------------------------------------------------------------------------------------------------------------ 338 void SAL_CALL UndoManager::reset( ) throw (RuntimeException) 339 { 340 UndoManagerMethodGuard aGuard( *m_pImpl ); 341 m_pImpl->aUndoHelper.reset( aGuard ); 342 } 343 344 //------------------------------------------------------------------------------------------------------------------ 345 void SAL_CALL UndoManager::addUndoManagerListener( const Reference< XUndoManagerListener >& i_listener ) throw (RuntimeException) 346 { 347 UndoManagerMethodGuard aGuard( *m_pImpl ); 348 m_pImpl->aUndoHelper.addUndoManagerListener( i_listener ); 349 } 350 351 //------------------------------------------------------------------------------------------------------------------ 352 void SAL_CALL UndoManager::removeUndoManagerListener( const Reference< XUndoManagerListener >& i_listener ) throw (RuntimeException) 353 { 354 UndoManagerMethodGuard aGuard( *m_pImpl ); 355 m_pImpl->aUndoHelper.removeUndoManagerListener( i_listener ); 356 } 357 358 //------------------------------------------------------------------------------------------------------------------ 359 void SAL_CALL UndoManager::lock( ) throw (RuntimeException) 360 { 361 UndoManagerMethodGuard aGuard( *m_pImpl ); 362 m_pImpl->aUndoHelper.lock(); 363 } 364 365 //------------------------------------------------------------------------------------------------------------------ 366 void SAL_CALL UndoManager::unlock( ) throw (NotLockedException, RuntimeException) 367 { 368 UndoManagerMethodGuard aGuard( *m_pImpl ); 369 m_pImpl->aUndoHelper.unlock(); 370 } 371 372 //------------------------------------------------------------------------------------------------------------------ 373 ::sal_Bool SAL_CALL UndoManager::isLocked( ) throw (RuntimeException) 374 { 375 UndoManagerMethodGuard aGuard( *m_pImpl ); 376 return m_pImpl->aUndoHelper.isLocked(); 377 } 378 379 //------------------------------------------------------------------------------------------------------------------ 380 Reference< XInterface > SAL_CALL UndoManager::getParent( ) throw (RuntimeException) 381 { 382 UndoManagerMethodGuard aGuard( *m_pImpl ); 383 return *&m_pImpl->rParent; 384 } 385 386 //------------------------------------------------------------------------------------------------------------------ 387 void SAL_CALL UndoManager::setParent( const Reference< XInterface >& i_parent ) throw (NoSupportException, RuntimeException) 388 { 389 (void)i_parent; 390 throw NoSupportException( ::rtl::OUString(), m_pImpl->getThis() ); 391 } 392 393 //...................................................................................................................... 394 } // namespace dbaui 395 //...................................................................................................................... 396