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