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 #ifndef FRAMEWORK_UNDOMANAGERHELPER_HXX
25 #define FRAMEWORK_UNDOMANAGERHELPER_HXX
26 
27 #include "framework/fwedllapi.h"
28 #include "framework/iguard.hxx"
29 #include "framework/imutex.hxx"
30 
31 /** === begin UNO includes === **/
32 #include <com/sun/star/document/XUndoManager.hpp>
33 #include <com/sun/star/util/XModifyListener.hpp>
34 /** === end UNO includes === **/
35 
36 #include <boost/scoped_ptr.hpp>
37 
38 namespace svl
39 {
40     class IUndoManager;
41 }
42 
43 //......................................................................................................................
44 namespace framework
45 {
46 //......................................................................................................................
47 
48 	//==================================================================================================================
49 	//= IMutexGuard
50 	//==================================================================================================================
51     class SAL_NO_VTABLE IMutexGuard : public IGuard
52     {
53     public:
54         /** returns the mutex guarded by the instance.
55 
56             Even if the guard currently has not a lock on the mutex, this method must succeed.
57         */
58         virtual IMutex& getGuardedMutex() = 0;
59     };
60 
61 	//==================================================================================================================
62 	//= IUndoManagerImplementation
63 	//==================================================================================================================
64     class SAL_NO_VTABLE IUndoManagerImplementation
65     {
66     public:
67         /** returns the IUndoManager interface to the actual Undo stack
68 
69             @throws com::sun::star::lang::DisposedException
70                 when the instance is already disposed, and no IUndoManager can be provided
71 
72             @throws com::sun::star::lang::NotInitializedException
73                 when the instance is not initialized, yet, and no IUndoManager can be provided
74         */
75         virtual ::svl::IUndoManager&    getImplUndoManager() = 0;
76 
77         /** provides access to an UNO interface for the XUndoManager implementation. Used when throwing exceptions.
78         */
79         virtual ::com::sun::star::uno::Reference< ::com::sun::star::document::XUndoManager >
80                                         getThis() = 0;
81     };
82 
83 	//==================================================================================================================
84 	//= UndoManagerHelper
85 	//==================================================================================================================
86     class UndoManagerHelper_Impl;
87     /** helper class for implementing an XUndoManager
88 
89         Several of the methods of the class take an IMutexGuard instance. It is assumed that this guard has a lock on
90         its mutext at the moment the method is entered. The lock will be released before any notifications to the
91         registered XUndoManagerListeners happen.
92 
93         The following locking strategy is used for this mutex:
94         <ul><li>Any notifications to the registered XUndoManagerListeners are after the guard has been cleared. i.e.
95                 without the mutex being locked.</p>
96             <li>Any calls into the <code>IUndoManager</code> implementation is made without the mutex being locked.
97                 Note that this implies that the <code>IUndoManager</code> implementation must be thread-safe in itself
98                 (which is true for the default implementation, SfxUndoManager).</li>
99             <li>An exception to the previous item are the <member>IUndoManager::Undo</member> and
100                 <member>IUndoManager::Redo</member> methods: They're called with the given external mutex being
101                 locked.</li>
102         </ul>
103 
104         The reason for the exception for IUndoManager::Undo and IUndoManager::Redo is that those are expected to
105         modify the actual document which the UndoManager works for. And as long as our documents are not thread-safe,
106         and as long as we do not re-fit <strong>all</strong> existing SfxUndoImplementations to <em>not</em> expect
107         the dreaded SolarMutex being locked when they're called, the above behavior is a compromise between "how it should
108         be" and "how it can realistically be".
109     */
110 	class FWE_DLLPUBLIC UndoManagerHelper
111 	{
112     public:
113         UndoManagerHelper( IUndoManagerImplementation& i_undoManagerImpl );
114         ~UndoManagerHelper();
115 
116         // life time control
117         void disposing();
118 
119         // XUndoManager equivalents
120         void            enterUndoContext( const ::rtl::OUString& i_title, IMutexGuard& i_instanceLock );
121         void            enterHiddenUndoContext( IMutexGuard& i_instanceLock );
122         void            leaveUndoContext( IMutexGuard& i_instanceLock );
123         void            addUndoAction( const ::com::sun::star::uno::Reference< ::com::sun::star::document::XUndoAction >& i_action, IMutexGuard& i_instanceLock );
124         void            undo( IMutexGuard& i_instanceLock );
125         void            redo( IMutexGuard& i_instanceLock );
126         ::sal_Bool      isUndoPossible() const;
127         ::sal_Bool      isRedoPossible() const;
128         ::rtl::OUString getCurrentUndoActionTitle() const;
129         ::rtl::OUString getCurrentRedoActionTitle() const;
130         ::com::sun::star::uno::Sequence< ::rtl::OUString >
131                         getAllUndoActionTitles() const;
132         ::com::sun::star::uno::Sequence< ::rtl::OUString >
133                         getAllRedoActionTitles() const;
134         void            clear( IMutexGuard& i_instanceLock );
135         void            clearRedo( IMutexGuard& i_instanceLock );
136         void            reset( IMutexGuard& i_instanceLock );
137         void            addUndoManagerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::document::XUndoManagerListener >& i_listener );
138         void            removeUndoManagerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::document::XUndoManagerListener >& i_listener );
139 
140         // XLockable, base of XUndoManager, equivalents
141         void            lock();
142         void            unlock();
143         ::sal_Bool      isLocked();
144 
145         // XModifyBroadcaster equivalents
146         void            addModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& i_listener );
147         void            removeModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& i_listener );
148 
149     private:
150         ::boost::scoped_ptr< UndoManagerHelper_Impl >   m_pImpl;
151 	};
152 
153 //......................................................................................................................
154 } // namespace framework
155 //......................................................................................................................
156 
157 #endif // FRAMEWORK_UNDOMANAGERHELPER_HXX
158