From 2fa2988f755500952b523a48ba51b1c5ea606ad5 Mon Sep 17 00:00:00 2001 From: "kin%netscape.com" Date: Sat, 21 Nov 1998 01:02:55 +0000 Subject: [PATCH] First pass implementations of Do, Undo, and Redo. --- editor/txmgr/src/nsTransactionManager.cpp | 101 +++++++++++++++++++++- editor/txmgr/src/nsTransactionManager.h | 29 ++++++- 2 files changed, 125 insertions(+), 5 deletions(-) diff --git a/editor/txmgr/src/nsTransactionManager.cpp b/editor/txmgr/src/nsTransactionManager.cpp index 0734c85d7c1..b84440688c8 100644 --- a/editor/txmgr/src/nsTransactionManager.cpp +++ b/editor/txmgr/src/nsTransactionManager.cpp @@ -22,7 +22,8 @@ static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); static NS_DEFINE_IID(kITransactionManagerIID, NS_ITRANSACTIONMANAGER_IID); -nsTransactionManager::nsTransactionManager() +nsTransactionManager::nsTransactionManager(PRInt32 aMaxLevelsOfUndo) + : mMaxLevelsOfUndo(aMaxLevelsOfUndo), mRF(), mUndoStack(mRF), mRedoStack(mRF) { } @@ -56,19 +57,98 @@ nsTransactionManager::QueryInterface(REFNSIID aIID, void** aInstancePtr) nsresult nsTransactionManager::Do(nsITransaction *aTransaction) { - return NS_OK; + nsresult result = NS_OK; + + if (!aTransaction) + return NS_ERROR_NULL_POINTER; + + // XXX: LOCK the transaction manager + + result = aTransaction->Do(); + + if (! NS_SUCCEEDED(result)) { + // XXX: UNLOCK the transaction manager + return result; + } + + // XXX: Check if we can coalesce this transaction with the one + // at the top of the undo stack. If we can, merge this one + // into the one currently on the stack. + + // XXX: Check to see if we've hit the max level of undo. If so, + // pop the bottom transaction of the undo stack and release it! + + NS_ADDREF(aTransaction); + mUndoStack.Push(aTransaction); + + result = PruneRedoStack(); + + if (! NS_SUCCEEDED(result)) { + // XXX: What do we do in the case where a prune fails? + // Remove the transaction from the stack, and release it? + } + + // XXX: UNLOCK the transaction manager + + return result; } nsresult nsTransactionManager::Undo() { - return NS_OK; + nsresult result = NS_OK; + nsITransaction *tx = 0; + + // XXX: LOCK the transaction manager + + // Peek at the top of the undo stack. Don't remove the transaction + // until it has successfully completed. + tx = (nsITransaction *)(--mUndoStack.End()); + + // Bail if there's nothing on the stack. + if (!tx) { + // XXX: UNLOCK the transaction manager + return NS_OK; + } + + result = tx->Undo(); + + if (NS_SUCCEEDED(result)) { + mRedoStack.Push(mUndoStack.Pop()); + } + + // XXX: UNLOCK the transaction manager + + return result; } nsresult nsTransactionManager::Redo() { - return NS_OK; + nsresult result = NS_OK; + nsITransaction *tx = 0; + + // XXX: LOCK the transaction manager + + // Peek at the top of the redo stack. Don't remove the transaction + // until it has successfully completed. + tx = (nsITransaction *)(--mRedoStack.End()); + + // Bail if there's nothing on the stack. + if (!tx) { + // XXX: UNLOCK the transaction manager + return NS_OK; + } + + result = tx->Redo(); + + if (NS_SUCCEEDED(result)) { + mUndoStack.Push(mRedoStack.Pop()); + } + + // XXX: UNLOCK the transaction manager + + return result; } nsresult @@ -77,6 +157,8 @@ nsTransactionManager::GetNumberOfUndoItems(PRInt32 *aNumItems) if (aNumItems) *aNumItems = 0; + *aNumItems = mUndoStack.GetSize(); + return NS_OK; } @@ -86,6 +168,8 @@ nsTransactionManager::GetNumberOfRedoItems(PRInt32 *aNumItems) if (aNumItems) *aNumItems = 0; + *aNumItems = mRedoStack.GetSize(); + return NS_OK; } @@ -107,3 +191,12 @@ nsTransactionManager::RemoveListener(nsITransactionListener *aListener) return NS_OK; } +nsresult +nsTransactionManager::PruneRedoStack() +{ + // XXX: The order in which you release things off this stack matters! + // We may not be able to use Erase(). + mRedoStack.Erase(); + return NS_OK; +} + diff --git a/editor/txmgr/src/nsTransactionManager.h b/editor/txmgr/src/nsTransactionManager.h index 0bbb2441939..472ffcd507a 100644 --- a/editor/txmgr/src/nsTransactionManager.h +++ b/editor/txmgr/src/nsTransactionManager.h @@ -20,17 +20,41 @@ #define nsTransactionManager_h__ #include "nsITransactionManager.h" +#include "nsDeque.h" + +class nsTransactionReleaseFunctor : public nsDequeFunctor +{ +public: + + nsTransactionReleaseFunctor() {} + + ~nsTransactionReleaseFunctor() {} + + virtual void *operator()(void *aObject) + { + nsITransaction *t = (nsITransaction *)aObject; + NS_IF_RELEASE(t); + return 0; + } +}; /** implementation of a transaction manager object. * */ class nsTransactionManager : public nsITransactionManager { +private: + + PRInt32 mMaxLevelsOfUndo; + nsTransactionReleaseFunctor mRF; + nsDeque mUndoStack; + nsDeque mRedoStack; + public: /** The default constructor. */ - nsTransactionManager(); + nsTransactionManager(PRInt32 aMaxLevelsOfUndo=-1); /** The default destructor. */ @@ -48,6 +72,9 @@ public: virtual nsresult Write(nsIOutputStream *aOutputStream); virtual nsresult AddListener(nsITransactionListener *aListener); virtual nsresult RemoveListener(nsITransactionListener *aListener); + + /* nsTransactionManager specific methods. */ + virtual nsresult PruneRedoStack(); }; #endif // nsTransactionManager_h__