diff --git a/layout/html/table/src/nsTableRowGroupFrame.cpp b/layout/html/table/src/nsTableRowGroupFrame.cpp index 570b4925df19..ae8d6864bd41 100644 --- a/layout/html/table/src/nsTableRowGroupFrame.cpp +++ b/layout/html/table/src/nsTableRowGroupFrame.cpp @@ -410,17 +410,6 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresC for ( ; nsnull != kidFrame; ) { - if (ExcludeFrameFromReflow(kidFrame)) { - // The tree widget has some frames that aren't reflowed by - // the normal row group reflow. - if (PR_FALSE==aDoSiblings) - break; - - // Get the next child - GetNextFrameForReflow(aPresContext, kidFrame, &kidFrame); - continue; - } - nsSize kidAvailSize(aReflowState.availSize); if (0>=kidAvailSize.height) kidAvailSize.height = 1; // XXX: HaCk - we don't handle negative heights yet @@ -758,7 +747,7 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext& aPresContext, rowGroupHeight += rowHeights[rowIndex]; rowIndex++; } - else if (!ExcludeFrameFromReflow(rowFrame)) { + else { // Anything that isn't a row contributes to the row group's total height. nsSize frameSize; rowFrame->GetSize(frameSize); diff --git a/layout/html/table/src/nsTableRowGroupFrame.h b/layout/html/table/src/nsTableRowGroupFrame.h index c95ae5909b4f..0f53c7cd86da 100644 --- a/layout/html/table/src/nsTableRowGroupFrame.h +++ b/layout/html/table/src/nsTableRowGroupFrame.h @@ -295,7 +295,6 @@ protected: nsReflowStatus& aStatus, nsReflowReason aReason) { return NS_OK; }; - virtual PRBool ExcludeFrameFromReflow(nsIFrame* aFrame) { return PR_FALSE; }; virtual nsIFrame* GetFirstFrameForReflow(nsIPresContext& aPresContext) { return mFrames.FirstChild(); }; virtual void GetNextFrameForReflow(nsIPresContext& aPresContext, nsIFrame* aFrame, nsIFrame** aResult) { aFrame->GetNextSibling(aResult); }; void GetNextRowSibling(nsIFrame** aRowFrame); diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp index 570b4925df19..ae8d6864bd41 100644 --- a/layout/tables/nsTableRowGroupFrame.cpp +++ b/layout/tables/nsTableRowGroupFrame.cpp @@ -410,17 +410,6 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresC for ( ; nsnull != kidFrame; ) { - if (ExcludeFrameFromReflow(kidFrame)) { - // The tree widget has some frames that aren't reflowed by - // the normal row group reflow. - if (PR_FALSE==aDoSiblings) - break; - - // Get the next child - GetNextFrameForReflow(aPresContext, kidFrame, &kidFrame); - continue; - } - nsSize kidAvailSize(aReflowState.availSize); if (0>=kidAvailSize.height) kidAvailSize.height = 1; // XXX: HaCk - we don't handle negative heights yet @@ -758,7 +747,7 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext& aPresContext, rowGroupHeight += rowHeights[rowIndex]; rowIndex++; } - else if (!ExcludeFrameFromReflow(rowFrame)) { + else { // Anything that isn't a row contributes to the row group's total height. nsSize frameSize; rowFrame->GetSize(frameSize); diff --git a/layout/tables/nsTableRowGroupFrame.h b/layout/tables/nsTableRowGroupFrame.h index c95ae5909b4f..0f53c7cd86da 100644 --- a/layout/tables/nsTableRowGroupFrame.h +++ b/layout/tables/nsTableRowGroupFrame.h @@ -295,7 +295,6 @@ protected: nsReflowStatus& aStatus, nsReflowReason aReason) { return NS_OK; }; - virtual PRBool ExcludeFrameFromReflow(nsIFrame* aFrame) { return PR_FALSE; }; virtual nsIFrame* GetFirstFrameForReflow(nsIPresContext& aPresContext) { return mFrames.FirstChild(); }; virtual void GetNextFrameForReflow(nsIPresContext& aPresContext, nsIFrame* aFrame, nsIFrame** aResult) { aFrame->GetNextSibling(aResult); }; void GetNextRowSibling(nsIFrame** aRowFrame); diff --git a/layout/xul/base/src/nsTreeRowGroupFrame.cpp b/layout/xul/base/src/nsTreeRowGroupFrame.cpp index 110dc66ab1eb..0ea6ab053a60 100644 --- a/layout/xul/base/src/nsTreeRowGroupFrame.cpp +++ b/layout/xul/base/src/nsTreeRowGroupFrame.cpp @@ -73,6 +73,14 @@ nsTreeRowGroupFrame::~nsTreeRowGroupFrame() NS_IF_RELEASE(mContentChain); } +NS_IMETHODIMP +nsTreeRowGroupFrame::DeleteFrame(nsIPresContext& aPresContext) +{ + if (mScrollbar) + mScrollbar->DeleteFrame(aPresContext); + return NS_OK; +} + NS_IMPL_ADDREF(nsTreeRowGroupFrame) NS_IMPL_RELEASE(nsTreeRowGroupFrame) @@ -201,6 +209,68 @@ nsTreeRowGroupFrame::GetFirstRowContent(nsIContent** aResult) } } +void +nsTreeRowGroupFrame::FindRowContentAtIndex(PRInt32& aIndex, nsIContent* aParent, + nsIContent** aResult) +{ + // Init to nsnull. + *aResult = nsnull; + + // It disappoints me that this function is completely tied to the content nodes, + // but I can't see any other way to handle this. I don't have the frames, so I have nothing + // else to fall back on but the content nodes. + + PRInt32 childCount; + aParent->ChildCount(childCount); + + for (PRInt32 i = 0; i < childCount; i++) { + nsCOMPtr childContent; + aParent->ChildAt(i, *getter_AddRefs(childContent)); + nsCOMPtr tag; + childContent->GetTag(*getter_AddRefs(tag)); + if (tag.get() == nsXULAtoms::treerow) { + aIndex--; + if (aIndex < 0) { + *aResult = childContent; + NS_IF_ADDREF(*aResult); + return; + } + } + else if (tag.get() == nsXULAtoms::treeitem) { + // Descend into this row group and try to find the next row. + FindRowContentAtIndex(aIndex, childContent, aResult); + if (aIndex < 0) + return; + + // If it's open, descend into its treechildren. + nsCOMPtr openAtom = dont_AddRef(NS_NewAtom("open")); + nsString isOpen; + childContent->GetAttribute(kNameSpaceID_None, openAtom, isOpen); + if (isOpen == "true") { + // Find the node. + PRInt32 childContentCount; + nsCOMPtr grandChild; + childContent->ChildCount(childContentCount); + + PRInt32 j; + for (j = childContentCount-1; j >= 0; j--) { + + childContent->ChildAt(j, *getter_AddRefs(grandChild)); + nsCOMPtr grandChildTag; + grandChild->GetTag(*getter_AddRefs(grandChildTag)); + if (grandChildTag.get() == nsXULAtoms::treechildren) + break; + } + if (j >= 0 && grandChild) + FindRowContentAtIndex(aIndex, grandChild, aResult); + + if (aIndex < 0) + return; + } + } + } +} + void nsTreeRowGroupFrame::FindPreviousRowContent(PRInt32& aDelta, nsIContent* aUpwardHint, nsIContent* aDownwardHint, nsIContent** aResult) @@ -215,6 +285,10 @@ nsTreeRowGroupFrame::FindPreviousRowContent(PRInt32& aDelta, nsIContent* aUpward nsCOMPtr parentContent; if (aUpwardHint) { aUpwardHint->GetParent(*getter_AddRefs(parentContent)); + if (!parentContent) { + NS_ERROR("Parent content should not be NULL!"); + return; + } parentContent->IndexOf(aUpwardHint, index); } else if (aDownwardHint) { @@ -326,14 +400,22 @@ nsTreeRowGroupFrame::PositionChanged(nsIPresContext& aPresContext, PRInt32 aOldI else { // Just blow away all our frames, but keep a content chain // as a hint to figure out how to build the frames. - NS_ERROR("Not yet implemented!\n"); - //mFrames.DeleteFrames(aPresContext); // Destroys everything. + // Remove the scrollbar first. + mFrames.DeleteFrames(aPresContext); + nsCOMPtr topRowContent; + FindRowContentAtIndex(aNewIndex, mContent, getter_AddRefs(topRowContent)); + ConstructContentChain(topRowContent); } // Invalidate the cell map and column cache. tableFrame->InvalidateCellMap(); tableFrame->InvalidateColumnCache(); + mTopFrame = mBottomFrame = nsnull; // Make sure everything is cleared out. + + // Force a reflow. + OnContentAdded(aPresContext); + return NS_OK; } @@ -349,6 +431,7 @@ nsTreeRowGroupFrame::SetScrollbarFrame(nsIFrame* aFrame) { mIsLazy = PR_TRUE; mScrollbar = aFrame; + nsCOMPtr sliderAtom = dont_AddRef(NS_NewAtom("slider")); nsCOMPtr incrementAtom = dont_AddRef(NS_NewAtom("increment")); nsCOMPtr pageIncrementAtom = dont_AddRef(NS_NewAtom("pageincrement")); @@ -400,6 +483,32 @@ nsTreeRowGroupFrame::GetFrameForPoint(const nsPoint& aPoint, nsIFrame** aFrame) return nsTableRowGroupFrame::GetFrameForPoint(aPoint, aFrame); } +NS_IMETHODIMP +nsTreeRowGroupFrame::FirstChild(nsIAtom* aListName, nsIFrame** aFirstChild) const +{ + nsCOMPtr scrollList = dont_AddRef(NS_NewAtom("scrollbarlist")); + if (scrollList.get() == aListName) { + *aFirstChild = mScrollbarList.FirstChild(); + return NS_OK; + } + + nsTableRowGroupFrame::FirstChild(aListName, aFirstChild); + return NS_OK; +} + +NS_IMETHODIMP +nsTreeRowGroupFrame::GetAdditionalChildListName(PRInt32 aIndex, + nsIAtom** aListName) const +{ + *aListName = nsnull; + + if (aIndex == 0) { + *aListName = NS_NewAtom("scrollbarlist"); // AddRefs + } + + return NS_OK; +} + void nsTreeRowGroupFrame::PaintChildren(nsIPresContext& aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect, @@ -479,29 +588,21 @@ nsTreeRowGroupFrame::ReflowBeforeRowLayout(nsIPresContext& aPresContext, return rv; } - -PRBool nsTreeRowGroupFrame::ExcludeFrameFromReflow(nsIFrame* aFrame) -{ - if (aFrame == mScrollbar) - return PR_TRUE; - else return PR_FALSE; -} - void nsTreeRowGroupFrame::LocateFrame(nsIFrame* aStartFrame, nsIFrame** aResult) { if (aStartFrame == nsnull) { - aStartFrame = mFrames.FirstChild(); + *aResult = mFrames.FirstChild(); } - else aStartFrame->GetNextSibling(&aStartFrame); + else aStartFrame->GetNextSibling(aResult); - if (!aStartFrame) { - *aResult = nsnull; - } else if (aStartFrame != mScrollbar) { - *aResult = aStartFrame; - } else { - aStartFrame->GetNextSibling(&aStartFrame); - *aResult = aStartFrame; + if (mScrollbar && (*aResult == mScrollbar)) { + // Get this out of our flow. + mScrollbar->GetNextSibling(aResult); + mFrames.RemoveFrame(mScrollbar); + + // Put it into a special list of our own. + mScrollbarList.AppendFrame(this, mScrollbar); } } diff --git a/layout/xul/base/src/nsTreeRowGroupFrame.h b/layout/xul/base/src/nsTreeRowGroupFrame.h index ef267afd87aa..fcd158bd77c1 100644 --- a/layout/xul/base/src/nsTreeRowGroupFrame.h +++ b/layout/xul/base/src/nsTreeRowGroupFrame.h @@ -30,7 +30,9 @@ class nsTreeRowGroupFrame : public nsTableRowGroupFrame, public nsIScrollbarList public: friend nsresult NS_NewTreeRowGroupFrame(nsIFrame** aNewFrame); - virtual PRBool ExcludeFrameFromReflow(nsIFrame* aFrame); + NS_IMETHOD GetAdditionalChildListName(PRInt32 aIndex, + nsIAtom** aListName) const; + NS_IMETHOD FirstChild(nsIAtom* aListName, nsIFrame** aFirstChild) const; void SetScrollbarFrame(nsIFrame* aFrame); void SetFrameConstructor(nsCSSFrameConstructor* aFrameConstructor) { mFrameConstructor = aFrameConstructor; }; @@ -93,8 +95,12 @@ protected: void ConstructContentChain(nsIContent* aRowContent); void FindPreviousRowContent(PRInt32& aDelta, nsIContent* aUpwardHint, nsIContent* aDownwardHint, nsIContent** aResult); + void FindRowContentAtIndex(PRInt32& aIndex, nsIContent* aParent, + nsIContent** aResult); void GetFirstRowContent(nsIContent** aRowContent); + NS_IMETHOD DeleteFrame(nsIPresContext& aPresContext); + protected: // Data Members nsIFrame* mTopFrame; // The current topmost frame in the view. nsIFrame* mBottomFrame; // The current bottom frame in the view. @@ -104,7 +110,8 @@ protected: // Data Members PRBool mIsFull; // Whether or not we have any more room. nsIFrame* mScrollbar; // Our scrollbar. - + nsFrameList mScrollbarList; // A frame list that holds our scrollbar. + nsISupportsArray* mContentChain; // Our content chain nsCSSFrameConstructor* mFrameConstructor; // We don't own this. (No addref/release allowed, punk.)