sl@0: /* sl@0: * Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: sl@0: * sl@0: */ sl@0: sl@0: sl@0: #ifndef UNDOSYSTEMIMPL_H_ sl@0: #define UNDOSYSTEMIMPL_H_ sl@0: sl@0: #include sl@0: #include "UndoSystem.h" sl@0: sl@0: namespace UndoSystem sl@0: { sl@0: class CCommand; sl@0: class CSingleCommand; sl@0: class CBatchCommand; sl@0: sl@0: /** sl@0: * Undo panic codes sl@0: * sl@0: * @internalComponent sl@0: */ sl@0: enum TPanicCode sl@0: { sl@0: /** sl@0: * CSingleCommand::PrepareToAddInverseToLast() overridden to return ETrue, but sl@0: * CSingleCommand::AddInverseToLast() not overridden. sl@0: */ sl@0: KAddToLastOnlyHalfImplemented = 1, sl@0: /** sl@0: * CCommandStack or CSingleCommandStack::Pop() called on an empty stack sl@0: */ sl@0: KCommandStackUnderflow, sl@0: /** sl@0: * CCommandStack or CSingleCommandStack::Push() called without adequate sl@0: * space being reserved via PrepareToPushL() sl@0: */ sl@0: KCommandStackPushNotPrepared, sl@0: /** sl@0: * No shared undo system passed when expected sl@0: */ sl@0: KEditorUndoNoCommandManager sl@0: }; sl@0: sl@0: /** sl@0: * Panic from Undo DLL sl@0: * sl@0: * @internalComponent sl@0: */ sl@0: void Panic(TPanicCode aCode); sl@0: sl@0: /** sl@0: * Stack of commands. A bookmark is maintianed so that we can tell if the stack sl@0: * is in the same state it was at a previous time. sl@0: * sl@0: * @internalComponent sl@0: * @since App-frameworks6.1 sl@0: */ sl@0: NONSHARABLE_CLASS(CCommandStack) : public CBase sl@0: { sl@0: public: sl@0: static CCommandStack* NewL(); sl@0: ~CCommandStack(); sl@0: CCommandStack(); sl@0: void ConstructL(); sl@0: sl@0: CCommand* Top() const; sl@0: CCommand* Pop(); sl@0: /** sl@0: * Allows aNumberOfItems Push()s to be done before the next sl@0: * call to another non-const member function apart from Push(). sl@0: * aNumberOfItems must be non-negative. sl@0: */ sl@0: void PrepareToPushL(TInt aNumberOfItems); sl@0: void Push(CCommand* aCommand); sl@0: void PruneTo(TInt aNumberOfItems); sl@0: TInt Count() const; sl@0: /** sl@0: * Removes all elements from the stack and deletes the bookmark. sl@0: */ sl@0: void Reset(); sl@0: /** sl@0: * Adds aStack to the top of this CCommandStack, emptying it completely. sl@0: * Enough items must have been reserved with PrepareToPushL(TInt). sl@0: */ sl@0: void Concatenate(CCommandStack& aStack); sl@0: /** sl@0: * Sets the current position in the stack as the location of the bookmark. sl@0: * The bookmark will be lost if the bookmarked object is removed from the sl@0: * stack. Bookmark begins set at the zero position. sl@0: */ sl@0: void SetBookmark(); sl@0: /** sl@0: * Returns true iff we are at the current bookmark position. sl@0: */ sl@0: TBool IsAtBookmark() const; sl@0: sl@0: private: sl@0: CArrayFix* iStack; sl@0: /** sl@0: * One-past-top element in the array. Less than Count() after a call sl@0: * to PrepareToPushL() with non-zero argument. sl@0: */ sl@0: TInt iEnd; sl@0: /** sl@0: * The bookmark into the stack. We are at the bookmark when iEnd == sl@0: * iBookmark. No bookmark is represented by iBookmark < 0. sl@0: */ sl@0: TInt iBookmark; sl@0: }; sl@0: sl@0: /** sl@0: * Stack of single commands sl@0: * sl@0: * @internalComponent sl@0: * @since App-frameworks6.1 sl@0: */ sl@0: class CSingleCommandStack : public CBase sl@0: { sl@0: public: sl@0: static CSingleCommandStack* NewL(); sl@0: sl@0: inline CSingleCommand* Top() const; sl@0: inline CSingleCommand* Pop(); sl@0: inline void PrepareToPushL(TInt aNumberOfItems); sl@0: inline void Push(CSingleCommand* aCommand); sl@0: inline void PruneTo(TInt aNumberOfItems); sl@0: inline TInt Count() const; sl@0: inline void Reset(); sl@0: inline void Concatenate(CSingleCommandStack& aStack); sl@0: sl@0: private: sl@0: CSingleCommandStack() {} sl@0: sl@0: CCommandStack iStack; sl@0: }; sl@0: sl@0: /** sl@0: * A stack of commands supporting batching and a flag for whether a batch sl@0: * has had its undo option waived. A bookmark is also supported, so that we can sl@0: * tell whether the history is in the same state as it was at a previous time. sl@0: * sl@0: * @internalComponent sl@0: * @since App-frameworks6.1 sl@0: */ sl@0: NONSHARABLE_CLASS(CCommandHistory) : public CBase sl@0: { sl@0: public: sl@0: ~CCommandHistory(); sl@0: static CCommandHistory* NewL(); sl@0: sl@0: /** sl@0: * Returns the command at the top of the stack. sl@0: */ sl@0: CCommand* Top() const; sl@0: /** sl@0: * Returns the single command at the top of the stack. sl@0: */ sl@0: CSingleCommand* TopSingleCommand() const; sl@0: /** sl@0: * Allocates enough resources for one call to AddCommand(CCommand* aCommand). sl@0: */ sl@0: void PrepareToAddCommandL(CCommand* aCommand); sl@0: /** sl@0: * Adds the command to the top of the stack. PrepareToAddCommandL() must sl@0: * have been called successfully since the last call to AddCommand or NewL. sl@0: */ sl@0: void AddCommand(CCommand*); sl@0: /** sl@0: * Returns ETrue iff SetUndoWaived() has been called during this batch. If sl@0: * there is no batch currently open, this function will always return sl@0: * EFalse. sl@0: */ sl@0: TBool UndoHasBeenWaived() const; sl@0: /** sl@0: * Sets a flag to indicated that undo is not required for this current sl@0: * batch. This function has no effect if there is no batch currently open. sl@0: * sl@0: * @see UndoHasBeenWaived sl@0: */ sl@0: void SetUndoWaived(); sl@0: /** sl@0: * Sets the maximum height of the stack to aMaxItems. If it is exceeded, sl@0: * the stack is truncated to aPrunedItems. sl@0: */ sl@0: void SetMaxItems(TInt aMaxItems); sl@0: /** sl@0: * Returns ETrue iff the stack has no elements. sl@0: */ sl@0: TBool IsEmpty() const { return Top()? EFalse : ETrue; } sl@0: /** sl@0: * Begins a new batch. All commands added subsequently will be exeuted all sl@0: * at once. Close the batch with CleanupStack::PopAndDestroy(); sl@0: */ sl@0: void BeginBatchLC(); sl@0: /** sl@0: * Returns ETrue iff there is a batch currently open. sl@0: */ sl@0: TBool IsWithinBatch() const; sl@0: /** sl@0: * Removes and returns the top element. There must be no batch currently sl@0: * open before a call to Pop(). sl@0: */ sl@0: CCommand* Pop(); sl@0: /** sl@0: * Removes all elements from the stack. If a batch is currently open, any sl@0: * commands added subsequently will not be added to it. Deletes the sl@0: * bookmark. sl@0: */ sl@0: void Reset(); sl@0: /** sl@0: * Removes and destroys the top element iff it is an empty batch. Must not sl@0: * be called if a batch is currently open. sl@0: */ sl@0: void Clean(); sl@0: /** sl@0: * Sets the bookmark to the current position. sl@0: */ sl@0: void SetBookmark(); sl@0: /** sl@0: * Returns true iff the bookmark is at the current position. sl@0: */ sl@0: TBool IsAtBookmark(); sl@0: sl@0: private: sl@0: sl@0: CCommandHistory(); sl@0: void ConstructL(); sl@0: void Prune(); sl@0: sl@0: static void CloseBatch(void* aCCommandHistory); sl@0: static void DownBatchLevel(void* aCCommandHistory); sl@0: sl@0: CCommandStack* iStack; sl@0: CBatchCommand* iCurrent; // either == 0 or points to the most sl@0: // recent CBatchCommand within iStack sl@0: sl@0: TInt iMaxItems; sl@0: sl@0: TBool iBatchUndoHasBeenWaived; sl@0: }; sl@0: sl@0: // sl@0: // CSingleCommandStack inlines sl@0: // sl@0: CSingleCommand* CSingleCommandStack::Top() const sl@0: { return static_cast(iStack.Top()); } sl@0: sl@0: CSingleCommand* CSingleCommandStack::Pop() sl@0: { return static_cast(iStack.Pop()); } sl@0: sl@0: void CSingleCommandStack::PrepareToPushL(TInt aNumberOfItems) sl@0: { iStack.PrepareToPushL(aNumberOfItems); } sl@0: sl@0: void CSingleCommandStack::Push(CSingleCommand* aCommand) sl@0: { iStack.Push(aCommand); } sl@0: sl@0: void CSingleCommandStack::PruneTo(TInt aNumberOfItems) sl@0: { iStack.PruneTo(aNumberOfItems); } sl@0: sl@0: TInt CSingleCommandStack::Count() const sl@0: { return iStack.Count(); } sl@0: sl@0: void CSingleCommandStack::Reset() sl@0: { iStack.Reset(); } sl@0: sl@0: void CSingleCommandStack::Concatenate(CSingleCommandStack& aStack) sl@0: { iStack.Concatenate(aStack.iStack); } sl@0: sl@0: } sl@0: sl@0: #endif sl@0: