bump product version to 6.3.0.0.beta1
[LibreOffice.git] / include / svl / undo.hxx
blob22e1805702688a947be141cd2654d5245ea3ba99
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
19 #ifndef INCLUDED_SVL_UNDO_HXX
20 #define INCLUDED_SVL_UNDO_HXX
22 #include <svl/svldllapi.h>
23 #include <rtl/ustring.hxx>
24 #include <tools/datetime.hxx>
25 #include <o3tl/strong_int.hxx>
27 #include <memory>
28 #include <vector>
30 typedef o3tl::strong_int<sal_Int32, struct ViewShellIdTag> ViewShellId;
31 typedef struct _xmlTextWriter* xmlTextWriterPtr;
33 class SVL_DLLPUBLIC SfxRepeatTarget
35 public:
36 virtual ~SfxRepeatTarget() = 0;
40 class SVL_DLLPUBLIC SfxUndoContext
42 public:
43 virtual ~SfxUndoContext() = 0;
47 class SVL_DLLPUBLIC SfxUndoAction
49 public:
50 SfxUndoAction();
51 virtual ~SfxUndoAction() COVERITY_NOEXCEPT_FALSE;
53 virtual void Undo();
54 virtual void UndoWithContext( SfxUndoContext& i_context );
55 virtual void Redo();
56 virtual void RedoWithContext( SfxUndoContext& i_context );
57 virtual void Repeat(SfxRepeatTarget&);
58 virtual bool CanRepeat(SfxRepeatTarget&) const;
60 virtual bool Merge( SfxUndoAction *pNextAction );
62 virtual OUString GetComment() const;
63 virtual OUString GetRepeatComment(SfxRepeatTarget&) const;
64 /// ID of the view shell that created this undo action.
65 virtual ViewShellId GetViewShellId() const;
66 /// Timestamp when this undo item was created.
67 const DateTime& GetDateTime() const;
68 virtual void dumpAsXml(xmlTextWriterPtr pWriter) const;
70 private:
71 SfxUndoAction( const SfxUndoAction& ) = delete;
72 SfxUndoAction& operator=( const SfxUndoAction& ) = delete;
74 DateTime m_aDateTime;
78 /// is a mark on the Undo stack
79 typedef sal_Int32 UndoStackMark;
80 #define MARK_INVALID ::std::numeric_limits< UndoStackMark >::max()
82 struct MarkedUndoAction
84 std::unique_ptr<SfxUndoAction> pAction;
85 ::std::vector< UndoStackMark > aMarks;
87 MarkedUndoAction(std::unique_ptr<SfxUndoAction> p) : pAction(std::move(p)) {}
90 /** do not make use of these implementation details, unless you
91 really really have to! */
92 struct SVL_DLLPUBLIC SfxUndoArray
94 std::vector<MarkedUndoAction> maUndoActions;
95 size_t nMaxUndoActions;
96 size_t nCurUndoAction;
97 SfxUndoArray *pFatherUndoArray;
99 SfxUndoArray(size_t nMax=0) :
100 nMaxUndoActions(nMax), nCurUndoAction(0), pFatherUndoArray(nullptr) {}
101 virtual ~SfxUndoArray();
103 SfxUndoArray& operator=( SfxUndoArray const & ) = delete; // MSVC2017 workaround
104 SfxUndoArray( SfxUndoArray const & ) = delete; // MSVC2017 workaround
106 SfxUndoAction* GetUndoAction(size_t idx) { return maUndoActions[idx].pAction.get(); }
107 std::unique_ptr<SfxUndoAction> Remove(int idx);
108 void Remove( size_t i_pos, size_t i_count );
109 void Insert( std::unique_ptr<SfxUndoAction> i_action, size_t i_pos );
113 /** do not make use of these implementation details, unless you
114 really really have to! */
115 class SVL_DLLPUBLIC SfxListUndoAction : public SfxUndoAction, public SfxUndoArray
117 /* [Explanation]
119 UndoAction to composite multiple Undos in one UndoAction.
120 These actions are used by SfxUndomanager. With < SfxUndoManager::EnterListAction >
121 you can go one composite level down and with < SfxUndoManager::LeaveListAction > up again.
122 Redo and Undo work element wise on SfxListUndoActions.
125 struct Impl;
126 std::unique_ptr<Impl> mpImpl;
128 public:
130 SfxListUndoAction(
131 const OUString &rComment, const OUString& rRepeatComment, sal_uInt16 nId, ViewShellId nViewShellId, SfxUndoArray *pFather );
132 virtual ~SfxListUndoAction() override;
134 virtual void Undo() override;
135 virtual void UndoWithContext( SfxUndoContext& i_context ) override;
136 virtual void Redo() override;
137 virtual void RedoWithContext( SfxUndoContext& i_context ) override;
138 virtual void Repeat(SfxRepeatTarget&) override;
139 virtual bool CanRepeat(SfxRepeatTarget&) const override;
141 virtual bool Merge( SfxUndoAction *pNextAction ) override;
143 virtual OUString GetComment() const override;
144 /// See SfxUndoAction::GetViewShellId().
145 ViewShellId GetViewShellId() const override;
146 virtual OUString GetRepeatComment(SfxRepeatTarget&) const override;
147 sal_uInt16 GetId() const;
149 void SetComment(const OUString& rComment);
150 void dumpAsXml(xmlTextWriterPtr pWriter) const override;
154 /** is a callback interface for notifications about state changes of an SfxUndoManager
156 class SAL_NO_VTABLE SfxUndoListener
158 public:
159 virtual void actionUndone( const OUString& i_actionComment ) = 0;
160 virtual void actionRedone( const OUString& i_actionComment ) = 0;
161 virtual void undoActionAdded( const OUString& i_actionComment ) = 0;
162 virtual void cleared() = 0;
163 virtual void clearedRedo() = 0;
164 virtual void resetAll() = 0;
165 virtual void listActionEntered( const OUString& i_comment ) = 0;
166 virtual void listActionLeft( const OUString& i_comment ) = 0;
167 virtual void listActionCancelled() = 0;
168 virtual void undoManagerDying() = 0;
170 protected:
171 ~SfxUndoListener() {}
175 namespace svl { namespace undo { namespace impl
177 class UndoManagerGuard;
178 class LockGuard;
179 } } }
181 struct SfxUndoManager_Data;
182 class SVL_DLLPUBLIC SfxUndoManager
184 std::unique_ptr< SfxUndoManager_Data >
185 m_xData;
186 public:
187 static bool const CurrentLevel = true;
188 static bool const TopLevel = false;
190 SfxUndoManager( size_t nMaxUndoActionCount = 20 );
191 virtual ~SfxUndoManager();
193 void SetMaxUndoActionCount( size_t nMaxUndoActionCount );
194 virtual void AddUndoAction( std::unique_ptr<SfxUndoAction> pAction, bool bTryMerg=false );
195 virtual size_t GetUndoActionCount( bool const i_currentLevel = CurrentLevel ) const;
196 OUString GetUndoActionComment( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const;
197 SfxUndoAction* GetUndoAction( size_t nNo=0 ) const;
198 /// Get info about all undo actions (comment, view shell id, etc.)
199 OUString GetUndoActionsInfo() const;
200 virtual size_t GetRedoActionCount( bool const i_currentLevel = CurrentLevel ) const;
201 OUString GetRedoActionComment( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const;
202 SfxUndoAction* GetRedoAction() const;
203 /// Get info about all redo actions (comment, view shell id, etc.)
204 OUString GetRedoActionsInfo() const;
205 virtual bool Undo();
206 virtual bool Redo();
207 /** Clears both the Redo and the Undo stack.
208 Will assert and bail out when called while within a list action (<member>IsInListAction</member>).
210 virtual void Clear();
211 /** Clears the Redo stack.
212 Will assert and bail out when called while within a list action (<member>IsInListAction</member>).
214 virtual void ClearRedo();
215 /** leaves any possible open list action (<member>IsInListAction</member>), and clears both the Undo and the
216 Redo stack.
218 Effectively, calling this method is equivalent to <code>while ( IsInListAction() ) LeaveListAction();</code>,
219 followed by <code>Clear()</code>. The only difference to this calling sequence is that Reset is an
220 atomic operation, also resulting in only one notification.
222 void Reset();
223 /** determines whether an Undo or Redo is currently running
225 bool IsDoing() const;
226 size_t GetRepeatActionCount() const;
227 OUString GetRepeatActionComment( SfxRepeatTarget &rTarget) const;
228 bool Repeat( SfxRepeatTarget &rTarget );
229 bool CanRepeat( SfxRepeatTarget &rTarget ) const;
230 virtual void EnterListAction(const OUString &rComment, const OUString& rRepeatComment, sal_uInt16 nId, ViewShellId nViewShellId);
231 /** Leaves the list action entered with EnterListAction
232 @return the number of the sub actions in the list which has just been left. Note that in case no such
233 actions exist, the list action does not contribute to the Undo stack, but is silently removed.
235 size_t LeaveListAction();
237 /** Leaves the list action entered with EnterListAction, and forcefully merges the previous
238 action on the stack into the newly created list action.
240 Say you have an Undo action A on the stack, then call EnterListAction, followed by one or more calls to
241 AddUndoAction, followed by a call to LeaveAndMergeListAction. In opposite to LeaveListAction, your Undo
242 stack will now still contain one undo action: the newly created list action, whose first child is the
243 original A, whose other children are those you added via AddUndoAction, and whose comment is the same as
244 the comment of A.
246 Effectively, this means that all actions added between EnterListAction and LeaveAndMergeListAction are
247 hidden from the user.
249 @return the number of the sub actions in the list which has just been left. Note that in case no such
250 actions exist, the list action does not contribute to the Undo stack, but is silently removed.
252 size_t LeaveAndMergeListAction();
253 /// determines whether we're within a ListAction context, i.e. a LeaveListAction/LeaveAndMergeListAction call is pending
254 bool IsInListAction() const;
255 /// Determines how many nested list actions are currently open
256 size_t GetListActionDepth() const;
257 /** Clears the redo stack and removes the top undo action */
258 void RemoveLastUndoAction();
259 /** enables (true) or disables (false) recording of undo actions
261 If undo actions are added while undo is disabled, they are deleted.
262 Disabling undo does not clear the current undo buffer!
264 Multiple calls to <code>EnableUndo</code> are not cumulative. That is, calling <code>EnableUndo( false )</code>
265 twice, and then calling <code>EnableUndo( true )</code> means that Undo is enable afterwards.
267 void EnableUndo( bool bEnable );
268 /// returns true if undo is currently enabled.
269 /// This returns false if undo was disabled using EnableUndo( false ) and
270 /// also during the runtime of the Undo() and Redo() methods.
271 bool IsUndoEnabled() const;
272 /// Adds a new listener to be notified about changes in the UndoManager's state
273 void AddUndoListener( SfxUndoListener& i_listener );
274 void RemoveUndoListener( SfxUndoListener& i_listener );
275 bool IsEmptyActions() const;
278 /** marks the current top-level element of the Undo stack, and returns a unique ID for it
280 UndoStackMark MarkTopUndoAction();
282 /** removes a mark given by its ID.
283 After the call, the mark ID is invalid.
285 void RemoveMark( UndoStackMark const i_mark );
287 /** determines whether the top action on the Undo stack has a given mark
289 bool HasTopUndoActionMark( UndoStackMark const i_mark );
291 /** removes the oldest Undo actions from the stack
293 void RemoveOldestUndoAction();
295 void dumpAsXml(xmlTextWriterPtr pWriter) const;
297 protected:
298 bool UndoWithContext( SfxUndoContext& i_context );
299 bool RedoWithContext( SfxUndoContext& i_context );
301 void ImplClearRedo_NoLock( bool const i_currentLevel );
303 /** clears all undo actions on the current level, plus all undo actions on superordinate levels,
304 as soon as those levels are reached.
306 If no list action is active currently, i.e. we're on the top level already, this method is equivalent to
307 ->Clear.
309 Otherwise, the Undo actions on the current level are removed. Upon leaving the current list action, all
310 undo actions on the then-current level are removed, too. This is continued until the top level is reached.
312 void ClearAllLevels();
313 virtual void EmptyActionsChanged();
315 private:
316 size_t ImplLeaveListAction( const bool i_merge, ::svl::undo::impl::UndoManagerGuard& i_guard );
317 bool ImplAddUndoAction_NoNotify( std::unique_ptr<SfxUndoAction> pAction, bool bTryMerge, bool bClearRedo, ::svl::undo::impl::UndoManagerGuard& i_guard );
318 void ImplClearRedo( ::svl::undo::impl::UndoManagerGuard& i_guard, bool const i_currentLevel );
319 void ImplClearUndo( ::svl::undo::impl::UndoManagerGuard& i_guard );
320 void ImplClearCurrentLevel_NoNotify( ::svl::undo::impl::UndoManagerGuard& i_guard );
321 size_t ImplGetRedoActionCount_Lock( bool const i_currentLevel = CurrentLevel ) const;
322 bool ImplIsUndoEnabled_Lock() const;
323 bool ImplIsInListAction_Lock() const;
324 void ImplEnableUndo_Lock( bool const i_enable );
326 bool ImplUndo( SfxUndoContext* i_contextOrNull );
327 bool ImplRedo( SfxUndoContext* i_contextOrNull );
328 void ImplCheckEmptyActions();
329 inline bool ImplIsEmptyActions() const;
331 friend class ::svl::undo::impl::LockGuard;
334 #endif
336 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */