Bug 377577 Allow templates to generate arbitrarily nested treeitems r=Enn sr=roc

This commit is contained in:
neil@parkwaycc.co.uk 2007-04-19 12:27:11 -07:00
Родитель 9d85f96e43
Коммит 9482900979
2 изменённых файлов: 47 добавлений и 53 удалений

Просмотреть файл

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