From 948290097940d79a09b7ae6b14aa18665bf51aae Mon Sep 17 00:00:00 2001 From: "neil@parkwaycc.co.uk" Date: Thu, 19 Apr 2007 12:27:11 -0700 Subject: [PATCH] Bug 377577 Allow templates to generate arbitrarily nested treeitems r=Enn sr=roc --- content/xul/templates/src/nsTreeRows.cpp | 65 +++++++++++------------- content/xul/templates/src/nsTreeRows.h | 35 ++++++------- 2 files changed, 47 insertions(+), 53 deletions(-) diff --git a/content/xul/templates/src/nsTreeRows.cpp b/content/xul/templates/src/nsTreeRows.cpp index c8064f21fb82..0e67c12e3e30 100644 --- a/content/xul/templates/src/nsTreeRows.cpp +++ b/content/xul/templates/src/nsTreeRows.cpp @@ -117,7 +117,7 @@ nsTreeRows::Last() } while (current && ((count = current->Count()) != 0)); // Now, at the bottom rightmost leaf, advance us one off the end. - result.mLink[result.mTop].mChildIndex++; + result.GetTop().mChildIndex++; // Our row index will be the size of the root subree, plus one. result.SetRowIndex(mRoot.GetSubtreeSize() + 1); @@ -362,71 +362,64 @@ nsTreeRows::Subtree::RemoveRowAt(PRInt32 aIndex) // nsTreeRows::iterator::iterator(const iterator& aIterator) - : mTop(aIterator.mTop), - mRowIndex(aIterator.mRowIndex) + : mRowIndex(aIterator.mRowIndex), + mLink(aIterator.mLink) { - for (PRInt32 i = mTop; i >= 0; --i) - mLink[i] = aIterator.mLink[i]; } nsTreeRows::iterator& nsTreeRows::iterator::operator=(const iterator& aIterator) { - mTop = aIterator.mTop; mRowIndex = aIterator.mRowIndex; - for (PRInt32 i = mTop; i >= 0; --i) - mLink[i] = aIterator.mLink[i]; + mLink = aIterator.mLink; return *this; } void nsTreeRows::iterator::Append(Subtree* aParent, PRInt32 aChildIndex) { - if (mTop < kMaxDepth - 1) { - ++mTop; - mLink[mTop].mParent = aParent; - mLink[mTop].mChildIndex = aChildIndex; + Link *link = mLink.AppendElement(); + if (link) { + link->mParent = aParent; + link->mChildIndex = aChildIndex; } else - NS_ERROR("overflow"); + NS_ERROR("out of memory"); } void nsTreeRows::iterator::Push(Subtree *aParent, PRInt32 aChildIndex) { - if (mTop < kMaxDepth - 1) { - for (PRInt32 i = mTop; i >= 0; --i) - mLink[i + 1] = mLink[i]; - - mLink[0].mParent = aParent; - mLink[0].mChildIndex = aChildIndex; - ++mTop; + Link *link = mLink.InsertElementAt(0); + if (link) { + link->mParent = aParent; + link->mChildIndex = aChildIndex; } else - NS_ERROR("overflow"); + NS_ERROR("out of memory"); } PRBool nsTreeRows::iterator::operator==(const iterator& aIterator) const { - if (mTop != aIterator.mTop) + if (GetDepth() != aIterator.GetDepth()) return PR_FALSE; - if (mTop == -1) + if (GetDepth() == 0) return PR_TRUE; - return PRBool(mLink[mTop] == aIterator.mLink[mTop]); + return GetTop() == aIterator.GetTop(); } void nsTreeRows::iterator::Next() { - NS_PRECONDITION(mTop >= 0, "cannot increment an uninitialized iterator"); + NS_PRECONDITION(GetDepth() > 0, "cannot increment an uninitialized iterator"); // Increment the absolute row index ++mRowIndex; - Link& top = mLink[mTop]; + Link& top = GetTop(); // Is there a child subtree? If so, descend into the child // subtree. @@ -443,7 +436,7 @@ nsTreeRows::iterator::Next() // the tree, period. Walk back up the stack, looking for any // unfinished subtrees. PRInt32 unfinished; - for (unfinished = mTop - 1; unfinished >= 0; --unfinished) { + for (unfinished = GetDepth() - 2; unfinished >= 0; --unfinished) { const Link& link = mLink[unfinished]; if (link.mChildIndex < link.mParent->Count() - 1) break; @@ -459,31 +452,31 @@ nsTreeRows::iterator::Next() // Otherwise, we ran off the end of one of the inner // subtrees. Pop up to the next unfinished level in the stack. - mTop = unfinished; + mLink.SetLength(unfinished + 1); } // Advance to the next child in this subtree - ++(mLink[mTop].mChildIndex); + ++(GetTop().mChildIndex); } void nsTreeRows::iterator::Prev() { - NS_PRECONDITION(mTop >= 0, "cannot increment an uninitialized iterator"); + NS_PRECONDITION(GetDepth() > 0, "cannot increment an uninitialized iterator"); // Decrement the absolute row index --mRowIndex; // Move to the previous child in this subtree - --(mLink[mTop].mChildIndex); + --(GetTop().mChildIndex); // Have we exhausted the current subtree? - if (mLink[mTop].mChildIndex < 0) { + if (GetTop().mChildIndex < 0) { // Yep. See if we've just iterated back to the first element // in the tree, period. Walk back up the stack, looking for // any unfinished subtrees. PRInt32 unfinished; - for (unfinished = mTop - 1; unfinished >= 0; --unfinished) { + for (unfinished = GetDepth() - 2; unfinished >= 0; --unfinished) { const Link& link = mLink[unfinished]; if (link.mChildIndex >= 0) break; @@ -497,15 +490,15 @@ nsTreeRows::iterator::Prev() // Otherwise, we ran off the end of one of the inner // subtrees. Pop up to the next unfinished level in the stack. - mTop = unfinished; + mLink.SetLength(unfinished + 1); return; } // Is there a child subtree immediately prior to our current // position? If so, descend into it, grovelling down to the // deepest, rightmost left edge. - Subtree* parent = mLink[mTop].GetParent(); - PRInt32 index = mLink[mTop].GetChildIndex(); + Subtree* parent = GetTop().GetParent(); + PRInt32 index = GetTop().GetChildIndex(); Subtree* subtree = (*parent)[index].mSubtree; diff --git a/content/xul/templates/src/nsTreeRows.h b/content/xul/templates/src/nsTreeRows.h index 880602223dd9..c2e455f1c2ae 100644 --- a/content/xul/templates/src/nsTreeRows.h +++ b/content/xul/templates/src/nsTreeRows.h @@ -40,6 +40,7 @@ #define nsTreeRows_h__ #include "nsCOMPtr.h" +#include "nsTArray.h" #include "pldhash.h" #include "nsIXULTemplateResult.h" #include "nsTemplateMatch.h" @@ -186,8 +187,6 @@ public: friend class Subtree; - enum { kMaxDepth = 32 }; - protected: /** * A link in the path through the view's tree. @@ -222,9 +221,8 @@ public: */ class iterator { protected: - PRInt32 mTop; PRInt32 mRowIndex; - Link mLink[kMaxDepth]; + nsAutoTArray mLink; void Next(); void Prev(); @@ -247,8 +245,14 @@ public: */ void SetRowIndex(PRInt32 aRowIndex) { mRowIndex = aRowIndex; } + /** + * Handy accessors to the top element. + */ + Link& GetTop() { return mLink[mLink.Length() - 1]; } + const Link& GetTop() const { return mLink[mLink.Length() - 1]; } + public: - iterator() : mTop(-1), mRowIndex(-1) {} + iterator() : mRowIndex(-1) {} iterator(const iterator& aIterator); iterator& operator=(const iterator& aIterator); @@ -258,11 +262,11 @@ public: PRBool operator!=(const iterator& aIterator) const { return !aIterator.operator==(*this); } - const Row& operator*() const { return mLink[mTop].GetRow(); } - Row& operator*() { return mLink[mTop].GetRow(); } + const Row& operator*() const { return GetTop().GetRow(); } + Row& operator*() { return GetTop().GetRow(); } - const Row* operator->() const { return &(mLink[mTop].GetRow()); } - Row* operator->() { return &(mLink[mTop].GetRow()); } + const Row* operator->() const { return &(GetTop().GetRow()); } + Row* operator->() { return &(GetTop().GetRow()); } iterator& operator++() { Next(); return *this; } iterator operator++(int) { iterator temp(*this); Next(); return temp; } @@ -272,23 +276,20 @@ public: /** * Return the current parent link */ - Subtree* GetParent() { - return mLink[mTop].GetParent(); } + Subtree* GetParent() { return GetTop().GetParent(); } - const Subtree* GetParent() const { - return mLink[mTop].GetParent(); } + const Subtree* GetParent() const { return GetTop().GetParent(); } /** * Return the current child index */ - PRInt32 GetChildIndex() const { - return mLink[mTop].GetChildIndex(); } + PRInt32 GetChildIndex() const { return GetTop().GetChildIndex(); } /** * Return the depth of the path the iterator is maintaining * into the tree. */ - PRInt32 GetDepth() const { return mTop + 1; } + PRInt32 GetDepth() const { return mLink.Length(); } /** * Return the current row index of the iterator @@ -298,7 +299,7 @@ public: /** * Pop the iterator up a level. */ - iterator& Pop() { --mTop; return *this; } + iterator& Pop() { mLink.SetLength(GetDepth() - 1); return *this; } }; /**