Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
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/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
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 .
18 : : */
19 : :
20 : :
21 : : #include "framework/documentundoguard.hxx"
22 : :
23 : : #include <com/sun/star/document/XUndoManagerSupplier.hpp>
24 : :
25 : : #include <cppuhelper/implbase1.hxx>
26 : : #include <rtl/ref.hxx>
27 : : #include <tools/diagnose_ex.h>
28 : :
29 : : //......................................................................................................................
30 : : namespace framework
31 : : {
32 : : //......................................................................................................................
33 : :
34 : : /** === begin UNO using === **/
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::Exception;
40 : : using ::com::sun::star::uno::RuntimeException;
41 : : using ::com::sun::star::uno::Any;
42 : : using ::com::sun::star::uno::makeAny;
43 : : using ::com::sun::star::uno::Sequence;
44 : : using ::com::sun::star::uno::Type;
45 : : using ::com::sun::star::document::XUndoManagerSupplier;
46 : : using ::com::sun::star::document::XUndoManager;
47 : : using ::com::sun::star::document::XUndoManagerListener;
48 : : using ::com::sun::star::document::UndoManagerEvent;
49 : : using ::com::sun::star::lang::EventObject;
50 : : /** === end UNO using === **/
51 : :
52 : : //==================================================================================================================
53 : : //= UndoManagerContextListener
54 : : //==================================================================================================================
55 : : typedef ::cppu::WeakImplHelper1 < XUndoManagerListener
56 : : > UndoManagerContextListener_Base;
57 [ - + ]: 38 : class UndoManagerContextListener : public UndoManagerContextListener_Base
58 : : {
59 : : public:
60 : 19 : UndoManagerContextListener( const Reference< XUndoManager >& i_undoManager )
61 : : :m_xUndoManager( i_undoManager, UNO_QUERY_THROW )
62 : : ,m_nRelativeContextDepth( 0 )
63 [ + - ]: 19 : ,m_documentDisposed( false )
64 : : {
65 [ + - ]: 19 : osl_incrementInterlockedCount( &m_refCount );
66 : : {
67 [ + - ][ + - ]: 19 : m_xUndoManager->addUndoManagerListener( this );
[ + - ]
68 : : }
69 [ + - ]: 19 : osl_decrementInterlockedCount( &m_refCount );
70 : 19 : }
71 : :
72 : : UndoManagerContextListener()
73 : : {
74 : : }
75 : :
76 : 19 : void finish()
77 : : {
78 : : OSL_ENSURE( m_nRelativeContextDepth >= 0, "UndoManagerContextListener: more contexts left than entered?" );
79 : :
80 [ + + ]: 19 : if ( m_documentDisposed )
81 : 19 : return;
82 : :
83 : : // work with a copy of m_nRelativeContextDepth, to be independent from possible bugs in the
84 : : // listener notifications (where it would be decremented with every leaveUndoContext)
85 : 17 : sal_Int32 nDepth = m_nRelativeContextDepth;
86 [ + + ]: 23 : while ( nDepth-- > 0 )
87 : : {
88 : 6 : m_xUndoManager->leaveUndoContext();
89 : : }
90 [ + - ]: 17 : m_xUndoManager->removeUndoManagerListener( this );
91 : : }
92 : :
93 : : // XUndoManagerListener
94 : : virtual void SAL_CALL undoActionAdded( const UndoManagerEvent& i_event ) throw (RuntimeException);
95 : : virtual void SAL_CALL actionUndone( const UndoManagerEvent& i_event ) throw (RuntimeException);
96 : : virtual void SAL_CALL actionRedone( const UndoManagerEvent& i_event ) throw (RuntimeException);
97 : : virtual void SAL_CALL allActionsCleared( const EventObject& i_event ) throw (RuntimeException);
98 : : virtual void SAL_CALL redoActionsCleared( const EventObject& i_event ) throw (RuntimeException);
99 : : virtual void SAL_CALL resetAll( const EventObject& i_event ) throw (RuntimeException);
100 : : virtual void SAL_CALL enteredContext( const UndoManagerEvent& i_event ) throw (RuntimeException);
101 : : virtual void SAL_CALL enteredHiddenContext( const UndoManagerEvent& i_event ) throw (RuntimeException);
102 : : virtual void SAL_CALL leftContext( const UndoManagerEvent& i_event ) throw (RuntimeException);
103 : : virtual void SAL_CALL leftHiddenContext( const UndoManagerEvent& i_event ) throw (RuntimeException);
104 : : virtual void SAL_CALL cancelledContext( const UndoManagerEvent& i_event ) throw (RuntimeException);
105 : :
106 : : // XEventListener
107 : : virtual void SAL_CALL disposing( const EventObject& i_event ) throw (RuntimeException);
108 : :
109 : : private:
110 : : Reference< XUndoManager > const m_xUndoManager;
111 : : oslInterlockedCount m_nRelativeContextDepth;
112 : : bool m_documentDisposed;
113 : : };
114 : :
115 : : //------------------------------------------------------------------------------------------------------------------
116 : 10 : void SAL_CALL UndoManagerContextListener::undoActionAdded( const UndoManagerEvent& i_event ) throw (RuntimeException)
117 : : {
118 : : (void)i_event;
119 : : // not interested in
120 : 10 : }
121 : :
122 : : //------------------------------------------------------------------------------------------------------------------
123 : 0 : void SAL_CALL UndoManagerContextListener::actionUndone( const UndoManagerEvent& i_event ) throw (RuntimeException)
124 : : {
125 : : (void)i_event;
126 : : // not interested in
127 : 0 : }
128 : :
129 : : //------------------------------------------------------------------------------------------------------------------
130 : 0 : void SAL_CALL UndoManagerContextListener::actionRedone( const UndoManagerEvent& i_event ) throw (RuntimeException)
131 : : {
132 : : (void)i_event;
133 : : // not interested in
134 : 0 : }
135 : :
136 : : //------------------------------------------------------------------------------------------------------------------
137 : 0 : void SAL_CALL UndoManagerContextListener::allActionsCleared( const EventObject& i_event ) throw (RuntimeException)
138 : : {
139 : : (void)i_event;
140 : : // not interested in
141 : 0 : }
142 : :
143 : : //------------------------------------------------------------------------------------------------------------------
144 : 0 : void SAL_CALL UndoManagerContextListener::redoActionsCleared( const EventObject& i_event ) throw (RuntimeException)
145 : : {
146 : : (void)i_event;
147 : : // not interested in
148 : 0 : }
149 : :
150 : : //------------------------------------------------------------------------------------------------------------------
151 : 0 : void SAL_CALL UndoManagerContextListener::resetAll( const EventObject& i_event ) throw (RuntimeException)
152 : : {
153 : : (void)i_event;
154 : 0 : m_nRelativeContextDepth = 0;
155 : 0 : }
156 : :
157 : : //------------------------------------------------------------------------------------------------------------------
158 : 8 : void SAL_CALL UndoManagerContextListener::enteredContext( const UndoManagerEvent& i_event ) throw (RuntimeException)
159 : : {
160 : : (void)i_event;
161 : 8 : osl_incrementInterlockedCount( &m_nRelativeContextDepth );
162 : 8 : }
163 : :
164 : : //------------------------------------------------------------------------------------------------------------------
165 : 0 : void SAL_CALL UndoManagerContextListener::enteredHiddenContext( const UndoManagerEvent& i_event ) throw (RuntimeException)
166 : : {
167 : : (void)i_event;
168 : 0 : osl_incrementInterlockedCount( &m_nRelativeContextDepth );
169 : 0 : }
170 : :
171 : : //------------------------------------------------------------------------------------------------------------------
172 : 0 : void SAL_CALL UndoManagerContextListener::leftContext( const UndoManagerEvent& i_event ) throw (RuntimeException)
173 : : {
174 : : (void)i_event;
175 : 0 : osl_decrementInterlockedCount( &m_nRelativeContextDepth );
176 : 0 : }
177 : :
178 : : //------------------------------------------------------------------------------------------------------------------
179 : 0 : void SAL_CALL UndoManagerContextListener::leftHiddenContext( const UndoManagerEvent& i_event ) throw (RuntimeException)
180 : : {
181 : : (void)i_event;
182 : 0 : osl_decrementInterlockedCount( &m_nRelativeContextDepth );
183 : 0 : }
184 : :
185 : : //------------------------------------------------------------------------------------------------------------------
186 : 6 : void SAL_CALL UndoManagerContextListener::cancelledContext( const UndoManagerEvent& i_event ) throw (RuntimeException)
187 : : {
188 : : (void)i_event;
189 : 6 : osl_decrementInterlockedCount( &m_nRelativeContextDepth );
190 : 6 : }
191 : :
192 : : //------------------------------------------------------------------------------------------------------------------
193 : 2 : void SAL_CALL UndoManagerContextListener::disposing( const EventObject& i_event ) throw (RuntimeException)
194 : : {
195 : : (void)i_event;
196 : 2 : m_documentDisposed = true;
197 : 2 : }
198 : :
199 : : //==================================================================================================================
200 : : //= DocumentUndoGuard_Data
201 : : //==================================================================================================================
202 : 38 : struct DocumentUndoGuard_Data
203 : : {
204 : : Reference< XUndoManager > xUndoManager;
205 : : ::rtl::Reference< UndoManagerContextListener > pContextListener;
206 : : };
207 : :
208 : : namespace
209 : : {
210 : : //--------------------------------------------------------------------------------------------------------------
211 : 19 : void lcl_init( DocumentUndoGuard_Data& i_data, const Reference< XInterface >& i_undoSupplierComponent )
212 : : {
213 : : try
214 : : {
215 [ + - ]: 19 : Reference< XUndoManagerSupplier > xUndoSupplier( i_undoSupplierComponent, UNO_QUERY );
216 [ + - ]: 19 : if ( xUndoSupplier.is() )
217 [ + - ][ + - ]: 19 : i_data.xUndoManager.set( xUndoSupplier->getUndoManager(), UNO_QUERY_THROW );
[ + - ]
218 : :
219 [ + - ]: 19 : if ( i_data.xUndoManager.is() )
220 [ + - ][ # # ]: 19 : i_data.pContextListener.set( new UndoManagerContextListener( i_data.xUndoManager ) );
221 : : }
222 : 0 : catch( const Exception& )
223 : : {
224 : : DBG_UNHANDLED_EXCEPTION();
225 : : }
226 : 19 : }
227 : :
228 : : //--------------------------------------------------------------------------------------------------------------
229 : 19 : void lcl_restore( DocumentUndoGuard_Data& i_data )
230 : : {
231 : : try
232 : : {
233 [ + - ]: 19 : if ( i_data.pContextListener.is() )
234 [ + - ]: 19 : i_data.pContextListener->finish();
235 : 19 : i_data.pContextListener.clear();
236 : : }
237 : 0 : catch( const Exception& )
238 : : {
239 : : DBG_UNHANDLED_EXCEPTION();
240 : : }
241 [ # # ]: 19 : }
242 : : }
243 : :
244 : : //==================================================================================================================
245 : : //= DocumentUndoGuard
246 : : //==================================================================================================================
247 : : //------------------------------------------------------------------------------------------------------------------
248 : 19 : DocumentUndoGuard::DocumentUndoGuard( const Reference< XInterface >& i_undoSupplierComponent )
249 [ + - ]: 19 : :m_pData( new DocumentUndoGuard_Data )
250 : : {
251 [ + - ]: 19 : lcl_init( *m_pData, i_undoSupplierComponent );
252 : 19 : }
253 : :
254 : 19 : DocumentUndoGuard::~DocumentUndoGuard()
255 : : {
256 [ + - ]: 19 : lcl_restore( *m_pData );
257 : 19 : }
258 : :
259 : : //......................................................................................................................
260 : : } // namespace framework
261 : : //......................................................................................................................
262 : :
263 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|