bump product version to 4.1.6.2
[LibreOffice.git] / include / svl / undo.hxx
blobf36cd816b607b50d53d28bebd78389f2b1a123f6
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 _UNDO_HXX
20 #define _UNDO_HXX
22 #include "svl/svldllapi.h"
23 #include <tools/rtti.hxx>
24 #include <tools/string.hxx>
26 #include <boost/scoped_ptr.hpp>
28 #include <vector>
29 #include <limits>
31 //====================================================================
33 class SVL_DLLPUBLIC SfxRepeatTarget
35 public:
36 TYPEINFO();
37 virtual ~SfxRepeatTarget() = 0;
40 //====================================================================
42 class SVL_DLLPUBLIC SfxUndoContext
44 public:
45 virtual ~SfxUndoContext() = 0;
48 //====================================================================
50 class SVL_DLLPUBLIC SfxUndoAction
52 sal_Bool bLinked;
53 public:
54 TYPEINFO();
55 SfxUndoAction();
56 virtual ~SfxUndoAction();
58 virtual sal_Bool IsLinked();
59 virtual void SetLinked( sal_Bool bIsLinked = sal_True );
60 virtual void Undo();
61 virtual void UndoWithContext( SfxUndoContext& i_context );
62 virtual void Redo();
63 virtual void RedoWithContext( SfxUndoContext& i_context );
64 virtual void Repeat(SfxRepeatTarget&);
65 virtual sal_Bool CanRepeat(SfxRepeatTarget&) const;
67 virtual sal_Bool Merge( SfxUndoAction *pNextAction );
69 virtual OUString GetComment() const;
70 virtual OUString GetRepeatComment(SfxRepeatTarget&) const;
71 virtual sal_uInt16 GetId() const;
73 private:
74 SfxUndoAction& operator=( const SfxUndoAction& ); // n.i.!!
77 //========================================================================
79 /// is a mark on the Undo stack
80 typedef sal_Int32 UndoStackMark;
81 #define MARK_INVALID ::std::numeric_limits< UndoStackMark >::max()
83 //========================================================================
85 struct MarkedUndoAction
87 SfxUndoAction* pAction;
88 ::std::vector< UndoStackMark > aMarks;
90 MarkedUndoAction( SfxUndoAction* i_action )
91 :pAction( i_action )
92 ,aMarks()
97 class SfxUndoActions
99 private:
100 ::std::vector< MarkedUndoAction > m_aActions;
102 public:
103 SfxUndoActions()
107 bool empty() const { return m_aActions.empty(); }
108 size_t size() const { return m_aActions.size(); }
110 const MarkedUndoAction& operator[]( size_t i ) const { return m_aActions[i]; }
111 MarkedUndoAction& operator[]( size_t i ) { return m_aActions[i]; }
113 void Remove( size_t i_pos )
115 m_aActions.erase( m_aActions.begin() + i_pos );
118 void Remove( size_t i_pos, size_t i_count )
120 m_aActions.erase( m_aActions.begin() + i_pos, m_aActions.begin() + i_pos + i_count );
123 void Insert( SfxUndoAction* i_action, size_t i_pos )
125 m_aActions.insert( m_aActions.begin() + i_pos, MarkedUndoAction( i_action ) );
129 //====================================================================
131 /** do not make use of these implementation details, unless you
132 really really have to! */
133 struct SVL_DLLPUBLIC SfxUndoArray
135 SfxUndoActions aUndoActions;
136 size_t nMaxUndoActions;
137 size_t nCurUndoAction;
138 SfxUndoArray *pFatherUndoArray;
139 SfxUndoArray(size_t nMax=0):
140 nMaxUndoActions(nMax), nCurUndoAction(0),
141 pFatherUndoArray(0) {}
142 ~SfxUndoArray();
145 //=========================================================================
147 /** do not make use of these implementation details, unless you
148 really really have to! */
149 class SVL_DLLPUBLIC SfxListUndoAction : public SfxUndoAction, public SfxUndoArray
151 /* [Beschreibung]
153 UndoAction zur Klammerung mehrerer Undos in einer UndoAction.
154 Diese Actions werden vom SfxUndoManager verwendet. Dort
155 wird mit < SfxUndoManager::EnterListAction > eine Klammerebene
156 geoeffnet und mit <SfxUndoManager::LeaveListAction > wieder
157 geschlossen. Redo und Undo auf SfxListUndoActions wirken
158 Elementweise.
162 public:
163 TYPEINFO();
165 SfxListUndoAction( const OUString &rComment,
166 const OUString rRepeatComment, sal_uInt16 Id, SfxUndoArray *pFather);
167 virtual void Undo();
168 virtual void UndoWithContext( SfxUndoContext& i_context );
169 virtual void Redo();
170 virtual void RedoWithContext( SfxUndoContext& i_context );
171 virtual void Repeat(SfxRepeatTarget&);
172 virtual sal_Bool CanRepeat(SfxRepeatTarget&) const;
174 virtual sal_Bool Merge( SfxUndoAction *pNextAction );
176 virtual OUString GetComment() const;
177 virtual OUString GetRepeatComment(SfxRepeatTarget&) const;
178 virtual sal_uInt16 GetId() const;
180 void SetComment(const OUString& rComment);
182 private:
184 sal_uInt16 nId;
185 OUString aComment;
186 OUString aRepeatComment;
190 //=========================================================================
192 /** is a callback interface for notifications about state changes of an SfxUndoManager
194 class SAL_NO_VTABLE SfxUndoListener
196 public:
197 virtual void actionUndone( const String& i_actionComment ) = 0;
198 virtual void actionRedone( const String& i_actionComment ) = 0;
199 virtual void undoActionAdded( const String& i_actionComment ) = 0;
200 virtual void cleared() = 0;
201 virtual void clearedRedo() = 0;
202 virtual void resetAll() = 0;
203 virtual void listActionEntered( const String& i_comment ) = 0;
204 virtual void listActionLeft( const String& i_comment ) = 0;
205 virtual void listActionLeftAndMerged() = 0;
206 virtual void listActionCancelled() = 0;
207 virtual void undoManagerDying() = 0;
209 protected:
210 ~SfxUndoListener() {}
213 //=========================================================================
215 namespace svl
217 class SAL_NO_VTABLE IUndoManager
219 public:
220 enum
222 CurrentLevel = true,
223 TopLevel = false
226 virtual ~IUndoManager() { };
228 virtual void SetMaxUndoActionCount( size_t nMaxUndoActionCount ) = 0;
229 virtual size_t GetMaxUndoActionCount() const = 0;
231 virtual void AddUndoAction( SfxUndoAction *pAction, sal_Bool bTryMerg=sal_False ) = 0;
233 virtual size_t GetUndoActionCount( bool const i_currentLevel = CurrentLevel ) const = 0;
234 virtual sal_uInt16 GetUndoActionId() const = 0;
235 virtual OUString GetUndoActionComment( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const = 0;
236 virtual SfxUndoAction* GetUndoAction( size_t nNo=0 ) const = 0;
238 virtual size_t GetRedoActionCount( bool const i_currentLevel = CurrentLevel ) const = 0;
239 virtual OUString GetRedoActionComment( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const = 0;
241 virtual sal_Bool Undo() = 0;
242 virtual sal_Bool Redo() = 0;
244 /** clears both the Redo and the Undo stack.
246 Will assert and bail out when called while within a list action (<member>IsInListAction</member>).
248 virtual void Clear() = 0;
250 /** clears the Redo stack.
252 Will assert and bail out when called while within a list action (<member>IsInListAction</member>).
254 virtual void ClearRedo() = 0;
256 /** leaves any possible open list action (<member>IsInListAction</member>), and clears both the Undo and the
257 Redo stack.
259 Effectively, calling this method is equivalent to <code>while ( IsInListAction() ) LeaveListAction();</code>,
260 followed by <code>Clear()</code>. The only difference to this calling sequence is that Reset is an
261 atomic operation, also resulting in only one notification.
263 virtual void Reset() = 0;
265 /** determines whether an Undo or Redo is currently running
267 virtual bool IsDoing() const = 0;
269 virtual size_t GetRepeatActionCount() const = 0;
270 virtual OUString GetRepeatActionComment( SfxRepeatTarget &rTarget) const = 0;
271 virtual sal_Bool Repeat( SfxRepeatTarget &rTarget ) = 0;
272 virtual sal_Bool CanRepeat( SfxRepeatTarget &rTarget ) const = 0;
274 virtual void EnterListAction(const OUString &rComment, const OUString& rRepeatComment, sal_uInt16 nId=0) = 0;
276 /** leaves the list action entered with EnterListAction
277 @return the number of the sub actions in the list which has just been left. Note that in case no such
278 actions exist, the list action does not contribute to the Undo stack, but is silently removed.
280 virtual size_t LeaveListAction() = 0;
282 /** leaves the list action entered with EnterListAction, and forcefully merges the previous
283 action on the stack into the newly created list action.
285 Say you have an Undo action A on the stack, then call EnterListAction, followed by one or more calls to
286 AddUndoAction, followed by a call to LeaveAndMergeListAction. In opposite to LeaveListAction, your Undo
287 stack will now still contain one undo action: the newly created list action, whose first child is the
288 original A, whose other children are those you added via AddUndoAction, and whose comment is the same as
289 the comment of A.
291 Effectively, this means that all actions added between EnterListAction and LeaveAndMergeListAction are
292 hidden from the user.
294 @return the number of the sub actions in the list which has just been left. Note that in case no such
295 actions exist, the list action does not contribute to the Undo stack, but is silently removed.
297 virtual size_t LeaveAndMergeListAction() = 0;
299 /// determines whether we're within a ListAction context, i.e. a LeaveListAction/LeaveAndMergeListAction call is pending
300 virtual bool IsInListAction() const = 0;
302 /// determines how many nested list actions are currently open
303 virtual size_t GetListActionDepth() const = 0;
305 /** clears the redo stack and removes the top undo action */
306 virtual void RemoveLastUndoAction() = 0;
308 /** enables (true) or disables (false) recording of undo actions
310 If undo actions are added while undo is disabled, they are deleted.
311 Disabling undo does not clear the current undo buffer!
313 Multiple calls to <code>EnableUndo</code> are not cumulative. That is, calling <code>EnableUndo( false )</code>
314 twice, and then calling <code>EnableUndo( true )</code> means that Undo is enable afterwards.
316 virtual void EnableUndo( bool bEnable ) = 0;
318 // returns true if undo is currently enabled
319 // This returns false if undo was disabled using EnableUndo( false ) and
320 // also during the runtime of the Undo() and Redo() methods.
321 virtual bool IsUndoEnabled() const = 0;
323 /// adds a new listener to be notified about changes in the UndoManager's state
324 virtual void AddUndoListener( SfxUndoListener& i_listener ) = 0;
325 virtual void RemoveUndoListener( SfxUndoListener& i_listener ) = 0;
329 //=========================================================================
331 namespace svl { namespace undo { namespace impl
333 class UndoManagerGuard;
334 class LockGuard;
335 } } }
337 struct SfxUndoManager_Data;
338 class SVL_DLLPUBLIC SfxUndoManager : public ::svl::IUndoManager
340 friend class SfxLinkUndoAction;
342 ::boost::scoped_ptr< SfxUndoManager_Data >
343 m_pData;
344 public:
345 SfxUndoManager( size_t nMaxUndoActionCount = 20 );
346 virtual ~SfxUndoManager();
348 // IUndoManager overridables
349 virtual void SetMaxUndoActionCount( size_t nMaxUndoActionCount );
350 virtual size_t GetMaxUndoActionCount() const;
351 virtual void AddUndoAction( SfxUndoAction *pAction, sal_Bool bTryMerg=sal_False );
352 virtual size_t GetUndoActionCount( bool const i_currentLevel = CurrentLevel ) const;
353 virtual sal_uInt16 GetUndoActionId() const;
354 virtual OUString GetUndoActionComment( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const;
355 virtual SfxUndoAction* GetUndoAction( size_t nNo=0 ) const;
356 virtual size_t GetRedoActionCount( bool const i_currentLevel = CurrentLevel ) const;
357 virtual OUString GetRedoActionComment( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const;
358 virtual sal_Bool Undo();
359 virtual sal_Bool Redo();
360 virtual void Clear();
361 virtual void ClearRedo();
362 virtual void Reset();
363 virtual bool IsDoing() const;
364 virtual size_t GetRepeatActionCount() const;
365 virtual OUString GetRepeatActionComment( SfxRepeatTarget &rTarget) const;
366 virtual sal_Bool Repeat( SfxRepeatTarget &rTarget );
367 virtual sal_Bool CanRepeat( SfxRepeatTarget &rTarget ) const;
368 virtual void EnterListAction(const OUString &rComment, const OUString& rRepeatComment, sal_uInt16 nId=0);
369 virtual size_t LeaveListAction();
370 virtual size_t LeaveAndMergeListAction();
371 virtual bool IsInListAction() const;
372 virtual size_t GetListActionDepth() const;
373 virtual void RemoveLastUndoAction();
374 virtual void EnableUndo( bool bEnable );
375 virtual bool IsUndoEnabled() const;
376 virtual void AddUndoListener( SfxUndoListener& i_listener );
377 virtual void RemoveUndoListener( SfxUndoListener& i_listener );
379 /** marks the current top-level element of the Undo stack, and returns a unique ID for it
381 UndoStackMark MarkTopUndoAction();
383 /** removes a mark given by its ID.
384 After the call, the mark ID is invalid.
386 void RemoveMark( UndoStackMark const i_mark );
388 /** determines whether the top action on the Undo stack has a given mark
390 bool HasTopUndoActionMark( UndoStackMark const i_mark );
392 /** removes the oldest Undo actions from the stack
394 void RemoveOldestUndoActions( size_t const i_count );
396 protected:
397 sal_Bool UndoWithContext( SfxUndoContext& i_context );
398 sal_Bool RedoWithContext( SfxUndoContext& i_context );
400 void ImplClearRedo_NoLock( bool const i_currentLevel );
402 /** clears all undo actions on the current level, plus all undo actions on superordinate levels,
403 as soon as those levels are reached.
405 If no list action is active currently, i.e. we're on the top level already, this method is equivalent to
406 ->Clear.
408 Otherwise, the Undo actions on the current level are removed. Upon leaving the current list action, all
409 undo actions on the then-current level are removed, too. This is continued until the top level is reached.
411 void ClearAllLevels();
413 private:
414 size_t ImplLeaveListAction( const bool i_merge, ::svl::undo::impl::UndoManagerGuard& i_guard );
415 bool ImplAddUndoAction_NoNotify( SfxUndoAction* pAction, bool bTryMerge, bool bClearRedo, ::svl::undo::impl::UndoManagerGuard& i_guard );
416 void ImplClearRedo( ::svl::undo::impl::UndoManagerGuard& i_guard, bool const i_currentLevel );
417 void ImplClearUndo( ::svl::undo::impl::UndoManagerGuard& i_guard );
418 void ImplClearCurrentLevel_NoNotify( ::svl::undo::impl::UndoManagerGuard& i_guard );
419 size_t ImplGetRedoActionCount_Lock( bool const i_currentLevel = CurrentLevel ) const;
420 bool ImplIsUndoEnabled_Lock() const;
421 bool ImplIsInListAction_Lock() const;
422 void ImplEnableUndo_Lock( bool const i_enable );
424 sal_Bool ImplUndo( SfxUndoContext* i_contextOrNull );
425 sal_Bool ImplRedo( SfxUndoContext* i_contextOrNull );
427 friend class ::svl::undo::impl::LockGuard;
430 //=========================================================================
432 class SVL_DLLPUBLIC SfxLinkUndoAction : public SfxUndoAction
434 /* [Beschreibung]
436 Die SfxLinkUndoAction dient zur Verbindung zweier SfxUndoManager. Die
437 im ersten SfxUndoManager eingefuegten SfxUndoAction leiten ihr Undo und Redo
438 an den zweiten weiter, so dass ein Undo und Redo am ersten
439 SfxUndoManager wie eine am zweiten wirkt.
441 Die SfxLinkUndoAction ist nach dem Einfuegen der SfxUndoAction am
442 zweiten SfxUndoManager einzufuegen. Waehrend der zweite SfxUndoManager
443 vom ersten ferngesteuert wird, duerfen an ihm weder Actions eingefuegt werden,
444 noch darf Undo/Redo aufgerufen werden.
449 public:
450 TYPEINFO();
451 SfxLinkUndoAction(::svl::IUndoManager *pManager);
452 ~SfxLinkUndoAction();
454 virtual void Undo();
455 virtual void Redo();
456 virtual sal_Bool CanRepeat(SfxRepeatTarget& r) const;
458 virtual void Repeat(SfxRepeatTarget&r);
460 virtual OUString GetComment() const;
461 virtual OUString GetRepeatComment(SfxRepeatTarget&r) const;
462 virtual sal_uInt16 GetId() const;
464 SfxUndoAction* GetAction() const { return pAction; }
466 protected:
467 ::svl::IUndoManager *pUndoManager;
468 SfxUndoAction *pAction;
472 #endif
474 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */