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_chart2.hxx" 25 26 #include "UndoManager.hxx" 27 #include "ChartViewHelper.hxx" 28 29 /** === begin UNO includes === **/ 30 #include <com/sun/star/lang/DisposedException.hpp> 31 /** === end UNO includes === **/ 32 33 #include <framework/undomanagerhelper.hxx> 34 #include <svl/undo.hxx> 35 #include <unotools/undoopt.hxx> 36 37 //...................................................................................................................... 38 namespace chart 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::lang::DisposedException; 55 using ::com::sun::star::document::XUndoManager; 56 using ::com::sun::star::document::EmptyUndoStackException; 57 using ::com::sun::star::document::UndoContextNotClosedException; 58 using ::com::sun::star::document::UndoFailedException; 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 using ::com::sun::star::util::XModifyListener; 66 using ::com::sun::star::frame::XModel; 67 /** === end UNO using === **/ 68 69 namespace impl 70 { 71 //============================================================================================================== 72 //= UndoManager_Impl 73 //============================================================================================================== 74 class UndoManager_Impl : public ::framework::IUndoManagerImplementation 75 { 76 public: 77 UndoManager_Impl( UndoManager& i_antiImpl, ::cppu::OWeakObject& i_parent, ::osl::Mutex& i_mutex ) 78 :m_rAntiImpl( i_antiImpl ) 79 ,m_rParent( i_parent ) 80 ,m_rMutex( i_mutex ) 81 ,m_bDisposed( false ) 82 ,m_aUndoManager() 83 ,m_aUndoHelper( *this ) 84 { 85 m_aUndoManager.SetMaxUndoActionCount( (sal_uInt16)SvtUndoOptions().GetUndoCount() ); 86 } 87 88 virtual ~UndoManager_Impl() 89 { 90 } 91 92 // ......................................................................................................... 93 // IUndoManagerImplementation 94 virtual ::osl::Mutex& getMutex(); 95 virtual ::svl::IUndoManager& getImplUndoManager(); 96 virtual Reference< XUndoManager > getThis(); 97 98 // ......................................................................................................... 99 // attribute access 100 ::cppu::OWeakObject& getParent() { return m_rParent; } 101 ::framework::UndoManagerHelper& getUndoHelper() { return m_aUndoHelper; } 102 103 // ......................................................................................................... 104 // public interface 105 106 /// is called when the owner of the UndoManager is being disposed 107 void disposing(); 108 109 /// checks whether we're already disposed, throws a DisposedException if so 110 void checkDisposed_lck(); 111 112 private: 113 UndoManager& m_rAntiImpl; 114 ::cppu::OWeakObject& m_rParent; 115 ::osl::Mutex& m_rMutex; 116 bool m_bDisposed; 117 118 SfxUndoManager m_aUndoManager; 119 ::framework::UndoManagerHelper m_aUndoHelper; 120 }; 121 122 //-------------------------------------------------------------------------------------------------------------- 123 ::osl::Mutex& UndoManager_Impl::getMutex() 124 { 125 return m_rMutex; 126 } 127 128 //-------------------------------------------------------------------------------------------------------------- 129 ::svl::IUndoManager& UndoManager_Impl::getImplUndoManager() 130 { 131 return m_aUndoManager; 132 } 133 134 //-------------------------------------------------------------------------------------------------------------- 135 Reference< XUndoManager > UndoManager_Impl::getThis() 136 { 137 return &m_rAntiImpl; 138 } 139 140 //-------------------------------------------------------------------------------------------------------------- 141 void UndoManager_Impl::disposing() 142 { 143 { 144 ::osl::MutexGuard aGuard( m_rMutex ); 145 m_bDisposed = true; 146 } 147 m_aUndoHelper.disposing(); 148 } 149 150 //-------------------------------------------------------------------------------------------------------------- 151 void UndoManager_Impl::checkDisposed_lck() 152 { 153 if ( m_bDisposed ) 154 throw DisposedException( ::rtl::OUString(), getThis() ); 155 } 156 157 //============================================================================================================== 158 //= UndoManagerMethodGuard 159 //============================================================================================================== 160 /** guard for public UNO methods of the UndoManager 161 162 The only purpose of this guard is to check for the instance being disposed already. Everything else, 163 in particular the IMutexGuard functionality required by the UndoManagerHelper class, is a dummy only, 164 as all involved classes (means we ourselves, the UndoManagerHelper, the SfxUndoManager, and the Undo actions 165 we create) are inherently thread-safe, thus need no external lock (in particular no SolarMutex!). 166 */ 167 class UndoManagerMethodGuard : public ::framework::IMutexGuard 168 { 169 public: 170 UndoManagerMethodGuard( UndoManager_Impl& i_impl ) 171 { 172 ::osl::MutexGuard aGuard( i_impl.getMutex() ); 173 // throw if the instance is already disposed 174 i_impl.checkDisposed_lck(); 175 } 176 virtual ~UndoManagerMethodGuard() 177 { 178 } 179 180 // IMutexGuard 181 virtual ::framework::IMutex& getGuardedMutex(); 182 183 // IGuard 184 virtual void clear(); 185 virtual void reset(); 186 }; 187 188 class DummyMutex : public ::framework::IMutex 189 { 190 public: 191 virtual void acquire() { } 192 virtual void release() { } 193 }; 194 195 //-------------------------------------------------------------------------------------------------------------- 196 ::framework::IMutex& UndoManagerMethodGuard::getGuardedMutex() 197 { 198 static DummyMutex s_aDummyMutex; 199 return s_aDummyMutex; 200 } 201 202 //-------------------------------------------------------------------------------------------------------------- 203 void UndoManagerMethodGuard::clear() 204 { 205 // nothing to do. This interface implementation is a dummy. 206 } 207 208 //-------------------------------------------------------------------------------------------------------------- 209 void UndoManagerMethodGuard::reset() 210 { 211 // nothing to do. This interface implementation is a dummy. 212 } 213 } 214 215 //================================================================================================================== 216 //= UndoManager 217 //================================================================================================================== 218 using impl::UndoManagerMethodGuard; 219 220 //------------------------------------------------------------------------------------------------------------------ 221 UndoManager::UndoManager( ::cppu::OWeakObject& i_parent, ::osl::Mutex& i_mutex ) 222 :m_pImpl( new impl::UndoManager_Impl( *this, i_parent, i_mutex ) ) 223 { 224 } 225 226 //------------------------------------------------------------------------------------------------------------------ 227 UndoManager::~UndoManager() 228 { 229 } 230 231 //------------------------------------------------------------------------------------------------------------------ 232 void SAL_CALL UndoManager::acquire() throw () 233 { 234 m_pImpl->getParent().acquire(); 235 } 236 237 //------------------------------------------------------------------------------------------------------------------ 238 void SAL_CALL UndoManager::release() throw () 239 { 240 m_pImpl->getParent().release(); 241 } 242 243 //------------------------------------------------------------------------------------------------------------------ 244 void UndoManager::disposing() 245 { 246 m_pImpl->disposing(); 247 } 248 249 //------------------------------------------------------------------------------------------------------------------ 250 void SAL_CALL UndoManager::enterUndoContext( const ::rtl::OUString& i_title ) throw (RuntimeException) 251 { 252 UndoManagerMethodGuard aGuard( *m_pImpl ); 253 m_pImpl->getUndoHelper().enterUndoContext( i_title, aGuard ); 254 } 255 256 //------------------------------------------------------------------------------------------------------------------ 257 void SAL_CALL UndoManager::enterHiddenUndoContext( ) throw (EmptyUndoStackException, RuntimeException) 258 { 259 UndoManagerMethodGuard aGuard( *m_pImpl ); 260 m_pImpl->getUndoHelper().enterHiddenUndoContext( aGuard ); 261 } 262 263 //------------------------------------------------------------------------------------------------------------------ 264 void SAL_CALL UndoManager::leaveUndoContext( ) throw (InvalidStateException, RuntimeException) 265 { 266 UndoManagerMethodGuard aGuard( *m_pImpl ); 267 m_pImpl->getUndoHelper().leaveUndoContext( aGuard ); 268 } 269 270 //------------------------------------------------------------------------------------------------------------------ 271 void SAL_CALL UndoManager::addUndoAction( const Reference< XUndoAction >& i_action ) throw (IllegalArgumentException, RuntimeException) 272 { 273 UndoManagerMethodGuard aGuard( *m_pImpl ); 274 m_pImpl->getUndoHelper().addUndoAction( i_action, aGuard ); 275 } 276 277 //------------------------------------------------------------------------------------------------------------------ 278 void SAL_CALL UndoManager::undo( ) throw (EmptyUndoStackException, UndoContextNotClosedException, UndoFailedException, RuntimeException) 279 { 280 UndoManagerMethodGuard aGuard( *m_pImpl ); 281 m_pImpl->getUndoHelper().undo( aGuard ); 282 283 ChartViewHelper::setViewToDirtyState( Reference< XModel >( getParent(), UNO_QUERY ) ); 284 } 285 286 //------------------------------------------------------------------------------------------------------------------ 287 void SAL_CALL UndoManager::redo( ) throw (EmptyUndoStackException, UndoContextNotClosedException, UndoFailedException, RuntimeException) 288 { 289 UndoManagerMethodGuard aGuard( *m_pImpl ); 290 m_pImpl->getUndoHelper().redo( aGuard ); 291 292 ChartViewHelper::setViewToDirtyState( Reference< XModel >( getParent(), UNO_QUERY ) ); 293 } 294 295 //------------------------------------------------------------------------------------------------------------------ 296 ::sal_Bool SAL_CALL UndoManager::isUndoPossible( ) throw (RuntimeException) 297 { 298 UndoManagerMethodGuard aGuard( *m_pImpl ); 299 return m_pImpl->getUndoHelper().isUndoPossible(); 300 } 301 302 //------------------------------------------------------------------------------------------------------------------ 303 ::sal_Bool SAL_CALL UndoManager::isRedoPossible( ) throw (RuntimeException) 304 { 305 UndoManagerMethodGuard aGuard( *m_pImpl ); 306 return m_pImpl->getUndoHelper().isRedoPossible(); 307 } 308 309 //------------------------------------------------------------------------------------------------------------------ 310 ::rtl::OUString SAL_CALL UndoManager::getCurrentUndoActionTitle( ) throw (EmptyUndoStackException, RuntimeException) 311 { 312 UndoManagerMethodGuard aGuard( *m_pImpl ); 313 return m_pImpl->getUndoHelper().getCurrentUndoActionTitle(); 314 } 315 316 //------------------------------------------------------------------------------------------------------------------ 317 ::rtl::OUString SAL_CALL UndoManager::getCurrentRedoActionTitle( ) throw (EmptyUndoStackException, RuntimeException) 318 { 319 UndoManagerMethodGuard aGuard( *m_pImpl ); 320 return m_pImpl->getUndoHelper().getCurrentRedoActionTitle(); 321 } 322 323 //------------------------------------------------------------------------------------------------------------------ 324 Sequence< ::rtl::OUString > SAL_CALL UndoManager::getAllUndoActionTitles( ) throw (RuntimeException) 325 { 326 UndoManagerMethodGuard aGuard( *m_pImpl ); 327 return m_pImpl->getUndoHelper().getAllUndoActionTitles(); 328 } 329 330 //------------------------------------------------------------------------------------------------------------------ 331 Sequence< ::rtl::OUString > SAL_CALL UndoManager::getAllRedoActionTitles( ) throw (RuntimeException) 332 { 333 UndoManagerMethodGuard aGuard( *m_pImpl ); 334 return m_pImpl->getUndoHelper().getAllRedoActionTitles(); 335 } 336 337 //------------------------------------------------------------------------------------------------------------------ 338 void SAL_CALL UndoManager::clear( ) throw (UndoContextNotClosedException, RuntimeException) 339 { 340 UndoManagerMethodGuard aGuard( *m_pImpl ); 341 m_pImpl->getUndoHelper().clear( aGuard ); 342 } 343 344 //------------------------------------------------------------------------------------------------------------------ 345 void SAL_CALL UndoManager::clearRedo( ) throw (UndoContextNotClosedException, RuntimeException) 346 { 347 UndoManagerMethodGuard aGuard( *m_pImpl ); 348 m_pImpl->getUndoHelper().clearRedo( aGuard ); 349 } 350 351 //------------------------------------------------------------------------------------------------------------------ 352 void SAL_CALL UndoManager::reset( ) throw (RuntimeException) 353 { 354 UndoManagerMethodGuard aGuard( *m_pImpl ); 355 m_pImpl->getUndoHelper().reset( aGuard ); 356 } 357 358 //------------------------------------------------------------------------------------------------------------------ 359 void SAL_CALL UndoManager::addUndoManagerListener( const Reference< XUndoManagerListener >& i_listener ) throw (RuntimeException) 360 { 361 UndoManagerMethodGuard aGuard( *m_pImpl ); 362 m_pImpl->getUndoHelper().addUndoManagerListener( i_listener ); 363 } 364 365 //------------------------------------------------------------------------------------------------------------------ 366 void SAL_CALL UndoManager::removeUndoManagerListener( const Reference< XUndoManagerListener >& i_listener ) throw (RuntimeException) 367 { 368 UndoManagerMethodGuard aGuard( *m_pImpl ); 369 m_pImpl->getUndoHelper().removeUndoManagerListener( i_listener ); 370 } 371 372 //------------------------------------------------------------------------------------------------------------------ 373 void SAL_CALL UndoManager::lock( ) throw (RuntimeException) 374 { 375 UndoManagerMethodGuard aGuard( *m_pImpl ); 376 m_pImpl->getUndoHelper().lock(); 377 } 378 379 //------------------------------------------------------------------------------------------------------------------ 380 void SAL_CALL UndoManager::unlock( ) throw (NotLockedException, RuntimeException) 381 { 382 UndoManagerMethodGuard aGuard( *m_pImpl ); 383 m_pImpl->getUndoHelper().unlock(); 384 } 385 386 //------------------------------------------------------------------------------------------------------------------ 387 ::sal_Bool SAL_CALL UndoManager::isLocked( ) throw (RuntimeException) 388 { 389 UndoManagerMethodGuard aGuard( *m_pImpl ); 390 return m_pImpl->getUndoHelper().isLocked(); 391 } 392 393 //------------------------------------------------------------------------------------------------------------------ 394 Reference< XInterface > SAL_CALL UndoManager::getParent( ) throw (RuntimeException) 395 { 396 UndoManagerMethodGuard aGuard( *m_pImpl ); 397 return *&m_pImpl->getParent(); 398 } 399 400 //------------------------------------------------------------------------------------------------------------------ 401 void SAL_CALL UndoManager::setParent( const Reference< XInterface >& i_parent ) throw (NoSupportException, RuntimeException) 402 { 403 UndoManagerMethodGuard aGuard( *m_pImpl ); 404 (void)i_parent; 405 throw NoSupportException( ::rtl::OUString(), m_pImpl->getThis() ); 406 } 407 408 //------------------------------------------------------------------------------------------------------------------ 409 void SAL_CALL UndoManager::addModifyListener( const Reference< XModifyListener >& i_listener ) throw (RuntimeException) 410 { 411 UndoManagerMethodGuard aGuard( *m_pImpl ); 412 m_pImpl->getUndoHelper().addModifyListener( i_listener ); 413 } 414 415 //------------------------------------------------------------------------------------------------------------------ 416 void SAL_CALL UndoManager::removeModifyListener( const Reference< XModifyListener >& i_listener ) throw (RuntimeException) 417 { 418 UndoManagerMethodGuard aGuard( *m_pImpl ); 419 m_pImpl->getUndoHelper().removeModifyListener( i_listener ); 420 } 421 422 //...................................................................................................................... 423 } // namespace chart 424 //...................................................................................................................... 425