LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/include/svl - undo.hxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 26 31 83.9 %
Date: 2013-07-09 Functions: 20 24 83.3 %
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 _UNDO_HXX
      20             : #define _UNDO_HXX
      21             : 
      22             : #include "svl/svldllapi.h"
      23             : #include <tools/rtti.hxx>
      24             : #include <tools/string.hxx>
      25             : 
      26             : #include <boost/scoped_ptr.hpp>
      27             : 
      28             : #include <vector>
      29             : #include <limits>
      30             : 
      31             : //====================================================================
      32             : 
      33        3152 : class SVL_DLLPUBLIC SfxRepeatTarget
      34             : {
      35             : public:
      36             :                         TYPEINFO();
      37             :     virtual             ~SfxRepeatTarget() = 0;
      38             : };
      39             : 
      40             : //====================================================================
      41             : 
      42          26 : 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     1467689 : struct MarkedUndoAction
      89             : {
      90             :     SfxUndoAction*                  pAction;
      91             :     ::std::vector< UndoStackMark >  aMarks;
      92             : 
      93      139537 :     MarkedUndoAction( SfxUndoAction* i_action )
      94             :         :pAction( i_action )
      95      139537 :         ,aMarks()
      96             :     {
      97      139537 :     }
      98             : };
      99             : 
     100       92410 : class SfxUndoActions
     101             : {
     102             : private:
     103             :     ::std::vector< MarkedUndoAction > m_aActions;
     104             : 
     105             : public:
     106       92530 :     SfxUndoActions()
     107       92530 :     {
     108       92530 :     }
     109             : 
     110     2443123 :     bool    empty() const { return m_aActions.empty(); }
     111      345325 :     size_t  size() const { return m_aActions.size(); }
     112             : 
     113         418 :     const MarkedUndoAction& operator[]( size_t i ) const { return m_aActions[i]; }
     114      218232 :           MarkedUndoAction& operator[]( size_t i )       { return m_aActions[i]; }
     115             : 
     116      139441 :     void    Remove( size_t i_pos )
     117             :     {
     118      139441 :         m_aActions.erase( m_aActions.begin() + i_pos );
     119      139441 :     }
     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      139537 :     void    Insert( SfxUndoAction* i_action, size_t i_pos )
     127             :     {
     128      139537 :         m_aActions.insert( m_aActions.begin() + i_pos, MarkedUndoAction( i_action ) );
     129      139537 :     }
     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       92530 :                             SfxUndoArray(size_t nMax=0):
     143             :                                 nMaxUndoActions(nMax), nCurUndoAction(0),
     144       92530 :                                 pFatherUndoArray(0) {}
     145             :                            ~SfxUndoArray();
     146             : };
     147             : 
     148             : //=========================================================================
     149             : 
     150             : /** do not make use of these implementation details, unless you
     151             :     really really have to! */
     152      154938 : class SVL_DLLPUBLIC SfxListUndoAction : public SfxUndoAction, public SfxUndoArray
     153             : 
     154             : /*  [Beschreibung]
     155             : 
     156             :     UndoAction zur Klammerung mehrerer Undos in einer UndoAction.
     157             :     Diese Actions werden vom SfxUndoManager verwendet. Dort
     158             :     wird mit < SfxUndoManager::EnterListAction > eine Klammerebene
     159             :     geoeffnet und mit <SfxUndoManager::LeaveListAction > wieder
     160             :     geschlossen. Redo und Undo auf SfxListUndoActions wirken
     161             :     Elementweise.
     162             : 
     163             : */
     164             : {
     165             :     public:
     166             :                             TYPEINFO();
     167             : 
     168             :                             SfxListUndoAction( const OUString &rComment,
     169             :                                 const OUString rRepeatComment, sal_uInt16 Id, SfxUndoArray *pFather);
     170             :     virtual void            Undo();
     171             :     virtual void            UndoWithContext( SfxUndoContext& i_context );
     172             :     virtual void            Redo();
     173             :     virtual void            RedoWithContext( SfxUndoContext& i_context );
     174             :     virtual void            Repeat(SfxRepeatTarget&);
     175             :     virtual bool            CanRepeat(SfxRepeatTarget&) const;
     176             : 
     177             :     virtual bool            Merge( SfxUndoAction *pNextAction );
     178             : 
     179             :     virtual OUString        GetComment() const;
     180             :     virtual OUString        GetRepeatComment(SfxRepeatTarget&) const;
     181             :     virtual sal_uInt16      GetId() const;
     182             : 
     183             :     void SetComment(const OUString& rComment);
     184             : 
     185             :     private:
     186             : 
     187             :     sal_uInt16          nId;
     188             :     OUString            aComment;
     189             :     OUString            aRepeatComment;
     190             : 
     191             : };
     192             : 
     193             : //=========================================================================
     194             : 
     195             : /**  is a callback interface for notifications about state changes of an SfxUndoManager
     196             : */
     197          49 : class SAL_NO_VTABLE SfxUndoListener
     198             : {
     199             : public:
     200             :     virtual void actionUndone( const OUString& i_actionComment ) = 0;
     201             :     virtual void actionRedone( const OUString& i_actionComment ) = 0;
     202             :     virtual void undoActionAdded( const OUString& i_actionComment ) = 0;
     203             :     virtual void cleared() = 0;
     204             :     virtual void clearedRedo() = 0;
     205             :     virtual void resetAll() = 0;
     206             :     virtual void listActionEntered( const OUString& i_comment ) = 0;
     207             :     virtual void listActionLeft( const OUString& i_comment ) = 0;
     208             :     virtual void listActionLeftAndMerged() = 0;
     209             :     virtual void listActionCancelled() = 0;
     210             :     virtual void undoManagerDying() = 0;
     211             : 
     212             : protected:
     213           0 :     ~SfxUndoListener() {}
     214             : };
     215             : 
     216             : //=========================================================================
     217             : 
     218             : namespace svl
     219             : {
     220       15023 :     class SAL_NO_VTABLE IUndoManager
     221             :     {
     222             :     public:
     223             :         enum
     224             :         {
     225             :             CurrentLevel = true,
     226             :             TopLevel = false
     227             :         };
     228             : 
     229       14941 :         virtual                 ~IUndoManager() { };
     230             : 
     231             :         virtual void            SetMaxUndoActionCount( size_t nMaxUndoActionCount ) = 0;
     232             :         virtual size_t          GetMaxUndoActionCount() const = 0;
     233             : 
     234             :         virtual void            AddUndoAction( SfxUndoAction *pAction, bool bTryMerg=false ) = 0;
     235             : 
     236             :         virtual size_t          GetUndoActionCount( bool const i_currentLevel = CurrentLevel ) const = 0;
     237             :         virtual sal_uInt16      GetUndoActionId() const = 0;
     238             :         virtual OUString        GetUndoActionComment( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const = 0;
     239             :         virtual SfxUndoAction*  GetUndoAction( size_t nNo=0 ) const = 0;
     240             : 
     241             :         virtual size_t          GetRedoActionCount( bool const i_currentLevel = CurrentLevel ) const = 0;
     242             :         virtual OUString        GetRedoActionComment( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const = 0;
     243             :         virtual SfxUndoAction*  GetRedoAction( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const = 0;
     244             : 
     245             :         virtual bool            Undo() = 0;
     246             :         virtual bool            Redo() = 0;
     247             : 
     248             :         /** clears both the Redo and the Undo stack.
     249             : 
     250             :             Will assert and bail out when called while within a list action (<member>IsInListAction</member>).
     251             :         */
     252             :         virtual void            Clear() = 0;
     253             : 
     254             :         /** clears the Redo stack.
     255             : 
     256             :             Will assert and bail out when called while within a list action (<member>IsInListAction</member>).
     257             :         */
     258             :         virtual void            ClearRedo() = 0;
     259             : 
     260             :         /** leaves any possible open list action (<member>IsInListAction</member>), and clears both the Undo and the
     261             :             Redo stack.
     262             : 
     263             :             Effectively, calling this method is equivalent to <code>while ( IsInListAction() ) LeaveListAction();</code>,
     264             :             followed by <code>Clear()</code>. The only difference to this calling sequence is that Reset is an
     265             :             atomic operation, also resulting in only one notification.
     266             :         */
     267             :         virtual void            Reset() = 0;
     268             : 
     269             :         /** determines whether an Undo or Redo is currently running
     270             :         */
     271             :         virtual bool            IsDoing() const = 0;
     272             : 
     273             :         virtual size_t          GetRepeatActionCount() const = 0;
     274             :         virtual OUString        GetRepeatActionComment( SfxRepeatTarget &rTarget) const = 0;
     275             :         virtual bool            Repeat( SfxRepeatTarget &rTarget ) = 0;
     276             :         virtual bool            CanRepeat( SfxRepeatTarget &rTarget ) const = 0;
     277             : 
     278             :         virtual void            EnterListAction(const OUString &rComment, const OUString& rRepeatComment, sal_uInt16 nId=0) = 0;
     279             : 
     280             :         /** leaves the list action entered with EnterListAction
     281             :             @return the number of the sub actions in the list which has just been left. Note that in case no such
     282             :                 actions exist, the list action does not contribute to the Undo stack, but is silently removed.
     283             :         */
     284             :         virtual size_t          LeaveListAction() = 0;
     285             : 
     286             :         /** leaves the list action entered with EnterListAction, and forcefully merges the previous
     287             :             action on the stack into the newly created list action.
     288             : 
     289             :             Say you have an Undo action A on the stack, then call EnterListAction, followed by one or more calls to
     290             :             AddUndoAction, followed by a call to LeaveAndMergeListAction. In opposite to LeaveListAction, your Undo
     291             :             stack will now still contain one undo action: the newly created list action, whose first child is the
     292             :             original A, whose other children are those you added via AddUndoAction, and whose comment is the same as
     293             :             the comment of A.
     294             : 
     295             :             Effectively, this means that all actions added between EnterListAction and LeaveAndMergeListAction are
     296             :             hidden from the user.
     297             : 
     298             :             @return the number of the sub actions in the list which has just been left. Note that in case no such
     299             :                 actions exist, the list action does not contribute to the Undo stack, but is silently removed.
     300             :         */
     301             :         virtual size_t          LeaveAndMergeListAction() = 0;
     302             : 
     303             :         /// determines whether we're within a ListAction context, i.e. a LeaveListAction/LeaveAndMergeListAction call is pending
     304             :         virtual bool            IsInListAction() const = 0;
     305             : 
     306             :         /// determines how many nested list actions are currently open
     307             :         virtual size_t          GetListActionDepth() const = 0;
     308             : 
     309             :         /** clears the redo stack and removes the top undo action */
     310             :         virtual void            RemoveLastUndoAction() = 0;
     311             : 
     312             :         /** enables (true) or disables (false) recording of undo actions
     313             : 
     314             :             If undo actions are added while undo is disabled, they are deleted.
     315             :             Disabling undo does not clear the current undo buffer!
     316             : 
     317             :             Multiple calls to <code>EnableUndo</code> are not cumulative. That is, calling <code>EnableUndo( false )</code>
     318             :             twice, and then calling <code>EnableUndo( true )</code> means that Undo is enable afterwards.
     319             :         */
     320             :         virtual void            EnableUndo( bool bEnable ) = 0;
     321             : 
     322             :         // returns true if undo is currently enabled
     323             :         // This returns false if undo was disabled using EnableUndo( false ) and
     324             :         // also during the runtime of the Undo() and Redo() methods.
     325             :         virtual bool            IsUndoEnabled() const = 0;
     326             : 
     327             :         /// adds a new listener to be notified about changes in the UndoManager's state
     328             :         virtual void            AddUndoListener( SfxUndoListener& i_listener ) = 0;
     329             :         virtual void            RemoveUndoListener( SfxUndoListener& i_listener ) = 0;
     330             :    };
     331             : }
     332             : 
     333             : //=========================================================================
     334             : 
     335             : namespace svl { namespace undo { namespace impl
     336             : {
     337             :     class UndoManagerGuard;
     338             :     class LockGuard;
     339             : } } }
     340             : 
     341             : struct SfxUndoManager_Data;
     342             : class SVL_DLLPUBLIC SfxUndoManager : public ::svl::IUndoManager
     343             : {
     344             :     friend class SfxLinkUndoAction;
     345             : 
     346             :     ::boost::scoped_ptr< SfxUndoManager_Data >
     347             :                             m_pData;
     348             : public:
     349             :                             SfxUndoManager( size_t nMaxUndoActionCount = 20 );
     350             :     virtual                 ~SfxUndoManager();
     351             : 
     352             :     // IUndoManager overridables
     353             :     virtual void            SetMaxUndoActionCount( size_t nMaxUndoActionCount );
     354             :     virtual size_t          GetMaxUndoActionCount() const;
     355             :     virtual void            AddUndoAction( SfxUndoAction *pAction, bool bTryMerg=false );
     356             :     virtual size_t          GetUndoActionCount( bool const i_currentLevel = CurrentLevel ) const;
     357             :     virtual sal_uInt16      GetUndoActionId() const;
     358             :     virtual OUString        GetUndoActionComment( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const;
     359             :     virtual SfxUndoAction*  GetUndoAction( size_t nNo=0 ) const;
     360             :     virtual size_t          GetRedoActionCount( bool const i_currentLevel = CurrentLevel ) const;
     361             :     virtual OUString        GetRedoActionComment( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const;
     362             :     virtual SfxUndoAction*  GetRedoAction( size_t nNo=0, bool const i_currentLevel = CurrentLevel ) const;
     363             :     virtual bool            Undo();
     364             :     virtual bool            Redo();
     365             :     virtual void            Clear();
     366             :     virtual void            ClearRedo();
     367             :     virtual void            Reset();
     368             :     virtual bool            IsDoing() const;
     369             :     virtual size_t          GetRepeatActionCount() const;
     370             :     virtual OUString        GetRepeatActionComment( SfxRepeatTarget &rTarget) const;
     371             :     virtual bool            Repeat( SfxRepeatTarget &rTarget );
     372             :     virtual bool            CanRepeat( SfxRepeatTarget &rTarget ) const;
     373             :     virtual void            EnterListAction(const OUString &rComment, const OUString& rRepeatComment, sal_uInt16 nId=0);
     374             :     virtual size_t          LeaveListAction();
     375             :     virtual size_t          LeaveAndMergeListAction();
     376             :     virtual bool            IsInListAction() const;
     377             :     virtual size_t          GetListActionDepth() const;
     378             :     virtual void            RemoveLastUndoAction();
     379             :     virtual void            EnableUndo( bool bEnable );
     380             :     virtual bool            IsUndoEnabled() const;
     381             :     virtual void            AddUndoListener( SfxUndoListener& i_listener );
     382             :     virtual void            RemoveUndoListener( SfxUndoListener& i_listener );
     383             : 
     384             :     /** marks the current top-level element of the Undo stack, and returns a unique ID for it
     385             :     */
     386             :     UndoStackMark   MarkTopUndoAction();
     387             : 
     388             :     /** removes a mark given by its ID.
     389             :         After the call, the mark ID is invalid.
     390             :     */
     391             :     void            RemoveMark( UndoStackMark const i_mark );
     392             : 
     393             :     /** determines whether the top action on the Undo stack has a given mark
     394             :     */
     395             :     bool            HasTopUndoActionMark( UndoStackMark const i_mark );
     396             : 
     397             :     /** removes the oldest Undo actions from the stack
     398             :     */
     399             :     void            RemoveOldestUndoActions( size_t const i_count );
     400             : 
     401             : protected:
     402             :     bool    UndoWithContext( SfxUndoContext& i_context );
     403             :     bool    RedoWithContext( SfxUndoContext& i_context );
     404             : 
     405             :     void    ImplClearRedo_NoLock( bool const i_currentLevel );
     406             : 
     407             :     /** clears all undo actions on the current level, plus all undo actions on superordinate levels,
     408             :         as soon as those levels are reached.
     409             : 
     410             :         If no list action is active currently, i.e. we're on the top level already, this method is equivalent to
     411             :         ->Clear.
     412             : 
     413             :         Otherwise, the Undo actions on the current level are removed. Upon leaving the current list action, all
     414             :         undo actions on the then-current level are removed, too. This is continued until the top level is reached.
     415             :     */
     416             :     void    ClearAllLevels();
     417             : 
     418             : private:
     419             :     size_t  ImplLeaveListAction( const bool i_merge, ::svl::undo::impl::UndoManagerGuard& i_guard );
     420             :     bool    ImplAddUndoAction_NoNotify( SfxUndoAction* pAction, bool bTryMerge, bool bClearRedo, ::svl::undo::impl::UndoManagerGuard& i_guard );
     421             :     void    ImplClearRedo( ::svl::undo::impl::UndoManagerGuard& i_guard, bool const i_currentLevel );
     422             :     void    ImplClearUndo( ::svl::undo::impl::UndoManagerGuard& i_guard );
     423             :     void    ImplClearCurrentLevel_NoNotify( ::svl::undo::impl::UndoManagerGuard& i_guard );
     424             :     size_t  ImplGetRedoActionCount_Lock( bool const i_currentLevel = CurrentLevel ) const;
     425             :     bool    ImplIsUndoEnabled_Lock() const;
     426             :     bool    ImplIsInListAction_Lock() const;
     427             :     void    ImplEnableUndo_Lock( bool const i_enable );
     428             : 
     429             :     bool ImplUndo( SfxUndoContext* i_contextOrNull );
     430             :     bool ImplRedo( SfxUndoContext* i_contextOrNull );
     431             : 
     432             :     friend class ::svl::undo::impl::LockGuard;
     433             : };
     434             : 
     435             : //=========================================================================
     436             : 
     437             : class SVL_DLLPUBLIC SfxLinkUndoAction : public SfxUndoAction
     438             : 
     439             : /*  [Beschreibung]
     440             : 
     441             :     Die SfxLinkUndoAction dient zur Verbindung zweier SfxUndoManager. Die
     442             :     im ersten SfxUndoManager eingefuegten SfxUndoAction leiten ihr Undo und Redo
     443             :     an den zweiten weiter, so dass ein Undo und Redo am ersten
     444             :     SfxUndoManager wie eine am zweiten wirkt.
     445             : 
     446             :     Die SfxLinkUndoAction ist nach dem Einfuegen der SfxUndoAction am
     447             :     zweiten SfxUndoManager einzufuegen. Waehrend der zweite SfxUndoManager
     448             :     vom ersten ferngesteuert wird, duerfen an ihm weder Actions eingefuegt werden,
     449             :     noch darf Undo/Redo aufgerufen werden.
     450             : 
     451             : */
     452             : 
     453             : {
     454             : private:
     455             :     friend class SfxUndoAction;
     456             :     void LinkedSfxUndoActionDestructed(const SfxUndoAction& rCandidate);
     457             : 
     458             : public:
     459             :                             TYPEINFO();
     460             :                             SfxLinkUndoAction(::svl::IUndoManager *pManager);
     461             :                             ~SfxLinkUndoAction();
     462             : 
     463             :     virtual void            Undo();
     464             :     virtual void            Redo();
     465             :     virtual bool            CanRepeat(SfxRepeatTarget& r) const;
     466             : 
     467             :     virtual void            Repeat(SfxRepeatTarget&r);
     468             : 
     469             :     virtual OUString        GetComment() const;
     470             :     virtual OUString        GetRepeatComment(SfxRepeatTarget&r) const;
     471             :     virtual sal_uInt16      GetId() const;
     472             : 
     473           0 :     SfxUndoAction*          GetAction() const { return pAction; }
     474             : 
     475             : protected:
     476             :     ::svl::IUndoManager*    pUndoManager;
     477             :     SfxUndoAction*          pAction;
     478             : 
     479             : };
     480             : 
     481             : #endif
     482             : 
     483             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10