summaryrefslogtreecommitdiff
path: root/svl/inc/svl/undo.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'svl/inc/svl/undo.hxx')
-rw-r--r--svl/inc/svl/undo.hxx377
1 files changed, 306 insertions, 71 deletions
diff --git a/svl/inc/svl/undo.hxx b/svl/inc/svl/undo.hxx
index 5aea03207626..3d2c46af496c 100644
--- a/svl/inc/svl/undo.hxx
+++ b/svl/inc/svl/undo.hxx
@@ -32,6 +32,10 @@
#include <tools/string.hxx>
#include <svl/svarray.hxx>
+#include <boost/scoped_ptr.hpp>
+
+#include <vector>
+
//====================================================================
class SVL_DLLPUBLIC SfxRepeatTarget
@@ -43,26 +47,36 @@ public:
//====================================================================
+class SVL_DLLPUBLIC SfxUndoContext
+{
+public:
+ virtual ~SfxUndoContext() = 0;
+};
+
+//====================================================================
+
class SVL_DLLPUBLIC SfxUndoAction
{
- BOOL bLinked;
+ sal_Bool bLinked;
public:
TYPEINFO();
SfxUndoAction();
virtual ~SfxUndoAction();
- virtual BOOL IsLinked();
- virtual void SetLinked( BOOL bIsLinked = TRUE );
+ virtual sal_Bool IsLinked();
+ virtual void SetLinked( sal_Bool bIsLinked = sal_True );
virtual void Undo();
+ virtual void UndoWithContext( SfxUndoContext& i_context );
virtual void Redo();
+ virtual void RedoWithContext( SfxUndoContext& i_context );
virtual void Repeat(SfxRepeatTarget&);
- virtual BOOL CanRepeat(SfxRepeatTarget&) const;
+ virtual sal_Bool CanRepeat(SfxRepeatTarget&) const;
- virtual BOOL Merge( SfxUndoAction *pNextAction );
+ virtual sal_Bool Merge( SfxUndoAction *pNextAction );
- virtual UniString GetComment() const;
- virtual UniString GetRepeatComment(SfxRepeatTarget&) const;
- virtual USHORT GetId() const;
+ virtual UniString GetComment() const;
+ virtual UniString GetRepeatComment(SfxRepeatTarget&) const;
+ virtual sal_uInt16 GetId() const;
private:
SfxUndoAction& operator=( const SfxUndoAction& ); // n.i.!!
@@ -70,19 +84,67 @@ private:
//========================================================================
-SV_DECL_PTRARR( SfxUndoActions, SfxUndoAction*, 20, 8 )
+/// is a mark on the Undo stack
+typedef sal_Int32 UndoStackMark;
+#define MARK_INVALID ::std::numeric_limits< UndoStackMark >::max()
+
+//========================================================================
+
+struct MarkedUndoAction
+{
+ SfxUndoAction* pAction;
+ ::std::vector< UndoStackMark > aMarks;
+
+ MarkedUndoAction( SfxUndoAction* i_action )
+ :pAction( i_action )
+ ,aMarks()
+ {
+ }
+};
+
+class SfxUndoActions
+{
+private:
+ ::std::vector< MarkedUndoAction > m_aActions;
+
+public:
+ SfxUndoActions()
+ {
+ }
+
+ bool empty() const { return m_aActions.empty(); }
+ size_t size() const { return m_aActions.size(); }
+
+ const MarkedUndoAction& operator[]( size_t i ) const { return m_aActions[i]; }
+ MarkedUndoAction& operator[]( size_t i ) { return m_aActions[i]; }
+
+ void Remove( size_t i_pos )
+ {
+ m_aActions.erase( m_aActions.begin() + i_pos );
+ }
+
+ void Remove( size_t i_pos, size_t i_count )
+ {
+ m_aActions.erase( m_aActions.begin() + i_pos, m_aActions.begin() + i_pos + i_count );
+ }
+
+ void Insert( SfxUndoAction* i_action, size_t i_pos )
+ {
+ m_aActions.insert( m_aActions.begin() + i_pos, MarkedUndoAction( i_action ) );
+ }
+};
//====================================================================
-/** do not make use of this implementation details, unless you
+/** do not make use of these implementation details, unless you
really really have to! */
struct SVL_DLLPUBLIC SfxUndoArray
{
SfxUndoActions aUndoActions;
- USHORT nMaxUndoActions;
- USHORT nCurUndoAction;
+ size_t nMaxUndoActions;
+ size_t nCurUndoAction;
SfxUndoArray *pFatherUndoArray;
- SfxUndoArray(USHORT nMax=0):
+ SfxUndoArray(size_t nMax=0):
nMaxUndoActions(nMax), nCurUndoAction(0),
pFatherUndoArray(0) {}
~SfxUndoArray();
@@ -90,7 +152,7 @@ struct SVL_DLLPUBLIC SfxUndoArray
//=========================================================================
-/** do not make use of this implementation details, unless you
+/** do not make use of these implementation details, unless you
really really have to! */
class SVL_DLLPUBLIC SfxListUndoAction : public SfxUndoAction, public SfxUndoArray
@@ -109,87 +171,260 @@ class SVL_DLLPUBLIC SfxListUndoAction : public SfxUndoAction, public SfxUndoArra
TYPEINFO();
SfxListUndoAction( const UniString &rComment,
- const UniString rRepeatComment, USHORT Id, SfxUndoArray *pFather);
+ const UniString rRepeatComment, sal_uInt16 Id, SfxUndoArray *pFather);
virtual void Undo();
+ virtual void UndoWithContext( SfxUndoContext& i_context );
virtual void Redo();
+ virtual void RedoWithContext( SfxUndoContext& i_context );
virtual void Repeat(SfxRepeatTarget&);
- virtual BOOL CanRepeat(SfxRepeatTarget&) const;
+ virtual sal_Bool CanRepeat(SfxRepeatTarget&) const;
- virtual BOOL Merge( SfxUndoAction *pNextAction );
+ virtual sal_Bool Merge( SfxUndoAction *pNextAction );
- virtual UniString GetComment() const;
- virtual UniString GetRepeatComment(SfxRepeatTarget&) const;
- virtual USHORT GetId() const;
+ virtual UniString GetComment() const;
+ virtual UniString GetRepeatComment(SfxRepeatTarget&) const;
+ virtual sal_uInt16 GetId() const;
void SetComment( const UniString& rComment );
private:
- USHORT nId;
- UniString aComment, aRepeatComment;
+ sal_uInt16 nId;
+ UniString aComment;
+ UniString aRepeatComment;
};
//=========================================================================
-class SVL_DLLPUBLIC SfxUndoManager
+/** is a callback interface for notifications about state changes of an SfxUndoManager
+*/
+class SAL_NO_VTABLE SfxUndoListener
{
- friend class SfxLinkUndoAction;
+public:
+ virtual void actionUndone( const String& i_actionComment ) = 0;
+ virtual void actionRedone( const String& i_actionComment ) = 0;
+ virtual void undoActionAdded( const String& i_actionComment ) = 0;
+ virtual void cleared() = 0;
+ virtual void clearedRedo() = 0;
+ virtual void resetAll() = 0;
+ virtual void listActionEntered( const String& i_comment ) = 0;
+ virtual void listActionLeft( const String& i_comment ) = 0;
+ virtual void listActionLeftAndMerged() = 0;
+ virtual void listActionCancelled() = 0;
+ virtual void undoManagerDying() = 0;
+};
- SfxUndoArray *pUndoArray;
- SfxUndoArray *pActUndoArray;
- SfxUndoArray *pFatherUndoArray;
+//=========================================================================
- bool mbUndoEnabled;
-public:
- SfxUndoManager( USHORT nMaxUndoActionCount = 20 );
- virtual ~SfxUndoManager();
+namespace svl
+{
+ class SAL_NO_VTABLE IUndoManager
+ {
+ public:
+ enum
+ {
+ CurrentLevel = true,
+ TopLevel = false
+ };
- virtual void SetMaxUndoActionCount( USHORT nMaxUndoActionCount );
- virtual USHORT GetMaxUndoActionCount() const;
- virtual void Clear();
+ virtual ~IUndoManager() { };
+
+ virtual void SetMaxUndoActionCount( size_t nMaxUndoActionCount ) = 0;
+ virtual size_t GetMaxUndoActionCount() const = 0;
+
+ virtual void AddUndoAction( SfxUndoAction *pAction, sal_Bool bTryMerg=sal_False ) = 0;
+
+ virtual size_t GetUndoActionCount( bool const i_currentLevel = CurrentLevel ) const = 0;
+ virtual sal_uInt16 GetUndoActionId() const = 0;
+ virtual UniString GetUndoActionComment( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const = 0;
+ virtual SfxUndoAction* GetUndoAction( size_t nNo=0 ) const = 0;
- virtual void AddUndoAction( SfxUndoAction *pAction, BOOL bTryMerg=FALSE );
+ virtual size_t GetRedoActionCount( bool const i_currentLevel = CurrentLevel ) const = 0;
+ virtual UniString GetRedoActionComment( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const = 0;
- virtual USHORT GetUndoActionCount() const;
- virtual USHORT GetUndoActionId(USHORT nNo=0) const;
- virtual UniString GetUndoActionComment( USHORT nNo=0 ) const;
- /** returns the nNo'th undo action from the top */
- SfxUndoAction* GetUndoAction( USHORT nNo=0 ) const;
+ virtual sal_Bool Undo() = 0;
+ virtual sal_Bool Redo() = 0;
- virtual BOOL Undo( USHORT nCount=1 );
- virtual void Undo( SfxUndoAction &rAction );
+ /** clears both the Redo and the Undo stack.
- virtual USHORT GetRedoActionCount() const;
- virtual USHORT GetRedoActionId(USHORT nNo=0) const;
- virtual UniString GetRedoActionComment( USHORT nNo=0 ) const;
+ Will assert and bail out when called while within a list action (<member>IsInListAction</member>).
+ */
+ virtual void Clear() = 0;
- virtual BOOL Redo( USHORT nCount=1 );
- virtual void Redo( SfxUndoAction &rAction );
+ /** clears the Redo stack.
+
+ Will assert and bail out when called while within a list action (<member>IsInListAction</member>).
+ */
+ virtual void ClearRedo() = 0;
+
+ /** leaves any possible open list action (<member>IsInListAction</member>), and clears both the Undo and the
+ Redo stack.
+
+ Effectively, calling this method is equivalent to <code>while ( IsInListAction() ) LeaveListAction();</code>,
+ followed by <code>Clear()</code>. The only difference to this calling sequence is that Reset is an
+ atomar operation, also resulting in only one notification.
+ */
+ virtual void Reset() = 0;
+
+ /** determines whether an Undo or Redo is currently running
+ */
+ virtual bool IsDoing() const = 0;
+
+ virtual size_t GetRepeatActionCount() const = 0;
+ virtual UniString GetRepeatActionComment( SfxRepeatTarget &rTarget) const = 0;
+ virtual sal_Bool Repeat( SfxRepeatTarget &rTarget ) = 0;
+ virtual sal_Bool CanRepeat( SfxRepeatTarget &rTarget ) const = 0;
+
+ virtual void EnterListAction(const UniString &rComment, const UniString& rRepeatComment, sal_uInt16 nId=0) = 0;
+
+ /** leaves the list action entered with EnterListAction
+ @return the number of the sub actions in the list which has just been left. Note that in case no such
+ actions exist, the list action does not contribute to the Undo stack, but is silently removed.
+ */
+ virtual size_t LeaveListAction() = 0;
+
+ /** leaves the list action entered with EnterListAction, and forcefully merges the previous
+ action on the stack into the newly created list action.
+
+ Say you have an Undo action A on the stack, then call EnterListAction, followed by one or more calls to
+ AddUndoAction, followed by a call to LeaveAndMergeListAction. In opposite to LeaveListAction, your Undo
+ stack will now still contain one undo action: the newly created list action, whose first child is the
+ original A, whose other children are those you added via AddUndoAction, and whose comment is the same as
+ the comment of A.
+
+ Effectively, this means that all actions added between EnterListAction and LeaveAndMergeListAction are
+ hidden from the user.
+
+ @return the number of the sub actions in the list which has just been left. Note that in case no such
+ actions exist, the list action does not contribute to the Undo stack, but is silently removed.
+ */
+ virtual size_t LeaveAndMergeListAction() = 0;
+
+ /// determines whether we're within a ListAction context, i.e. a LeaveListAction/LeaveAndMergeListAction call is pending
+ virtual bool IsInListAction() const = 0;
+
+ /// determines how many nested list actions are currently open
+ virtual size_t GetListActionDepth() const = 0;
+
+ /** clears the redo stack and removes the top undo action */
+ virtual void RemoveLastUndoAction() = 0;
+
+ // enables (true) or disables (false) recording of undo actions
+ // If undo actions are added while undo is disabled, they are deleted.
+ // Disabling undo does not clear the current undo buffer!
+ virtual void EnableUndo( bool bEnable ) = 0;
+
+ // returns true if undo is currently enabled
+ // This returns false if undo was disabled using EnableUndo( false ) and
+ // also during the runtime of the Undo() and Redo() methods.
+ virtual bool IsUndoEnabled() const = 0;
+
+ /// adds a new listener to be notified about changes in the UndoManager's state
+ virtual void AddUndoListener( SfxUndoListener& i_listener ) = 0;
+ virtual void RemoveUndoListener( SfxUndoListener& i_listener ) = 0;
+ };
+}
+
+//=========================================================================
+
+namespace svl { namespace undo { namespace impl
+{
+ class UndoManagerGuard;
+ class LockGuard;
+} } }
+
+struct SfxUndoManager_Data;
+class SVL_DLLPUBLIC SfxUndoManager : public ::svl::IUndoManager
+{
+ friend class SfxLinkUndoAction;
+
+ ::boost::scoped_ptr< SfxUndoManager_Data >
+ m_pData;
+public:
+ SfxUndoManager( size_t nMaxUndoActionCount = 20 );
+ virtual ~SfxUndoManager();
+
+ // IUndoManager overridables
+ virtual void SetMaxUndoActionCount( size_t nMaxUndoActionCount );
+ virtual size_t GetMaxUndoActionCount() const;
+ virtual void AddUndoAction( SfxUndoAction *pAction, sal_Bool bTryMerg=sal_False );
+ virtual size_t GetUndoActionCount( bool const i_currentLevel = CurrentLevel ) const;
+ virtual sal_uInt16 GetUndoActionId() const;
+ virtual UniString GetUndoActionComment( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const;
+ virtual SfxUndoAction* GetUndoAction( size_t nNo=0 ) const;
+ virtual size_t GetRedoActionCount( bool const i_currentLevel = CurrentLevel ) const;
+ virtual UniString GetRedoActionComment( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const;
+ virtual sal_Bool Undo();
+ virtual sal_Bool Redo();
+ virtual void Clear();
virtual void ClearRedo();
+ virtual void Reset();
+ virtual bool IsDoing() const;
+ virtual size_t GetRepeatActionCount() const;
+ virtual UniString GetRepeatActionComment( SfxRepeatTarget &rTarget) const;
+ virtual sal_Bool Repeat( SfxRepeatTarget &rTarget );
+ virtual sal_Bool CanRepeat( SfxRepeatTarget &rTarget ) const;
+ virtual void EnterListAction(const UniString &rComment, const UniString& rRepeatComment, sal_uInt16 nId=0);
+ virtual size_t LeaveListAction();
+ virtual size_t LeaveAndMergeListAction();
+ virtual bool IsInListAction() const;
+ virtual size_t GetListActionDepth() const;
+ virtual void RemoveLastUndoAction();
+ virtual void EnableUndo( bool bEnable );
+ virtual bool IsUndoEnabled() const;
+ virtual void AddUndoListener( SfxUndoListener& i_listener );
+ virtual void RemoveUndoListener( SfxUndoListener& i_listener );
+
+ /** marks the current top-level element of the Undo stack, and returns a unique ID for it
+ */
+ UndoStackMark MarkTopUndoAction();
+
+ /** removes a mark given by its ID.
+ After the call, the mark ID is invalid.
+ */
+ void RemoveMark( UndoStackMark const i_mark );
+
+ /** determines whether the top action on the Undo stack has a given mark
+ */
+ bool HasTopUndoActionMark( UndoStackMark const i_mark );
+
+ /** removes the oldest Undo actions from the stack
+ */
+ void RemoveOldestUndoActions( size_t const i_count );
+
+protected:
+ sal_Bool UndoWithContext( SfxUndoContext& i_context );
+ sal_Bool RedoWithContext( SfxUndoContext& i_context );
- virtual USHORT GetRepeatActionCount() const;
- virtual UniString GetRepeatActionComment( SfxRepeatTarget &rTarget, USHORT nNo = 0) const;
- virtual BOOL Repeat( SfxRepeatTarget &rTarget, USHORT nFrom=0, USHORT nCount=1 );
- virtual void Repeat( SfxRepeatTarget &rTarget, SfxUndoAction &rAction );
- virtual BOOL CanRepeat( SfxRepeatTarget &rTarget, USHORT nNo = 0 ) const;
- virtual BOOL CanRepeat( SfxRepeatTarget &rTarget, SfxUndoAction &rAction ) const;
+ void ImplClearRedo_NoLock( bool const i_currentLevel );
- virtual void EnterListAction(const UniString &rComment, const UniString& rRepeatComment, USHORT nId=0);
- virtual void LeaveListAction();
+ /** clears all undo actions on the current level, plus all undo actions on superordinate levels,
+ as soon as those levels are reached.
- /** clears the redo stack and removes the top undo action */
- void RemoveLastUndoAction();
+ If no list action is active currently, i.e. we're on the top level already, this method is equivalent to
+ ->Clear.
- // enables (true) or disables (false) recording of undo actions
- // If undo actions are added while undo is disabled, they are deleted.
- // Disabling undo does not clear the current undo buffer!
- void EnableUndo( bool bEnable );
+ Otherwise, the Undo actions on the current level are removed. Upon leaving the current list action, all
+ undo actions on the then-current level are removed, too. This is continued until the top level is reached.
+ */
+ void ClearAllLevels();
- // returns true if undo is currently enabled
- // This returns false if undo was disabled using EnableUndo( false ) and
- // also during the runtime of the Undo() and Redo() methods.
- bool IsUndoEnabled() const { return mbUndoEnabled; }
+private:
+ size_t ImplLeaveListAction( const bool i_merge, ::svl::undo::impl::UndoManagerGuard& i_guard );
+ bool ImplAddUndoAction_NoNotify( SfxUndoAction* pAction, bool bTryMerge, bool bClearRedo, ::svl::undo::impl::UndoManagerGuard& i_guard );
+ void ImplClearRedo( ::svl::undo::impl::UndoManagerGuard& i_guard, bool const i_currentLevel );
+ void ImplClearUndo( ::svl::undo::impl::UndoManagerGuard& i_guard );
+ void ImplClearCurrentLevel_NoNotify( ::svl::undo::impl::UndoManagerGuard& i_guard );
+ size_t ImplGetRedoActionCount_Lock( bool const i_currentLevel = CurrentLevel ) const;
+ bool ImplIsUndoEnabled_Lock() const;
+ bool ImplIsInListAction_Lock() const;
+ void ImplEnableUndo_Lock( bool const i_enable );
+
+ sal_Bool ImplUndo( SfxUndoContext* i_contextOrNull );
+ sal_Bool ImplRedo( SfxUndoContext* i_contextOrNull );
+
+ friend class ::svl::undo::impl::LockGuard;
};
//=========================================================================
@@ -213,23 +448,23 @@ class SVL_DLLPUBLIC SfxLinkUndoAction : public SfxUndoAction
{
public:
TYPEINFO();
- SfxLinkUndoAction(SfxUndoManager *pManager);
+ SfxLinkUndoAction(::svl::IUndoManager *pManager);
~SfxLinkUndoAction();
virtual void Undo();
virtual void Redo();
- virtual BOOL CanRepeat(SfxRepeatTarget& r) const;
+ virtual sal_Bool CanRepeat(SfxRepeatTarget& r) const;
virtual void Repeat(SfxRepeatTarget&r);
- virtual UniString GetComment() const;
- virtual UniString GetRepeatComment(SfxRepeatTarget&r) const;
- virtual USHORT GetId() const;
+ virtual UniString GetComment() const;
+ virtual UniString GetRepeatComment(SfxRepeatTarget&r) const;
+ virtual sal_uInt16 GetId() const;
SfxUndoAction* GetAction() const { return pAction; }
protected:
- SfxUndoManager *pUndoManager;
+ ::svl::IUndoManager *pUndoManager;
SfxUndoAction *pAction;
};