First pass implementations of Do, Undo, and Redo.

This commit is contained in:
kin%netscape.com 1998-11-21 01:02:55 +00:00
parent 1c5e61830b
commit be08e6d153
2 changed files with 125 additions and 5 deletions

View File

@ -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;
}

View File

@ -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__