LCOV - code coverage report
Current view: top level - libreoffice/svl/inc/svl - undo.hxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 22 26 84.6 %
Date: 2012-12-27 Functions: 16 19 84.2 %
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             : class SVL_DLLPUBLIC SfxRepeatTarget
      34             : {
      35             : public:
      36             :                         TYPEINFO();
      37             :     virtual             ~SfxRepeatTarget() = 0;
      38             : };
      39             : 
      40             : //====================================================================
      41             : 
      42             : class SVL_DLLPUBLIC SfxUndoContext
      43             : {
      44             : public:
      45             :     virtual             ~SfxUndoContext() = 0;
      46             : };
      47             : 
      48             : //====================================================================
      49             : 
      50             : class SVL_DLLPUBLIC SfxUndoAction
      51             : {
      52             :     sal_Bool bLinked;
      53             : public:
      54             :                             TYPEINFO();
      55             :                             SfxUndoAction();
      56             :     virtual                 ~SfxUndoAction();
      57             : 
      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;
      66             : 
      67             :     virtual sal_Bool            Merge( SfxUndoAction *pNextAction );
      68             : 
      69             :     virtual OUString    GetComment() const;
      70             :     virtual OUString    GetRepeatComment(SfxRepeatTarget&) const;
      71             :     virtual sal_uInt16  GetId() const;
      72             : 
      73             : private:
      74             :     SfxUndoAction&          operator=( const SfxUndoAction& );    // n.i.!!
      75             : };
      76             : 
      77             : //========================================================================
      78             : 
      79             : /// is a mark on the Undo stack
      80             : typedef sal_Int32 UndoStackMark;
      81             : #define MARK_INVALID    ::std::numeric_limits< UndoStackMark >::max()
      82             : 
      83             : //========================================================================
      84             : 
      85      220997 : struct MarkedUndoAction
      86             : {
      87             :     SfxUndoAction*                  pAction;
      88             :     ::std::vector< UndoStackMark >  aMarks;
      89             : 
      90       67541 :     MarkedUndoAction( SfxUndoAction* i_action )
      91             :         :pAction( i_action )
      92       67541 :         ,aMarks()
      93             :     {
      94       67541 :     }
      95             : };
      96             : 
      97       45798 : class SfxUndoActions
      98             : {
      99             : private:
     100             :     ::std::vector< MarkedUndoAction > m_aActions;
     101             : 
     102             : public:
     103       46417 :     SfxUndoActions()
     104       46417 :     {
     105       46417 :     }
     106             : 
     107      196522 :     bool    empty() const { return m_aActions.empty(); }
     108      158389 :     size_t  size() const { return m_aActions.size(); }
     109             : 
     110           0 :     const MarkedUndoAction& operator[]( size_t i ) const { return m_aActions[i]; }
     111       95991 :           MarkedUndoAction& operator[]( size_t i )       { return m_aActions[i]; }
     112             : 
     113       67456 :     void    Remove( size_t i_pos )
     114             :     {
     115       67456 :         m_aActions.erase( m_aActions.begin() + i_pos );
     116       67456 :     }
     117             : 
     118           0 :     void    Remove( size_t i_pos, size_t i_count )
     119             :     {
     120           0 :         m_aActions.erase( m_aActions.begin() + i_pos, m_aActions.begin() + i_pos + i_count );
     121           0 :     }
     122             : 
     123       67541 :     void    Insert( SfxUndoAction* i_action, size_t i_pos )
     124             :     {
     125       67541 :         m_aActions.insert( m_aActions.begin() + i_pos, MarkedUndoAction( i_action ) );
     126       67541 :     }
     127             : };
     128             : 
     129             : //====================================================================
     130             : 
     131             : /** do not make use of these implementation details, unless you
     132             :     really really have to! */
     133             : struct SVL_DLLPUBLIC SfxUndoArray
     134             : {
     135             :     SfxUndoActions          aUndoActions;
     136             :     size_t                  nMaxUndoActions;
     137             :     size_t                  nCurUndoAction;
     138             :     SfxUndoArray            *pFatherUndoArray;
     139       46417 :                             SfxUndoArray(size_t nMax=0):
     140             :                                 nMaxUndoActions(nMax), nCurUndoAction(0),
     141       46417 :                                 pFatherUndoArray(0) {}
     142             :                            ~SfxUndoArray();
     143             : };
     144             : 
     145             : //=========================================================================
     146             : 
     147             : /** do not make use of these implementation details, unless you
     148             :     really really have to! */
     149       85380 : class SVL_DLLPUBLIC SfxListUndoAction : public SfxUndoAction, public SfxUndoArray
     150             : 
     151             : /*  [Beschreibung]
     152             : 
     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.
     159             : 
     160             : */
     161             : {
     162             :     public:
     163             :                             TYPEINFO();
     164             : 
     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;
     173             : 
     174             :     virtual sal_Bool            Merge( SfxUndoAction *pNextAction );
     175             : 
     176             :     virtual OUString    GetComment() const;
     177             :     virtual OUString    GetRepeatComment(SfxRepeatTarget&) const;
     178             :     virtual sal_uInt16  GetId() const;
     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             : class SAL_NO_VTABLE SfxUndoListener
     195             : {
     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;
     208             : 
     209             : protected:
     210             :     ~SfxUndoListener() {}
     211             : };
     212             : 
     213             : //=========================================================================
     214             : 
     215             : namespace svl
     216             : {
     217        3692 :     class SAL_NO_VTABLE IUndoManager
     218             :     {
     219             :     public:
     220             :         enum
     221             :         {
     222             :             CurrentLevel = true,
     223             :             TopLevel = false
     224             :         };
     225             : 
     226        3108 :         virtual                 ~IUndoManager() { };
     227             : 
     228             :         virtual void            SetMaxUndoActionCount( size_t nMaxUndoActionCount ) = 0;
     229             :         virtual size_t          GetMaxUndoActionCount() const = 0;
     230             : 
     231             :         virtual void            AddUndoAction( SfxUndoAction *pAction, sal_Bool bTryMerg=sal_False ) = 0;
     232             : 
     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;
     237             : 
     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;
     240             : 
     241             :         virtual sal_Bool        Undo() = 0;
     242             :         virtual sal_Bool        Redo() = 0;
     243             : 
     244             :         /** clears both the Redo and the Undo stack.
     245             : 
     246             :             Will assert and bail out when called while within a list action (<member>IsInListAction</member>).
     247             :         */
     248             :         virtual void            Clear() = 0;
     249             : 
     250             :         /** clears the Redo stack.
     251             : 
     252             :             Will assert and bail out when called while within a list action (<member>IsInListAction</member>).
     253             :         */
     254             :         virtual void            ClearRedo() = 0;
     255             : 
     256             :         /** leaves any possible open list action (<member>IsInListAction</member>), and clears both the Undo and the
     257             :             Redo stack.
     258             : 
     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             :             atomar operation, also resulting in only one notification.
     262             :         */
     263             :         virtual void            Reset() = 0;
     264             : 
     265             :         /** determines whether an Undo or Redo is currently running
     266             :         */
     267             :         virtual bool            IsDoing() const = 0;
     268             : 
     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;
     273             : 
     274             :         virtual void            EnterListAction(const OUString &rComment, const OUString& rRepeatComment, sal_uInt16 nId=0) = 0;
     275             : 
     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.
     279             :         */
     280             :         virtual size_t          LeaveListAction() = 0;
     281             : 
     282             :         /** leaves the list action entered with EnterListAction, and forcefully merges the previous
     283             :             action on the stack into the newly created list action.
     284             : 
     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.
     290             : 
     291             :             Effectively, this means that all actions added between EnterListAction and LeaveAndMergeListAction are
     292             :             hidden from the user.
     293             : 
     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.
     296             :         */
     297             :         virtual size_t          LeaveAndMergeListAction() = 0;
     298             : 
     299             :         /// determines whether we're within a ListAction context, i.e. a LeaveListAction/LeaveAndMergeListAction call is pending
     300             :         virtual bool            IsInListAction() const = 0;
     301             : 
     302             :         /// determines how many nested list actions are currently open
     303             :         virtual size_t          GetListActionDepth() const = 0;
     304             : 
     305             :         /** clears the redo stack and removes the top undo action */
     306             :         virtual void            RemoveLastUndoAction() = 0;
     307             : 
     308             :         /** enables (true) or disables (false) recording of undo actions
     309             : 
     310             :             If undo actions are added while undo is disabled, they are deleted.
     311             :             Disabling undo does not clear the current undo buffer!
     312             : 
     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.
     315             :         */
     316             :         virtual void            EnableUndo( bool bEnable ) = 0;
     317             : 
     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;
     322             : 
     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;
     326             :    };
     327             : }
     328             : 
     329             : //=========================================================================
     330             : 
     331             : namespace svl { namespace undo { namespace impl
     332             : {
     333             :     class UndoManagerGuard;
     334             :     class LockGuard;
     335             : } } }
     336             : 
     337             : struct SfxUndoManager_Data;
     338             : class SVL_DLLPUBLIC SfxUndoManager : public ::svl::IUndoManager
     339             : {
     340             :     friend class SfxLinkUndoAction;
     341             : 
     342             :     ::boost::scoped_ptr< SfxUndoManager_Data >
     343             :                             m_pData;
     344             : public:
     345             :                             SfxUndoManager( size_t nMaxUndoActionCount = 20 );
     346             :     virtual                 ~SfxUndoManager();
     347             : 
     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 );
     378             : 
     379             :     /** marks the current top-level element of the Undo stack, and returns a unique ID for it
     380             :     */
     381             :     UndoStackMark   MarkTopUndoAction();
     382             : 
     383             :     /** removes a mark given by its ID.
     384             :         After the call, the mark ID is invalid.
     385             :     */
     386             :     void            RemoveMark( UndoStackMark const i_mark );
     387             : 
     388             :     /** determines whether the top action on the Undo stack has a given mark
     389             :     */
     390             :     bool            HasTopUndoActionMark( UndoStackMark const i_mark );
     391             : 
     392             :     /** removes the oldest Undo actions from the stack
     393             :     */
     394             :     void            RemoveOldestUndoActions( size_t const i_count );
     395             : 
     396             : protected:
     397             :     sal_Bool UndoWithContext( SfxUndoContext& i_context );
     398             :     sal_Bool RedoWithContext( SfxUndoContext& i_context );
     399             : 
     400             :     void    ImplClearRedo_NoLock( bool const i_currentLevel );
     401             : 
     402             :     /** clears all undo actions on the current level, plus all undo actions on superordinate levels,
     403             :         as soon as those levels are reached.
     404             : 
     405             :         If no list action is active currently, i.e. we're on the top level already, this method is equivalent to
     406             :         ->Clear.
     407             : 
     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.
     410             :     */
     411             :     void    ClearAllLevels();
     412             : 
     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 );
     423             : 
     424             :     sal_Bool ImplUndo( SfxUndoContext* i_contextOrNull );
     425             :     sal_Bool ImplRedo( SfxUndoContext* i_contextOrNull );
     426             : 
     427             :     friend class ::svl::undo::impl::LockGuard;
     428             : };
     429             : 
     430             : //=========================================================================
     431             : 
     432             : class SVL_DLLPUBLIC SfxLinkUndoAction : public SfxUndoAction
     433             : 
     434             : /*  [Beschreibung]
     435             : 
     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.
     440             : 
     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.
     445             : 
     446             : */
     447             : 
     448             : {
     449             : public:
     450             :                             TYPEINFO();
     451             :                             SfxLinkUndoAction(::svl::IUndoManager *pManager);
     452             :                             ~SfxLinkUndoAction();
     453             : 
     454             :     virtual void            Undo();
     455             :     virtual void            Redo();
     456             :     virtual sal_Bool            CanRepeat(SfxRepeatTarget& r) const;
     457             : 
     458             :     virtual void            Repeat(SfxRepeatTarget&r);
     459             : 
     460             :     virtual OUString    GetComment() const;
     461             :     virtual OUString    GetRepeatComment(SfxRepeatTarget&r) const;
     462             :     virtual sal_uInt16  GetId() const;
     463             : 
     464             :     SfxUndoAction*          GetAction() const { return pAction; }
     465             : 
     466             : protected:
     467             :     ::svl::IUndoManager     *pUndoManager;
     468             :     SfxUndoAction           *pAction;
     469             : 
     470             : };
     471             : 
     472             : #endif
     473             : 
     474             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10