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