Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Static Public Member Functions | Public Attributes | Protected Member Functions | Protected Attributes | Private Member Functions | Friends
DeleteRangeTxn Class Reference

A transaction that deletes an entire range in the content tree. More...

#include <DeleteRangeTxn.h>

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

List of all members.

Public Member Functions

NS_IMETHOD Init (nsIEditor *aEditor, nsIDOMRange *aRange, nsRangeUpdater *aRangeUpdater)
 initialize the transaction.
virtual ~DeleteRangeTxn ()
NS_IMETHOD DoTransaction (void)
NS_IMETHOD UndoTransaction (void)
NS_IMETHOD RedoTransaction (void)
NS_IMETHOD Merge (nsITransaction *aTransaction, PRBool *aDidMerge)
NS_IMETHOD GetTxnDescription (nsAString &aTxnDescription)
NS_IMETHOD GetIsTransient (PRBool *aIsTransient)
NS_IMETHOD AppendChild (EditTxn *aTxn)
 append a transaction to this aggregate
NS_IMETHOD GetCount (PRUint32 *aCount)
 get the number of nested txns.
NS_IMETHOD GetTxnAt (PRInt32 aIndex, EditTxn **aTxn)
 get the txn at index aIndex.
NS_IMETHOD SetName (nsIAtom *aName)
 set the name assigned to this txn
NS_IMETHOD GetName (nsIAtom **aName)
 get the name assigned to this txn
void doTransaction ()
 Executes the transaction.
void undoTransaction ()
 Restores the state to what it was before the transaction was executed.
void redoTransaction ()
 Executes the transaction again.
boolean merge (in nsITransaction aTransaction)
 Attempts to merge a transaction into "this" transaction.

Static Public Member Functions

static const nsIIDGetCID ()

Public Attributes

readonly attribute boolean isTransient
 The transaction's transient state.
readonly attribute DOMString txnDescription

Protected Member Functions

NS_IMETHOD CreateTxnsToDeleteBetween (nsIDOMNode *aStartParent, PRUint32 aStartOffset, PRUint32 aEndOffset)
NS_IMETHOD CreateTxnsToDeleteNodesBetween ()
NS_IMETHOD CreateTxnsToDeleteContent (nsIDOMNode *aParent, PRUint32 aOffset, nsIEditor::EDirection aAction)

Protected Attributes

nsCOMPtr< nsIDOMRangemRange
 p1 in the range
nsCOMPtr< nsIDOMNodemStartParent
 p1 in the range
PRInt32 mStartOffset
 p1 offset
nsCOMPtr< nsIDOMNodemEndParent
 p2 in the range
nsCOMPtr< nsIDOMNodemCommonParent
 the closest common parent of p1 and p2
PRInt32 mEndOffset
 p2 offset
nsIEditormEditor
 the editor for this transaction
nsRangeUpdatermRangeUpdater
 range updater object
nsCOMPtr< nsISupportsArraymChildren
nsCOMPtr< nsIAtommName

Private Member Functions

 DeleteRangeTxn ()

Friends

class TransactionFactory

Detailed Description

A transaction that deletes an entire range in the content tree.

Definition at line 59 of file DeleteRangeTxn.h.


Constructor & Destructor Documentation

Definition at line 131 of file DeleteRangeTxn.cpp.

{
}

Member Function Documentation

append a transaction to this aggregate

Definition at line 156 of file EditAggregateTxn.cpp.

{
  if (mChildren && aTxn)
  {
    // aaahhhh! broken interfaces drive me crazy!!!
    nsCOMPtr<nsISupports> isupports;
    aTxn->QueryInterface(NS_GET_IID(nsISupports), getter_AddRefs(isupports));
    mChildren->AppendElement(isupports);
    return NS_OK;
  }
  return NS_ERROR_NULL_POINTER;
}

Here is the call graph for this function:

Here is the caller graph for this function:

NS_IMETHODIMP DeleteRangeTxn::CreateTxnsToDeleteBetween ( nsIDOMNode aStartParent,
PRUint32  aStartOffset,
PRUint32  aEndOffset 
) [protected]

Definition at line 231 of file DeleteRangeTxn.cpp.

{
  nsresult result;
  // see what kind of node we have
  nsCOMPtr<nsIDOMCharacterData> textNode = do_QueryInterface(aStartParent);
  if (textNode)
  { // if the node is a text node, then delete text content
    DeleteTextTxn *txn;
    result = TransactionFactory::GetNewTransaction(DeleteTextTxn::GetCID(), (EditTxn **)&txn);
    if (NS_FAILED(result)) return result;
    if (!txn) return NS_ERROR_NULL_POINTER;

    PRInt32 numToDel;
    if (aStartOffset==aEndOffset)
      numToDel = 1;
    else
      numToDel = aEndOffset-aStartOffset;
    txn->Init(mEditor, textNode, aStartOffset, numToDel, mRangeUpdater);
    AppendChild(txn);
    NS_RELEASE(txn);
  }
  else
  {
    nsCOMPtr<nsIDOMNodeList> children;
    result = aStartParent->GetChildNodes(getter_AddRefs(children));
    if (NS_FAILED(result)) return result;
    if (!children) return NS_ERROR_NULL_POINTER;

#ifdef DEBUG
    PRUint32 childCount;
    children->GetLength(&childCount);
    NS_ASSERTION(aEndOffset<=childCount, "bad aEndOffset");
#endif
    PRUint32 i;
    for (i=aStartOffset; i<aEndOffset; i++)
    {
      nsCOMPtr<nsIDOMNode> child;
      result = children->Item(i, getter_AddRefs(child));
      if (NS_FAILED(result)) return result;
      if (!child) return NS_ERROR_NULL_POINTER;

      DeleteElementTxn *txn;
      result = TransactionFactory::GetNewTransaction(DeleteElementTxn::GetCID(), (EditTxn **)&txn);
      if (NS_FAILED(result)) return result;
      if (!txn) return NS_ERROR_NULL_POINTER;

      txn->Init(child, mRangeUpdater);
      AppendChild(txn);
      NS_RELEASE(txn);
    }
  }
  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 287 of file DeleteRangeTxn.cpp.

{
  nsresult result = NS_OK;
  // see what kind of node we have
  nsCOMPtr<nsIDOMCharacterData> textNode = do_QueryInterface(aParent);
  if (textNode)
  { // if the node is a text node, then delete text content
    PRUint32 start, numToDelete;
    if (nsIEditor::eNext == aAction)
    {
      start=aOffset;
      textNode->GetLength(&numToDelete);
      numToDelete -= aOffset;
    }
    else
    {
      start=0;
      numToDelete=aOffset;
    }
    
    if (numToDelete)
    {
      DeleteTextTxn *txn;
      result = TransactionFactory::GetNewTransaction(DeleteTextTxn::GetCID(), (EditTxn **)&txn);
      if (NS_FAILED(result)) return result;
      if (!txn) return NS_ERROR_NULL_POINTER;

      txn->Init(mEditor, textNode, start, numToDelete, mRangeUpdater);
      AppendChild(txn);
      NS_RELEASE(txn);
    }
  }

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 325 of file DeleteRangeTxn.cpp.

{
  nsCOMPtr<nsIContentIterator> iter = do_CreateInstance("@mozilla.org/content/subtree-content-iterator;1");
  if (!iter) return NS_ERROR_NULL_POINTER;

  nsresult result = iter->Init(mRange);
  if (NS_FAILED(result)) return result;

  while (!iter->IsDone())
  {
    nsCOMPtr<nsIDOMNode> node = do_QueryInterface(iter->GetCurrentNode());
    if (!node)
      return NS_ERROR_NULL_POINTER;

    DeleteElementTxn *txn;
    result = TransactionFactory::GetNewTransaction(DeleteElementTxn::GetCID(), (EditTxn **)&txn);
    if (NS_FAILED(result)) return result;
    if (!txn) return NS_ERROR_NULL_POINTER;

    txn->Init(node, mRangeUpdater);
    AppendChild(txn);
    NS_RELEASE(txn);
    iter->Next();
  }
  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Executes the transaction.

Reimplemented from EditAggregateTxn.

Definition at line 135 of file DeleteRangeTxn.cpp.

{
#ifdef NS_DEBUG
  if (gNoisy) { printf("Do Delete Range\n"); }
#endif

  if (!mStartParent || !mEndParent || !mCommonParent || !mEditor) 
    return NS_ERROR_NOT_INITIALIZED;

  nsresult result; 
  // build the child transactions

  if (mStartParent==mEndParent)
  { // the selection begins and ends in the same node
    result = CreateTxnsToDeleteBetween(mStartParent, mStartOffset, mEndOffset);
  }
  else
  { // the selection ends in a different node from where it started
    // delete the relevant content in the start node
    result = CreateTxnsToDeleteContent(mStartParent, mStartOffset, nsIEditor::eNext);
    if (NS_SUCCEEDED(result))
    {
      // delete the intervening nodes
      result = CreateTxnsToDeleteNodesBetween();
      if (NS_SUCCEEDED(result))
      {
        // delete the relevant content in the end node
        result = CreateTxnsToDeleteContent(mEndParent, mEndOffset, nsIEditor::ePrevious);
      }
    }
  }

  // if we've successfully built this aggregate transaction, then do it.
  if (NS_SUCCEEDED(result)) {
    result = EditAggregateTxn::DoTransaction();
  }

  if (NS_FAILED(result)) return result;
  
  // only set selection to deletion point if editor gives permission
  PRBool bAdjustSelection;
  mEditor->ShouldTxnSetSelection(&bAdjustSelection);
  if (bAdjustSelection)
  {
    nsCOMPtr<nsISelection> selection;
    result = mEditor->GetSelection(getter_AddRefs(selection));
    if (NS_FAILED(result)) return result;
    if (!selection) return NS_ERROR_NULL_POINTER;
    result = selection->Collapse(mStartParent, mStartOffset);
  }
  else
  {
    // do nothing - dom range gravity will adjust selection
  }

  return result;
}

Here is the call graph for this function:

static const nsIID& DeleteRangeTxn::GetCID ( ) [inline, static]

Reimplemented from EditAggregateTxn.

Definition at line 63 of file DeleteRangeTxn.h.

{ static const nsIID iid = DELETE_RANGE_TXN_CID; return iid; }

Here is the caller graph for this function:

get the number of nested txns.

This is the number of top-level txns, it does not do recursive decent.

Definition at line 169 of file EditAggregateTxn.cpp.

{
  if (!aCount) {
    return NS_ERROR_NULL_POINTER;
  }
  *aCount=0;
  if (mChildren) {
    mChildren->Count(aCount);
  }
  return NS_OK;
}
NS_IMETHODIMP EditAggregateTxn::GetIsTransient ( PRBool aIsTransient) [inherited]

Reimplemented from EditTxn.

Definition at line 114 of file EditAggregateTxn.cpp.

{
  if (aIsTransient)
    *aIsTransient = PR_FALSE;
  return NS_OK;
}
NS_IMETHODIMP EditAggregateTxn::GetName ( nsIAtom **  aName) [inherited]

get the name assigned to this txn

Definition at line 215 of file EditAggregateTxn.cpp.

{
  if (aName && mName)
  {
    *aName = mName;
    NS_ADDREF(*aName);
    return NS_OK;
  }
  return NS_ERROR_NULL_POINTER;
}

Here is the call graph for this function:

Here is the caller graph for this function:

NS_IMETHODIMP EditAggregateTxn::GetTxnAt ( PRInt32  aIndex,
EditTxn **  aTxn 
) [inherited]

get the txn at index aIndex.

returns NS_ERROR_UNEXPECTED if there is no txn at aIndex.

Definition at line 181 of file EditAggregateTxn.cpp.

{
  // preconditions
  NS_PRECONDITION(aTxn, "null out param");
  NS_PRECONDITION(mChildren, "bad internal state");

  if (!aTxn) {
    return NS_ERROR_NULL_POINTER;
  }
  *aTxn = nsnull; // initialize out param as soon as we know it's a valid pointer
  if (!mChildren) {
    return NS_ERROR_UNEXPECTED;
  }

  // get the transaction at aIndex
  PRUint32 txnCount;
  mChildren->Count(&txnCount);
  if (0>aIndex || ((PRInt32)txnCount)<=aIndex) {
    return NS_ERROR_UNEXPECTED;
  }
  // ugh, this is all wrong - what a mess we have with editor transaction interfaces
  mChildren->QueryElementAt(aIndex, EditTxn::GetCID(), (void**)aTxn);
  if (!*aTxn)
    return NS_ERROR_UNEXPECTED;
  return NS_OK;
}

Here is the call graph for this function:

NS_IMETHODIMP DeleteRangeTxn::GetTxnDescription ( nsAString &  aTxnDescription)

Reimplemented from EditAggregateTxn.

Definition at line 224 of file DeleteRangeTxn.cpp.

{
  aString.AssignLiteral("DeleteRangeTxn");
  return NS_OK;
}
NS_IMETHODIMP DeleteRangeTxn::Init ( nsIEditor aEditor,
nsIDOMRange aRange,
nsRangeUpdater aRangeUpdater 
)

initialize the transaction.

Parameters:
aEditorthe object providing basic editing operations
aRangethe range to delete

Definition at line 69 of file DeleteRangeTxn.cpp.

{
  NS_ASSERTION(aEditor && aRange, "bad state");
  if (!aEditor || !aRange) { return NS_ERROR_NOT_INITIALIZED; }

  mEditor = aEditor;
  mRange  = do_QueryInterface(aRange);
  mRangeUpdater = aRangeUpdater;
  
  nsresult result = aRange->GetStartContainer(getter_AddRefs(mStartParent));
  NS_ASSERTION((NS_SUCCEEDED(result)), "GetStartParent failed.");
  result = aRange->GetEndContainer(getter_AddRefs(mEndParent));
  NS_ASSERTION((NS_SUCCEEDED(result)), "GetEndParent failed.");
  result = aRange->GetStartOffset(&mStartOffset);
  NS_ASSERTION((NS_SUCCEEDED(result)), "GetStartOffset failed.");
  result = aRange->GetEndOffset(&mEndOffset);
  NS_ASSERTION((NS_SUCCEEDED(result)), "GetEndOffset failed.");
  result = aRange->GetCommonAncestorContainer(getter_AddRefs(mCommonParent));
  NS_ASSERTION((NS_SUCCEEDED(result)), "GetCommonParent failed.");

#ifdef NS_DEBUG
  {
    PRUint32 count;
    nsCOMPtr<nsIDOMCharacterData> textNode = do_QueryInterface(mStartParent);
    if (textNode)
      textNode->GetLength(&count);
    else
    {
      nsCOMPtr<nsIDOMNodeList> children;
      result = mStartParent->GetChildNodes(getter_AddRefs(children));
      NS_ASSERTION(((NS_SUCCEEDED(result)) && children), "bad start child list");
      children->GetLength(&count);
    }
    NS_ASSERTION(mStartOffset<=(PRInt32)count, "bad start offset");

    textNode = do_QueryInterface(mEndParent);
    if (textNode)
      textNode->GetLength(&count);
    else
    {
      nsCOMPtr<nsIDOMNodeList> children;
      result = mEndParent->GetChildNodes(getter_AddRefs(children));
      NS_ASSERTION(((NS_SUCCEEDED(result)) && children), "bad end child list");
      children->GetLength(&count);
    }
    NS_ASSERTION(mEndOffset<=(PRInt32)count, "bad end offset");

#ifdef NS_DEBUG
    if (gNoisy)
    {
      printf ("DeleteRange: %d of %p to %d of %p\n", 
               mStartOffset, (void *)mStartParent, mEndOffset, (void *)mEndParent);
    }         
#endif
  }
#endif
  return result;

}

Here is the call graph for this function:

NS_IMETHODIMP DeleteRangeTxn::Merge ( nsITransaction aTransaction,
PRBool aDidMerge 
)

Reimplemented from EditAggregateTxn.

Definition at line 217 of file DeleteRangeTxn.cpp.

{
  if (aDidMerge)
    *aDidMerge = PR_FALSE;
  return NS_OK;
}
boolean nsITransaction::merge ( in nsITransaction  aTransaction) [inherited]

Attempts to merge a transaction into "this" transaction.

Both transactions must be in their undo state, doTransaction() methods already called. The transaction manager calls this method to coalesce a new transaction with the transaction on the top of the undo stack. This method returns a boolean value that indicates the merge result. A true value indicates that the transactions were merged successfully, a false value if the merge was not possible or failed. If true, the transaction manager will Release() the new transacton instead of pushing it on the undo stack.

Parameters:
aTransactionthe previously executed transaction to merge.

Executes the transaction again.

Can only be called on a transaction that was previously undone.

In most cases, the redoTransaction() method will actually call the doTransaction() method to execute the transaction again.

Reimplemented from EditAggregateTxn.

Definition at line 205 of file DeleteRangeTxn.cpp.

{
#ifdef NS_DEBUG
  if (gNoisy) { printf("Redo Delete Range\n"); }
#endif

  if (!mStartParent || !mEndParent || !mCommonParent || !mEditor) 
    return NS_ERROR_NOT_INITIALIZED;

  return EditAggregateTxn::RedoTransaction();
}

set the name assigned to this txn

Definition at line 209 of file EditAggregateTxn.cpp.

{
  mName = do_QueryInterface(aName);
  return NS_OK;
}

Here is the call graph for this function:

Restores the state to what it was before the transaction was executed.

Reimplemented from EditAggregateTxn.

Definition at line 193 of file DeleteRangeTxn.cpp.

{
#ifdef NS_DEBUG
  if (gNoisy) { printf("Undo Delete Range\n"); }
#endif

  if (!mStartParent || !mEndParent || !mCommonParent || !mEditor) 
    return NS_ERROR_NOT_INITIALIZED;

  return EditAggregateTxn::UndoTransaction();
}

Friends And Related Function Documentation

friend class TransactionFactory [friend]

Definition at line 128 of file DeleteRangeTxn.h.


Member Data Documentation

The transaction's transient state.

This attribute is checked by the transaction manager after the transaction's Execute() method is called. If the transient state is false, a reference to the transaction is held by the transaction manager so that the transactions' undoTransaction() and redoTransaction() methods can be called. If the transient state is true, the transaction manager returns immediately after the transaction's doTransaction() method is called, no references to the transaction are maintained. Transient transactions cannot be undone or redone by the transaction manager.

Definition at line 79 of file nsITransaction.idl.

Definition at line 101 of file EditAggregateTxn.h.

the closest common parent of p1 and p2

Definition at line 117 of file DeleteRangeTxn.h.

the editor for this transaction

Definition at line 123 of file DeleteRangeTxn.h.

p2 offset

Definition at line 120 of file DeleteRangeTxn.h.

p2 in the range

Definition at line 114 of file DeleteRangeTxn.h.

nsCOMPtr<nsIAtom> EditAggregateTxn::mName [protected, inherited]

Definition at line 102 of file EditAggregateTxn.h.

p1 in the range

Definition at line 105 of file DeleteRangeTxn.h.

range updater object

Definition at line 126 of file DeleteRangeTxn.h.

p1 offset

Definition at line 111 of file DeleteRangeTxn.h.

p1 in the range

Definition at line 108 of file DeleteRangeTxn.h.

readonly attribute DOMString nsPIEditorTransaction::txnDescription [inherited]

Definition at line 50 of file nsPIEditorTransaction.idl.


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