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 #ifndef INCLUDED_FRAMEWORK_UNDOMANAGERHELPER_HXX
21 #define INCLUDED_FRAMEWORK_UNDOMANAGERHELPER_HXX
23 #include <framework/fwedllapi.h>
24 #include <framework/imutex.hxx>
26 #include <com/sun/star/document/XUndoManager.hpp>
27 #include <com/sun/star/util/XModifyListener.hpp>
43 class SAL_NO_VTABLE IMutexGuard
46 /** clears the lock. If the guard does not currently hold the lock, nothing happens.
48 virtual void clear() = 0;
50 /** returns the mutex guarded by the instance.
52 Even if the guard currently has not a lock on the mutex, this method must succeed.
54 virtual IMutex
& getGuardedMutex() = 0;
61 //= IUndoManagerImplementation
63 class SAL_NO_VTABLE IUndoManagerImplementation
66 /** returns the IUndoManager interface to the actual Undo stack
68 @throws css::lang::DisposedException
69 when the instance is already disposed, and no IUndoManager can be provided
71 @throws css::lang::NotInitializedException
72 when the instance is not initialized, yet, and no IUndoManager can be provided
74 virtual ::svl::IUndoManager
& getImplUndoManager() = 0;
76 /** provides access to an UNO interface for the XUndoManager implementation. Used when throwing exceptions.
78 virtual css::uno::Reference
< css::document::XUndoManager
>
82 ~IUndoManagerImplementation() {}
88 class UndoManagerHelper_Impl
;
89 /** helper class for implementing an XUndoManager
91 Several of the methods of the class take an IMutexGuard instance. It is assumed that this guard has a lock on
92 its mutex at the moment the method is entered. The lock will be released before any notifications to the
93 registered XUndoManagerListeners happen.
95 The following locking strategy is used for this mutex:
96 <ul><li>Any notifications to the registered XUndoManagerListeners are after the guard has been cleared. i.e.
97 without the mutex being locked.</p>
98 <li>Any calls into the <code>IUndoManager</code> implementation is made without the mutex being locked.
99 Note that this implies that the <code>IUndoManager</code> implementation must be thread-safe in itself
100 (which is true for the default implementation, SfxUndoManager).</li>
101 <li>An exception to the previous item are the <member>IUndoManager::Undo</member> and
102 <member>IUndoManager::Redo</member> methods: They're called with the given external mutex being
106 The reason for the exception for IUndoManager::Undo and IUndoManager::Redo is that those are expected to
107 modify the actual document which the UndoManager works for. And as long as our documents are not thread-safe,
108 and as long as we do not re-fit <strong>all</strong> existing SfxUndoImplementations to <em>not</em> expect
109 the dreaded SolarMutex being locked when they're called, the above behavior is a compromise between "how it should
110 be" and "how it can realistically be".
112 class FWE_DLLPUBLIC UndoManagerHelper
115 UndoManagerHelper( IUndoManagerImplementation
& i_undoManagerImpl
);
116 ~UndoManagerHelper();
121 // XUndoManager equivalents
122 void enterUndoContext( const OUString
& i_title
, IMutexGuard
& i_instanceLock
);
123 void enterHiddenUndoContext( IMutexGuard
& i_instanceLock
);
124 void leaveUndoContext( IMutexGuard
& i_instanceLock
);
125 void addUndoAction( const css::uno::Reference
< css::document::XUndoAction
>& i_action
, IMutexGuard
& i_instanceLock
);
126 void undo( IMutexGuard
& i_instanceLock
);
127 void redo( IMutexGuard
& i_instanceLock
);
128 bool isUndoPossible() const;
129 bool isRedoPossible() const;
130 OUString
getCurrentUndoActionTitle() const;
131 OUString
getCurrentRedoActionTitle() const;
132 css::uno::Sequence
< OUString
>
133 getAllUndoActionTitles() const;
134 css::uno::Sequence
< OUString
>
135 getAllRedoActionTitles() const;
136 void clear( IMutexGuard
& i_instanceLock
);
137 void clearRedo( IMutexGuard
& i_instanceLock
);
138 void reset( IMutexGuard
& i_instanceLock
);
139 void addUndoManagerListener( const css::uno::Reference
< css::document::XUndoManagerListener
>& i_listener
);
140 void removeUndoManagerListener( const css::uno::Reference
< css::document::XUndoManagerListener
>& i_listener
);
142 // XLockable, base of XUndoManager, equivalents
147 // XModifyBroadcaster equivalents
148 void addModifyListener( const css::uno::Reference
< css::util::XModifyListener
>& i_listener
);
149 void removeModifyListener( const css::uno::Reference
< css::util::XModifyListener
>& i_listener
);
152 std::unique_ptr
< UndoManagerHelper_Impl
> m_xImpl
;
156 } // namespace framework
159 #endif // INCLUDED_FRAMEWORK_UNDOMANAGERHELPER_HXX
161 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */