1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "UndoManager.hxx"
22 #include "ChartViewHelper.hxx"
24 #include <com/sun/star/lang/DisposedException.hpp>
26 #include <framework/undomanagerhelper.hxx>
27 #include <officecfg/Office/Common.hxx>
28 #include <svl/undo.hxx>
30 //......................................................................................................................
33 //......................................................................................................................
35 using ::com::sun::star::uno::Reference
;
36 using ::com::sun::star::uno::XInterface
;
37 using ::com::sun::star::uno::UNO_QUERY
;
38 using ::com::sun::star::uno::UNO_QUERY_THROW
;
39 using ::com::sun::star::uno::UNO_SET_THROW
;
40 using ::com::sun::star::uno::Exception
;
41 using ::com::sun::star::uno::RuntimeException
;
42 using ::com::sun::star::uno::Any
;
43 using ::com::sun::star::uno::makeAny
;
44 using ::com::sun::star::uno::Sequence
;
45 using ::com::sun::star::uno::Type
;
46 using ::com::sun::star::lang::DisposedException
;
47 using ::com::sun::star::document::XUndoManager
;
48 using ::com::sun::star::document::EmptyUndoStackException
;
49 using ::com::sun::star::document::UndoContextNotClosedException
;
50 using ::com::sun::star::document::UndoFailedException
;
51 using ::com::sun::star::util::InvalidStateException
;
52 using ::com::sun::star::document::XUndoAction
;
53 using ::com::sun::star::lang::IllegalArgumentException
;
54 using ::com::sun::star::document::XUndoManagerListener
;
55 using ::com::sun::star::util::NotLockedException
;
56 using ::com::sun::star::lang::NoSupportException
;
57 using ::com::sun::star::util::XModifyListener
;
58 using ::com::sun::star::frame::XModel
;
62 //==============================================================================================================
64 //==============================================================================================================
65 class UndoManager_Impl
: public ::framework::IUndoManagerImplementation
68 UndoManager_Impl( UndoManager
& i_antiImpl
, ::cppu::OWeakObject
& i_parent
, ::osl::Mutex
& i_mutex
)
69 :m_rAntiImpl( i_antiImpl
)
70 ,m_rParent( i_parent
)
74 ,m_aUndoHelper( *this )
76 m_aUndoManager
.SetMaxUndoActionCount(
77 officecfg::Office::Common::Undo::Steps::get());
80 virtual ~UndoManager_Impl()
84 // .........................................................................................................
85 // IUndoManagerImplementation
86 virtual ::osl::Mutex
& getMutex();
87 virtual ::svl::IUndoManager
& getImplUndoManager();
88 virtual Reference
< XUndoManager
> getThis();
90 // .........................................................................................................
92 ::cppu::OWeakObject
& getParent() { return m_rParent
; }
93 ::framework::UndoManagerHelper
& getUndoHelper() { return m_aUndoHelper
; }
95 // .........................................................................................................
98 /// is called when the owner of the UndoManager is being disposed
101 /// checks whether we're already disposed, throws a DisposedException if so
102 void checkDisposed_lck();
105 UndoManager
& m_rAntiImpl
;
106 ::cppu::OWeakObject
& m_rParent
;
107 ::osl::Mutex
& m_rMutex
;
110 SfxUndoManager m_aUndoManager
;
111 ::framework::UndoManagerHelper m_aUndoHelper
;
114 //--------------------------------------------------------------------------------------------------------------
115 ::osl::Mutex
& UndoManager_Impl::getMutex()
120 //--------------------------------------------------------------------------------------------------------------
121 ::svl::IUndoManager
& UndoManager_Impl::getImplUndoManager()
123 return m_aUndoManager
;
126 //--------------------------------------------------------------------------------------------------------------
127 Reference
< XUndoManager
> UndoManager_Impl::getThis()
132 //--------------------------------------------------------------------------------------------------------------
133 void UndoManager_Impl::disposing()
136 ::osl::MutexGuard
aGuard( m_rMutex
);
139 m_aUndoHelper
.disposing();
142 //--------------------------------------------------------------------------------------------------------------
143 void UndoManager_Impl::checkDisposed_lck()
146 throw DisposedException( OUString(), getThis() );
149 //==============================================================================================================
150 //= UndoManagerMethodGuard
151 //==============================================================================================================
152 /** guard for public UNO methods of the UndoManager
154 The only purpose of this guard is to check for the instance being disposed already. Everything else,
155 in particular the IMutexGuard functionality required by the UndoManagerHelper class, is a dummy only,
156 as all involved classes (means we ourselves, the UndoManagerHelper, the SfxUndoManager, and the Undo actions
157 we create) are inherently thread-safe, thus need no external lock (in particular no SolarMutex!).
159 class UndoManagerMethodGuard
: public ::framework::IMutexGuard
162 UndoManagerMethodGuard( UndoManager_Impl
& i_impl
)
164 ::osl::MutexGuard
aGuard( i_impl
.getMutex() );
165 // throw if the instance is already disposed
166 i_impl
.checkDisposed_lck();
168 virtual ~UndoManagerMethodGuard()
173 virtual ::framework::IMutex
& getGuardedMutex();
176 virtual void clear();
177 virtual void reset();
180 class DummyMutex
: public ::framework::IMutex
183 virtual ~DummyMutex() {}
184 virtual void acquire() { }
185 virtual void release() { }
188 //--------------------------------------------------------------------------------------------------------------
189 ::framework::IMutex
& UndoManagerMethodGuard::getGuardedMutex()
191 static DummyMutex s_aDummyMutex
;
192 return s_aDummyMutex
;
195 //--------------------------------------------------------------------------------------------------------------
196 void UndoManagerMethodGuard::clear()
198 // nothing to do. This interface implementation is a dummy.
201 //--------------------------------------------------------------------------------------------------------------
202 void UndoManagerMethodGuard::reset()
204 // nothing to do. This interface implementation is a dummy.
208 //==================================================================================================================
210 //==================================================================================================================
211 using impl::UndoManagerMethodGuard
;
213 //------------------------------------------------------------------------------------------------------------------
214 UndoManager::UndoManager( ::cppu::OWeakObject
& i_parent
, ::osl::Mutex
& i_mutex
)
215 :m_pImpl( new impl::UndoManager_Impl( *this, i_parent
, i_mutex
) )
219 //------------------------------------------------------------------------------------------------------------------
220 UndoManager::~UndoManager()
224 //------------------------------------------------------------------------------------------------------------------
225 void SAL_CALL
UndoManager::acquire() throw ()
227 m_pImpl
->getParent().acquire();
230 //------------------------------------------------------------------------------------------------------------------
231 void SAL_CALL
UndoManager::release() throw ()
233 m_pImpl
->getParent().release();
236 //------------------------------------------------------------------------------------------------------------------
237 void UndoManager::disposing()
239 m_pImpl
->disposing();
242 //------------------------------------------------------------------------------------------------------------------
243 void SAL_CALL
UndoManager::enterUndoContext( const OUString
& i_title
) throw (RuntimeException
)
245 UndoManagerMethodGuard
aGuard( *m_pImpl
);
246 m_pImpl
->getUndoHelper().enterUndoContext( i_title
, aGuard
);
249 //------------------------------------------------------------------------------------------------------------------
250 void SAL_CALL
UndoManager::enterHiddenUndoContext( ) throw (EmptyUndoStackException
, RuntimeException
)
252 UndoManagerMethodGuard
aGuard( *m_pImpl
);
253 m_pImpl
->getUndoHelper().enterHiddenUndoContext( aGuard
);
256 //------------------------------------------------------------------------------------------------------------------
257 void SAL_CALL
UndoManager::leaveUndoContext( ) throw (InvalidStateException
, RuntimeException
)
259 UndoManagerMethodGuard
aGuard( *m_pImpl
);
260 m_pImpl
->getUndoHelper().leaveUndoContext( aGuard
);
263 //------------------------------------------------------------------------------------------------------------------
264 void SAL_CALL
UndoManager::addUndoAction( const Reference
< XUndoAction
>& i_action
) throw (IllegalArgumentException
, RuntimeException
)
266 UndoManagerMethodGuard
aGuard( *m_pImpl
);
267 m_pImpl
->getUndoHelper().addUndoAction( i_action
, aGuard
);
270 //------------------------------------------------------------------------------------------------------------------
271 void SAL_CALL
UndoManager::undo( ) throw (EmptyUndoStackException
, UndoContextNotClosedException
, UndoFailedException
, RuntimeException
)
273 UndoManagerMethodGuard
aGuard( *m_pImpl
);
274 m_pImpl
->getUndoHelper().undo( aGuard
);
276 ChartViewHelper::setViewToDirtyState( Reference
< XModel
>( getParent(), UNO_QUERY
) );
279 //------------------------------------------------------------------------------------------------------------------
280 void SAL_CALL
UndoManager::redo( ) throw (EmptyUndoStackException
, UndoContextNotClosedException
, UndoFailedException
, RuntimeException
)
282 UndoManagerMethodGuard
aGuard( *m_pImpl
);
283 m_pImpl
->getUndoHelper().redo( aGuard
);
285 ChartViewHelper::setViewToDirtyState( Reference
< XModel
>( getParent(), UNO_QUERY
) );
288 //------------------------------------------------------------------------------------------------------------------
289 ::sal_Bool SAL_CALL
UndoManager::isUndoPossible( ) throw (RuntimeException
)
291 UndoManagerMethodGuard
aGuard( *m_pImpl
);
292 return m_pImpl
->getUndoHelper().isUndoPossible();
295 //------------------------------------------------------------------------------------------------------------------
296 ::sal_Bool SAL_CALL
UndoManager::isRedoPossible( ) throw (RuntimeException
)
298 UndoManagerMethodGuard
aGuard( *m_pImpl
);
299 return m_pImpl
->getUndoHelper().isRedoPossible();
302 //------------------------------------------------------------------------------------------------------------------
303 OUString SAL_CALL
UndoManager::getCurrentUndoActionTitle( ) throw (EmptyUndoStackException
, RuntimeException
)
305 UndoManagerMethodGuard
aGuard( *m_pImpl
);
306 return m_pImpl
->getUndoHelper().getCurrentUndoActionTitle();
309 //------------------------------------------------------------------------------------------------------------------
310 OUString SAL_CALL
UndoManager::getCurrentRedoActionTitle( ) throw (EmptyUndoStackException
, RuntimeException
)
312 UndoManagerMethodGuard
aGuard( *m_pImpl
);
313 return m_pImpl
->getUndoHelper().getCurrentRedoActionTitle();
316 //------------------------------------------------------------------------------------------------------------------
317 Sequence
< OUString
> SAL_CALL
UndoManager::getAllUndoActionTitles( ) throw (RuntimeException
)
319 UndoManagerMethodGuard
aGuard( *m_pImpl
);
320 return m_pImpl
->getUndoHelper().getAllUndoActionTitles();
323 //------------------------------------------------------------------------------------------------------------------
324 Sequence
< OUString
> SAL_CALL
UndoManager::getAllRedoActionTitles( ) throw (RuntimeException
)
326 UndoManagerMethodGuard
aGuard( *m_pImpl
);
327 return m_pImpl
->getUndoHelper().getAllRedoActionTitles();
330 //------------------------------------------------------------------------------------------------------------------
331 void SAL_CALL
UndoManager::clear( ) throw (UndoContextNotClosedException
, RuntimeException
)
333 UndoManagerMethodGuard
aGuard( *m_pImpl
);
334 m_pImpl
->getUndoHelper().clear( aGuard
);
337 //------------------------------------------------------------------------------------------------------------------
338 void SAL_CALL
UndoManager::clearRedo( ) throw (UndoContextNotClosedException
, RuntimeException
)
340 UndoManagerMethodGuard
aGuard( *m_pImpl
);
341 m_pImpl
->getUndoHelper().clearRedo( aGuard
);
344 //------------------------------------------------------------------------------------------------------------------
345 void SAL_CALL
UndoManager::reset( ) throw (RuntimeException
)
347 UndoManagerMethodGuard
aGuard( *m_pImpl
);
348 m_pImpl
->getUndoHelper().reset( aGuard
);
351 //------------------------------------------------------------------------------------------------------------------
352 void SAL_CALL
UndoManager::addUndoManagerListener( const Reference
< XUndoManagerListener
>& i_listener
) throw (RuntimeException
)
354 UndoManagerMethodGuard
aGuard( *m_pImpl
);
355 m_pImpl
->getUndoHelper().addUndoManagerListener( i_listener
);
358 //------------------------------------------------------------------------------------------------------------------
359 void SAL_CALL
UndoManager::removeUndoManagerListener( const Reference
< XUndoManagerListener
>& i_listener
) throw (RuntimeException
)
361 UndoManagerMethodGuard
aGuard( *m_pImpl
);
362 m_pImpl
->getUndoHelper().removeUndoManagerListener( i_listener
);
365 //------------------------------------------------------------------------------------------------------------------
366 void SAL_CALL
UndoManager::lock( ) throw (RuntimeException
)
368 UndoManagerMethodGuard
aGuard( *m_pImpl
);
369 m_pImpl
->getUndoHelper().lock();
372 //------------------------------------------------------------------------------------------------------------------
373 void SAL_CALL
UndoManager::unlock( ) throw (NotLockedException
, RuntimeException
)
375 UndoManagerMethodGuard
aGuard( *m_pImpl
);
376 m_pImpl
->getUndoHelper().unlock();
379 //------------------------------------------------------------------------------------------------------------------
380 ::sal_Bool SAL_CALL
UndoManager::isLocked( ) throw (RuntimeException
)
382 UndoManagerMethodGuard
aGuard( *m_pImpl
);
383 return m_pImpl
->getUndoHelper().isLocked();
386 //------------------------------------------------------------------------------------------------------------------
387 Reference
< XInterface
> SAL_CALL
UndoManager::getParent( ) throw (RuntimeException
)
389 UndoManagerMethodGuard
aGuard( *m_pImpl
);
390 return *&m_pImpl
->getParent();
393 //------------------------------------------------------------------------------------------------------------------
394 void SAL_CALL
UndoManager::setParent( const Reference
< XInterface
>& i_parent
) throw (NoSupportException
, RuntimeException
)
396 UndoManagerMethodGuard
aGuard( *m_pImpl
);
398 throw NoSupportException( OUString(), m_pImpl
->getThis() );
401 //------------------------------------------------------------------------------------------------------------------
402 void SAL_CALL
UndoManager::addModifyListener( const Reference
< XModifyListener
>& i_listener
) throw (RuntimeException
)
404 UndoManagerMethodGuard
aGuard( *m_pImpl
);
405 m_pImpl
->getUndoHelper().addModifyListener( i_listener
);
408 //------------------------------------------------------------------------------------------------------------------
409 void SAL_CALL
UndoManager::removeModifyListener( const Reference
< XModifyListener
>& i_listener
) throw (RuntimeException
)
411 UndoManagerMethodGuard
aGuard( *m_pImpl
);
412 m_pImpl
->getUndoHelper().removeModifyListener( i_listener
);
415 //......................................................................................................................
417 //......................................................................................................................
419 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */