LibreOffice Module sfx2 (master) 1
docundomanager.cxx
Go to the documentation of this file.
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 <docundomanager.hxx>
22#include <sfx2/sfxbasemodel.hxx>
23#include <sfx2/objsh.hxx>
24#include <sfx2/viewfrm.hxx>
25#include <sfx2/viewsh.hxx>
26#include <sfx2/bindings.hxx>
27#include <sfx2/sfxsids.hrc>
28#include <com/sun/star/lang/NoSupportException.hpp>
29#include <com/sun/star/lang/NotInitializedException.hpp>
30#include <svl/undo.hxx>
33#include <framework/imutex.hxx>
34
35
36namespace sfx2
37{
38
39
40 using ::com::sun::star::uno::Reference;
41 using ::com::sun::star::uno::XInterface;
42 using ::com::sun::star::uno::Sequence;
43 using ::com::sun::star::document::XUndoAction;
44 using ::com::sun::star::lang::NotInitializedException;
45 using ::com::sun::star::document::XUndoManagerListener;
46 using ::com::sun::star::document::XUndoManager;
47 using ::com::sun::star::lang::NoSupportException;
48 using ::com::sun::star::frame::XModel;
49
50 //= DocumentUndoManager_Impl
51
53 {
57
59 :rAntiImpl( i_antiImpl )
60 ,pUndoManager( impl_retrieveUndoManager( i_antiImpl.getBaseModel() ) )
61 // do this *before* the construction of aUndoHelper (which actually means: put pUndoManager before
62 // aUndoHelper in the member list)!
63 ,aUndoHelper( *this )
64 {
65 }
66
68 {
69 };
70
71 // IUndoManagerImplementation
72 virtual SfxUndoManager& getImplUndoManager() override;
73 virtual Reference< XUndoManager > getThis() override;
74
75 void disposing()
76 {
78 ENSURE_OR_RETURN_VOID( pUndoManager, "DocumentUndoManager_Impl::disposing: already disposed!" );
79 pUndoManager = nullptr;
80 }
81
83
84 private:
86 {
87 SfxUndoManager* pUndoManager( nullptr );
88 SfxObjectShell* pObjectShell = i_baseModel.GetObjectShell();
89 if ( pObjectShell != nullptr )
90 pUndoManager = pObjectShell->GetUndoManager();
91 if ( !pUndoManager )
92 throw NotInitializedException( OUString(), i_baseModel );
93 return pUndoManager;
94 }
95 };
96
97
99 {
100 ENSURE_OR_THROW( pUndoManager != nullptr, "DocumentUndoManager_Impl::getImplUndoManager: no access to the doc's UndoManager implementation!" );
101
102#if OSL_DEBUG_LEVEL > 0
103 // in a non-product build, assert if the current UndoManager at the shell is not the same we obtained
104 // (and cached) at construction time
106 OSL_ENSURE( ( pObjectShell != nullptr ) && ( pUndoManager == pObjectShell->GetUndoManager() ),
107 "DocumentUndoManager_Impl::getImplUndoManager: the UndoManager changed meanwhile - what about our listener?" );
108#endif
109
110 return *pUndoManager;
111 }
112
113
114 Reference< XUndoManager > DocumentUndoManager_Impl::getThis()
115 {
116 return static_cast< XUndoManager* >( &rAntiImpl );
117 }
118
119
121 {
122 SfxModelGuard aGuard( rAntiImpl );
123
125 ENSURE_OR_THROW( pDocShell != nullptr, "lcl_invalidateUndo: no access to the doc shell!" );
126 SfxViewFrame* pViewFrame = SfxViewFrame::GetFirst( pDocShell );
127 while ( pViewFrame )
128 {
129 pViewFrame->GetBindings().Invalidate( SID_UNDO );
130 pViewFrame->GetBindings().Invalidate( SID_REDO );
131 pViewFrame = SfxViewFrame::GetNext( *pViewFrame, pDocShell );
132 }
133 }
134
135
136 //= SolarMutexFacade
137
138 namespace {
139
142 class SolarMutexFacade : public ::framework::IMutex
143 {
144 public:
145 SolarMutexFacade()
146 {
147 }
148
149 virtual ~SolarMutexFacade() {}
150
151 virtual void acquire() override
152 {
154 }
155
156 virtual void release() override
157 {
159 }
160 };
161
162
163 //= UndoManagerGuard
164
165 class UndoManagerGuard :public ::framework::IMutexGuard
166 {
167 public:
168 explicit UndoManagerGuard( DocumentUndoManager& i_undoManager )
169 :m_guard( i_undoManager )
170 {
171 }
172
173 virtual ~UndoManagerGuard()
174 {
175 }
176
177 UndoManagerGuard(const UndoManagerGuard&) = delete;
178 UndoManagerGuard& operator=(const UndoManagerGuard&) = delete;
179
180 virtual void clear() override
181 {
182 m_guard.clear();
183 }
184
185 virtual ::framework::IMutex& getGuardedMutex() override
186 {
187 // note that this means that we *know* that SfxModelGuard also locks the SolarMutex (nothing more, nothing less).
188 // If this ever changes, we need to adjust this code here, too.
189 return m_solarMutexFacade;
190 }
191
192 private:
194 SolarMutexFacade m_solarMutexFacade;
195 };
196
197 }
198
199 //= DocumentUndoManager
200
201
203 :SfxModelSubComponent( i_document )
204 ,m_pImpl( new DocumentUndoManager_Impl( *this ) )
205 {
206 }
207
209 {
210 }
211
213 {
214 m_pImpl->disposing();
215 }
216
217
219 {
220 // No mutex locking within this method, no disposal check - this is the responsibility of the owner.
221 return m_pImpl->getImplUndoManager().IsInListAction();
222 }
223
224
225 void SAL_CALL DocumentUndoManager::acquire() noexcept
226 {
227 OWeakObject::acquire();
229 }
230
231
232 void SAL_CALL DocumentUndoManager::release() noexcept
233 {
235 OWeakObject::release();
236 }
237
238
239 void SAL_CALL DocumentUndoManager::enterUndoContext( const OUString& i_title )
240 {
241 // SYNCHRONIZED --->
242 UndoManagerGuard aGuard( *this );
243 m_pImpl->aUndoHelper.enterUndoContext( i_title, aGuard );
244 // <--- SYNCHRONIZED
245 m_pImpl->invalidateXDo_nolck();
246 }
247
248
250 {
251 // SYNCHRONIZED --->
252 UndoManagerGuard aGuard( *this );
253 m_pImpl->aUndoHelper.enterHiddenUndoContext( aGuard );
254 // <--- SYNCHRONIZED
255 m_pImpl->invalidateXDo_nolck();
256 }
257
258
260 {
261 // SYNCHRONIZED --->
262 UndoManagerGuard aGuard( *this );
263 m_pImpl->aUndoHelper.leaveUndoContext( aGuard );
264 // <--- SYNCHRONIZED
265 m_pImpl->invalidateXDo_nolck();
266 }
267
268
269 void SAL_CALL DocumentUndoManager::addUndoAction( const Reference< XUndoAction >& i_action )
270 {
271 // SYNCHRONIZED --->
272 UndoManagerGuard aGuard( *this );
273 m_pImpl->aUndoHelper.addUndoAction( i_action, aGuard );
274 // <--- SYNCHRONIZED
275 m_pImpl->invalidateXDo_nolck();
276 }
277
278
280 {
281 // SYNCHRONIZED --->
282 UndoManagerGuard aGuard( *this );
283 m_pImpl->aUndoHelper.undo( aGuard );
284 // <--- SYNCHRONIZED
285 m_pImpl->invalidateXDo_nolck();
286 }
287
288
290 {
291 // SYNCHRONIZED --->
292 UndoManagerGuard aGuard( *this );
293 m_pImpl->aUndoHelper.redo( aGuard );
294 // <--- SYNCHRONIZED
295 m_pImpl->invalidateXDo_nolck();
296 }
297
298
300 {
301 UndoManagerGuard aGuard( *this );
302 return m_pImpl->aUndoHelper.isUndoPossible();
303 }
304
305
307 {
308 UndoManagerGuard aGuard( *this );
309 return m_pImpl->aUndoHelper.isRedoPossible();
310 }
311
312
314 {
315 UndoManagerGuard aGuard( *this );
316 return m_pImpl->aUndoHelper.getCurrentUndoActionTitle();
317 }
318
319
321 {
322 UndoManagerGuard aGuard( *this );
323 return m_pImpl->aUndoHelper.getCurrentRedoActionTitle();
324 }
325
326
327 Sequence< OUString > SAL_CALL DocumentUndoManager::getAllUndoActionTitles( )
328 {
329 UndoManagerGuard aGuard( *this );
330 return m_pImpl->aUndoHelper.getAllUndoActionTitles();
331 }
332
333
334 Sequence< OUString > SAL_CALL DocumentUndoManager::getAllRedoActionTitles( )
335 {
336 UndoManagerGuard aGuard( *this );
337 return m_pImpl->aUndoHelper.getAllRedoActionTitles();
338 }
339
340
342 {
343 // SYNCHRONIZED --->
344 UndoManagerGuard aGuard( *this );
345 m_pImpl->aUndoHelper.clear( aGuard );
346 // <--- SYNCHRONIZED
347 m_pImpl->invalidateXDo_nolck();
348 }
349
350
352 {
353 // SYNCHRONIZED --->
354 UndoManagerGuard aGuard( *this );
355 m_pImpl->aUndoHelper.clearRedo( aGuard );
356 // <--- SYNCHRONIZED
357 m_pImpl->invalidateXDo_nolck();
358 }
359
360
362 {
363 // SYNCHRONIZED --->
364 UndoManagerGuard aGuard( *this );
365 m_pImpl->aUndoHelper.reset( aGuard );
366 // <--- SYNCHRONIZED
367 m_pImpl->invalidateXDo_nolck();
368 }
369
370
372 {
373 UndoManagerGuard aGuard( *this );
374 m_pImpl->aUndoHelper.lock();
375 }
376
377
379 {
380 UndoManagerGuard aGuard( *this );
381 m_pImpl->aUndoHelper.unlock();
382 }
383
384
386 {
387 UndoManagerGuard aGuard( *this );
388 return m_pImpl->aUndoHelper.isLocked();
389 }
390
391
392 void SAL_CALL DocumentUndoManager::addUndoManagerListener( const Reference< XUndoManagerListener >& i_listener )
393 {
394 UndoManagerGuard aGuard( *this );
395 return m_pImpl->aUndoHelper.addUndoManagerListener( i_listener );
396 }
397
398
399 void SAL_CALL DocumentUndoManager::removeUndoManagerListener( const Reference< XUndoManagerListener >& i_listener )
400 {
401 UndoManagerGuard aGuard( *this );
402 return m_pImpl->aUndoHelper.removeUndoManagerListener( i_listener );
403 }
404
405
406 Reference< XInterface > SAL_CALL DocumentUndoManager::getParent( )
407 {
408 UndoManagerGuard aGuard( *this );
409 return static_cast< XModel* >( &getBaseModel() );
410 }
411
412
413 void SAL_CALL DocumentUndoManager::setParent( const Reference< XInterface >& )
414 {
415 throw NoSupportException( OUString(), m_pImpl->getThis() );
416 }
417
418
419} // namespace sfx2
420
421
422/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
::std::unique_ptr< XmlIdRegistry_Impl > m_pImpl
static comphelper::SolarMutex & GetSolarMutex()
SfxObjectShell * GetObjectShell() const
void Invalidate(sal_uInt16 nId)
Definition: bindings.cxx:639
base class for sub components of an SfxBaseModel, which share their ref count and lifetime with the S...
const SfxBaseModel & getBaseModel() const
virtual SfxUndoManager * GetUndoManager()
Each Subclass of SfxShell can have a <SfxUndoManager>.
Definition: shell.cxx:203
SfxBindings & GetBindings()
Definition: viewfrm.hxx:110
static SAL_WARN_UNUSED_RESULT SfxViewFrame * GetNext(const SfxViewFrame &rPrev, const SfxObjectShell *pDoc=nullptr, bool bOnlyVisible=true)
Definition: viewfrm.cxx:2006
static SAL_WARN_UNUSED_RESULT SfxViewFrame * GetFirst(const SfxObjectShell *pDoc=nullptr, bool bOnlyVisible=true)
Definition: viewfrm.cxx:1983
sal_uInt32 release(bool bUnlockAll=false)
void acquire(sal_uInt32 nLockCount=1)
virtual sal_Bool SAL_CALL isUndoPossible() override
virtual void SAL_CALL redo() override
virtual void SAL_CALL clear() override
virtual css::uno::Sequence< OUString > SAL_CALL getAllRedoActionTitles() override
virtual void SAL_CALL undo() override
virtual OUString SAL_CALL getCurrentUndoActionTitle() override
virtual void SAL_CALL enterHiddenUndoContext() override
virtual void SAL_CALL clearRedo() override
virtual void SAL_CALL setParent(const css::uno::Reference< css::uno::XInterface > &Parent) override
virtual void SAL_CALL addUndoManagerListener(const css::uno::Reference< css::document::XUndoManagerListener > &i_listener) override
virtual void SAL_CALL release() noexcept override
virtual void SAL_CALL leaveUndoContext() override
virtual void SAL_CALL enterUndoContext(const OUString &i_title) override
bool isInContext() const
determines whether we have an open Undo context.
std::unique_ptr< DocumentUndoManager_Impl > m_pImpl
virtual OUString SAL_CALL getCurrentRedoActionTitle() override
virtual void SAL_CALL unlock() override
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getParent() override
virtual void SAL_CALL removeUndoManagerListener(const css::uno::Reference< css::document::XUndoManagerListener > &i_listener) override
DocumentUndoManager(SfxBaseModel &i_document)
virtual void SAL_CALL reset() override
virtual sal_Bool SAL_CALL isRedoPossible() override
virtual void SAL_CALL lock() override
virtual css::uno::Sequence< OUString > SAL_CALL getAllUndoActionTitles() override
virtual ~DocumentUndoManager() override
virtual void SAL_CALL addUndoAction(const css::uno::Reference< css::document::XUndoAction > &i_action) override
virtual void SAL_CALL acquire() noexcept override
virtual sal_Bool SAL_CALL isLocked() override
#define ENSURE_OR_THROW(c, m)
#define ENSURE_OR_RETURN_VOID(c, m)
SolarMutexFacade m_solarMutexFacade
SfxModelGuard m_guard
::framework::UndoManagerHelper aUndoHelper
virtual SfxUndoManager & getImplUndoManager() override
virtual Reference< XUndoManager > getThis() override
static SfxUndoManager * impl_retrieveUndoManager(SfxBaseModel &i_baseModel)
DocumentUndoManager & rAntiImpl
DocumentUndoManager_Impl(DocumentUndoManager &i_antiImpl)
unsigned char sal_Bool