Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Public Attributes | Private Member Functions | Private Attributes
nsTransactionManager Class Reference

implementation of a transaction manager object. More...

#include <nsTransactionManager.h>

Inheritance diagram for nsTransactionManager:
Inheritance graph
[legend]
Collaboration diagram for nsTransactionManager:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 nsTransactionManager (PRInt32 aMaxTransactionCount=-1)
 The default constructor.
virtual ~nsTransactionManager ()
 The default destructor.
NS_DECL_ISUPPORTS virtual
NS_DECL_NSITRANSACTIONMANAGER
nsresult 
ClearUndoStack (void)
virtual nsresult ClearRedoStack (void)
virtual nsresult WillDoNotify (nsITransaction *aTransaction, PRBool *aInterrupt)
virtual nsresult DidDoNotify (nsITransaction *aTransaction, nsresult aExecuteResult)
virtual nsresult WillUndoNotify (nsITransaction *aTransaction, PRBool *aInterrupt)
virtual nsresult DidUndoNotify (nsITransaction *aTransaction, nsresult aUndoResult)
virtual nsresult WillRedoNotify (nsITransaction *aTransaction, PRBool *aInterrupt)
virtual nsresult DidRedoNotify (nsITransaction *aTransaction, nsresult aRedoResult)
virtual nsresult WillBeginBatchNotify (PRBool *aInterrupt)
virtual nsresult DidBeginBatchNotify (nsresult aResult)
virtual nsresult WillEndBatchNotify (PRBool *aInterrupt)
virtual nsresult DidEndBatchNotify (nsresult aResult)
virtual nsresult WillMergeNotify (nsITransaction *aTop, nsITransaction *aTransaction, PRBool *aInterrupt)
virtual nsresult DidMergeNotify (nsITransaction *aTop, nsITransaction *aTransaction, PRBool aDidMerge, nsresult aMergeResult)
void doTransaction (in nsITransaction aTransaction)
 Calls a transaction's doTransaction() method, then pushes it on the undo stack.
void undoTransaction ()
 Pops the topmost transaction on the undo stack, calls it's undoTransaction() method, then pushes it on the redo stack.
void redoTransaction ()
 Pops the topmost transaction on the redo stack, calls it's redoTransaction() method, then pushes it on the undo stack.
void clear ()
 Clears the undo and redo stacks.
void beginBatch ()
 Turns on the transaction manager's batch mode, forcing all transactions executed by the transaction manager's doTransaction() method to be aggregated together until EndBatch() is called.
void endBatch ()
 Turns off the transaction manager's batch mode.
nsITransaction peekUndoStack ()
 Returns an AddRef'd pointer to the transaction at the top of the undo stack.
nsITransaction peekRedoStack ()
 Returns an AddRef'd pointer to the transaction at the top of the redo stack.
nsITransactionList getUndoList ()
 Returns the list of transactions on the undo stack.
nsITransactionList getRedoList ()
 Returns the list of transactions on the redo stack.
void AddListener (in nsITransactionListener aListener)
 Adds a listener to the transaction manager's notification list.
void RemoveListener (in nsITransactionListener aListener)
 Removes a listener from the transaction manager's notification list.

Public Attributes

readonly attribute long numberOfUndoItems
 The number of items on the undo stack.
readonly attribute long numberOfRedoItems
 The number of items on the redo stack.
attribute long maxTransactionCount
 Sets the maximum number of transaction items the transaction manager will maintain at any time.

Private Member Functions

virtual nsresult BeginTransaction (nsITransaction *aTransaction)
virtual nsresult EndTransaction (void)
virtual nsresult Lock (void)
virtual nsresult Unlock (void)

Private Attributes

PRInt32 mMaxTransactionCount
nsTransactionStack mDoStack
nsTransactionStack mUndoStack
nsTransactionRedoStack mRedoStack
nsVoidArraymListeners
PRMonitormMonitor

Detailed Description

implementation of a transaction manager object.

Definition at line 55 of file nsTransactionManager.h.


Constructor & Destructor Documentation

nsTransactionManager::nsTransactionManager ( PRInt32  aMaxTransactionCount = -1)

The default constructor.

Definition at line 53 of file nsTransactionManager.cpp.

  : mMaxTransactionCount(aMaxTransactionCount), mListeners(0)
{
  mMonitor = ::PR_NewMonitor();
}

Here is the call graph for this function:

The default destructor.

Definition at line 59 of file nsTransactionManager.cpp.

{
  if (mListeners)
  {
    PRInt32 i;
    nsITransactionListener *listener;

    for (i = 0; i < mListeners->Count(); i++)
    {
      listener = (nsITransactionListener *)mListeners->ElementAt(i);
      NS_IF_RELEASE(listener);
    }

    delete mListeners;
    mListeners = 0;
  }

  if (mMonitor)
  {
    ::PR_DestroyMonitor(mMonitor);
    mMonitor = 0;
  }
}

Here is the call graph for this function:


Member Function Documentation

Adds a listener to the transaction manager's notification list.

Listeners are notified whenever a transaction is done, undone, or redone.

The listener's AddRef() method is called.

Parameters:
aListenerthe lister to add.

Turns on the transaction manager's batch mode, forcing all transactions executed by the transaction manager's doTransaction() method to be aggregated together until EndBatch() is called.

This mode allows an application to execute and group together several independent transactions so they can be undone with a single call to undoTransaction().

nsresult nsTransactionManager::BeginTransaction ( nsITransaction aTransaction) [private, virtual]

Definition at line 1045 of file nsTransactionManager.cpp.

{
  nsTransactionItem *tx;
  nsresult result = NS_OK;

  // No need for LOCK/UNLOCK_TX_MANAGER() calls since the calling routine
  // should have done this already!

  NS_IF_ADDREF(aTransaction);

  // XXX: POSSIBLE OPTIMIZATION
  //      We could use a factory that pre-allocates/recycles transaction items.
  tx = new nsTransactionItem(aTransaction);

  if (!tx) {
    NS_IF_RELEASE(aTransaction);
    return NS_ERROR_OUT_OF_MEMORY;
  }

  result = mDoStack.Push(tx);

  if (NS_FAILED(result)) {
    delete tx;
    return result;
  }

  result = tx->DoTransaction();

  if (NS_FAILED(result)) {
    mDoStack.Pop(&tx);
    delete tx;
    return result;
  }

  return NS_OK;
}

Here is the call graph for this function:

Clears the undo and redo stacks.

Definition at line 730 of file nsTransactionManager.cpp.

{
  nsresult result;

  LOCK_TX_MANAGER(this);
  result = mRedoStack.Clear();
  UNLOCK_TX_MANAGER(this);

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 718 of file nsTransactionManager.cpp.

{
  nsresult result;

  LOCK_TX_MANAGER(this);
  result = mUndoStack.Clear();
  UNLOCK_TX_MANAGER(this);

  return result;
}

Here is the call graph for this function:

Definition at line 917 of file nsTransactionManager.cpp.

{
  if (!mListeners)
    return NS_OK;

  nsresult result = NS_OK;
  PRInt32 i, lcount = mListeners->Count();

  for (i = 0; i < lcount; i++)
  {
    nsITransactionListener *listener = (nsITransactionListener *)mListeners->ElementAt(i);

    if (!listener)
      return NS_ERROR_FAILURE;

    result = listener->DidBeginBatch(this, aResult);
    
    if (NS_FAILED(result))
      break;
  }

  return result;
}
nsresult nsTransactionManager::DidDoNotify ( nsITransaction aTransaction,
nsresult  aExecuteResult 
) [virtual]

Definition at line 767 of file nsTransactionManager.cpp.

{
  if (!mListeners)
    return NS_OK;

  nsresult result = NS_OK;
  PRInt32 i, lcount = mListeners->Count();

  for (i = 0; i < lcount; i++)
  {
    nsITransactionListener *listener = (nsITransactionListener *)mListeners->ElementAt(i);

    if (!listener)
      return NS_ERROR_FAILURE;

    result = listener->DidDo(this, aTransaction, aDoResult);
    
    if (NS_FAILED(result))
      break;
  }

  return result;
}

Definition at line 967 of file nsTransactionManager.cpp.

{
  if (!mListeners)
    return NS_OK;

  nsresult result = NS_OK;
  PRInt32 i, lcount = mListeners->Count();

  for (i = 0; i < lcount; i++)
  {
    nsITransactionListener *listener = (nsITransactionListener *)mListeners->ElementAt(i);

    if (!listener)
      return NS_ERROR_FAILURE;

    result = listener->DidEndBatch(this, aResult);
    
    if (NS_FAILED(result))
      break;
  }

  return result;
}
nsresult nsTransactionManager::DidMergeNotify ( nsITransaction aTop,
nsITransaction aTransaction,
PRBool  aDidMerge,
nsresult  aMergeResult 
) [virtual]

Definition at line 1017 of file nsTransactionManager.cpp.

{
  if (!mListeners)
    return NS_OK;

  nsresult result = NS_OK;
  PRInt32 i, lcount = mListeners->Count();

  for (i = 0; i < lcount; i++)
  {
    nsITransactionListener *listener = (nsITransactionListener *)mListeners->ElementAt(i);

    if (!listener)
      return NS_ERROR_FAILURE;

    result = listener->DidMerge(this, aTop, aTransaction, aDidMerge, aMergeResult);
    
    if (NS_FAILED(result))
      break;
  }

  return result;
}

Here is the caller graph for this function:

nsresult nsTransactionManager::DidRedoNotify ( nsITransaction aTransaction,
nsresult  aRedoResult 
) [virtual]

Definition at line 867 of file nsTransactionManager.cpp.

{
  if (!mListeners)
    return NS_OK;

  nsresult result = NS_OK;
  PRInt32 i, lcount = mListeners->Count();

  for (i = 0; i < lcount; i++)
  {
    nsITransactionListener *listener = (nsITransactionListener *)mListeners->ElementAt(i);

    if (!listener)
      return NS_ERROR_FAILURE;

    result = listener->DidRedo(this, aTransaction, aRedoResult);
    
    if (NS_FAILED(result))
      break;
  }

  return result;
}
nsresult nsTransactionManager::DidUndoNotify ( nsITransaction aTransaction,
nsresult  aUndoResult 
) [virtual]

Definition at line 817 of file nsTransactionManager.cpp.

{
  if (!mListeners)
    return NS_OK;

  nsresult result = NS_OK;
  PRInt32 i, lcount = mListeners->Count();

  for (i = 0; i < lcount; i++)
  {
    nsITransactionListener *listener = (nsITransactionListener *)mListeners->ElementAt(i);

    if (!listener)
      return NS_ERROR_FAILURE;

    result = listener->DidUndo(this, aTransaction, aUndoResult);
    
    if (NS_FAILED(result))
      break;
  }

  return result;
}

Here is the caller graph for this function:

Calls a transaction's doTransaction() method, then pushes it on the undo stack.

This method calls the transaction's AddRef() method. The transaction's Release() method will be called when the undo or redo stack is pruned or when the transaction manager is destroyed.

Parameters:
aTransactionthe transaction to do.

Turns off the transaction manager's batch mode.

Definition at line 1083 of file nsTransactionManager.cpp.

{
  nsITransaction *tint = 0;
  nsTransactionItem *tx        = 0;
  nsresult result              = NS_OK;

  // No need for LOCK/UNLOCK_TX_MANAGER() calls since the calling routine
  // should have done this already!

  result = mDoStack.Pop(&tx);

  if (NS_FAILED(result) || !tx)
    return result;

  result = tx->GetTransaction(&tint);

  if (NS_FAILED(result)) {
    // XXX: What do we do with the transaction item at this point?
    return result;
  }

  if (!tint) {
    PRInt32 nc = 0;

    // If we get here, the transaction must be a dummy batch transaction
    // created by BeginBatch(). If it contains no children, get rid of it!

    tx->GetNumberOfChildren(&nc);

    if (!nc) {
      delete tx;
      return result;
    }
  }

  // Check if the transaction is transient. If it is, there's nothing
  // more to do, just return.

  PRBool isTransient = PR_FALSE;

  if (tint)
    result = tint->GetIsTransient(&isTransient);

  if (NS_FAILED(result) || isTransient || !mMaxTransactionCount) {
    // XXX: Should we be clearing the redo stack if the transaction
    //      is transient and there is nothing on the do stack?
    delete tx;
    return result;
  }

  nsTransactionItem *top = 0;

  // Check if there is a transaction on the do stack. If there is,
  // the current transaction is a "sub" transaction, and should
  // be added to the transaction at the top of the do stack.

  result = mDoStack.Peek(&top);
  if (top) {
    result = top->AddChild(tx);

    // XXX: What do we do if this fails?

    return result;
  }

  // The transaction succeeded, so clear the redo stack.

  result = ClearRedoStack();

  if (NS_FAILED(result)) {
    // XXX: What do we do if this fails?
  }

  // Check if we can coalesce this transaction with the one at the top
  // of the undo stack.

  top = 0;
  result = mUndoStack.Peek(&top);

  if (tint && top) {
    PRBool didMerge = PR_FALSE;
    nsITransaction *topTransaction = 0;

    result = top->GetTransaction(&topTransaction);

    if (topTransaction) {

      PRBool doInterrupt = PR_FALSE;

      result = WillMergeNotify(topTransaction, tint, &doInterrupt);

      if (NS_FAILED(result))
        return result;

      if (!doInterrupt) {
        result = topTransaction->Merge(tint, &didMerge);

        nsresult result2 = DidMergeNotify(topTransaction, tint, didMerge, result);

        if (NS_SUCCEEDED(result))
          result = result2;

        if (NS_FAILED(result)) {
          // XXX: What do we do if this fails?
        }

        if (didMerge) {
          delete tx;
          return result;
        }
      }
    }
  }

  // Check to see if we've hit the max level of undo. If so,
  // pop the bottom transaction off the undo stack and release it!

  PRInt32 sz = 0;

  result = mUndoStack.GetSize(&sz);

  if (mMaxTransactionCount > 0 && sz >= mMaxTransactionCount) {
    nsTransactionItem *overflow = 0;

    result = mUndoStack.PopBottom(&overflow);

    // XXX: What do we do in the case where this fails?

    if (overflow)
      delete overflow;
  }

  // Push the transaction on the undo stack:

  result = mUndoStack.Push(tx);

  if (NS_FAILED(result)) {
    // XXX: What do we do in the case where a clear fails?
    //      Remove the transaction from the stack, and release it?
  }

  return result;
}

Here is the call graph for this function:

Returns the list of transactions on the redo stack.

Note that the transaction at the top of the redo stack will actually be at the index 'n-1' in the list, where 'n' is the number of items in the list.

Returns the list of transactions on the undo stack.

Note that the transaction at the top of the undo stack will actually be at the index 'n-1' in the list, where 'n' is the number of items in the list.

nsresult nsTransactionManager::Lock ( void  ) [private, virtual]

Definition at line 1228 of file nsTransactionManager.cpp.

Here is the call graph for this function:

Returns an AddRef'd pointer to the transaction at the top of the redo stack.

Callers should be aware that this method could return return a null in some implementations if there is a batch at the top of the redo stack.

Returns an AddRef'd pointer to the transaction at the top of the undo stack.

Callers should be aware that this method could return return a null in some implementations if there is a batch at the top of the undo stack.

Pops the topmost transaction on the redo stack, calls it's redoTransaction() method, then pushes it on the undo stack.

Removes a listener from the transaction manager's notification list.

The listener's Release() method is called.

Parameters:
aListenerthe lister to remove.

Pops the topmost transaction on the undo stack, calls it's undoTransaction() method, then pushes it on the redo stack.

nsresult nsTransactionManager::Unlock ( void  ) [private, virtual]

Definition at line 1237 of file nsTransactionManager.cpp.

Here is the call graph for this function:

Definition at line 892 of file nsTransactionManager.cpp.

{
  if (!mListeners)
    return NS_OK;

  nsresult result = NS_OK;
  PRInt32 i, lcount = mListeners->Count();

  for (i = 0; i < lcount; i++)
  {
    nsITransactionListener *listener = (nsITransactionListener *)mListeners->ElementAt(i);

    if (!listener)
      return NS_ERROR_FAILURE;

    result = listener->WillBeginBatch(this, aInterrupt);
    
    if (NS_FAILED(result) || *aInterrupt)
      break;
  }

  return result;
}
nsresult nsTransactionManager::WillDoNotify ( nsITransaction aTransaction,
PRBool aInterrupt 
) [virtual]

Definition at line 742 of file nsTransactionManager.cpp.

{
  if (!mListeners)
    return NS_OK;

  nsresult result = NS_OK;
  PRInt32 i, lcount = mListeners->Count();

  for (i = 0; i < lcount; i++)
  {
    nsITransactionListener *listener = (nsITransactionListener *)mListeners->ElementAt(i);

    if (!listener)
      return NS_ERROR_FAILURE;

    result = listener->WillDo(this, aTransaction, aInterrupt);
    
    if (NS_FAILED(result) || *aInterrupt)
      break;
  }

  return result;
}

Definition at line 942 of file nsTransactionManager.cpp.

{
  if (!mListeners)
    return NS_OK;

  nsresult result = NS_OK;
  PRInt32 i, lcount = mListeners->Count();

  for (i = 0; i < lcount; i++)
  {
    nsITransactionListener *listener = (nsITransactionListener *)mListeners->ElementAt(i);

    if (!listener)
      return NS_ERROR_FAILURE;

    result = listener->WillEndBatch(this, aInterrupt);
    
    if (NS_FAILED(result) || *aInterrupt)
      break;
  }

  return result;
}
nsresult nsTransactionManager::WillMergeNotify ( nsITransaction aTop,
nsITransaction aTransaction,
PRBool aInterrupt 
) [virtual]

Definition at line 992 of file nsTransactionManager.cpp.

{
  if (!mListeners)
    return NS_OK;

  nsresult result = NS_OK;
  PRInt32 i, lcount = mListeners->Count();

  for (i = 0; i < lcount; i++)
  {
    nsITransactionListener *listener = (nsITransactionListener *)mListeners->ElementAt(i);

    if (!listener)
      return NS_ERROR_FAILURE;

    result = listener->WillMerge(this, aTop, aTransaction, aInterrupt);
    
    if (NS_FAILED(result) || *aInterrupt)
      break;
  }

  return result;
}

Here is the caller graph for this function:

nsresult nsTransactionManager::WillRedoNotify ( nsITransaction aTransaction,
PRBool aInterrupt 
) [virtual]

Definition at line 842 of file nsTransactionManager.cpp.

{
  if (!mListeners)
    return NS_OK;

  nsresult result = NS_OK;
  PRInt32 i, lcount = mListeners->Count();

  for (i = 0; i < lcount; i++)
  {
    nsITransactionListener *listener = (nsITransactionListener *)mListeners->ElementAt(i);

    if (!listener)
      return NS_ERROR_FAILURE;

    result = listener->WillRedo(this, aTransaction, aInterrupt);
    
    if (NS_FAILED(result) || *aInterrupt)
      break;
  }

  return result;
}

Here is the caller graph for this function:

nsresult nsTransactionManager::WillUndoNotify ( nsITransaction aTransaction,
PRBool aInterrupt 
) [virtual]

Definition at line 792 of file nsTransactionManager.cpp.

{
  if (!mListeners)
    return NS_OK;

  nsresult result = NS_OK;
  PRInt32 i, lcount = mListeners->Count();

  for (i = 0; i < lcount; i++)
  {
    nsITransactionListener *listener = (nsITransactionListener *)mListeners->ElementAt(i);

    if (!listener)
      return NS_ERROR_FAILURE;

    result = listener->WillUndo(this, aTransaction, aInterrupt);
    
    if (NS_FAILED(result) || *aInterrupt)
      break;
  }

  return result;
}

Here is the caller graph for this function:


Member Data Documentation

Sets the maximum number of transaction items the transaction manager will maintain at any time.

This is commonly referred to as the number of levels of undo.

Parameters:
aMaxCountA value of -1 means no limit. A value of zero means the transaction manager will execute each transaction, then immediately release all references it has to the transaction without pushing it on the undo stack. A value greater than zero indicates the max number of transactions that can exist at any time on both the undo and redo stacks. This method will prune the necessary number of transactions on the undo and redo stacks if the value specified is less than the number of items that exist on both the undo and redo stacks.

Definition at line 123 of file nsITransactionManager.idl.

Definition at line 61 of file nsTransactionManager.h.

Definition at line 64 of file nsTransactionManager.h.

Definition at line 60 of file nsTransactionManager.h.

Definition at line 66 of file nsTransactionManager.h.

Definition at line 63 of file nsTransactionManager.h.

Definition at line 62 of file nsTransactionManager.h.

The number of items on the redo stack.

Definition at line 108 of file nsITransactionManager.idl.

The number of items on the undo stack.

Definition at line 103 of file nsITransactionManager.idl.


The documentation for this class was generated from the following files: