diff --git a/layout/xul/base/src/nsTreeFrame.cpp b/layout/xul/base/src/nsTreeFrame.cpp index 65194ea04bab..83f279388ef6 100644 --- a/layout/xul/base/src/nsTreeFrame.cpp +++ b/layout/xul/base/src/nsTreeFrame.cpp @@ -72,6 +72,24 @@ nsTreeFrame::~nsTreeFrame() { } +NS_IMPL_ADDREF_INHERITED(nsTreeFrame, nsTableFrame) +NS_IMPL_RELEASE_INHERITED(nsTreeFrame, nsTableFrame) + +NS_IMETHODIMP nsTreeFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr) +{ + if (NULL == aInstancePtr) { + return NS_ERROR_NULL_POINTER; + } + + *aInstancePtr = NULL; + if (aIID.Equals(NS_GET_IID(nsISelfScrollingFrame))) { + *aInstancePtr = (void*)(nsISelfScrollingFrame*) this; + return NS_OK; + } + + return nsTableFrame::QueryInterface(aIID, aInstancePtr); +} + void nsTreeFrame::SetSelection(nsIPresContext& aPresContext, nsTreeCellFrame* aFrame) { nsCOMPtr cellContent; @@ -207,12 +225,19 @@ nsTreeFrame::HandleEvent(nsIPresContext& aPresContext, rowIndex++; else if (keyCode == NS_VK_UP) rowIndex--; - - if (!treeRowGroup->IsValidRow(rowIndex)) - return NS_OK; - // Ensure that the required index is visible. - treeRowGroup->EnsureRowIsVisible(rowIndex); + // adjust for zero-based mRowCount + nsTableRowFrame* firstRow=nsnull; + treeRowGroup->GetFirstRowFrame(&firstRow); + if (firstRow) { + PRInt32 rowNumber = rowIndex - firstRow->GetRowIndex(); + + if (!treeRowGroup->IsValidRow(rowNumber)) + return NS_OK; + + // Ensure that the required index is visible. + treeRowGroup->EnsureRowIsVisible(rowNumber); + } // Now that the row is scrolled into view, we have a frame created. We can retrieve the cell. nsTreeCellFrame* cellFrame=nsnull; @@ -454,3 +479,20 @@ nsTreeFrame::GetInsertionIndex(nsIFrame *aFrame) } return index; } + + +NS_IMETHODIMP +nsTreeFrame::ScrollByLines(nsIPresContext& aPresContext, PRInt32 lines) +{ + // Get our treechildren child frame. + nsTreeRowGroupFrame* treeRowGroup = nsnull; + GetTreeBody(&treeRowGroup); + + if (!treeRowGroup) + return NS_OK; // No tree body. Just bail. + + treeRowGroup->ScrollByLines(aPresContext, lines); + return NS_OK; +} + + diff --git a/layout/xul/base/src/nsTreeFrame.h b/layout/xul/base/src/nsTreeFrame.h index ae62bd9b8823..09a00a162c92 100644 --- a/layout/xul/base/src/nsTreeFrame.h +++ b/layout/xul/base/src/nsTreeFrame.h @@ -22,16 +22,19 @@ #include "nsTableFrame.h" #include "nsVoidArray.h" +#include "nsISelfScrollingFrame.h" class nsTreeCellFrame; class nsTreeRowGroupFrame; class nsTreeTwistyListener; -class nsTreeFrame : public nsTableFrame +class nsTreeFrame : public nsTableFrame, public nsISelfScrollingFrame { public: friend nsresult NS_NewTreeFrame(nsIFrame** aNewFrame); + NS_DECL_ISUPPORTS_INHERITED + void SetSelection(nsIPresContext& presContext, nsTreeCellFrame* pFrame); void ToggleSelection(nsIPresContext& presContext, nsTreeCellFrame* pFrame); void RangedSelection(nsIPresContext& aPresContext, nsTreeCellFrame* pEndFrame); @@ -83,6 +86,9 @@ public: PRInt32 GetInsertionIndex(nsIFrame *aFrame); + // nsISelfScrollingFrame interface + NS_IMETHOD ScrollByLines(nsIPresContext& aPresContext, PRInt32 lines); + protected: nsTreeFrame(); virtual ~nsTreeFrame(); diff --git a/layout/xul/base/src/nsTreeRowGroupFrame.cpp b/layout/xul/base/src/nsTreeRowGroupFrame.cpp index 0978426032d7..4aa17d01b89d 100644 --- a/layout/xul/base/src/nsTreeRowGroupFrame.cpp +++ b/layout/xul/base/src/nsTreeRowGroupFrame.cpp @@ -476,7 +476,7 @@ nsTreeRowGroupFrame::FindRowContentAtIndex(PRInt32& aIndex, // If it's open, descend into its treechildren. nsCOMPtr openAtom = dont_AddRef(NS_NewAtom("open")); - nsString isOpen; + nsAutoString isOpen; childContent->GetAttribute(kNameSpaceID_None, openAtom, isOpen); if (isOpen == "true") { // Find the node. @@ -532,7 +532,7 @@ nsTreeRowGroupFrame::FindPreviousRowContent(PRInt32& aDelta, nsIContent* aUpward /* Let me see inside the damn nsCOMptrs nsIAtom* aAtom; parentContent->GetTag(aAtom); - nsString result; + nsAutoString result; aAtom->ToString(result); */ @@ -552,7 +552,7 @@ nsTreeRowGroupFrame::FindPreviousRowContent(PRInt32& aDelta, nsIContent* aUpward else if (tag.get() == nsXULAtoms::treeitem) { // If it's open, descend into its treechildren node first. nsCOMPtr openAtom = dont_AddRef(NS_NewAtom("open")); - nsString isOpen; + nsAutoString isOpen; childContent->GetAttribute(kNameSpaceID_None, openAtom, isOpen); if (isOpen == "true") { // Find the node. @@ -618,7 +618,7 @@ nsTreeRowGroupFrame::ComputeTotalRowCount(PRInt32& aCount, nsIContent* aParent) else if (tag.get() == nsXULAtoms::treechildren) { // If it's open, descend into its treechildren. nsCOMPtr openAtom = dont_AddRef(NS_NewAtom("open")); - nsString isOpen; + nsAutoString isOpen; nsCOMPtr parent; childContent->GetParent(*getter_AddRefs(parent)); parent->GetAttribute(kNameSpaceID_None, openAtom, isOpen); @@ -733,7 +733,7 @@ nsTreeRowGroupFrame::PagedUpDown() #ifdef DEBUG_tree printf("PagedUpDown, setting increment to %d\n", rowGroupCount); #endif - scrollbarContent->SetAttribute(kNameSpaceID_None, nsXULAtoms::pageincrement, nsString(ch), PR_FALSE); + scrollbarContent->SetAttribute(kNameSpaceID_None, nsXULAtoms::pageincrement, nsAutoString(ch), PR_FALSE); } return NS_OK; @@ -960,7 +960,7 @@ nsTreeRowGroupFrame::ReflowAfterRowLayout(nsIPresContext& aPresContext, if (rowCount < 0) rowCount = 0; - nsString maxpos; + nsAutoString maxpos; if (!mIsFull) { // We are not full. This means that we are not allowed to scroll any further. We are // at the max position right now. @@ -1444,11 +1444,6 @@ nsTreeRowGroupFrame::IndexOfRow(nsIPresContext& aPresContext, PRBool nsTreeRowGroupFrame::IsValidRow(PRInt32 aRowIndex) { - // adjust for zero-based mRowCount - nsTableRowFrame* firstRow=nsnull; - GetFirstRow(&firstRow); - aRowIndex -= firstRow->GetRowIndex(); - if (aRowIndex >= 0 && aRowIndex < mRowCount) return PR_TRUE; return PR_FALSE; @@ -1460,11 +1455,6 @@ nsTreeRowGroupFrame::EnsureRowIsVisible(PRInt32 aRowIndex) // if no scrollbar, then it must be visible if (!mScrollbar) return; - // adjust row index for zero-based scrollbar - nsTableRowFrame* firstRow=nsnull; - GetFirstRow(&firstRow); - aRowIndex -= firstRow->GetRowIndex(); - PRInt32 rows; GetRowCount(rows); PRInt32 bottomIndex = mCurrentIndex + rows - 1; @@ -1501,7 +1491,7 @@ nsTreeRowGroupFrame::EnsureRowIsVisible(PRInt32 aRowIndex) } - nsString value; + nsAutoString value; #ifdef DEBUG_tree // dump state @@ -1574,6 +1564,31 @@ void nsTreeRowGroupFrame::PostAppendRow(nsIFrame* aRowFrame, nsIPresContext& aPr } } +void nsTreeRowGroupFrame::ScrollByLines(nsIPresContext& aPresContext, + PRInt32 lines) +{ + if (nsnull == mScrollbar) // nothing to scroll + return; + + PRInt32 scrollTo = mCurrentIndex + lines; + PRInt32 visRows, totalRows; + totalRows = GetVisibleRowCount(); + GetRowCount(visRows); + + if (scrollTo < 0) + scrollTo = 0; + if (!IsValidRow(scrollTo + visRows - 1)) // don't go down too far + scrollTo = totalRows - visRows + 1; + nsAutoString value; + value.Append(scrollTo); + + nsCOMPtr scrollbarContent; + mScrollbar->GetContent(getter_AddRefs(scrollbarContent)); + if (scrollbarContent) + scrollbarContent->SetAttribute(kNameSpaceID_None, nsXULAtoms::curpos, + value, PR_TRUE); +} + void nsTreeRowGroupFrame::MarkTreeAsDirty(nsIPresContext& aPresContext, nsTreeFrame* aTreeFrame) @@ -1686,7 +1701,7 @@ nsTreeRowGroupFrame::GetInsertionIndex(nsIFrame *aFrame, PRInt32 aCurrentIndex, } void -nsTreeRowGroupFrame::GetFirstRow(nsTableRowFrame **aRowFrame) +nsTreeRowGroupFrame::GetFirstRowFrame(nsTableRowFrame **aRowFrame) { nsIFrame* child = mFrames.FirstChild(); @@ -1697,7 +1712,7 @@ nsTreeRowGroupFrame::GetFirstRow(nsTableRowFrame **aRowFrame) } if (IsTableRowGroupFrame(child)) { - ((nsTreeRowGroupFrame*)child)->GetFirstRow(aRowFrame); + ((nsTreeRowGroupFrame*)child)->GetFirstRowFrame(aRowFrame); if (*aRowFrame) return; } diff --git a/layout/xul/base/src/nsTreeRowGroupFrame.h b/layout/xul/base/src/nsTreeRowGroupFrame.h index 609bb52a1cdf..69b3767b5a32 100644 --- a/layout/xul/base/src/nsTreeRowGroupFrame.h +++ b/layout/xul/base/src/nsTreeRowGroupFrame.h @@ -95,6 +95,8 @@ public: NS_IMETHOD PositionChanged(nsIPresContext& aPresContext, PRInt32 aOldIndex, PRInt32 aNewIndex); NS_IMETHOD PagedUpDown(); + void ScrollByLines(nsIPresContext& aPresContext, PRInt32 lines); + protected: nsTreeRowGroupFrame(); virtual ~nsTreeRowGroupFrame(); @@ -150,8 +152,6 @@ protected: void PostAppendRow(nsIFrame* aRowFrame, nsIPresContext& aPresContext); - void GetFirstRow(nsTableRowFrame **aRowFrame); - public: // Helpers that allow access to info. The tree is the primary consumer of this // info. @@ -165,6 +165,9 @@ public: // This method is expensive. void IndexOfRow(nsIPresContext& aPresContext, nsIContent* aRowContent, PRInt32& aRowIndex); + // get the first frame + void GetFirstRowFrame(nsTableRowFrame **aRowFrame); + // Whether or not the row is valid. This is a cheap method, since the total row count // is cached. PRBool IsValidRow(PRInt32 aRowIndex);