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 .
20 #include "UndoManager.hxx"
21 #include "ChartViewHelper.hxx"
23 #include <com/sun/star/lang/DisposedException.hpp>
25 #include <framework/undomanagerhelper.hxx>
26 #include <officecfg/Office/Common.hxx>
27 #include <svl/undo.hxx>
32 using ::com::sun::star::uno::Reference
;
33 using ::com::sun::star::uno::XInterface
;
34 using ::com::sun::star::uno::UNO_QUERY
;
35 using ::com::sun::star::uno::UNO_QUERY_THROW
;
36 using ::com::sun::star::uno::UNO_SET_THROW
;
37 using ::com::sun::star::uno::Exception
;
38 using ::com::sun::star::uno::RuntimeException
;
39 using ::com::sun::star::uno::Any
;
40 using ::com::sun::star::uno::makeAny
;
41 using ::com::sun::star::uno::Sequence
;
42 using ::com::sun::star::uno::Type
;
43 using ::com::sun::star::lang::DisposedException
;
44 using ::com::sun::star::document::XUndoManager
;
45 using ::com::sun::star::document::EmptyUndoStackException
;
46 using ::com::sun::star::document::UndoContextNotClosedException
;
47 using ::com::sun::star::document::UndoFailedException
;
48 using ::com::sun::star::util::InvalidStateException
;
49 using ::com::sun::star::document::XUndoAction
;
50 using ::com::sun::star::lang::IllegalArgumentException
;
51 using ::com::sun::star::document::XUndoManagerListener
;
52 using ::com::sun::star::util::NotLockedException
;
53 using ::com::sun::star::lang::NoSupportException
;
54 using ::com::sun::star::util::XModifyListener
;
55 using ::com::sun::star::frame::XModel
;
59 class UndoManager_Impl
: public ::framework::IUndoManagerImplementation
62 UndoManager_Impl( UndoManager
& i_antiImpl
, ::cppu::OWeakObject
& i_parent
, ::osl::Mutex
& i_mutex
)
63 :m_rAntiImpl( i_antiImpl
)
64 ,m_rParent( i_parent
)
68 ,m_aUndoHelper( *this )
70 m_aUndoManager
.SetMaxUndoActionCount(
71 officecfg::Office::Common::Undo::Steps::get());
74 virtual ~UndoManager_Impl()
78 ::osl::Mutex
& getMutex();
79 // IUndoManagerImplementation
80 virtual ::svl::IUndoManager
& getImplUndoManager() SAL_OVERRIDE
;
81 virtual Reference
< XUndoManager
> getThis() SAL_OVERRIDE
;
84 ::cppu::OWeakObject
& getParent() { return m_rParent
; }
85 ::framework::UndoManagerHelper
& getUndoHelper() { return m_aUndoHelper
; }
89 /// is called when the owner of the UndoManager is being disposed
92 /// checks whether we're already disposed, throws a DisposedException if so
93 void checkDisposed_lck();
96 UndoManager
& m_rAntiImpl
;
97 ::cppu::OWeakObject
& m_rParent
;
98 ::osl::Mutex
& m_rMutex
;
101 SfxUndoManager m_aUndoManager
;
102 ::framework::UndoManagerHelper m_aUndoHelper
;
105 ::osl::Mutex
& UndoManager_Impl::getMutex()
110 ::svl::IUndoManager
& UndoManager_Impl::getImplUndoManager()
112 return m_aUndoManager
;
115 Reference
< XUndoManager
> UndoManager_Impl::getThis()
120 void UndoManager_Impl::disposing()
123 ::osl::MutexGuard
aGuard( m_rMutex
);
126 m_aUndoHelper
.disposing();
129 void UndoManager_Impl::checkDisposed_lck()
132 throw DisposedException( OUString(), getThis() );
135 /** guard for public UNO methods of the UndoManager
137 The only purpose of this guard is to check for the instance being disposed already. Everything else,
138 in particular the IMutexGuard functionality required by the UndoManagerHelper class, is a dummy only,
139 as all involved classes (means we ourselves, the UndoManagerHelper, the SfxUndoManager, and the Undo actions
140 we create) are inherently thread-safe, thus need no external lock (in particular no SolarMutex!).
142 class UndoManagerMethodGuard
: public ::framework::IMutexGuard
145 UndoManagerMethodGuard( UndoManager_Impl
& i_impl
)
147 ::osl::MutexGuard
aGuard( i_impl
.getMutex() );
148 // throw if the instance is already disposed
149 i_impl
.checkDisposed_lck();
151 virtual ~UndoManagerMethodGuard()
156 virtual void clear() SAL_OVERRIDE
;
157 virtual ::framework::IMutex
& getGuardedMutex() SAL_OVERRIDE
;
160 class DummyMutex
: public ::framework::IMutex
163 virtual ~DummyMutex() {}
164 virtual void acquire() SAL_OVERRIDE
{ }
165 virtual void release() SAL_OVERRIDE
{ }
168 ::framework::IMutex
& UndoManagerMethodGuard::getGuardedMutex()
170 static DummyMutex s_aDummyMutex
;
171 return s_aDummyMutex
;
174 void UndoManagerMethodGuard::clear()
176 // nothing to do. This interface implementation is a dummy.
180 using impl::UndoManagerMethodGuard
;
182 UndoManager::UndoManager( ::cppu::OWeakObject
& i_parent
, ::osl::Mutex
& i_mutex
)
183 :m_pImpl( new impl::UndoManager_Impl( *this, i_parent
, i_mutex
) )
187 UndoManager::~UndoManager()
191 void SAL_CALL
UndoManager::acquire() throw ()
193 m_pImpl
->getParent().acquire();
196 void SAL_CALL
UndoManager::release() throw ()
198 m_pImpl
->getParent().release();
201 void UndoManager::disposing()
203 m_pImpl
->disposing();
206 void SAL_CALL
UndoManager::enterUndoContext( const OUString
& i_title
) throw (RuntimeException
, std::exception
)
208 UndoManagerMethodGuard
aGuard( *m_pImpl
);
209 m_pImpl
->getUndoHelper().enterUndoContext( i_title
, aGuard
);
212 void SAL_CALL
UndoManager::enterHiddenUndoContext( ) throw (EmptyUndoStackException
, RuntimeException
, std::exception
)
214 UndoManagerMethodGuard
aGuard( *m_pImpl
);
215 m_pImpl
->getUndoHelper().enterHiddenUndoContext( aGuard
);
218 void SAL_CALL
UndoManager::leaveUndoContext( ) throw (InvalidStateException
, RuntimeException
, std::exception
)
220 UndoManagerMethodGuard
aGuard( *m_pImpl
);
221 m_pImpl
->getUndoHelper().leaveUndoContext( aGuard
);
224 void SAL_CALL
UndoManager::addUndoAction( const Reference
< XUndoAction
>& i_action
) throw (IllegalArgumentException
, RuntimeException
, std::exception
)
226 UndoManagerMethodGuard
aGuard( *m_pImpl
);
227 m_pImpl
->getUndoHelper().addUndoAction( i_action
, aGuard
);
230 void SAL_CALL
UndoManager::undo( ) throw (EmptyUndoStackException
, UndoContextNotClosedException
, UndoFailedException
, RuntimeException
, std::exception
)
232 UndoManagerMethodGuard
aGuard( *m_pImpl
);
233 m_pImpl
->getUndoHelper().undo( aGuard
);
235 ChartViewHelper::setViewToDirtyState( Reference
< XModel
>( getParent(), UNO_QUERY
) );
238 void SAL_CALL
UndoManager::redo( ) throw (EmptyUndoStackException
, UndoContextNotClosedException
, UndoFailedException
, RuntimeException
, std::exception
)
240 UndoManagerMethodGuard
aGuard( *m_pImpl
);
241 m_pImpl
->getUndoHelper().redo( aGuard
);
243 ChartViewHelper::setViewToDirtyState( Reference
< XModel
>( getParent(), UNO_QUERY
) );
246 sal_Bool SAL_CALL
UndoManager::isUndoPossible( ) throw (RuntimeException
, std::exception
)
248 UndoManagerMethodGuard
aGuard( *m_pImpl
);
249 return m_pImpl
->getUndoHelper().isUndoPossible();
252 sal_Bool SAL_CALL
UndoManager::isRedoPossible( ) throw (RuntimeException
, std::exception
)
254 UndoManagerMethodGuard
aGuard( *m_pImpl
);
255 return m_pImpl
->getUndoHelper().isRedoPossible();
258 OUString SAL_CALL
UndoManager::getCurrentUndoActionTitle( ) throw (EmptyUndoStackException
, RuntimeException
, std::exception
)
260 UndoManagerMethodGuard
aGuard( *m_pImpl
);
261 return m_pImpl
->getUndoHelper().getCurrentUndoActionTitle();
264 OUString SAL_CALL
UndoManager::getCurrentRedoActionTitle( ) throw (EmptyUndoStackException
, RuntimeException
, std::exception
)
266 UndoManagerMethodGuard
aGuard( *m_pImpl
);
267 return m_pImpl
->getUndoHelper().getCurrentRedoActionTitle();
270 Sequence
< OUString
> SAL_CALL
UndoManager::getAllUndoActionTitles( ) throw (RuntimeException
, std::exception
)
272 UndoManagerMethodGuard
aGuard( *m_pImpl
);
273 return m_pImpl
->getUndoHelper().getAllUndoActionTitles();
276 Sequence
< OUString
> SAL_CALL
UndoManager::getAllRedoActionTitles( ) throw (RuntimeException
, std::exception
)
278 UndoManagerMethodGuard
aGuard( *m_pImpl
);
279 return m_pImpl
->getUndoHelper().getAllRedoActionTitles();
282 void SAL_CALL
UndoManager::clear( ) throw (UndoContextNotClosedException
, RuntimeException
, std::exception
)
284 UndoManagerMethodGuard
aGuard( *m_pImpl
);
285 m_pImpl
->getUndoHelper().clear( aGuard
);
288 void SAL_CALL
UndoManager::clearRedo( ) throw (UndoContextNotClosedException
, RuntimeException
, std::exception
)
290 UndoManagerMethodGuard
aGuard( *m_pImpl
);
291 m_pImpl
->getUndoHelper().clearRedo( aGuard
);
294 void SAL_CALL
UndoManager::reset( ) throw (RuntimeException
, std::exception
)
296 UndoManagerMethodGuard
aGuard( *m_pImpl
);
297 m_pImpl
->getUndoHelper().reset( aGuard
);
300 void SAL_CALL
UndoManager::addUndoManagerListener( const Reference
< XUndoManagerListener
>& i_listener
) throw (RuntimeException
, std::exception
)
302 UndoManagerMethodGuard
aGuard( *m_pImpl
);
303 m_pImpl
->getUndoHelper().addUndoManagerListener( i_listener
);
306 void SAL_CALL
UndoManager::removeUndoManagerListener( const Reference
< XUndoManagerListener
>& i_listener
) throw (RuntimeException
, std::exception
)
308 UndoManagerMethodGuard
aGuard( *m_pImpl
);
309 m_pImpl
->getUndoHelper().removeUndoManagerListener( i_listener
);
312 void SAL_CALL
UndoManager::lock( ) throw (RuntimeException
, std::exception
)
314 UndoManagerMethodGuard
aGuard( *m_pImpl
);
315 m_pImpl
->getUndoHelper().lock();
318 void SAL_CALL
UndoManager::unlock( ) throw (NotLockedException
, RuntimeException
, std::exception
)
320 UndoManagerMethodGuard
aGuard( *m_pImpl
);
321 m_pImpl
->getUndoHelper().unlock();
324 sal_Bool SAL_CALL
UndoManager::isLocked( ) throw (RuntimeException
, std::exception
)
326 UndoManagerMethodGuard
aGuard( *m_pImpl
);
327 return m_pImpl
->getUndoHelper().isLocked();
330 Reference
< XInterface
> SAL_CALL
UndoManager::getParent( ) throw (RuntimeException
, std::exception
)
332 UndoManagerMethodGuard
aGuard( *m_pImpl
);
333 return *&m_pImpl
->getParent();
336 void SAL_CALL
UndoManager::setParent( const Reference
< XInterface
>& i_parent
) throw (NoSupportException
, RuntimeException
, std::exception
)
338 UndoManagerMethodGuard
aGuard( *m_pImpl
);
340 throw NoSupportException( OUString(), m_pImpl
->getThis() );
343 void SAL_CALL
UndoManager::addModifyListener( const Reference
< XModifyListener
>& i_listener
) throw (RuntimeException
, std::exception
)
345 UndoManagerMethodGuard
aGuard( *m_pImpl
);
346 m_pImpl
->getUndoHelper().addModifyListener( i_listener
);
349 void SAL_CALL
UndoManager::removeModifyListener( const Reference
< XModifyListener
>& i_listener
) throw (RuntimeException
, std::exception
)
351 UndoManagerMethodGuard
aGuard( *m_pImpl
);
352 m_pImpl
->getUndoHelper().removeModifyListener( i_listener
);
357 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */