LCOV - code coverage report
Current view: top level - include/svl - undo.hxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 27 31 87.1 %
Date: 2014-11-03 Functions: 21 24 87.5 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : #ifndef INCLUDED_SVL_UNDO_HXX
      20             : #define INCLUDED_SVL_UNDO_HXX
      21             : 
      22             : #include <svl/svldllapi.h>
      23             : #include <rtl/ustring.hxx>
      24             : #include <tools/rtti.hxx>
      25             : 
      26             : #include <boost/scoped_ptr.hpp>
      27             : 
      28             : #include <vector>
      29             : #include <limits>
      30             : 
      31             : 
      32             : 
      33       16535 : class SVL_DLLPUBLIC SfxRepeatTarget
      34             : {
      35             : public:
      36             :                         TYPEINFO();
      37             :     virtual             ~SfxRepeatTarget() = 0;
      38             : };
      39             : 
      40             : 
      41             : 
      42          62 : class SVL_DLLPUBLIC SfxUndoContext
      43             : {
      44             : public:
      45             :     virtual             ~SfxUndoContext() = 0;
      46             : };
      47             : 
      48             : 
      49             : class SfxLinkUndoAction;
      50             : 
      51             : class SVL_DLLPUBLIC SfxUndoAction
      52             : {
      53             : private:
      54             :     SfxLinkUndoAction*      mpSfxLinkUndoAction;
      55             : 
      56             : public:
      57             :                             TYPEINFO();
      58             :                             SfxUndoAction();
      59             :     virtual                 ~SfxUndoAction();
      60             : 
      61             :     virtual void SetLinkToSfxLinkUndoAction(SfxLinkUndoAction* pSfxLinkUndoAction);
      62             : 
      63             :     virtual void            Undo();
      64             :     virtual void            UndoWithContext( SfxUndoContext& i_context );
      65             :     virtual void            Redo();
      66             :     virtual void            RedoWithContext( SfxUndoContext& i_context );
      67             :     virtual void            Repeat(SfxRepeatTarget&);
      68             :     virtual bool            CanRepeat(SfxRepeatTarget&) const;
      69             : 
      70             :     virtual bool            Merge( SfxUndoAction *pNextAction );
      71             : 
      72             :     virtual OUString    GetComment() const;
      73             :     virtual OUString    GetRepeatComment(SfxRepeatTarget&) const;
      74             :     virtual sal_uInt16  GetId() const;
      75             : 
      76             : private:
      77             :     SfxUndoAction&          operator=( const SfxUndoAction& );    // n.i.!!
      78             : };
      79             : 
      80             : 
      81             : 
      82             : /// is a mark on the Undo stack
      83             : typedef sal_Int32 UndoStackMark;
      84             : #define MARK_INVALID    ::std::numeric_limits< UndoStackMark >::max()
      85             : 
      86             : 
      87             : 
      88     5661681 : struct MarkedUndoAction
      89             : {
      90             :     SfxUndoAction*                  pAction;
      91             :     ::std::vector< UndoStackMark >  aMarks;
      92             : 
      93      329315 :     MarkedUndoAction( SfxUndoAction* i_action )
      94             :         :pAction( i_action )
      95      329315 :         ,aMarks()
      96             :     {
      97      329315 :     }
      98             : };
      99             : 
     100      202918 : class SfxUndoActions
     101             : {
     102             : private:
     103             :     ::std::vector< MarkedUndoAction > m_aActions;
     104             : 
     105             : public:
     106      203679 :     SfxUndoActions()
     107      203679 :     {
     108      203679 :     }
     109             : 
     110     2459131 :     bool    empty() const { return m_aActions.empty(); }
     111      853719 :     size_t  size() const { return m_aActions.size(); }
     112             : 
     113         709 :     const MarkedUndoAction& operator[]( size_t i ) const { return m_aActions[i]; }
     114      547841 :           MarkedUndoAction& operator[]( size_t i )       { return m_aActions[i]; }
     115             : 
     116      328586 :     void    Remove( size_t i_pos )
     117             :     {
     118      328586 :         m_aActions.erase( m_aActions.begin() + i_pos );
     119      328586 :     }
     120             : 
     121           0 :     void    Remove( size_t i_pos, size_t i_count )
     122             :     {
     123           0 :         m_aActions.erase( m_aActions.begin() + i_pos, m_aActions.begin() + i_pos + i_count );
     124           0 :     }
     125             : 
     126      329315 :     void    Insert( SfxUndoAction* i_action, size_t i_pos )
     127             :     {
     128      329315 :         m_aActions.insert( m_aActions.begin() + i_pos, MarkedUndoAction( i_action ) );
     129      329315 :     }
     130             : };
     131             : 
     132             : 
     133             : 
     134             : /** do not make use of these implementation details, unless you
     135             :     really really have to! */
     136             : struct SVL_DLLPUBLIC SfxUndoArray
     137             : {
     138             :     SfxUndoActions          aUndoActions;
     139             :     size_t                  nMaxUndoActions;
     140             :     size_t                  nCurUndoAction;
     141             :     SfxUndoArray            *pFatherUndoArray;
     142      203679 :                             SfxUndoArray(size_t nMax=0):
     143             :                                 nMaxUndoActions(nMax), nCurUndoAction(0),
     144      203679 :                                 pFatherUndoArray(0) {}
     145             :     virtual ~SfxUndoArray();
     146             : };
     147             : 
     148             : 
     149             : 
     150             : /** do not make use of these implementation details, unless you
     151             :     really really have to! */
     152      322764 : class SVL_DLLPUBLIC SfxListUndoAction : public SfxUndoAction, public SfxUndoArray
     153             : 
     154             : /*  [Explanation]
     155             : 
     156             :     UndoAction to composite multiple Undos in one UndoAction.
     157             :     These actions are used by SfxUndomanager. With < SfxUndoManager::EnterListAction >
     158             :     you can go one composite level down and with < SfxUndoManager::LeaveListAction > up again.
     159             :     Redo and Undo work element wise on SfxListUndoActions.
     160             : */
     161             : {
     162             :     public:
     163             :                             TYPEINFO_OVERRIDE();
     164             : 
     165             :                             SfxListUndoAction( const OUString &rComment,
     166             :                                 const OUString& rRepeatComment, sal_uInt16 Id, SfxUndoArray *pFather);
     167             :     virtual void            Undo() SAL_OVERRIDE;
     168             :     virtual void            UndoWithContext( SfxUndoContext& i_context ) SAL_OVERRIDE;
     169             :     virtual void            Redo() SAL_OVERRIDE;
     170             :     virtual void            RedoWithContext( SfxUndoContext& i_context ) SAL_OVERRIDE;
     171             :     virtual void            Repeat(SfxRepeatTarget&) SAL_OVERRIDE;
     172             :     virtual bool            CanRepeat(SfxRepeatTarget&) const SAL_OVERRIDE;
     173             : 
     174             :     virtual bool            Merge( SfxUndoAction *pNextAction ) SAL_OVERRIDE;
     175             : 
     176             :     virtual OUString        GetComment() const SAL_OVERRIDE;
     177             :     virtual OUString        GetRepeatComment(SfxRepeatTarget&) const SAL_OVERRIDE;
     178             :     virtual sal_uInt16      GetId() const SAL_OVERRIDE;
     179             : 
     180             :     void SetComment(const OUString& rComment);
     181             : 
     182             :     private:
     183             : 
     184             :     sal_uInt16          nId;
     185             :     OUString            aComment;
     186             :     OUString            aRepeatComment;
     187             : 
     188             : };
     189             : 
     190             : 
     191             : 
     192             : /**  is a callback interface for notifications about state changes of an SfxUndoManager
     193             : */
     194         840 : class SAL_NO_VTABLE SfxUndoListener
     195             : {
     196             : public:
     197             :     virtual void actionUndone( const OUString& i_actionComment ) = 0;
     198             :     virtual void actionRedone( const OUString& i_actionComment ) = 0;
     199             :     virtual void undoActionAdded( const OUString& i_actionComment ) = 0;
     200             :     virtual void cleared() = 0;
     201             :     virtual void clearedRedo() = 0;
     202             :     virtual void resetAll() = 0;
     203             :     virtual void listActionEntered( const OUString& i_comment ) = 0;
     204             :     virtual void listActionLeft( const OUString& i_comment ) = 0;
     205             :     virtual void listActionLeftAndMerged() = 0;
     206             :     virtual void listActionCancelled() = 0;
     207             :     virtual void undoManagerDying() = 0;
     208             : 
     209             : protected:
     210         806 :     ~SfxUndoListener() {}
     211             : };
     212             : 
     213             : 
     214             : 
     215             : namespace svl
     216             : {
     217       41953 :     class SAL_NO_VTABLE IUndoManager
     218             :     {
     219             :     public:
     220             :         static bool const CurrentLevel = true;
     221             :         static bool const TopLevel = false;
     222             : 
     223       41536 :         virtual                 ~IUndoManager() { };
     224             : 
     225             :         virtual void            SetMaxUndoActionCount( size_t nMaxUndoActionCount ) = 0;
     226             :         virtual size_t          GetMaxUndoActionCount() const = 0;
     227             : 
     228             :         virtual void            AddUndoAction( SfxUndoAction *pAction, bool bTryMerg=false ) = 0;
     229             : 
     230             :         virtual size_t          GetUndoActionCount( bool const i_currentLevel = CurrentLevel ) const = 0;
     231             :         virtual sal_uInt16      GetUndoActionId() const = 0;
     232             :         virtual OUString        GetUndoActionComment( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const = 0;
     233             :         virtual SfxUndoAction*  GetUndoAction( size_t nNo=0 ) const = 0;
     234             : 
     235             :         virtual size_t          GetRedoActionCount( bool const i_currentLevel = CurrentLevel ) const = 0;
     236             :         virtual OUString        GetRedoActionComment( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const = 0;
     237             :         virtual SfxUndoAction*  GetRedoAction( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const = 0;
     238             : 
     239             :         virtual bool            Undo() = 0;
     240             :         virtual bool            Redo() = 0;
     241             : 
     242             :         /** clears both the Redo and the Undo stack.
     243             : 
     244             :             Will assert and bail out when called while within a list action (<member>IsInListAction</member>).
     245             :         */
     246             :         virtual void            Clear() = 0;
     247             : 
     248             :         /** clears the Redo stack.
     249             : 
     250             :             Will assert and bail out when called while within a list action (<member>IsInListAction</member>).
     251             :         */
     252             :         virtual void            ClearRedo() = 0;
     253             : 
     254             :         /** leaves any possible open list action (<member>IsInListAction</member>), and clears both the Undo and the
     255             :             Redo stack.
     256             : 
     257             :             Effectively, calling this method is equivalent to <code>while ( IsInListAction() ) LeaveListAction();</code>,
     258             :             followed by <code>Clear()</code>. The only difference to this calling sequence is that Reset is an
     259             :             atomic operation, also resulting in only one notification.
     260             :         */
     261             :         virtual void            Reset() = 0;
     262             : 
     263             :         /** determines whether an Undo or Redo is currently running
     264             :         */
     265             :         virtual bool            IsDoing() const = 0;
     266             : 
     267             :         virtual size_t          GetRepeatActionCount() const = 0;
     268             :         virtual OUString        GetRepeatActionComment( SfxRepeatTarget &rTarget) const = 0;
     269             :         virtual bool            Repeat( SfxRepeatTarget &rTarget ) = 0;
     270             :         virtual bool            CanRepeat( SfxRepeatTarget &rTarget ) const = 0;
     271             : 
     272             :         virtual void            EnterListAction(const OUString &rComment, const OUString& rRepeatComment, sal_uInt16 nId=0) = 0;
     273             : 
     274             :         /** leaves the list action entered with EnterListAction
     275             :             @return the number of the sub actions in the list which has just been left. Note that in case no such
     276             :                 actions exist, the list action does not contribute to the Undo stack, but is silently removed.
     277             :         */
     278             :         virtual size_t          LeaveListAction() = 0;
     279             : 
     280             :         /** leaves the list action entered with EnterListAction, and forcefully merges the previous
     281             :             action on the stack into the newly created list action.
     282             : 
     283             :             Say you have an Undo action A on the stack, then call EnterListAction, followed by one or more calls to
     284             :             AddUndoAction, followed by a call to LeaveAndMergeListAction. In opposite to LeaveListAction, your Undo
     285             :             stack will now still contain one undo action: the newly created list action, whose first child is the
     286             :             original A, whose other children are those you added via AddUndoAction, and whose comment is the same as
     287             :             the comment of A.
     288             : 
     289             :             Effectively, this means that all actions added between EnterListAction and LeaveAndMergeListAction are
     290             :             hidden from the user.
     291             : 
     292             :             @return the number of the sub actions in the list which has just been left. Note that in case no such
     293             :                 actions exist, the list action does not contribute to the Undo stack, but is silently removed.
     294             :         */
     295             :         virtual size_t          LeaveAndMergeListAction() = 0;
     296             : 
     297             :         /// determines whether we're within a ListAction context, i.e. a LeaveListAction/LeaveAndMergeListAction call is pending
     298             :         virtual bool            IsInListAction() const = 0;
     299             : 
     300             :         /// determines how many nested list actions are currently open
     301             :         virtual size_t          GetListActionDepth() const = 0;
     302             : 
     303             :         /** clears the redo stack and removes the top undo action */
     304             :         virtual void            RemoveLastUndoAction() = 0;
     305             : 
     306             :         /** enables (true) or disables (false) recording of undo actions
     307             : 
     308             :             If undo actions are added while undo is disabled, they are deleted.
     309             :             Disabling undo does not clear the current undo buffer!
     310             : 
     311             :             Multiple calls to <code>EnableUndo</code> are not cumulative. That is, calling <code>EnableUndo( false )</code>
     312             :             twice, and then calling <code>EnableUndo( true )</code> means that Undo is enable afterwards.
     313             :         */
     314             :         virtual void            EnableUndo( bool bEnable ) = 0;
     315             : 
     316             :         // returns true if undo is currently enabled
     317             :         // This returns false if undo was disabled using EnableUndo( false ) and
     318             :         // also during the runtime of the Undo() and Redo() methods.
     319             :         virtual bool            IsUndoEnabled() const = 0;
     320             : 
     321             :         /// adds a new listener to be notified about changes in the UndoManager's state
     322             :         virtual void            AddUndoListener( SfxUndoListener& i_listener ) = 0;
     323             :         virtual void            RemoveUndoListener( SfxUndoListener& i_listener ) = 0;
     324             :    };
     325             : }
     326             : 
     327             : 
     328             : 
     329             : namespace svl { namespace undo { namespace impl
     330             : {
     331             :     class UndoManagerGuard;
     332             :     class LockGuard;
     333             : } } }
     334             : 
     335             : struct SfxUndoManager_Data;
     336             : class SVL_DLLPUBLIC SfxUndoManager : public ::svl::IUndoManager
     337             : {
     338             :     friend class SfxLinkUndoAction;
     339             : 
     340             :     ::boost::scoped_ptr< SfxUndoManager_Data >
     341             :                             m_pData;
     342             : public:
     343             :                             SfxUndoManager( size_t nMaxUndoActionCount = 20 );
     344             :     virtual                 ~SfxUndoManager();
     345             : 
     346             :     // IUndoManager overridables
     347             :     virtual void            SetMaxUndoActionCount( size_t nMaxUndoActionCount ) SAL_OVERRIDE;
     348             :     virtual size_t          GetMaxUndoActionCount() const SAL_OVERRIDE;
     349             :     virtual void            AddUndoAction( SfxUndoAction *pAction, bool bTryMerg=false ) SAL_OVERRIDE;
     350             :     virtual size_t          GetUndoActionCount( bool const i_currentLevel = CurrentLevel ) const SAL_OVERRIDE;
     351             :     virtual sal_uInt16      GetUndoActionId() const SAL_OVERRIDE;
     352             :     virtual OUString        GetUndoActionComment( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const SAL_OVERRIDE;
     353             :     virtual SfxUndoAction*  GetUndoAction( size_t nNo=0 ) const SAL_OVERRIDE;
     354             :     virtual size_t          GetRedoActionCount( bool const i_currentLevel = CurrentLevel ) const SAL_OVERRIDE;
     355             :     virtual OUString        GetRedoActionComment( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const SAL_OVERRIDE;
     356             :     virtual SfxUndoAction*  GetRedoAction( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const SAL_OVERRIDE;
     357             :     virtual bool            Undo() SAL_OVERRIDE;
     358             :     virtual bool            Redo() SAL_OVERRIDE;
     359             :     virtual void            Clear() SAL_OVERRIDE;
     360             :     virtual void            ClearRedo() SAL_OVERRIDE;
     361             :     virtual void            Reset() SAL_OVERRIDE;
     362             :     virtual bool            IsDoing() const SAL_OVERRIDE;
     363             :     virtual size_t          GetRepeatActionCount() const SAL_OVERRIDE;
     364             :     virtual OUString        GetRepeatActionComment( SfxRepeatTarget &rTarget) const SAL_OVERRIDE;
     365             :     virtual bool            Repeat( SfxRepeatTarget &rTarget ) SAL_OVERRIDE;
     366             :     virtual bool            CanRepeat( SfxRepeatTarget &rTarget ) const SAL_OVERRIDE;
     367             :     virtual void            EnterListAction(const OUString &rComment, const OUString& rRepeatComment, sal_uInt16 nId=0) SAL_OVERRIDE;
     368             :     virtual size_t          LeaveListAction() SAL_OVERRIDE;
     369             :     virtual size_t          LeaveAndMergeListAction() SAL_OVERRIDE;
     370             :     virtual bool            IsInListAction() const SAL_OVERRIDE;
     371             :     virtual size_t          GetListActionDepth() const SAL_OVERRIDE;
     372             :     virtual void            RemoveLastUndoAction() SAL_OVERRIDE;
     373             :     virtual void            EnableUndo( bool bEnable ) SAL_OVERRIDE;
     374             :     virtual bool            IsUndoEnabled() const SAL_OVERRIDE;
     375             :     virtual void            AddUndoListener( SfxUndoListener& i_listener ) SAL_OVERRIDE;
     376             :     virtual void            RemoveUndoListener( SfxUndoListener& i_listener ) SAL_OVERRIDE;
     377             : 
     378             :     /** marks the current top-level element of the Undo stack, and returns a unique ID for it
     379             :     */
     380             :     UndoStackMark   MarkTopUndoAction();
     381             : 
     382             :     /** removes a mark given by its ID.
     383             :         After the call, the mark ID is invalid.
     384             :     */
     385             :     void            RemoveMark( UndoStackMark const i_mark );
     386             : 
     387             :     /** determines whether the top action on the Undo stack has a given mark
     388             :     */
     389             :     bool            HasTopUndoActionMark( UndoStackMark const i_mark );
     390             : 
     391             :     /** removes the oldest Undo actions from the stack
     392             :     */
     393             :     void            RemoveOldestUndoActions( size_t const i_count );
     394             : 
     395             : protected:
     396             :     bool    UndoWithContext( SfxUndoContext& i_context );
     397             :     bool    RedoWithContext( SfxUndoContext& i_context );
     398             : 
     399             :     void    ImplClearRedo_NoLock( bool const i_currentLevel );
     400             : 
     401             :     /** clears all undo actions on the current level, plus all undo actions on superordinate levels,
     402             :         as soon as those levels are reached.
     403             : 
     404             :         If no list action is active currently, i.e. we're on the top level already, this method is equivalent to
     405             :         ->Clear.
     406             : 
     407             :         Otherwise, the Undo actions on the current level are removed. Upon leaving the current list action, all
     408             :         undo actions on the then-current level are removed, too. This is continued until the top level is reached.
     409             :     */
     410             :     void    ClearAllLevels();
     411             : 
     412             : private:
     413             :     size_t  ImplLeaveListAction( const bool i_merge, ::svl::undo::impl::UndoManagerGuard& i_guard );
     414             :     bool    ImplAddUndoAction_NoNotify( SfxUndoAction* pAction, bool bTryMerge, bool bClearRedo, ::svl::undo::impl::UndoManagerGuard& i_guard );
     415             :     void    ImplClearRedo( ::svl::undo::impl::UndoManagerGuard& i_guard, bool const i_currentLevel );
     416             :     void    ImplClearUndo( ::svl::undo::impl::UndoManagerGuard& i_guard );
     417             :     void    ImplClearCurrentLevel_NoNotify( ::svl::undo::impl::UndoManagerGuard& i_guard );
     418             :     size_t  ImplGetRedoActionCount_Lock( bool const i_currentLevel = CurrentLevel ) const;
     419             :     bool    ImplIsUndoEnabled_Lock() const;
     420             :     bool    ImplIsInListAction_Lock() const;
     421             :     void    ImplEnableUndo_Lock( bool const i_enable );
     422             : 
     423             :     bool ImplUndo( SfxUndoContext* i_contextOrNull );
     424             :     bool ImplRedo( SfxUndoContext* i_contextOrNull );
     425             : 
     426             :     friend class ::svl::undo::impl::LockGuard;
     427             : };
     428             : 
     429             : 
     430             : 
     431             : class SVL_DLLPUBLIC SfxLinkUndoAction : public SfxUndoAction
     432             : 
     433             : /*  [Explanation]
     434             : 
     435             :     SfxLinkUndoAction is used to link two SfxUndoManager. The Undo/Redos inserted
     436             :     in the first SfxUndoManager redict their Undo/Redo to the second. With this it
     437             :     does not matter, if the undo/redo initially was on the first or the second.
     438             : 
     439             :     After inserting SfxLinkUndoAction on the first SfxUndoManager, you have to
     440             :     insert it on the second as well. While the second SfxUndoManager is steered
     441             :     from the first, you must not insert neither Actions nor issue a  undo/redo
     442             :     command to the second, while it is steered by the first.
     443             : */
     444             : 
     445             : {
     446             : private:
     447             :     friend class SfxUndoAction;
     448             :     void LinkedSfxUndoActionDestructed(const SfxUndoAction& rCandidate);
     449             : 
     450             : public:
     451             :                             TYPEINFO_OVERRIDE();
     452             :                             SfxLinkUndoAction(::svl::IUndoManager *pManager);
     453             :                             virtual ~SfxLinkUndoAction();
     454             : 
     455             :     virtual void            Undo() SAL_OVERRIDE;
     456             :     virtual void            Redo() SAL_OVERRIDE;
     457             :     virtual bool            CanRepeat(SfxRepeatTarget& r) const SAL_OVERRIDE;
     458             : 
     459             :     virtual void            Repeat(SfxRepeatTarget&r) SAL_OVERRIDE;
     460             : 
     461             :     virtual OUString        GetComment() const SAL_OVERRIDE;
     462             :     virtual OUString        GetRepeatComment(SfxRepeatTarget&r) const SAL_OVERRIDE;
     463             :     virtual sal_uInt16      GetId() const SAL_OVERRIDE;
     464             : 
     465           0 :     SfxUndoAction*          GetAction() const { return pAction; }
     466             : 
     467             : protected:
     468             :     ::svl::IUndoManager*    pUndoManager;
     469             :     SfxUndoAction*          pAction;
     470             : 
     471             : };
     472             : 
     473             : #endif
     474             : 
     475             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10