зеркало из https://github.com/mozilla/gecko-dev.git
Bug 377577 Allow templates to generate arbitrarily nested treeitems r=Enn sr=roc
This commit is contained in:
Родитель
9d85f96e43
Коммит
9482900979
|
@ -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;
|
||||
|
||||
|
|
|
@ -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<Link, 8> 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; }
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Загрузка…
Ссылка в новой задаче