Outliner files are not part of build.

The other files are a fix for bug #70809.  r=attinasi, sr=brendan


git-svn-id: svn://10.0.0.236/trunk@88614 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
hyatt%netscape.com 2001-03-06 02:27:50 +00:00
parent 1d63570fda
commit 11b2e924f2
51 changed files with 1403 additions and 359 deletions

View File

@ -78,6 +78,7 @@ XUL_ATOM(open, "open") // Whether or not a menu, tree, etc. is open
XUL_ATOM(outliner, "outliner")
XUL_ATOM(outlinerbody, "outlinerbody")
XUL_ATOM(outlinercol, "outlinercol")
XUL_ATOM(cycler, "cycler")
XUL_ATOM(primary, "primary")
XUL_ATOM(current, "current")
@ -87,6 +88,7 @@ XUL_ATOM(mozoutlinercolumn, ":-moz-outliner-column")
XUL_ATOM(mozoutlinercelltext, ":-moz-outliner-cell-text")
XUL_ATOM(mozoutlinertwisty, ":-moz-outliner-twisty")
XUL_ATOM(mozoutlinerindentation, ":-moz-outliner-indentation")
XUL_ATOM(mozoutlinerline, ":-moz-outliner-line")
XUL_ATOM(menubar, "menubar") // An XP menu bar.
XUL_ATOM(menu, "menu") // Represents an XP menu

View File

@ -677,6 +677,17 @@ const PRInt32 nsCSSProps::kWhitespaceKTable[] = {
-1,-1
};
#ifdef INCLUDE_XUL
// Specific keyword tables for XUL.properties
const PRInt32 nsCSSProps::kBoxOrientKTable[] = {
eCSSKeyword_horizontal, NS_STYLE_BOX_ORIENT_HORIZONTAL,
eCSSKeyword_vertical, NS_STYLE_BOX_ORIENT_VERTICAL,
eCSSKeyword_inline_axis, NS_STYLE_BOX_ORIENT_HORIZONTAL,
eCSSKeyword_block_axis, NS_STYLE_BOX_ORIENT_VERTICAL,
-1,-1
};
#endif
PRInt32
nsCSSProps::SearchKeywordTableInt(PRInt32 aValue, const PRInt32 aTable[])
{
@ -763,6 +774,11 @@ static const PRInt32 kBackgroundYPositionKTable[] = {
case eCSSProperty_border_collapse:
return SearchKeywordTable(aValue, kBorderCollapseKTable);
#ifdef INCLUDE_XUL
case eCSSProperty_box_orient:
return SearchKeywordTable(aValue, kBoxOrientKTable);
#endif
case eCSSProperty_box_sizing:
return SearchKeywordTable(aValue, kBoxSizingKTable);

View File

@ -5271,7 +5271,7 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
// create a box. Its not root, its layout manager is default (nsnull) which is "sprocket" and
// its default orientation is horizontal for hbox and vertical for vbox
rv = NS_NewBoxFrame(aPresShell, &newFrame, PR_FALSE, nsnull, aTag != nsXULAtoms::vbox);
rv = NS_NewBoxFrame(aPresShell, &newFrame, PR_FALSE, nsnull);
// Boxes can scroll.
if (IsScrollable(aPresContext, display)) {
@ -5502,9 +5502,7 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
PRBool isHorizontal = (aTag == nsXULAtoms::columns)
|| (aTag == nsXULAtoms::treecolgroup) || (aTag == nsXULAtoms::treecols)
;
nsCOMPtr<nsIBoxLayout> layout;
PRBool treeScrollPort = PR_FALSE;
@ -5515,12 +5513,12 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
nsAutoString outer;
rv = aContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::outer, outer);
if (outer.EqualsIgnoreCase("true")) {
rv = NS_NewXULTreeOuterGroupFrame(aPresShell, &newFrame, PR_FALSE, layout, PR_FALSE);
rv = NS_NewXULTreeOuterGroupFrame(aPresShell, &newFrame, PR_FALSE, layout);
((nsXULTreeGroupFrame*)newFrame)->InitGroup(this, aPresContext, (nsXULTreeOuterGroupFrame*) newFrame);
treeScrollPort = PR_TRUE;
}
else {
rv = NS_NewXULTreeGroupFrame(aPresShell, &newFrame, PR_FALSE, layout, PR_FALSE);
rv = NS_NewXULTreeGroupFrame(aPresShell, &newFrame, PR_FALSE, layout);
((nsXULTreeGroupFrame*)newFrame)->InitGroup(this, aPresContext, ((nsXULTreeGroupFrame*)aParentFrame)->GetOuterFrame());
}
@ -5529,7 +5527,7 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
else
{
NS_NewTempleLayout(aPresShell, layout);
rv = NS_NewBoxFrame(aPresShell, &newFrame, PR_FALSE, layout, isHorizontal);
rv = NS_NewBoxFrame(aPresShell, &newFrame, PR_FALSE, layout);
}
const nsStyleDisplay* display = (const nsStyleDisplay*)
@ -5563,14 +5561,14 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
PRBool isHorizontal = (aTag == nsXULAtoms::row) || (aTag == nsXULAtoms::treerow);
nsCOMPtr<nsIBoxLayout> layout;
NS_NewObeliskLayout(aPresShell, layout);
if (aTag == nsXULAtoms::treerow)
rv = NS_NewXULTreeSliceFrame(aPresShell, &newFrame, PR_FALSE, layout, isHorizontal);
rv = NS_NewXULTreeSliceFrame(aPresShell, &newFrame, PR_FALSE, layout);
else
rv = NS_NewBoxFrame(aPresShell, &newFrame, PR_FALSE, layout, isHorizontal);
rv = NS_NewBoxFrame(aPresShell, &newFrame, PR_FALSE, layout);
const nsStyleDisplay* display = (const nsStyleDisplay*)
aStyleContext->GetStyleData(eStyleStruct_Display);

View File

@ -100,7 +100,9 @@
#define NS_STYLE_USER_MODIFY_READ_WRITE 1
#define NS_STYLE_USER_MODIFY_WRITE_ONLY 2
// box-orient
#define NS_STYLE_BOX_ORIENT_HORIZONTAL 0
#define NS_STYLE_BOX_ORIENT_VERTICAL 1
// Azimuth - See nsStyleAural
#define NS_STYLE_AZIMUTH_LEFT_SIDE 0x00

View File

@ -670,6 +670,19 @@ struct nsStylePrint: public nsStyleStruct {
nsStyleCoord mSizeHeight; // [reset] length, enum: see nsStyleConsts.h NS_STYLE_PAGE_SIZE_*
};
#ifdef INCLUDE_XUL
struct nsStyleXUL : public nsStyleStruct {
nsStyleXUL();
~nsStyleXUL();
// There will be seven more properties coming,
// which is why we warrant our own struct.
// box-align, box-direction, box-flex, box-flex-group, box-pack,
// stack-stretch, stack-policy
PRUint8 mBoxOrient; // [reset] see nsStyleConsts.h
};
#endif
#define BORDER_PRECEDENT_EQUAL 0
#define BORDER_PRECEDENT_LOWER 1
#define BORDER_PRECEDENT_HIGHER 2

View File

@ -100,7 +100,9 @@
#define NS_STYLE_USER_MODIFY_READ_WRITE 1
#define NS_STYLE_USER_MODIFY_WRITE_ONLY 2
// box-orient
#define NS_STYLE_BOX_ORIENT_HORIZONTAL 0
#define NS_STYLE_BOX_ORIENT_VERTICAL 1
// Azimuth - See nsStyleAural
#define NS_STYLE_AZIMUTH_LEFT_SIDE 0x00

View File

@ -37,13 +37,16 @@ enum nsStyleStructID {
eStyleStruct_Padding = 12,
eStyleStruct_Border = 13,
eStyleStruct_Outline = 14,
#ifdef INCLUDE_XUL
eStyleStruct_XUL = 15,
eStyleStruct_Max = eStyleStruct_XUL,
eStyleStruct_BorderPaddingShortcut = 16 // only for use in GetStyle()
#else
eStyleStruct_Max = eStyleStruct_Outline,
eStyleStruct_BorderPaddingShortcut = 15 // only for use in GetStyle()
#endif
};
struct nsStyleStruct {
};

View File

@ -416,6 +416,7 @@ noscript, noframes, param, :-moz-comment, :-moz-pi {
background: inherit;
padding: inherit;
display: inherit;
-moz-box-orient: inherit;
}
:wrapped-frame {

View File

@ -5271,7 +5271,7 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
// create a box. Its not root, its layout manager is default (nsnull) which is "sprocket" and
// its default orientation is horizontal for hbox and vertical for vbox
rv = NS_NewBoxFrame(aPresShell, &newFrame, PR_FALSE, nsnull, aTag != nsXULAtoms::vbox);
rv = NS_NewBoxFrame(aPresShell, &newFrame, PR_FALSE, nsnull);
// Boxes can scroll.
if (IsScrollable(aPresContext, display)) {
@ -5502,9 +5502,7 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
PRBool isHorizontal = (aTag == nsXULAtoms::columns)
|| (aTag == nsXULAtoms::treecolgroup) || (aTag == nsXULAtoms::treecols)
;
nsCOMPtr<nsIBoxLayout> layout;
PRBool treeScrollPort = PR_FALSE;
@ -5515,12 +5513,12 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
nsAutoString outer;
rv = aContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::outer, outer);
if (outer.EqualsIgnoreCase("true")) {
rv = NS_NewXULTreeOuterGroupFrame(aPresShell, &newFrame, PR_FALSE, layout, PR_FALSE);
rv = NS_NewXULTreeOuterGroupFrame(aPresShell, &newFrame, PR_FALSE, layout);
((nsXULTreeGroupFrame*)newFrame)->InitGroup(this, aPresContext, (nsXULTreeOuterGroupFrame*) newFrame);
treeScrollPort = PR_TRUE;
}
else {
rv = NS_NewXULTreeGroupFrame(aPresShell, &newFrame, PR_FALSE, layout, PR_FALSE);
rv = NS_NewXULTreeGroupFrame(aPresShell, &newFrame, PR_FALSE, layout);
((nsXULTreeGroupFrame*)newFrame)->InitGroup(this, aPresContext, ((nsXULTreeGroupFrame*)aParentFrame)->GetOuterFrame());
}
@ -5529,7 +5527,7 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
else
{
NS_NewTempleLayout(aPresShell, layout);
rv = NS_NewBoxFrame(aPresShell, &newFrame, PR_FALSE, layout, isHorizontal);
rv = NS_NewBoxFrame(aPresShell, &newFrame, PR_FALSE, layout);
}
const nsStyleDisplay* display = (const nsStyleDisplay*)
@ -5563,14 +5561,14 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell,
) {
processChildren = PR_TRUE;
isReplaced = PR_TRUE;
PRBool isHorizontal = (aTag == nsXULAtoms::row) || (aTag == nsXULAtoms::treerow);
nsCOMPtr<nsIBoxLayout> layout;
NS_NewObeliskLayout(aPresShell, layout);
if (aTag == nsXULAtoms::treerow)
rv = NS_NewXULTreeSliceFrame(aPresShell, &newFrame, PR_FALSE, layout, isHorizontal);
rv = NS_NewXULTreeSliceFrame(aPresShell, &newFrame, PR_FALSE, layout);
else
rv = NS_NewBoxFrame(aPresShell, &newFrame, PR_FALSE, layout, isHorizontal);
rv = NS_NewBoxFrame(aPresShell, &newFrame, PR_FALSE, layout);
const nsStyleDisplay* display = (const nsStyleDisplay*)
aStyleContext->GetStyleData(eStyleStruct_Display);

View File

@ -97,6 +97,7 @@ CSS_KEY(bengali, bengali)
CSS_KEY(bidi-override, bidi_override)
CSS_KEY(blink, blink)
CSS_KEY(block, block)
CSS_KEY(block-axis, block_axis)
CSS_KEY(bold, bold)
CSS_KEY(bolder, bolder)
CSS_KEY(border-box, border_box)

View File

@ -677,6 +677,17 @@ const PRInt32 nsCSSProps::kWhitespaceKTable[] = {
-1,-1
};
#ifdef INCLUDE_XUL
// Specific keyword tables for XUL.properties
const PRInt32 nsCSSProps::kBoxOrientKTable[] = {
eCSSKeyword_horizontal, NS_STYLE_BOX_ORIENT_HORIZONTAL,
eCSSKeyword_vertical, NS_STYLE_BOX_ORIENT_VERTICAL,
eCSSKeyword_inline_axis, NS_STYLE_BOX_ORIENT_HORIZONTAL,
eCSSKeyword_block_axis, NS_STYLE_BOX_ORIENT_VERTICAL,
-1,-1
};
#endif
PRInt32
nsCSSProps::SearchKeywordTableInt(PRInt32 aValue, const PRInt32 aTable[])
{
@ -763,6 +774,11 @@ static const PRInt32 kBackgroundYPositionKTable[] = {
case eCSSProperty_border_collapse:
return SearchKeywordTable(aValue, kBorderCollapseKTable);
#ifdef INCLUDE_XUL
case eCSSProperty_box_orient:
return SearchKeywordTable(aValue, kBoxOrientKTable);
#endif
case eCSSProperty_box_sizing:
return SearchKeywordTable(aValue, kBoxSizingKTable);

View File

@ -76,6 +76,9 @@ public:
static const PRInt32 kBorderColorKTable[];
static const PRInt32 kBorderStyleKTable[];
static const PRInt32 kBorderWidthKTable[];
#ifdef INCLUDE_XUL
static const PRInt32 kBoxOrientKTable[];
#endif
static const PRInt32 kBoxSizingKTable[];
static const PRInt32 kCaptionSideKTable[];
static const PRInt32 kClearKTable[];

View File

@ -416,6 +416,7 @@ noscript, noframes, param, :-moz-comment, :-moz-pi {
background: inherit;
padding: inherit;
display: inherit;
-moz-box-orient: inherit;
}
:wrapped-frame {

View File

@ -677,6 +677,17 @@ const PRInt32 nsCSSProps::kWhitespaceKTable[] = {
-1,-1
};
#ifdef INCLUDE_XUL
// Specific keyword tables for XUL.properties
const PRInt32 nsCSSProps::kBoxOrientKTable[] = {
eCSSKeyword_horizontal, NS_STYLE_BOX_ORIENT_HORIZONTAL,
eCSSKeyword_vertical, NS_STYLE_BOX_ORIENT_VERTICAL,
eCSSKeyword_inline_axis, NS_STYLE_BOX_ORIENT_HORIZONTAL,
eCSSKeyword_block_axis, NS_STYLE_BOX_ORIENT_VERTICAL,
-1,-1
};
#endif
PRInt32
nsCSSProps::SearchKeywordTableInt(PRInt32 aValue, const PRInt32 aTable[])
{
@ -763,6 +774,11 @@ static const PRInt32 kBackgroundYPositionKTable[] = {
case eCSSProperty_border_collapse:
return SearchKeywordTable(aValue, kBorderCollapseKTable);
#ifdef INCLUDE_XUL
case eCSSProperty_box_orient:
return SearchKeywordTable(aValue, kBoxOrientKTable);
#endif
case eCSSProperty_box_sizing:
return SearchKeywordTable(aValue, kBoxSizingKTable);

View File

@ -193,13 +193,13 @@ PRBool nsBoxFrameInner::gDebug = PR_FALSE;
nsIBox* nsBoxFrameInner::mDebugChild = nsnull;
nsresult
NS_NewBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRBool aIsRoot, nsIBoxLayout* aLayoutManager, PRBool aIsHorizontal)
NS_NewBoxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRBool aIsRoot, nsIBoxLayout* aLayoutManager)
{
NS_PRECONDITION(aNewFrame, "null OUT ptr");
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsBoxFrame* it = new (aPresShell) nsBoxFrame(aPresShell, aIsRoot, aLayoutManager, aIsHorizontal);
nsBoxFrame* it = new (aPresShell) nsBoxFrame(aPresShell, aIsRoot, aLayoutManager);
if (nsnull == it)
return NS_ERROR_OUT_OF_MEMORY;
@ -210,18 +210,14 @@ NS_NewBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRBool aIsRoot,
} // NS_NewBoxFrame
nsBoxFrame::nsBoxFrame(nsIPresShell* aPresShell, PRBool aIsRoot, nsIBoxLayout* aLayoutManager, PRBool aIsHorizontal):nsContainerBox(aPresShell)
nsBoxFrame::nsBoxFrame(nsIPresShell* aPresShell, PRBool aIsRoot, nsIBoxLayout* aLayoutManager)
:nsContainerBox(aPresShell)
{
mInner = new (aPresShell) nsBoxFrameInner(aPresShell, this);
mInner->mAttributesCached = PR_FALSE;
// if not otherwise specified boxes by default are horizontal.
if (aIsHorizontal) {
mState |= NS_STATE_IS_HORIZONTAL;
mState |= NS_STATE_DEFAULT_HORIZONTAL;
}
mState |= NS_STATE_IS_HORIZONTAL;
mState |= NS_STATE_AUTO_STRETCH;
if (aIsRoot)
@ -371,9 +367,6 @@ nsBoxFrameInner::CacheAttributes()
mOuter->GetInitialHAlignment(mHalign);
PRBool orient = PR_FALSE;
if (mOuter->mState & NS_STATE_DEFAULT_HORIZONTAL)
orient = PR_TRUE;
mOuter->GetInitialOrientation(orient);
if (orient)
mOuter->mState |= NS_STATE_IS_HORIZONTAL;
@ -548,7 +541,7 @@ nsBoxFrame::GetInitialVAlignment(nsBoxFrame::Valignment& aValign)
/* Returns true if it was set.
*/
PRBool
void
nsBoxFrame::GetInitialOrientation(PRBool& aIsHorizontal)
{
// see if we are a vertical or horizontal box.
@ -558,31 +551,33 @@ nsBoxFrame::GetInitialOrientation(PRBool& aIsHorizontal)
GetContentOf(getter_AddRefs(content));
if (!content)
return PR_FALSE;
return;
if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(kNameSpaceID_None, nsXULAtoms::orient, value))
{
if (value.EqualsIgnoreCase("vertical")) {
aIsHorizontal = PR_FALSE;
return PR_TRUE;
} else if (value.EqualsIgnoreCase("horizontal")) {
aIsHorizontal = PR_TRUE;
return PR_TRUE;
}
// Check the style system first.
const nsStyleXUL* boxInfo;
GetStyleData(eStyleStruct_XUL,
(const nsStyleStruct*&)boxInfo);
if (boxInfo->mBoxOrient == NS_STYLE_BOX_ORIENT_HORIZONTAL)
aIsHorizontal = PR_TRUE;
else
aIsHorizontal = PR_FALSE;
// Now see if we have an attribute. The attribute overrides
// the style system value.
if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(kNameSpaceID_None, nsXULAtoms::orient, value)) {
if (value.EqualsIgnoreCase("vertical"))
aIsHorizontal = PR_FALSE;
else if (value.EqualsIgnoreCase("horizontal"))
aIsHorizontal = PR_TRUE;
} else {
// depricated, use align
if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::align, value)) {
if (value.EqualsIgnoreCase("vertical")) {
aIsHorizontal = PR_FALSE;
return PR_TRUE;
} else if (value.EqualsIgnoreCase("horizontal")) {
aIsHorizontal = PR_TRUE;
return PR_TRUE;
}
}
}
return PR_FALSE;
// deprecated, use align
if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::align, value)) {
if (value.EqualsIgnoreCase("vertical"))
aIsHorizontal = PR_FALSE;
else if (value.EqualsIgnoreCase("horizontal"))
aIsHorizontal = PR_TRUE;
}
}
}
/* Returns true if it was set.
@ -1164,12 +1159,12 @@ nsBoxFrame::AttributeChanged(nsIPresContext* aPresContext,
GetInitialVAlignment(mInner->mValign);
GetInitialHAlignment(mInner->mHalign);
PRBool orient = mState & NS_STATE_DEFAULT_HORIZONTAL;
PRBool orient = PR_TRUE;
GetInitialOrientation(orient);
if (orient)
mState |= NS_STATE_IS_HORIZONTAL;
else
mState &= ~NS_STATE_IS_HORIZONTAL;
mState |= NS_STATE_IS_HORIZONTAL;
else
mState &= ~NS_STATE_IS_HORIZONTAL;
PRBool equalSize = PR_FALSE;
GetInitialEqualSize(equalSize);

View File

@ -56,9 +56,8 @@ class nsHTMLInfo;
#define NS_STATE_SET_TO_DEBUG 0x04000000
#define NS_STATE_DEBUG_WAS_SET 0x08000000
#define NS_STATE_IS_COLLAPSED 0x10000000
#define NS_STATE_DEFAULT_HORIZONTAL 0x20000000
#define NS_STATE_STYLE_CHANGE 0x40000000
#define NS_STATE_EQUAL_SIZE 0x80000000
#define NS_STATE_STYLE_CHANGE 0x20000000
#define NS_STATE_EQUAL_SIZE 0x40000000
class nsBoxFrame : public nsContainerFrame, public nsContainerBox
{
@ -67,8 +66,7 @@ public:
friend nsresult NS_NewBoxFrame(nsIPresShell* aPresShell,
nsIFrame** aNewFrame,
PRBool aIsRoot = PR_FALSE,
nsIBoxLayout* aLayoutManager = nsnull,
PRBool aDefaultHorizontal = PR_TRUE);
nsIBoxLayout* aLayoutManager = nsnull);
// gets the rect inside our border and debug border. If you wish to paint inside a box
// call this method to get the rect so you don't draw on the debug border or outer border.
@ -163,7 +161,7 @@ public:
virtual nsresult GetContentOf(nsIContent** aContent);
virtual nsresult SyncLayout(nsBoxLayoutState& aBoxLayoutState);
nsBoxFrame(nsIPresShell* aPresShell, PRBool aIsRoot = nsnull, nsIBoxLayout* aLayoutManager = nsnull, PRBool aDefaultHorizontal = PR_TRUE);
nsBoxFrame(nsIPresShell* aPresShell, PRBool aIsRoot = nsnull, nsIBoxLayout* aLayoutManager = nsnull);
static nsresult CreateViewForFrame(nsIPresContext* aPresContext,
nsIFrame* aChild,
@ -201,7 +199,7 @@ protected:
virtual PRBool GetInitialEqualSize(PRBool& aEqualSize);
virtual PRBool GetInitialOrientation(PRBool& aIsHorizontal);
virtual void GetInitialOrientation(PRBool& aIsHorizontal);
virtual PRBool GetInitialHAlignment(Halignment& aHalign);
virtual PRBool GetInitialVAlignment(Valignment& aValign);
virtual PRBool GetInitialAutoStretch(PRBool& aStretch);

View File

@ -48,7 +48,7 @@ public:
// make sure we our kids get our orient, align, and autostretch instead of us.
// our child box has no content node so it will search for a parent with one.
// that will be us.
virtual PRBool GetInitialOrientation(PRBool& aHorizontal) { aHorizontal = PR_FALSE; return PR_TRUE; }
virtual void GetInitialOrientation(PRBool& aHorizontal) { aHorizontal = PR_FALSE; }
virtual PRBool GetInitialHAlignment(Halignment& aHalign) { aHalign = hAlign_Left; return PR_TRUE; }
virtual PRBool GetInitialVAlignment(Valignment& aValign) { aValign = vAlign_Top; return PR_TRUE; }
virtual PRBool GetInitialAutoStretch(PRBool& aStretch) { aStretch = PR_TRUE; return PR_TRUE; }

View File

@ -191,14 +191,6 @@ nsMenuPopupFrame::GetLayoutFlags(PRUint32& aFlags)
aFlags = NS_FRAME_NO_SIZE_VIEW | NS_FRAME_NO_MOVE_VIEW | NS_FRAME_NO_VISIBILITY;
}
PRBool
nsMenuPopupFrame::GetInitialOrientation(PRBool& aIsHorizontal)
{
// by default we are vertical
aIsHorizontal = PR_FALSE;
return nsBoxFrame::GetInitialOrientation(aIsHorizontal);
}
void
nsMenuPopupFrame::GetViewOffset(nsIViewManager* aManager, nsIView* aView,
nsPoint& aPoint)

View File

@ -144,9 +144,6 @@ protected:
// views.
virtual void GetLayoutFlags(PRUint32& aFlags);
// return true if the alignment is horizontal false if vertical
virtual PRBool GetInitialOrientation(PRBool& aIsHorizontal);
// given x,y in client coordinates, compensate for nested documents like framesets.
void AdjustClientXYForNestedDocuments ( nsIDOMXULDocument* inPopupDoc, nsIPresShell* inPopupShell,
PRInt32 inClientX, PRInt32 inClientY,

View File

@ -452,27 +452,6 @@ nsSplitterFrame::DoLayout(nsBoxLayoutState& aState)
return nsBoxFrame::DoLayout(aState);
}
PRBool
nsSplitterFrame::GetInitialOrientation(PRBool& aIsHorizontal)
{
// find the box we are in
nsIFrame* box = nsnull;
nsScrollbarButtonFrame::GetParentWithTag(nsXULAtoms::box, this, box);
// if no box get the window because it is a box.
if (box == nsnull)
nsScrollbarButtonFrame::GetParentWithTag(nsXULAtoms::window, this, box);
// see if the box is horizontal or vertical we are the opposite
if (box) {
aIsHorizontal = !((nsBoxFrame*)box)->IsHorizontal();
return PR_TRUE;
}
return PR_FALSE;
}
NS_IMETHODIMP
nsSplitterFrame::HandlePress(nsIPresContext* aPresContext,
nsGUIEvent * aEvent,

View File

@ -104,8 +104,6 @@ public:
nsFramePaintLayer aWhichLayer,
nsIFrame** aFrame);
virtual PRBool GetInitialOrientation(PRBool& aIsHorizontal);
private:
friend class nsSplitterFrameInner;

View File

@ -48,7 +48,7 @@ public:
// make sure we our kids get our orient, align, and autostretch instead of us.
// our child box has no content node so it will search for a parent with one.
// that will be us.
virtual PRBool GetInitialOrientation(PRBool& aHorizontal) { aHorizontal = PR_FALSE; return PR_TRUE; }
virtual void GetInitialOrientation(PRBool& aHorizontal) { aHorizontal = PR_FALSE; }
virtual PRBool GetInitialHAlignment(Halignment& aHalign) { aHalign = hAlign_Left; return PR_TRUE; }
virtual PRBool GetInitialVAlignment(Valignment& aValign) { aValign = vAlign_Top; return PR_TRUE; }
virtual PRBool GetInitialAutoStretch(PRBool& aStretch) { aStretch = PR_TRUE; return PR_TRUE; }

View File

@ -42,13 +42,13 @@
//
nsresult
NS_NewXULTreeCellFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRBool aIsRoot,
nsIBoxLayout* aLayoutManager, PRBool aIsHorizontal)
nsIBoxLayout* aLayoutManager)
{
NS_PRECONDITION(aNewFrame, "null OUT ptr");
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsXULTreeCellFrame* it = new (aPresShell) nsXULTreeCellFrame(aPresShell, aIsRoot, aLayoutManager, aIsHorizontal);
nsXULTreeCellFrame* it = new (aPresShell) nsXULTreeCellFrame(aPresShell, aIsRoot, aLayoutManager);
if (!it)
return NS_ERROR_OUT_OF_MEMORY;
@ -59,8 +59,8 @@ NS_NewXULTreeCellFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRBool aI
// Constructor
nsXULTreeCellFrame::nsXULTreeCellFrame(nsIPresShell* aPresShell, PRBool aIsRoot, nsIBoxLayout* aLayoutManager, PRBool aIsHorizontal)
:nsBoxFrame(aPresShell, aIsRoot, aLayoutManager, aIsHorizontal)
nsXULTreeCellFrame::nsXULTreeCellFrame(nsIPresShell* aPresShell, PRBool aIsRoot, nsIBoxLayout* aLayoutManager)
:nsBoxFrame(aPresShell, aIsRoot, aLayoutManager)
{}
// Destructor

View File

@ -30,8 +30,7 @@ public:
friend nsresult NS_NewXULTreeCellFrame(nsIPresShell* aPresShell,
nsIFrame** aNewFrame,
PRBool aIsRoot = PR_FALSE,
nsIBoxLayout* aLayoutManager = nsnull,
PRBool aDefaultHorizontal = PR_TRUE);
nsIBoxLayout* aLayoutManager = nsnull);
NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext,
const nsPoint& aPoint, // Overridden to capture events
@ -39,7 +38,7 @@ public:
nsIFrame** aFrame);
protected:
nsXULTreeCellFrame(nsIPresShell* aPresShell, PRBool aIsRoot = nsnull, nsIBoxLayout* aLayoutManager = nsnull, PRBool aDefaultHorizontal = PR_TRUE);
nsXULTreeCellFrame(nsIPresShell* aPresShell, PRBool aIsRoot = nsnull, nsIBoxLayout* aLayoutManager = nsnull);
virtual ~nsXULTreeCellFrame();
protected: // Data Members

View File

@ -36,13 +36,13 @@
//
nsresult
NS_NewXULTreeFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRBool aIsRoot,
nsIBoxLayout* aLayoutManager, PRBool aIsHorizontal)
nsIBoxLayout* aLayoutManager)
{
NS_PRECONDITION(aNewFrame, "null OUT ptr");
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsXULTreeFrame* it = new (aPresShell) nsXULTreeFrame(aPresShell, aIsRoot, aLayoutManager, aIsHorizontal);
nsXULTreeFrame* it = new (aPresShell) nsXULTreeFrame(aPresShell, aIsRoot, aLayoutManager);
if (!it)
return NS_ERROR_OUT_OF_MEMORY;
@ -53,8 +53,8 @@ NS_NewXULTreeFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRBool aIsRoo
// Constructor
nsXULTreeFrame::nsXULTreeFrame(nsIPresShell* aPresShell, PRBool aIsRoot, nsIBoxLayout* aLayoutManager, PRBool aIsHorizontal)
:nsBoxFrame(aPresShell, aIsRoot, aLayoutManager, aIsHorizontal)
nsXULTreeFrame::nsXULTreeFrame(nsIPresShell* aPresShell, PRBool aIsRoot, nsIBoxLayout* aLayoutManager)
:nsBoxFrame(aPresShell, aIsRoot, aLayoutManager)
{
mPresShell = aPresShell;
}

View File

@ -34,8 +34,7 @@ public:
friend nsresult NS_NewXULTreeFrame(nsIPresShell* aPresShell,
nsIFrame** aNewFrame,
PRBool aIsRoot = PR_FALSE,
nsIBoxLayout* aLayoutManager = nsnull,
PRBool aDefaultHorizontal = PR_TRUE);
nsIBoxLayout* aLayoutManager = nsnull);
NS_DECL_ISUPPORTS
@ -55,7 +54,7 @@ public:
NS_IMETHOD EndBatch();
protected:
nsXULTreeFrame(nsIPresShell* aPresShell, PRBool aIsRoot = nsnull, nsIBoxLayout* aLayoutManager = nsnull, PRBool aDefaultHorizontal = PR_TRUE);
nsXULTreeFrame(nsIPresShell* aPresShell, PRBool aIsRoot = nsnull, nsIBoxLayout* aLayoutManager = nsnull);
virtual ~nsXULTreeFrame();
public:

View File

@ -54,13 +54,13 @@ static void LocateIndentationFrame ( nsIPresContext* aPresContext, nsIFrame* aPa
//
nsresult
NS_NewXULTreeGroupFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRBool aIsRoot,
nsIBoxLayout* aLayoutManager, PRBool aIsHorizontal)
nsIBoxLayout* aLayoutManager)
{
NS_PRECONDITION(aNewFrame, "null OUT ptr");
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsXULTreeGroupFrame* it = new (aPresShell) nsXULTreeGroupFrame(aPresShell, aIsRoot, aLayoutManager, aIsHorizontal);
nsXULTreeGroupFrame* it = new (aPresShell) nsXULTreeGroupFrame(aPresShell, aIsRoot, aLayoutManager);
if (!it)
return NS_ERROR_OUT_OF_MEMORY;
@ -89,8 +89,8 @@ NS_INTERFACE_MAP_BEGIN(nsXULTreeGroupFrame)
NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame)
// Constructor
nsXULTreeGroupFrame::nsXULTreeGroupFrame(nsIPresShell* aPresShell, PRBool aIsRoot, nsIBoxLayout* aLayoutManager, PRBool aIsHorizontal)
:nsBoxFrame(aPresShell, aIsRoot, aLayoutManager, aIsHorizontal), mFrameConstructor(nsnull), mPresContext(nsnull),
nsXULTreeGroupFrame::nsXULTreeGroupFrame(nsIPresShell* aPresShell, PRBool aIsRoot, nsIBoxLayout* aLayoutManager)
:nsBoxFrame(aPresShell, aIsRoot, aLayoutManager), mFrameConstructor(nsnull), mPresContext(nsnull),
mOuterFrame(nsnull), mAvailableHeight(10000), mTopFrame(nsnull), mBottomFrame(nsnull), mLinkupFrame(nsnull),
mContentChain(nsnull), mYDropLoc(nsTreeItemDragCapturer::kNoDropLoc), mDropOnContainer(PR_FALSE),
mOnScreenRowCount(-1)

View File

@ -42,11 +42,10 @@ public:
friend nsresult NS_NewXULTreeGroupFrame(nsIPresShell* aPresShell,
nsIFrame** aNewFrame,
PRBool aIsRoot = PR_FALSE,
nsIBoxLayout* aLayoutManager = nsnull,
PRBool aDefaultHorizontal = PR_TRUE);
nsIBoxLayout* aLayoutManager = nsnull);
protected:
nsXULTreeGroupFrame(nsIPresShell* aPresShell, PRBool aIsRoot = nsnull, nsIBoxLayout* aLayoutManager = nsnull, PRBool aDefaultHorizontal = PR_TRUE);
nsXULTreeGroupFrame(nsIPresShell* aPresShell, PRBool aIsRoot = nsnull, nsIBoxLayout* aLayoutManager = nsnull);
virtual ~nsXULTreeGroupFrame();
void LocateFrame(nsIFrame* aStartFrame, nsIFrame** aResult);

View File

@ -220,13 +220,13 @@ NS_IMPL_ISUPPORTS1(nsScrollSmoother, nsITimerCallback)
//
nsresult
NS_NewXULTreeOuterGroupFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRBool aIsRoot,
nsIBoxLayout* aLayoutManager, PRBool aIsHorizontal)
nsIBoxLayout* aLayoutManager)
{
NS_PRECONDITION(aNewFrame, "null OUT ptr");
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsXULTreeOuterGroupFrame* it = new (aPresShell) nsXULTreeOuterGroupFrame(aPresShell, aIsRoot, aLayoutManager, aIsHorizontal);
nsXULTreeOuterGroupFrame* it = new (aPresShell) nsXULTreeOuterGroupFrame(aPresShell, aIsRoot, aLayoutManager);
if (!it)
return NS_ERROR_OUT_OF_MEMORY;
@ -237,8 +237,8 @@ NS_NewXULTreeOuterGroupFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRB
// Constructor
nsXULTreeOuterGroupFrame::nsXULTreeOuterGroupFrame(nsIPresShell* aPresShell, PRBool aIsRoot, nsIBoxLayout* aLayoutManager, PRBool aIsHorizontal)
:nsXULTreeGroupFrame(aPresShell, aIsRoot, aLayoutManager, aIsHorizontal),
nsXULTreeOuterGroupFrame::nsXULTreeOuterGroupFrame(nsIPresShell* aPresShell, PRBool aIsRoot, nsIBoxLayout* aLayoutManager)
:nsXULTreeGroupFrame(aPresShell, aIsRoot, aLayoutManager),
mBatchCount(0), mRowGroupInfo(nsnull), mRowHeight(0), mCurrentIndex(0), mOldIndex(0),
mTreeIsSorted(PR_FALSE), mDragOverListener(nsnull), mCanDropBetweenRows(PR_TRUE),
mRowHeightWasSet(PR_FALSE), mReflowCallbackPosted(PR_FALSE), mYPosition(0), mScrolling(PR_FALSE),

View File

@ -83,7 +83,7 @@ public:
class nsXULTreeOuterGroupFrame : public nsXULTreeGroupFrame, public nsIScrollbarMediator,
public nsIReflowCallback /*, public nsITimerCallback */
{
nsXULTreeOuterGroupFrame(nsIPresShell* aPresShell, PRBool aIsRoot = nsnull, nsIBoxLayout* aLayoutManager = nsnull, PRBool aDefaultHorizontal = PR_TRUE);
nsXULTreeOuterGroupFrame(nsIPresShell* aPresShell, PRBool aIsRoot = nsnull, nsIBoxLayout* aLayoutManager = nsnull);
virtual ~nsXULTreeOuterGroupFrame();
public:
@ -94,8 +94,7 @@ public:
friend nsresult NS_NewXULTreeOuterGroupFrame(nsIPresShell* aPresShell,
nsIFrame** aNewFrame,
PRBool aIsRoot = PR_FALSE,
nsIBoxLayout* aLayoutManager = nsnull,
PRBool aDefaultHorizontal = PR_TRUE);
nsIBoxLayout* aLayoutManager = nsnull);
NS_IMETHOD Init(nsIPresContext* aPresContext, nsIContent* aContent,
nsIFrame* aParent, nsIStyleContext* aContext, nsIFrame* aPrevInFlow);

View File

@ -32,13 +32,13 @@
//
nsresult
NS_NewXULTreeSliceFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRBool aIsRoot,
nsIBoxLayout* aLayoutManager, PRBool aIsHorizontal)
nsIBoxLayout* aLayoutManager)
{
NS_PRECONDITION(aNewFrame, "null OUT ptr");
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsXULTreeSliceFrame* it = new (aPresShell) nsXULTreeSliceFrame(aPresShell, aIsRoot, aLayoutManager, aIsHorizontal);
nsXULTreeSliceFrame* it = new (aPresShell) nsXULTreeSliceFrame(aPresShell, aIsRoot, aLayoutManager);
if (!it)
return NS_ERROR_OUT_OF_MEMORY;
@ -68,8 +68,8 @@ NS_INTERFACE_MAP_BEGIN(nsXULTreeSliceFrame)
NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame)
// Constructor
nsXULTreeSliceFrame::nsXULTreeSliceFrame(nsIPresShell* aPresShell, PRBool aIsRoot, nsIBoxLayout* aLayoutManager, PRBool aIsHorizontal)
:nsBoxFrame(aPresShell, aIsRoot, aLayoutManager, aIsHorizontal)
nsXULTreeSliceFrame::nsXULTreeSliceFrame(nsIPresShell* aPresShell, PRBool aIsRoot, nsIBoxLayout* aLayoutManager)
:nsBoxFrame(aPresShell, aIsRoot, aLayoutManager)
{}
// Destructor

View File

@ -33,8 +33,7 @@ public:
friend nsresult NS_NewXULTreeSliceFrame(nsIPresShell* aPresShell,
nsIFrame** aNewFrame,
PRBool aIsRoot = PR_FALSE,
nsIBoxLayout* aLayoutManager = nsnull,
PRBool aDefaultHorizontal = PR_TRUE);
nsIBoxLayout* aLayoutManager = nsnull);
// nsIXULTreeSlice
NS_IMETHOD IsOutermostFrame(PRBool* aResult) { *aResult = PR_FALSE; return NS_OK; };
@ -46,7 +45,7 @@ public:
NS_IMETHOD GetPrefSize(nsBoxLayoutState& aState, nsSize& aSize);
protected:
nsXULTreeSliceFrame(nsIPresShell* aPresShell, PRBool aIsRoot = nsnull, nsIBoxLayout* aLayoutManager = nsnull, PRBool aDefaultHorizontal = PR_TRUE);
nsXULTreeSliceFrame(nsIPresShell* aPresShell, PRBool aIsRoot = nsnull, nsIBoxLayout* aLayoutManager = nsnull);
virtual ~nsXULTreeSliceFrame();
protected: // Data Members

View File

@ -43,13 +43,30 @@ interface nsIOutlinerBoxObject : nsISupports
readonly attribute nsIOutlinerSelection selection;
// Get the index of the first visible row.
long getIndexOfVisibleRow();
long getFirstVisibleRow();
// Get the index of the last visible row.
long getLastVisibleRow();
// Gets the number of possible visible rows.
long getPageCount();
// Ensures that a row at a given index is visible.
void ensureRowIsVisible(in long index);
// Scrolls such that the row at index is at the top of the visible view.
void scrollToRow(in long index);
// Scroll the outliner up or down by numLines lines. Positive
// values move down in the outliner. Prevents scrolling off the
// end of the outliner.
void scrollByLines(in long numLines);
// Scroll the outliner up or down by numPages pages. A page
// is considered to be the amount displayed by the outliner.
// Positive values move down in the outliner. Prevents scrolling
// off the end of the outliner.
void scrollByPages(in long numPages);
// Invalidation methods for fine-grained painting control.
void invalidate();
@ -62,12 +79,10 @@ interface nsIOutlinerBoxObject : nsISupports
void getCellAt(in long x, in long y, out long row, out wstring colID);
// The view is responsible for calling these notification methods when
// nodes are added or removed. Index is the position at which the new
// rows start. Count is the number of new contiguous rows added. For
// non-contiguous additions, these methods should be called multiple times.
void rowsAppended(in long count);
void rowsInserted(in long index, in long count);
void rowsRemoved(in long index, in long count);
// rows are added or removed. Index is the position at which the new
// rows were added or at which rows were removed. For
// non-contiguous additions/removals, this method should be called multiple times.
void rowCountChanged(in long index, in long count);
};
%{C++

View File

@ -50,6 +50,9 @@ interface nsIOutlinerSelection : nsISecurityCheckedComponent
// else. If augment is false, everything is cleared except for the specified range.
void rangedSelect(in long startIndex, in long endIndex, in boolean augment);
// Clears the range.
void clearRange(in long startIndex, in long endIndex);
// Clears the selection.
void clearSelection();
@ -63,6 +66,9 @@ interface nsIOutlinerSelection : nsISecurityCheckedComponent
long getRangeCount();
void getRangeAt(in long i, out long min, out long max);
// Called when the row count changes to adjust selection indices.
void adjustSelection(in long index, in long count);
// This attribute is a boolean indicating whether or not the
// "select" event should fire when the selection is changed using
// one of our methods. A view can use this to temporarily suppress

View File

@ -61,7 +61,17 @@ interface nsIOutlinerView : nsISupports
boolean isContainer(in long index);
boolean isContainerOpen(in long index);
boolean isContainerEmpty(in long index);
// Methods used by the outliner to draw vertical lines in the tree.
// GetParentIndex is used to obtain the index of a parent row.
long getParentIndex(in long rowIndex);
// HasNextSibling is used to determine if the row at rowIndex has a nextSibling
// that occurs *after* the index specified by afterIndex. Code that is forced
// to march down the view looking at levels can optimize the march by starting
// at afterIndex+1.
boolean hasNextSibling(in long rowIndex, in long afterIndex);
// The level is an integer value that represents
// the level of indentation. It is multiplied by the width specified in the
// :moz-outliner-indentation pseudoelement to compute the exact indendation.

View File

@ -53,6 +53,8 @@
#include "nsWidgetsCID.h"
#include "nsBoxFrame.h"
#define ELLIPSIS "..."
// The style context cache impl
nsresult
nsOutlinerStyleCache::GetStyleContext(nsICSSPseudoComparator* aComparator,
@ -132,9 +134,9 @@ nsOutlinerColumn::nsOutlinerColumn(nsIContent* aColElement, nsIFrame* aFrame)
mCropStyle = 0;
nsAutoString crop;
mColElement->GetAttribute(kNameSpaceID_None, nsXULAtoms::crop, crop);
if (crop.EqualsIgnoreCase("middle"))
if (crop.EqualsIgnoreCase("center"))
mCropStyle = 1;
else if (crop.EqualsIgnoreCase("right"))
else if (crop.EqualsIgnoreCase("left"))
mCropStyle = 2;
// Cache our text alignment policy.
@ -198,7 +200,7 @@ NS_NewOutlinerBodyFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
// Constructor
nsOutlinerBodyFrame::nsOutlinerBodyFrame(nsIPresShell* aPresShell)
:nsLeafBoxFrame(aPresShell), mPresContext(nsnull),
mTopRowIndex(0), mColumns(nsnull), mScrollbar(nsnull)
mTopRowIndex(0), mRowHeight(0), mIndentation(0), mColumns(nsnull), mScrollbar(nsnull)
{
NS_NewISupportsArray(getter_AddRefs(mScratchArray));
}
@ -267,12 +269,36 @@ nsOutlinerBodyFrame::Destroy(nsIPresContext* aPresContext)
mColumns = nsnull;
// Drop our ref to the view.
mView->SetOutliner(nsnull);
if (mView)
mView->SetOutliner(nsnull);
mView = nsnull;
return nsLeafBoxFrame::Destroy(aPresContext);
}
NS_IMETHODIMP nsOutlinerBodyFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aReflowMetrics,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
if ( mView && mRowHeight && aReflowState.reason == eReflowReason_Resize) {
mInnerBox = GetInnerBox();
mPageCount = mInnerBox.height / mRowHeight;
PRInt32 rowCount;
mView->GetRowCount(&rowCount);
PRInt32 lastPageTopRow = rowCount - mPageCount;
if (mTopRowIndex >= lastPageTopRow)
ScrollToRow(lastPageTopRow);
InvalidateScrollbar();
}
// nsLeafBoxFrame::Reflow(aPresContext, aReflowMetrics, aReflowState, aStatus);
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBodyFrame::GetView(nsIOutlinerView * *aView)
{
*aView = mView;
@ -284,7 +310,14 @@ NS_IMETHODIMP nsOutlinerBodyFrame::SetView(nsIOutlinerView * aView)
{
// Outliner, meet the view.
mView = aView;
// Changing the view causes us to refetch our data. This will
// necessarily entail a full invalidation of the outliner.
mTopRowIndex = 0;
delete mColumns;
mColumns = nsnull;
Invalidate();
if (mView) {
// View, meet the outliner.
mView->SetOutliner(this);
@ -294,15 +327,11 @@ NS_IMETHODIMP nsOutlinerBodyFrame::SetView(nsIOutlinerView * aView)
NS_NewOutlinerSelection(this, getter_AddRefs(sel));
mView->SetSelection(sel);
// The scrollbar will need to be updated.
InvalidateScrollbar();
}
// Changing the view causes us to refetch our data. This will
// necessarily entail a full invalidation of the outliner.
mTopRowIndex = 0;
delete mColumns;
mColumns = nsnull;
Invalidate();
return NS_OK;
}
@ -321,12 +350,18 @@ NS_IMETHODIMP nsOutlinerBodyFrame::GetSelection(nsIOutlinerSelection** aSelectio
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBodyFrame::GetIndexOfVisibleRow(PRInt32 *_retval)
NS_IMETHODIMP nsOutlinerBodyFrame::GetFirstVisibleRow(PRInt32 *_retval)
{
*_retval = mTopRowIndex;
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBodyFrame::GetLastVisibleRow(PRInt32 *_retval)
{
*_retval = mTopRowIndex + mPageCount + 1;
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBodyFrame::GetPageCount(PRInt32 *_retval)
{
*_retval = mPageCount;
@ -360,8 +395,9 @@ NS_IMETHODIMP nsOutlinerBodyFrame::InvalidateRange(PRInt32 aStart, PRInt32 aEnd)
if (aStart == aEnd)
return InvalidateRow(aStart);
if (aEnd < mTopRowIndex || aStart > mTopRowIndex + mPageCount + 1)
PRInt32 last;
GetLastVisibleRow(&last);
if (aEnd < mTopRowIndex || aStart > last)
return NS_OK;
if (aStart < mTopRowIndex)
@ -376,6 +412,21 @@ NS_IMETHODIMP nsOutlinerBodyFrame::InvalidateRange(PRInt32 aStart, PRInt32 aEnd)
return NS_OK;
}
void
nsOutlinerBodyFrame::UpdateScrollbar()
{
// Update the scrollbar.
nsCOMPtr<nsIContent> scrollbarContent;
mScrollbar->GetContent(getter_AddRefs(scrollbarContent));
float t2p;
mPresContext->GetTwipsToPixels(&t2p);
nscoord rowHeightAsPixels = NSToCoordRound((float)mRowHeight*t2p);
nsAutoString curPos;
curPos.AppendInt(mTopRowIndex*rowHeightAsPixels);
scrollbarContent->SetAttribute(kNameSpaceID_None, nsXULAtoms::curpos, curPos, PR_TRUE);
}
NS_IMETHODIMP nsOutlinerBodyFrame::InvalidateScrollbar()
{
if (!mScrollbar)
@ -397,7 +448,7 @@ NS_IMETHODIMP nsOutlinerBodyFrame::InvalidateScrollbar()
mPresContext->GetTwipsToPixels(&t2p);
nscoord rowHeightAsPixels = NSToCoordRound((float)mRowHeight*t2p);
PRInt32 size = rowHeightAsPixels*(rowCount-mPageCount+1);
PRInt32 size = rowHeightAsPixels*(rowCount-mPageCount);
maxposStr.AppendInt(size);
scrollbar->SetAttribute(kNameSpaceID_None, nsXULAtoms::maxpos, maxposStr, PR_TRUE);
@ -450,22 +501,70 @@ NS_IMETHODIMP nsOutlinerBodyFrame::GetCellAt(PRInt32 aX, PRInt32 aY, PRInt32* aR
// Now just mod by our total inner box height and add to our top row index.
*aRow = (y/mRowHeight)+mTopRowIndex;
// XXX Determine the column hit!
// Determine the column hit.
nscoord currX = mInnerBox.x;
for (nsOutlinerColumn* currCol = mColumns; currCol && currX < mInnerBox.x+mInnerBox.width;
currCol = currCol->GetNext()) {
nsRect colRect(currX, mInnerBox.y, currCol->GetWidth(), mInnerBox.height);
PRInt32 overflow = colRect.x+colRect.width-(mInnerBox.x+mInnerBox.width);
if (overflow > 0)
colRect.width -= overflow;
if (x >= colRect.x && x < colRect.x + colRect.width)
*aColID = nsXPIDLString::Copy(currCol->GetID());
currX += colRect.width;
}
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBodyFrame::RowsAppended(PRInt32 count)
NS_IMETHODIMP nsOutlinerBodyFrame::RowCountChanged(PRInt32 aIndex, PRInt32 aCount)
{
return NS_OK;
}
if (aCount == 0)
return NS_OK; // Nothing to do.
NS_IMETHODIMP nsOutlinerBodyFrame::RowsInserted(PRInt32 index, PRInt32 count)
{
return NS_OK;
}
PRInt32 count = aCount > 0 ? aCount : -aCount;
NS_IMETHODIMP nsOutlinerBodyFrame::RowsRemoved(PRInt32 index, PRInt32 count)
{
// Adjust our selection.
nsCOMPtr<nsIOutlinerSelection> sel;
mView->GetSelection(getter_AddRefs(sel));
sel->AdjustSelection(aIndex, aCount);
PRInt32 last;
GetLastVisibleRow(&last);
if (aIndex >= mTopRowIndex && aIndex <= last)
InvalidateRange(aIndex, last);
if (mTopRowIndex == 0) {
// Just update the scrollbar and return.
InvalidateScrollbar();
return NS_OK;
}
// Adjust our top row index.
if (aCount > 0) {
if (mTopRowIndex > aIndex) {
// Rows came in above us. Augment the top row index.
mTopRowIndex += aCount;
UpdateScrollbar();
}
}
else if (aCount < 0) {
if (mTopRowIndex > aIndex+count-1) {
// No need to invalidate. The remove happened
// completely offscreen.
mTopRowIndex -= count;
UpdateScrollbar();
}
else if (mTopRowIndex > aIndex) {
// This is a full-blown invalidate.
mTopRowIndex = aIndex+count-1;
UpdateScrollbar();
Invalidate();
}
}
InvalidateScrollbar();
return NS_OK;
}
@ -521,6 +620,23 @@ PRInt32 nsOutlinerBodyFrame::GetRowHeight()
return 19*15; // As good a default as any.
}
PRInt32 nsOutlinerBodyFrame::GetIndentation()
{
// Look up the correct indentation. It is equal to the specified indentation width.
nsCOMPtr<nsIStyleContext> indentContext;
mScratchArray->Clear();
GetPseudoStyleContext(mPresContext, nsXULAtoms::mozoutlinerindentation, getter_AddRefs(indentContext));
if (indentContext) {
const nsStylePosition* myPosition = (const nsStylePosition*)
indentContext->GetStyleData(eStyleStruct_Position);
if (myPosition->mWidth.GetUnit() == eStyleUnit_Coord) {
PRInt32 val = myPosition->mWidth.GetCoordValue();
return val;
}
}
return 16*15; // As good a default as any.
}
nsRect nsOutlinerBodyFrame::GetInnerBox()
{
nsRect r(0,0,mRect.width, mRect.height);
@ -532,6 +648,16 @@ nsRect nsOutlinerBodyFrame::GetInnerBox()
return r;
}
static void
AdjustForBorderPadding(nsIStyleContext* aContext, nsRect& aRect)
{
nsMargin m(0,0,0,0);
nsStyleBorderPadding bPad;
aContext->GetStyle(eStyleStruct_BorderPaddingShortcut, (nsStyleStruct&)bPad);
bPad.GetBorderPadding(m);
aRect.Deflate(m);
}
// Painting routines
NS_IMETHODIMP nsOutlinerBodyFrame::Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@ -556,13 +682,11 @@ NS_IMETHODIMP nsOutlinerBodyFrame::Paint(nsIPresContext* aPresContext,
return NS_OK;
PRBool clipState = PR_FALSE;
nsRect clipRect(mRect);
aRenderingContext.PushState();
aRenderingContext.SetClipRect(clipRect, nsClipCombine_kReplace, clipState);
// Update our page count, our available height and our row height.
PRInt32 oldRowHeight = mRowHeight;
mRowHeight = GetRowHeight();
mIndentation = GetIndentation();
mInnerBox = GetInnerBox();
mPageCount = mInnerBox.height/mRowHeight;
@ -580,8 +704,12 @@ NS_IMETHODIMP nsOutlinerBodyFrame::Paint(nsIPresContext* aPresContext,
// is contained in the rows.
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
nscoord currX = mInnerBox.x;
for (nsOutlinerColumn* currCol = mColumns; currCol; currCol = currCol->GetNext()) {
for (nsOutlinerColumn* currCol = mColumns; currCol && currX < mInnerBox.x+mInnerBox.width;
currCol = currCol->GetNext()) {
nsRect colRect(currX, mInnerBox.y, currCol->GetWidth(), mInnerBox.height);
PRInt32 overflow = colRect.x+colRect.width-(mInnerBox.x+mInnerBox.width);
if (overflow > 0)
colRect.width -= overflow;
nsRect dirtyRect;
if (dirtyRect.IntersectRect(aDirtyRect, colRect)) {
PaintColumn(currCol, colRect, aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
@ -594,12 +722,24 @@ NS_IMETHODIMP nsOutlinerBodyFrame::Paint(nsIPresContext* aPresContext,
for (PRInt32 i = mTopRowIndex; i < rowCount && i < mTopRowIndex+mPageCount+1; i++) {
nsRect rowRect(mInnerBox.x, mInnerBox.y+mRowHeight*(i-mTopRowIndex), mInnerBox.width, mRowHeight);
nsRect dirtyRect;
if (dirtyRect.IntersectRect(aDirtyRect, rowRect)) {
if (dirtyRect.IntersectRect(aDirtyRect, rowRect) && rowRect.y < (mInnerBox.y+mInnerBox.height)) {
PRBool clip = (rowRect.y + rowRect.height > mInnerBox.y + mInnerBox.height);
if (clip) {
// We need to clip the last row, since it extends outside our inner box. Push
// a clip rect down.
PRInt32 overflow = (rowRect.y+rowRect.height) - (mInnerBox.y+mInnerBox.height);
nsRect clipRect(rowRect.x, rowRect.y, mInnerBox.width, mRowHeight-overflow);
aRenderingContext.PushState();
aRenderingContext.SetClipRect(clipRect, nsClipCombine_kReplace, clipState);
}
PaintRow(i, rowRect, aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
if (clip)
aRenderingContext.PopState(clipState);
}
}
aRenderingContext.PopState(clipState);
return NS_OK;
}
@ -610,6 +750,9 @@ NS_IMETHODIMP nsOutlinerBodyFrame::PaintColumn(nsOutlinerColumn* aColumn,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
if (aColRect.width == 0)
return NS_OK; // Don't paint hidden columns.
// Now obtain the properties for our cell.
// XXX Automatically fill in the following props: open, container, selected, focused, and the col ID.
PrefillPropertyArray(-1, aColumn->GetID());
@ -670,10 +813,17 @@ NS_IMETHODIMP nsOutlinerBodyFrame::PaintRow(int aRowIndex, const nsRect& aRowRec
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer)
PaintBackgroundLayer(rowContext, aPresContext, aRenderingContext, rowRect, aDirtyRect);
// Adjust the rect for its border and padding.
AdjustForBorderPadding(rowContext, rowRect);
// Now loop over our cells. Only paint a cell if it intersects with our dirty rect.
nscoord currX = rowRect.x;
for (nsOutlinerColumn* currCol = mColumns; currCol; currCol = currCol->GetNext()) {
for (nsOutlinerColumn* currCol = mColumns; currCol && currX < mInnerBox.x+mInnerBox.width;
currCol = currCol->GetNext()) {
nsRect cellRect(currX, rowRect.y, currCol->GetWidth(), rowRect.height);
PRInt32 overflow = cellRect.x+cellRect.width-(mInnerBox.x+mInnerBox.width);
if (overflow > 0)
cellRect.width -= overflow;
nsRect dirtyRect;
if (dirtyRect.IntersectRect(aDirtyRect, cellRect)) {
PaintCell(aRowIndex, currCol, cellRect, aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
@ -683,7 +833,7 @@ NS_IMETHODIMP nsOutlinerBodyFrame::PaintRow(int aRowIndex, const nsRect& aRowRec
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBodyFrame::PaintCell(int aRowIndex,
nsOutlinerColumn* aColumn,
const nsRect& aCellRect,
@ -692,6 +842,9 @@ NS_IMETHODIMP nsOutlinerBodyFrame::PaintCell(int aRowIndex,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
if (aCellRect.width == 0)
return NS_OK; // Don't paint cells in hidden columns.
// Now obtain the properties for our cell.
// XXX Automatically fill in the following props: open, container, selected, focused, and the col ID.
PrefillPropertyArray(aRowIndex, NS_LITERAL_STRING(""));
@ -715,6 +868,9 @@ NS_IMETHODIMP nsOutlinerBodyFrame::PaintCell(int aRowIndex,
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer)
PaintBackgroundLayer(cellContext, aPresContext, aRenderingContext, cellRect, aDirtyRect);
// Adjust the rect for its border and padding.
AdjustForBorderPadding(cellContext, cellRect);
nscoord currX = cellRect.x;
nscoord remainingWidth = cellRect.width;
@ -724,15 +880,77 @@ NS_IMETHODIMP nsOutlinerBodyFrame::PaintCell(int aRowIndex,
// RIGHT means paint from right to left.
// XXX Implement RIGHT alignment!
// XXX If we're the primary column, we need to indent and paint the twisty.
if (aColumn->IsPrimary()) {
// If we're the primary column, we need to indent and paint the twisty.
// First we indent
PRInt32 level;
mView->GetLevel(aRowIndex, &level);
currX += mIndentation*level;
remainingWidth -= mIndentation*level;
// Resolve style for line.
nsCOMPtr<nsIStyleContext> lineContext;
GetPseudoStyleContext(aPresContext, nsXULAtoms::mozoutlinerline, getter_AddRefs(lineContext));
const nsStyleDisplay* displayStyle = (const nsStyleDisplay*)lineContext->GetStyleData(eStyleStruct_Display);
if (displayStyle->IsVisibleOrCollapsed() && level) {
// Paint lines to show a connections between rows
aRenderingContext.PushState();
const nsStyleBorder* borderStyle = (const nsStyleBorder*)lineContext->GetStyleData(eStyleStruct_Border);
nscolor color;
borderStyle->GetBorderColor(NS_SIDE_LEFT, color);
aRenderingContext.SetColor(color);
PRUint8 style;
style = borderStyle->GetBorderStyle(NS_SIDE_LEFT);
if (style == NS_STYLE_BORDER_STYLE_DOTTED)
aRenderingContext.SetLineStyle(nsLineStyle_kDotted);
else if (style == NS_STYLE_BORDER_STYLE_DASHED)
aRenderingContext.SetLineStyle(nsLineStyle_kDashed);
else
aRenderingContext.SetLineStyle(nsLineStyle_kSolid);
PRInt32 y = (aRowIndex - mTopRowIndex) * mRowHeight;
PRInt32 i;
PRInt32 currentParent = aRowIndex;
for (i = level; i > 0; i--) {
PRBool hasNextSibling;
mView->HasNextSibling(currentParent, aRowIndex, &hasNextSibling);
if (hasNextSibling)
aRenderingContext.DrawLine(aCellRect.x + (i - 1) * mIndentation, y, aCellRect.x + (i - 1) * mIndentation, y + mRowHeight);
else if (i == level)
aRenderingContext.DrawLine(aCellRect.x + (i - 1) * mIndentation, y, aCellRect.x + (i - 1) * mIndentation, y + mRowHeight / 2);
PRInt32 parent;
mView->GetParentIndex(currentParent, &parent);
if (parent == -1)
break;
currentParent = parent;
}
aRenderingContext.DrawLine(aCellRect.x + (level - 1) * mIndentation, y + mRowHeight / 2, aCellRect.x + level * mIndentation, aCellRect.y + mRowHeight /2);
PRBool clipState;
aRenderingContext.PopState(clipState);
}
// XXX Paint the twisty.
}
// XXX Now paint the various images.
// Now paint our text.
nsRect textRect(currX, cellRect.y, remainingWidth, cellRect.height);
nsRect dirtyRect;
if (dirtyRect.IntersectRect(aDirtyRect, textRect))
PaintText(aRowIndex, aColumn, textRect, aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
// Now paint our text, but only if we aren't a cycler column.
// XXX until we have the ability to load images, allow the view to
// insert text into cycler columns...
// if (!aColumn->IsCycler()) {
nsRect textRect(currX, cellRect.y, remainingWidth, cellRect.height);
nsRect dirtyRect;
if (dirtyRect.IntersectRect(aDirtyRect, textRect))
PaintText(aRowIndex, aColumn, textRect, aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
//}
return NS_OK;
}
@ -750,6 +968,9 @@ NS_IMETHODIMP nsOutlinerBodyFrame::PaintText(int aRowIndex,
nsAutoString realText(text);
if (realText.Length() == 0)
return NS_OK; // Don't paint an empty string. XXX What about background/borders? Still paint?
// Resolve style for the text. It contains all the info we need to lay ourselves
// out and to paint.
nsCOMPtr<nsIStyleContext> textContext;
@ -769,6 +990,8 @@ NS_IMETHODIMP nsOutlinerBodyFrame::PaintText(int aRowIndex,
PaintBackgroundLayer(textContext, aPresContext, aRenderingContext, textRect, aDirtyRect);
else {
// Time to paint our text.
// Adjust the rect for its border and padding.
AdjustForBorderPadding(textContext, textRect);
// Compute our text size.
const nsStyleFont* fontStyle = (const nsStyleFont*)textContext->GetStyleData(eStyleStruct_Font);
@ -787,12 +1010,83 @@ NS_IMETHODIMP nsOutlinerBodyFrame::PaintText(int aRowIndex,
textRect.height = height;
}
// XXX Crop if the width is too big!
// Set our font.
aRenderingContext.SetFont(fontMet);
nscoord width;
aRenderingContext.GetWidth(realText, width);
// Set our font.
aRenderingContext.SetFont(fontMet);
if (width > textRect.width) {
// See if the width is even smaller than the ellipsis
// If so, clear the text completely.
nscoord ellipsisWidth;
aRenderingContext.GetWidth(ELLIPSIS, ellipsisWidth);
nsAutoString ellipsis; ellipsis.AssignWithConversion(ELLIPSIS);
nscoord width = textRect.width;
if (ellipsisWidth > width)
realText.SetLength(0);
else if (ellipsisWidth == width)
realText = ellipsis;
else {
// We will be drawing an ellipsis, thank you very much.
// Subtract out the required width of the ellipsis.
// This is the total remaining width we have to play with.
width -= ellipsisWidth;
// Now we crop.
switch (aColumn->GetCropStyle()) {
default:
case 0: {
// Crop right.
nscoord cwidth;
nscoord twidth = 0;
int length = realText.Length();
int i;
for (i = 0; i < length; ++i) {
PRUnichar ch = realText.CharAt(i);
aRenderingContext.GetWidth(ch,cwidth);
if (twidth + cwidth > width)
break;
twidth += cwidth;
}
realText.Truncate(i);
realText += ellipsis;
}
break;
case 2: {
// Crop left.
nscoord cwidth;
nscoord twidth = 0;
int length = realText.Length();
int i;
for (i=length-1; i >= 0; --i) {
PRUnichar ch = realText.CharAt(i);
aRenderingContext.GetWidth(ch,cwidth);
if (twidth + cwidth > width)
break;
twidth += cwidth;
}
nsAutoString copy;
realText.Right(copy, length-1-i);
realText = ellipsis;
realText += copy;
}
break;
case 1:
{
// XXX Not yet implemented.
}
break;
}
}
}
// Set our color.
const nsStyleColor* colorStyle = (const nsStyleColor*)textContext->GetStyleData(eStyleStruct_Color);
@ -832,7 +1126,75 @@ nsOutlinerBodyFrame::PaintBackgroundLayer(nsIStyleContext* aStyleContext, nsIPre
}
// Scrolling
NS_IMETHODIMP nsOutlinerBodyFrame::EnsureRowIsVisible(PRInt32 aRow)
{
if (!mView)
return NS_OK;
if (mTopRowIndex <= aRow && mTopRowIndex+mPageCount > aRow)
return NS_OK;
if (aRow < mTopRowIndex)
ScrollToRow(aRow);
else {
// Bring it just on-screen.
PRInt32 distance = aRow - (mTopRowIndex+mPageCount)+1;
ScrollToRow(mTopRowIndex+distance);
}
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBodyFrame::ScrollToRow(PRInt32 aRow)
{
ScrollInternal(aRow);
UpdateScrollbar();
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBodyFrame::ScrollByLines(PRInt32 aNumLines)
{
if (!mView)
return NS_OK;
PRInt32 newIndex = mTopRowIndex + aNumLines;
if (newIndex < 0)
newIndex = 0;
else {
PRInt32 rowCount;
mView->GetRowCount(&rowCount);
PRInt32 lastPageTopRow = rowCount - mPageCount;
if (newIndex > lastPageTopRow)
newIndex = lastPageTopRow;
}
ScrollToRow(newIndex);
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBodyFrame::ScrollByPages(PRInt32 aNumPages)
{
if (!mView)
return NS_OK;
PRInt32 newIndex = mTopRowIndex + aNumPages * mPageCount;
if (newIndex < 0)
newIndex = 0;
else {
PRInt32 rowCount;
mView->GetRowCount(&rowCount);
PRInt32 lastPageTopRow = rowCount - mPageCount;
if (newIndex > lastPageTopRow)
newIndex = lastPageTopRow;
}
ScrollToRow(newIndex);
return NS_OK;
}
nsresult
nsOutlinerBodyFrame::ScrollInternal(PRInt32 aRow)
{
if (!mView)
return NS_OK;
@ -857,11 +1219,16 @@ NS_IMETHODIMP nsOutlinerBodyFrame::ScrollToRow(PRInt32 aRow)
mPresContext->GetTwipsToPixels(&t2p);
nscoord rowHeightAsPixels = NSToCoordRound((float)mRowHeight*t2p);
// See if we have a background image. If we do, then we cannot blit.
const nsStyleColor* myColor = (const nsStyleColor*)
mStyleContext->GetStyleData(eStyleStruct_Color);
PRBool hasBackground = myColor->mBackgroundImage.Length() > 0;
PRInt32 absDelta = delta > 0 ? delta : -delta;
if (absDelta*mRowHeight >= mRect.height)
if (hasBackground || absDelta*mRowHeight >= mRect.height)
Invalidate();
else if (mOutlinerWidget)
mOutlinerWidget->Scroll(0, delta > 0 ? -delta*rowHeightAsPixels : delta*rowHeightAsPixels, nsnull);
mOutlinerWidget->Scroll(0, -delta*rowHeightAsPixels, nsnull);
return NS_OK;
}
@ -871,19 +1238,8 @@ nsOutlinerBodyFrame::ScrollbarButtonPressed(PRInt32 aOldIndex, PRInt32 aNewIndex
{
if (aNewIndex > aOldIndex)
ScrollToRow(mTopRowIndex+1);
else ScrollToRow(mTopRowIndex-1);
// Update the scrollbar.
nsCOMPtr<nsIContent> scrollbarContent;
mScrollbar->GetContent(getter_AddRefs(scrollbarContent));
float t2p;
mPresContext->GetTwipsToPixels(&t2p);
nscoord rowHeightAsPixels = NSToCoordRound((float)mRowHeight*t2p);
nsAutoString curPos;
curPos.AppendInt(mTopRowIndex*rowHeightAsPixels);
scrollbarContent->SetAttribute(kNameSpaceID_None, nsXULAtoms::curpos, curPos, PR_TRUE);
else if (aNewIndex < aOldIndex)
ScrollToRow(mTopRowIndex-1);
return NS_OK;
}
@ -898,7 +1254,7 @@ nsOutlinerBodyFrame::PositionChanged(PRInt32 aOldIndex, PRInt32& aNewIndex)
nscoord newrow = aNewIndex/rh;
if (oldrow != newrow)
ScrollToRow(newrow);
ScrollInternal(newrow);
// Go exactly where we're supposed to
// Update the scrollbar.
@ -991,4 +1347,5 @@ NS_INTERFACE_MAP_BEGIN(nsOutlinerBodyFrame)
NS_INTERFACE_MAP_ENTRY(nsIOutlinerBoxObject)
NS_INTERFACE_MAP_ENTRY(nsICSSPseudoComparator)
NS_INTERFACE_MAP_ENTRY(nsIScrollbarMediator)
NS_INTERFACE_MAP_END_INHERITING(nsLeafFrame)
NS_INTERFACE_MAP_END_INHERITING(nsLeafFrame)

View File

@ -143,6 +143,11 @@ public:
nscoord GetWidth();
const PRUnichar* GetID() { return mID.GetUnicode(); };
PRBool IsPrimary() { return mIsPrimaryCol; };
PRBool IsCycler() { return mIsCyclerCol; };
PRInt32 GetCropStyle() { return mCropStyle; };
};
// The actual frame that paints the cells and rows.
@ -165,6 +170,11 @@ public:
NS_IMETHOD Init(nsIPresContext* aPresContext, nsIContent* aContent,
nsIFrame* aParent, nsIStyleContext* aContext, nsIFrame* aPrevInFlow);
NS_IMETHOD Destroy(nsIPresContext* aPresContext);
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aReflowMetrics,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
// Painting methods.
// Paint is the generic nsIFrame paint method. We override this method
@ -223,6 +233,9 @@ protected:
// Returns the height of rows in the tree.
PRInt32 GetRowHeight();
// Returns our indentation width.
PRInt32 GetIndentation();
// Returns our width/height once border and padding have been removed.
nsRect GetInnerBox();
@ -233,10 +246,16 @@ protected:
// Builds our cache of column info.
void EnsureColumns();
// Update the curpos of the scrollbar.
void UpdateScrollbar();
// Use to auto-fill some of the common properties without the view having to do it.
// Examples include container, open, selected, and focused.
void PrefillPropertyArray(PRInt32 aRowIndex, const PRUnichar* aColID);
// Our internal scroll method, used by all the public scroll methods.
nsresult ScrollInternal(PRInt32 aRow);
protected: // Data Members
// Our cached pres context.
nsIPresContext* mPresContext;
@ -266,9 +285,10 @@ protected: // Data Members
PRInt32 mTopRowIndex;
PRInt32 mPageCount;
// Cached heights.and info.
// Cached heights.and indent info.
nsRect mInnerBox;
PRInt32 mRowHeight;
PRInt32 mIndentation;
// A scratch array used when looking up cached style contexts.
nsCOMPtr<nsISupportsArray> mScratchArray;

View File

@ -144,11 +144,19 @@ NS_IMETHODIMP nsOutlinerBoxObject::GetSelection(nsIOutlinerSelection * *aSelecti
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBoxObject::GetIndexOfVisibleRow(PRInt32 *_retval)
NS_IMETHODIMP nsOutlinerBoxObject::GetFirstVisibleRow(PRInt32 *_retval)
{
nsIOutlinerBoxObject* body = GetOutlinerBody();
if (body)
return body->GetIndexOfVisibleRow(_retval);
return body->GetFirstVisibleRow(_retval);
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBoxObject::GetLastVisibleRow(PRInt32 *_retval)
{
nsIOutlinerBoxObject* body = GetOutlinerBody();
if (body)
return body->GetLastVisibleRow(_retval);
return NS_OK;
}
@ -160,6 +168,15 @@ NS_IMETHODIMP nsOutlinerBoxObject::GetPageCount(PRInt32 *_retval)
return NS_OK;
}
NS_IMETHODIMP
nsOutlinerBoxObject::EnsureRowIsVisible(PRInt32 aRow)
{
nsIOutlinerBoxObject* body = GetOutlinerBody();
if (body)
return body->EnsureRowIsVisible(aRow);
return NS_OK;
}
NS_IMETHODIMP
nsOutlinerBoxObject::ScrollToRow(PRInt32 aRow)
{
@ -169,6 +186,25 @@ nsOutlinerBoxObject::ScrollToRow(PRInt32 aRow)
return NS_OK;
}
NS_IMETHODIMP
nsOutlinerBoxObject::ScrollByLines(PRInt32 aNumLines)
{
nsIOutlinerBoxObject* body = GetOutlinerBody();
if (body)
return body->ScrollByLines(aNumLines);
return NS_OK;
}
NS_IMETHODIMP
nsOutlinerBoxObject::ScrollByPages(PRInt32 aNumPages)
{
nsIOutlinerBoxObject* body = GetOutlinerBody();
if (body)
return body->ScrollByPages(aNumPages);
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBoxObject::Invalidate()
{
nsIOutlinerBoxObject* body = GetOutlinerBody();
@ -217,27 +253,11 @@ NS_IMETHODIMP nsOutlinerBoxObject::GetCellAt(PRInt32 x, PRInt32 y, PRInt32 *row,
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBoxObject::RowsAppended(PRInt32 count)
NS_IMETHODIMP nsOutlinerBoxObject::RowCountChanged(PRInt32 aIndex, PRInt32 aDelta)
{
nsIOutlinerBoxObject* body = GetOutlinerBody();
if (body)
return body->RowsAppended(count);
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBoxObject::RowsInserted(PRInt32 index, PRInt32 count)
{
nsIOutlinerBoxObject* body = GetOutlinerBody();
if (body)
return body->RowsInserted(index, count);
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBoxObject::RowsRemoved(PRInt32 index, PRInt32 count)
{
nsIOutlinerBoxObject* body = GetOutlinerBody();
if (body)
return body->RowsRemoved(index, count);
return body->RowCountChanged(aIndex, aDelta);
return NS_OK;
}

View File

@ -25,9 +25,14 @@
#include "nsCOMPtr.h"
#include "nsOutlinerColFrame.h"
#include "nsXULAtoms.h"
#include "nsHTMLAtoms.h"
#include "nsIContent.h"
#include "nsIStyleContext.h"
#include "nsINameSpaceManager.h"
#include "nsIDOMNSDocument.h"
#include "nsIDocument.h"
#include "nsIBoxObject.h"
#include "nsIDOMElement.h"
//
// NS_NewOutlinerColFrame
@ -36,13 +41,13 @@
//
nsresult
NS_NewOutlinerColFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRBool aIsRoot,
nsIBoxLayout* aLayoutManager, PRBool aIsHorizontal)
nsIBoxLayout* aLayoutManager)
{
NS_PRECONDITION(aNewFrame, "null OUT ptr");
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsOutlinerColFrame* it = new (aPresShell) nsOutlinerColFrame(aPresShell, aIsRoot, aLayoutManager, aIsHorizontal);
nsOutlinerColFrame* it = new (aPresShell) nsOutlinerColFrame(aPresShell, aIsRoot, aLayoutManager);
if (!it)
return NS_ERROR_OUT_OF_MEMORY;
@ -70,8 +75,8 @@ NS_INTERFACE_MAP_BEGIN(nsOutlinerColFrame)
NS_INTERFACE_MAP_ENTRY(nsIOutlinerColFrame)
NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame)
// Constructor
nsOutlinerColFrame::nsOutlinerColFrame(nsIPresShell* aPresShell, PRBool aIsRoot, nsIBoxLayout* aLayoutManager, PRBool aIsHorizontal)
:nsBoxFrame(aPresShell, aIsRoot, aLayoutManager, aIsHorizontal)
nsOutlinerColFrame::nsOutlinerColFrame(nsIPresShell* aPresShell, PRBool aIsRoot, nsIBoxLayout* aLayoutManager)
:nsBoxFrame(aPresShell, aIsRoot, aLayoutManager)
{}
// Destructor
@ -144,3 +149,36 @@ nsOutlinerColFrame::GetFrameForPoint(nsIPresContext* aPresContext,
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsOutlinerColFrame::AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aHint)
{
nsresult rv = nsBoxFrame::AttributeChanged(aPresContext, aChild,
aNameSpaceID, aAttribute, aHint);
if (aAttribute == nsHTMLAtoms::width || aAttribute == nsHTMLAtoms::hidden) {
// Invalidate the outliner.
if (!mOutliner) {
// Get our parent node.
nsCOMPtr<nsIContent> parent;
mContent->GetParent(*getter_AddRefs(parent));
nsCOMPtr<nsIDocument> doc;
mContent->GetDocument(*getter_AddRefs(doc));
nsCOMPtr<nsIDOMNSDocument> nsDoc(do_QueryInterface(doc));
nsCOMPtr<nsIDOMElement> elt(do_QueryInterface(parent));
nsCOMPtr<nsIBoxObject> boxObject;
nsDoc->GetBoxObjectFor(elt, getter_AddRefs(boxObject));
mOutliner = do_QueryInterface(boxObject);
}
if (mOutliner)
mOutliner->Invalidate();
}
return rv;
}

View File

@ -24,6 +24,7 @@
#include "nsBoxFrame.h"
#include "nsIOutlinerColFrame.h"
#include "nsIOutlinerBoxObject.h"
class nsSupportsHashtable;
@ -37,16 +38,25 @@ public:
friend nsresult NS_NewOutlinerColFrame(nsIPresShell* aPresShell,
nsIFrame** aNewFrame,
PRBool aIsRoot = PR_FALSE,
nsIBoxLayout* aLayoutManager = nsnull,
PRBool aDefaultHorizontal = PR_TRUE);
nsIBoxLayout* aLayoutManager = nsnull);
NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext,
const nsPoint& aPoint, // Overridden to capture events
nsFramePaintLayer aWhichLayer,
nsIFrame** aFrame);
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aHint);
protected:
nsOutlinerColFrame(nsIPresShell* aPresShell, PRBool aIsRoot = nsnull, nsIBoxLayout* aLayoutManager = nsnull, PRBool aDefaultHorizontal = PR_TRUE);
nsOutlinerColFrame(nsIPresShell* aPresShell, PRBool aIsRoot = nsnull, nsIBoxLayout* aLayoutManager = nsnull);
virtual ~nsOutlinerColFrame();
protected:
// Members.
nsCOMPtr<nsIOutlinerBoxObject> mOutliner;
}; // class nsOutlinerColFrame

View File

@ -136,6 +136,12 @@ struct nsOutlinerRange
mMin++;
else if (aIndex == mMax)
mMax--;
else {
// We have to break this range.
nsOutlinerRange* newRange = new nsOutlinerRange(mSelection, aIndex + 1, mMax);
newRange->Connect(this, mNext);
mMax = aIndex - 1;
}
}
else if (mNext)
mNext->Remove(aIndex);
@ -305,6 +311,8 @@ NS_IMETHODIMP nsOutlinerSelection::Select(PRInt32 aIndex)
{
mShiftSelectPivot = -1;
SetCurrentIndex(aIndex);
if (mFirstRange) {
PRBool alreadySelected = mFirstRange->Contains(aIndex);
@ -324,8 +332,6 @@ NS_IMETHODIMP nsOutlinerSelection::Select(PRInt32 aIndex)
}
}
SetCurrentIndex(aIndex);
// Create our new selection.
mFirstRange = new nsOutlinerRange(this, aIndex);
mFirstRange->Invalidate();
@ -353,9 +359,9 @@ NS_IMETHODIMP nsOutlinerSelection::ToggleSelect(PRInt32 aIndex)
else {
if (!mFirstRange->Contains(aIndex))
mFirstRange->Add(aIndex);
else
else
mFirstRange->Remove(aIndex);
mOutliner->InvalidateRow(aIndex);
FireOnSelectHandler();
@ -368,8 +374,10 @@ NS_IMETHODIMP nsOutlinerSelection::RangedSelect(PRInt32 aStartIndex, PRInt32 aEn
{
if (!aAugment) {
// Clear our selection.
mFirstRange->Invalidate();
delete mFirstRange;
if (mFirstRange) {
mFirstRange->Invalidate();
delete mFirstRange;
}
}
if (aStartIndex == -1) {
@ -384,7 +392,7 @@ NS_IMETHODIMP nsOutlinerSelection::RangedSelect(PRInt32 aStartIndex, PRInt32 aEn
PRInt32 start = aStartIndex < aEndIndex ? aStartIndex : aEndIndex;
PRInt32 end = aStartIndex < aEndIndex ? aEndIndex : aStartIndex;
if (aAugment) {
if (aAugment && mFirstRange) {
// We need to remove all the items within our selected range from the selection,
// and then we insert our new range into the list.
mFirstRange->RemoveRange(start, end);
@ -403,11 +411,29 @@ NS_IMETHODIMP nsOutlinerSelection::RangedSelect(PRInt32 aStartIndex, PRInt32 aEn
return NS_OK;
}
NS_IMETHODIMP nsOutlinerSelection::ClearRange(PRInt32 aStartIndex, PRInt32 aEndIndex)
{
SetCurrentIndex(aEndIndex);
if (mFirstRange) {
PRInt32 start = aStartIndex < aEndIndex ? aStartIndex : aEndIndex;
PRInt32 end = aStartIndex < aEndIndex ? aEndIndex : aStartIndex;
mFirstRange->RemoveRange(start, end);
mOutliner->InvalidateRange(start, end);
}
return NS_OK;
}
NS_IMETHODIMP nsOutlinerSelection::ClearSelection()
{
mFirstRange->Invalidate();
delete mFirstRange;
mFirstRange = nsnull;
if (mFirstRange) {
mFirstRange->Invalidate();
delete mFirstRange;
mFirstRange = nsnull;
}
mShiftSelectPivot = -1;
FireOnSelectHandler();
@ -511,6 +537,12 @@ NS_IMETHODIMP nsOutlinerSelection::SetCurrentIndex(PRInt32 aIndex)
return NS_OK;
}
NS_IMETHODIMP
nsOutlinerSelection::AdjustSelection(PRInt32 aIndex, PRInt32 aCount)
{
return NS_OK;
}
nsresult
nsOutlinerSelection::FireOnSelectHandler()
{

View File

@ -43,13 +43,30 @@ interface nsIOutlinerBoxObject : nsISupports
readonly attribute nsIOutlinerSelection selection;
// Get the index of the first visible row.
long getIndexOfVisibleRow();
long getFirstVisibleRow();
// Get the index of the last visible row.
long getLastVisibleRow();
// Gets the number of possible visible rows.
long getPageCount();
// Ensures that a row at a given index is visible.
void ensureRowIsVisible(in long index);
// Scrolls such that the row at index is at the top of the visible view.
void scrollToRow(in long index);
// Scroll the outliner up or down by numLines lines. Positive
// values move down in the outliner. Prevents scrolling off the
// end of the outliner.
void scrollByLines(in long numLines);
// Scroll the outliner up or down by numPages pages. A page
// is considered to be the amount displayed by the outliner.
// Positive values move down in the outliner. Prevents scrolling
// off the end of the outliner.
void scrollByPages(in long numPages);
// Invalidation methods for fine-grained painting control.
void invalidate();
@ -62,12 +79,10 @@ interface nsIOutlinerBoxObject : nsISupports
void getCellAt(in long x, in long y, out long row, out wstring colID);
// The view is responsible for calling these notification methods when
// nodes are added or removed. Index is the position at which the new
// rows start. Count is the number of new contiguous rows added. For
// non-contiguous additions, these methods should be called multiple times.
void rowsAppended(in long count);
void rowsInserted(in long index, in long count);
void rowsRemoved(in long index, in long count);
// rows are added or removed. Index is the position at which the new
// rows were added or at which rows were removed. For
// non-contiguous additions/removals, this method should be called multiple times.
void rowCountChanged(in long index, in long count);
};
%{C++

View File

@ -50,6 +50,9 @@ interface nsIOutlinerSelection : nsISecurityCheckedComponent
// else. If augment is false, everything is cleared except for the specified range.
void rangedSelect(in long startIndex, in long endIndex, in boolean augment);
// Clears the range.
void clearRange(in long startIndex, in long endIndex);
// Clears the selection.
void clearSelection();
@ -63,6 +66,9 @@ interface nsIOutlinerSelection : nsISecurityCheckedComponent
long getRangeCount();
void getRangeAt(in long i, out long min, out long max);
// Called when the row count changes to adjust selection indices.
void adjustSelection(in long index, in long count);
// This attribute is a boolean indicating whether or not the
// "select" event should fire when the selection is changed using
// one of our methods. A view can use this to temporarily suppress

View File

@ -61,7 +61,17 @@ interface nsIOutlinerView : nsISupports
boolean isContainer(in long index);
boolean isContainerOpen(in long index);
boolean isContainerEmpty(in long index);
// Methods used by the outliner to draw vertical lines in the tree.
// GetParentIndex is used to obtain the index of a parent row.
long getParentIndex(in long rowIndex);
// HasNextSibling is used to determine if the row at rowIndex has a nextSibling
// that occurs *after* the index specified by afterIndex. Code that is forced
// to march down the view looking at levels can optimize the march by starting
// at afterIndex+1.
boolean hasNextSibling(in long rowIndex, in long afterIndex);
// The level is an integer value that represents
// the level of indentation. It is multiplied by the width specified in the
// :moz-outliner-indentation pseudoelement to compute the exact indendation.

View File

@ -53,6 +53,8 @@
#include "nsWidgetsCID.h"
#include "nsBoxFrame.h"
#define ELLIPSIS "..."
// The style context cache impl
nsresult
nsOutlinerStyleCache::GetStyleContext(nsICSSPseudoComparator* aComparator,
@ -132,9 +134,9 @@ nsOutlinerColumn::nsOutlinerColumn(nsIContent* aColElement, nsIFrame* aFrame)
mCropStyle = 0;
nsAutoString crop;
mColElement->GetAttribute(kNameSpaceID_None, nsXULAtoms::crop, crop);
if (crop.EqualsIgnoreCase("middle"))
if (crop.EqualsIgnoreCase("center"))
mCropStyle = 1;
else if (crop.EqualsIgnoreCase("right"))
else if (crop.EqualsIgnoreCase("left"))
mCropStyle = 2;
// Cache our text alignment policy.
@ -198,7 +200,7 @@ NS_NewOutlinerBodyFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
// Constructor
nsOutlinerBodyFrame::nsOutlinerBodyFrame(nsIPresShell* aPresShell)
:nsLeafBoxFrame(aPresShell), mPresContext(nsnull),
mTopRowIndex(0), mColumns(nsnull), mScrollbar(nsnull)
mTopRowIndex(0), mRowHeight(0), mIndentation(0), mColumns(nsnull), mScrollbar(nsnull)
{
NS_NewISupportsArray(getter_AddRefs(mScratchArray));
}
@ -267,12 +269,36 @@ nsOutlinerBodyFrame::Destroy(nsIPresContext* aPresContext)
mColumns = nsnull;
// Drop our ref to the view.
mView->SetOutliner(nsnull);
if (mView)
mView->SetOutliner(nsnull);
mView = nsnull;
return nsLeafBoxFrame::Destroy(aPresContext);
}
NS_IMETHODIMP nsOutlinerBodyFrame::Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aReflowMetrics,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
if ( mView && mRowHeight && aReflowState.reason == eReflowReason_Resize) {
mInnerBox = GetInnerBox();
mPageCount = mInnerBox.height / mRowHeight;
PRInt32 rowCount;
mView->GetRowCount(&rowCount);
PRInt32 lastPageTopRow = rowCount - mPageCount;
if (mTopRowIndex >= lastPageTopRow)
ScrollToRow(lastPageTopRow);
InvalidateScrollbar();
}
// nsLeafBoxFrame::Reflow(aPresContext, aReflowMetrics, aReflowState, aStatus);
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBodyFrame::GetView(nsIOutlinerView * *aView)
{
*aView = mView;
@ -284,7 +310,14 @@ NS_IMETHODIMP nsOutlinerBodyFrame::SetView(nsIOutlinerView * aView)
{
// Outliner, meet the view.
mView = aView;
// Changing the view causes us to refetch our data. This will
// necessarily entail a full invalidation of the outliner.
mTopRowIndex = 0;
delete mColumns;
mColumns = nsnull;
Invalidate();
if (mView) {
// View, meet the outliner.
mView->SetOutliner(this);
@ -294,15 +327,11 @@ NS_IMETHODIMP nsOutlinerBodyFrame::SetView(nsIOutlinerView * aView)
NS_NewOutlinerSelection(this, getter_AddRefs(sel));
mView->SetSelection(sel);
// The scrollbar will need to be updated.
InvalidateScrollbar();
}
// Changing the view causes us to refetch our data. This will
// necessarily entail a full invalidation of the outliner.
mTopRowIndex = 0;
delete mColumns;
mColumns = nsnull;
Invalidate();
return NS_OK;
}
@ -321,12 +350,18 @@ NS_IMETHODIMP nsOutlinerBodyFrame::GetSelection(nsIOutlinerSelection** aSelectio
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBodyFrame::GetIndexOfVisibleRow(PRInt32 *_retval)
NS_IMETHODIMP nsOutlinerBodyFrame::GetFirstVisibleRow(PRInt32 *_retval)
{
*_retval = mTopRowIndex;
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBodyFrame::GetLastVisibleRow(PRInt32 *_retval)
{
*_retval = mTopRowIndex + mPageCount + 1;
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBodyFrame::GetPageCount(PRInt32 *_retval)
{
*_retval = mPageCount;
@ -360,8 +395,9 @@ NS_IMETHODIMP nsOutlinerBodyFrame::InvalidateRange(PRInt32 aStart, PRInt32 aEnd)
if (aStart == aEnd)
return InvalidateRow(aStart);
if (aEnd < mTopRowIndex || aStart > mTopRowIndex + mPageCount + 1)
PRInt32 last;
GetLastVisibleRow(&last);
if (aEnd < mTopRowIndex || aStart > last)
return NS_OK;
if (aStart < mTopRowIndex)
@ -376,6 +412,21 @@ NS_IMETHODIMP nsOutlinerBodyFrame::InvalidateRange(PRInt32 aStart, PRInt32 aEnd)
return NS_OK;
}
void
nsOutlinerBodyFrame::UpdateScrollbar()
{
// Update the scrollbar.
nsCOMPtr<nsIContent> scrollbarContent;
mScrollbar->GetContent(getter_AddRefs(scrollbarContent));
float t2p;
mPresContext->GetTwipsToPixels(&t2p);
nscoord rowHeightAsPixels = NSToCoordRound((float)mRowHeight*t2p);
nsAutoString curPos;
curPos.AppendInt(mTopRowIndex*rowHeightAsPixels);
scrollbarContent->SetAttribute(kNameSpaceID_None, nsXULAtoms::curpos, curPos, PR_TRUE);
}
NS_IMETHODIMP nsOutlinerBodyFrame::InvalidateScrollbar()
{
if (!mScrollbar)
@ -397,7 +448,7 @@ NS_IMETHODIMP nsOutlinerBodyFrame::InvalidateScrollbar()
mPresContext->GetTwipsToPixels(&t2p);
nscoord rowHeightAsPixels = NSToCoordRound((float)mRowHeight*t2p);
PRInt32 size = rowHeightAsPixels*(rowCount-mPageCount+1);
PRInt32 size = rowHeightAsPixels*(rowCount-mPageCount);
maxposStr.AppendInt(size);
scrollbar->SetAttribute(kNameSpaceID_None, nsXULAtoms::maxpos, maxposStr, PR_TRUE);
@ -450,22 +501,70 @@ NS_IMETHODIMP nsOutlinerBodyFrame::GetCellAt(PRInt32 aX, PRInt32 aY, PRInt32* aR
// Now just mod by our total inner box height and add to our top row index.
*aRow = (y/mRowHeight)+mTopRowIndex;
// XXX Determine the column hit!
// Determine the column hit.
nscoord currX = mInnerBox.x;
for (nsOutlinerColumn* currCol = mColumns; currCol && currX < mInnerBox.x+mInnerBox.width;
currCol = currCol->GetNext()) {
nsRect colRect(currX, mInnerBox.y, currCol->GetWidth(), mInnerBox.height);
PRInt32 overflow = colRect.x+colRect.width-(mInnerBox.x+mInnerBox.width);
if (overflow > 0)
colRect.width -= overflow;
if (x >= colRect.x && x < colRect.x + colRect.width)
*aColID = nsXPIDLString::Copy(currCol->GetID());
currX += colRect.width;
}
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBodyFrame::RowsAppended(PRInt32 count)
NS_IMETHODIMP nsOutlinerBodyFrame::RowCountChanged(PRInt32 aIndex, PRInt32 aCount)
{
return NS_OK;
}
if (aCount == 0)
return NS_OK; // Nothing to do.
NS_IMETHODIMP nsOutlinerBodyFrame::RowsInserted(PRInt32 index, PRInt32 count)
{
return NS_OK;
}
PRInt32 count = aCount > 0 ? aCount : -aCount;
NS_IMETHODIMP nsOutlinerBodyFrame::RowsRemoved(PRInt32 index, PRInt32 count)
{
// Adjust our selection.
nsCOMPtr<nsIOutlinerSelection> sel;
mView->GetSelection(getter_AddRefs(sel));
sel->AdjustSelection(aIndex, aCount);
PRInt32 last;
GetLastVisibleRow(&last);
if (aIndex >= mTopRowIndex && aIndex <= last)
InvalidateRange(aIndex, last);
if (mTopRowIndex == 0) {
// Just update the scrollbar and return.
InvalidateScrollbar();
return NS_OK;
}
// Adjust our top row index.
if (aCount > 0) {
if (mTopRowIndex > aIndex) {
// Rows came in above us. Augment the top row index.
mTopRowIndex += aCount;
UpdateScrollbar();
}
}
else if (aCount < 0) {
if (mTopRowIndex > aIndex+count-1) {
// No need to invalidate. The remove happened
// completely offscreen.
mTopRowIndex -= count;
UpdateScrollbar();
}
else if (mTopRowIndex > aIndex) {
// This is a full-blown invalidate.
mTopRowIndex = aIndex+count-1;
UpdateScrollbar();
Invalidate();
}
}
InvalidateScrollbar();
return NS_OK;
}
@ -521,6 +620,23 @@ PRInt32 nsOutlinerBodyFrame::GetRowHeight()
return 19*15; // As good a default as any.
}
PRInt32 nsOutlinerBodyFrame::GetIndentation()
{
// Look up the correct indentation. It is equal to the specified indentation width.
nsCOMPtr<nsIStyleContext> indentContext;
mScratchArray->Clear();
GetPseudoStyleContext(mPresContext, nsXULAtoms::mozoutlinerindentation, getter_AddRefs(indentContext));
if (indentContext) {
const nsStylePosition* myPosition = (const nsStylePosition*)
indentContext->GetStyleData(eStyleStruct_Position);
if (myPosition->mWidth.GetUnit() == eStyleUnit_Coord) {
PRInt32 val = myPosition->mWidth.GetCoordValue();
return val;
}
}
return 16*15; // As good a default as any.
}
nsRect nsOutlinerBodyFrame::GetInnerBox()
{
nsRect r(0,0,mRect.width, mRect.height);
@ -532,6 +648,16 @@ nsRect nsOutlinerBodyFrame::GetInnerBox()
return r;
}
static void
AdjustForBorderPadding(nsIStyleContext* aContext, nsRect& aRect)
{
nsMargin m(0,0,0,0);
nsStyleBorderPadding bPad;
aContext->GetStyle(eStyleStruct_BorderPaddingShortcut, (nsStyleStruct&)bPad);
bPad.GetBorderPadding(m);
aRect.Deflate(m);
}
// Painting routines
NS_IMETHODIMP nsOutlinerBodyFrame::Paint(nsIPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
@ -556,13 +682,11 @@ NS_IMETHODIMP nsOutlinerBodyFrame::Paint(nsIPresContext* aPresContext,
return NS_OK;
PRBool clipState = PR_FALSE;
nsRect clipRect(mRect);
aRenderingContext.PushState();
aRenderingContext.SetClipRect(clipRect, nsClipCombine_kReplace, clipState);
// Update our page count, our available height and our row height.
PRInt32 oldRowHeight = mRowHeight;
mRowHeight = GetRowHeight();
mIndentation = GetIndentation();
mInnerBox = GetInnerBox();
mPageCount = mInnerBox.height/mRowHeight;
@ -580,8 +704,12 @@ NS_IMETHODIMP nsOutlinerBodyFrame::Paint(nsIPresContext* aPresContext,
// is contained in the rows.
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) {
nscoord currX = mInnerBox.x;
for (nsOutlinerColumn* currCol = mColumns; currCol; currCol = currCol->GetNext()) {
for (nsOutlinerColumn* currCol = mColumns; currCol && currX < mInnerBox.x+mInnerBox.width;
currCol = currCol->GetNext()) {
nsRect colRect(currX, mInnerBox.y, currCol->GetWidth(), mInnerBox.height);
PRInt32 overflow = colRect.x+colRect.width-(mInnerBox.x+mInnerBox.width);
if (overflow > 0)
colRect.width -= overflow;
nsRect dirtyRect;
if (dirtyRect.IntersectRect(aDirtyRect, colRect)) {
PaintColumn(currCol, colRect, aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
@ -594,12 +722,24 @@ NS_IMETHODIMP nsOutlinerBodyFrame::Paint(nsIPresContext* aPresContext,
for (PRInt32 i = mTopRowIndex; i < rowCount && i < mTopRowIndex+mPageCount+1; i++) {
nsRect rowRect(mInnerBox.x, mInnerBox.y+mRowHeight*(i-mTopRowIndex), mInnerBox.width, mRowHeight);
nsRect dirtyRect;
if (dirtyRect.IntersectRect(aDirtyRect, rowRect)) {
if (dirtyRect.IntersectRect(aDirtyRect, rowRect) && rowRect.y < (mInnerBox.y+mInnerBox.height)) {
PRBool clip = (rowRect.y + rowRect.height > mInnerBox.y + mInnerBox.height);
if (clip) {
// We need to clip the last row, since it extends outside our inner box. Push
// a clip rect down.
PRInt32 overflow = (rowRect.y+rowRect.height) - (mInnerBox.y+mInnerBox.height);
nsRect clipRect(rowRect.x, rowRect.y, mInnerBox.width, mRowHeight-overflow);
aRenderingContext.PushState();
aRenderingContext.SetClipRect(clipRect, nsClipCombine_kReplace, clipState);
}
PaintRow(i, rowRect, aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
if (clip)
aRenderingContext.PopState(clipState);
}
}
aRenderingContext.PopState(clipState);
return NS_OK;
}
@ -610,6 +750,9 @@ NS_IMETHODIMP nsOutlinerBodyFrame::PaintColumn(nsOutlinerColumn* aColumn,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
if (aColRect.width == 0)
return NS_OK; // Don't paint hidden columns.
// Now obtain the properties for our cell.
// XXX Automatically fill in the following props: open, container, selected, focused, and the col ID.
PrefillPropertyArray(-1, aColumn->GetID());
@ -670,10 +813,17 @@ NS_IMETHODIMP nsOutlinerBodyFrame::PaintRow(int aRowIndex, const nsRect& aRowRec
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer)
PaintBackgroundLayer(rowContext, aPresContext, aRenderingContext, rowRect, aDirtyRect);
// Adjust the rect for its border and padding.
AdjustForBorderPadding(rowContext, rowRect);
// Now loop over our cells. Only paint a cell if it intersects with our dirty rect.
nscoord currX = rowRect.x;
for (nsOutlinerColumn* currCol = mColumns; currCol; currCol = currCol->GetNext()) {
for (nsOutlinerColumn* currCol = mColumns; currCol && currX < mInnerBox.x+mInnerBox.width;
currCol = currCol->GetNext()) {
nsRect cellRect(currX, rowRect.y, currCol->GetWidth(), rowRect.height);
PRInt32 overflow = cellRect.x+cellRect.width-(mInnerBox.x+mInnerBox.width);
if (overflow > 0)
cellRect.width -= overflow;
nsRect dirtyRect;
if (dirtyRect.IntersectRect(aDirtyRect, cellRect)) {
PaintCell(aRowIndex, currCol, cellRect, aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
@ -683,7 +833,7 @@ NS_IMETHODIMP nsOutlinerBodyFrame::PaintRow(int aRowIndex, const nsRect& aRowRec
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBodyFrame::PaintCell(int aRowIndex,
nsOutlinerColumn* aColumn,
const nsRect& aCellRect,
@ -692,6 +842,9 @@ NS_IMETHODIMP nsOutlinerBodyFrame::PaintCell(int aRowIndex,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
if (aCellRect.width == 0)
return NS_OK; // Don't paint cells in hidden columns.
// Now obtain the properties for our cell.
// XXX Automatically fill in the following props: open, container, selected, focused, and the col ID.
PrefillPropertyArray(aRowIndex, NS_LITERAL_STRING(""));
@ -715,6 +868,9 @@ NS_IMETHODIMP nsOutlinerBodyFrame::PaintCell(int aRowIndex,
if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer)
PaintBackgroundLayer(cellContext, aPresContext, aRenderingContext, cellRect, aDirtyRect);
// Adjust the rect for its border and padding.
AdjustForBorderPadding(cellContext, cellRect);
nscoord currX = cellRect.x;
nscoord remainingWidth = cellRect.width;
@ -724,15 +880,77 @@ NS_IMETHODIMP nsOutlinerBodyFrame::PaintCell(int aRowIndex,
// RIGHT means paint from right to left.
// XXX Implement RIGHT alignment!
// XXX If we're the primary column, we need to indent and paint the twisty.
if (aColumn->IsPrimary()) {
// If we're the primary column, we need to indent and paint the twisty.
// First we indent
PRInt32 level;
mView->GetLevel(aRowIndex, &level);
currX += mIndentation*level;
remainingWidth -= mIndentation*level;
// Resolve style for line.
nsCOMPtr<nsIStyleContext> lineContext;
GetPseudoStyleContext(aPresContext, nsXULAtoms::mozoutlinerline, getter_AddRefs(lineContext));
const nsStyleDisplay* displayStyle = (const nsStyleDisplay*)lineContext->GetStyleData(eStyleStruct_Display);
if (displayStyle->IsVisibleOrCollapsed() && level) {
// Paint lines to show a connections between rows
aRenderingContext.PushState();
const nsStyleBorder* borderStyle = (const nsStyleBorder*)lineContext->GetStyleData(eStyleStruct_Border);
nscolor color;
borderStyle->GetBorderColor(NS_SIDE_LEFT, color);
aRenderingContext.SetColor(color);
PRUint8 style;
style = borderStyle->GetBorderStyle(NS_SIDE_LEFT);
if (style == NS_STYLE_BORDER_STYLE_DOTTED)
aRenderingContext.SetLineStyle(nsLineStyle_kDotted);
else if (style == NS_STYLE_BORDER_STYLE_DASHED)
aRenderingContext.SetLineStyle(nsLineStyle_kDashed);
else
aRenderingContext.SetLineStyle(nsLineStyle_kSolid);
PRInt32 y = (aRowIndex - mTopRowIndex) * mRowHeight;
PRInt32 i;
PRInt32 currentParent = aRowIndex;
for (i = level; i > 0; i--) {
PRBool hasNextSibling;
mView->HasNextSibling(currentParent, aRowIndex, &hasNextSibling);
if (hasNextSibling)
aRenderingContext.DrawLine(aCellRect.x + (i - 1) * mIndentation, y, aCellRect.x + (i - 1) * mIndentation, y + mRowHeight);
else if (i == level)
aRenderingContext.DrawLine(aCellRect.x + (i - 1) * mIndentation, y, aCellRect.x + (i - 1) * mIndentation, y + mRowHeight / 2);
PRInt32 parent;
mView->GetParentIndex(currentParent, &parent);
if (parent == -1)
break;
currentParent = parent;
}
aRenderingContext.DrawLine(aCellRect.x + (level - 1) * mIndentation, y + mRowHeight / 2, aCellRect.x + level * mIndentation, aCellRect.y + mRowHeight /2);
PRBool clipState;
aRenderingContext.PopState(clipState);
}
// XXX Paint the twisty.
}
// XXX Now paint the various images.
// Now paint our text.
nsRect textRect(currX, cellRect.y, remainingWidth, cellRect.height);
nsRect dirtyRect;
if (dirtyRect.IntersectRect(aDirtyRect, textRect))
PaintText(aRowIndex, aColumn, textRect, aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
// Now paint our text, but only if we aren't a cycler column.
// XXX until we have the ability to load images, allow the view to
// insert text into cycler columns...
// if (!aColumn->IsCycler()) {
nsRect textRect(currX, cellRect.y, remainingWidth, cellRect.height);
nsRect dirtyRect;
if (dirtyRect.IntersectRect(aDirtyRect, textRect))
PaintText(aRowIndex, aColumn, textRect, aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
//}
return NS_OK;
}
@ -750,6 +968,9 @@ NS_IMETHODIMP nsOutlinerBodyFrame::PaintText(int aRowIndex,
nsAutoString realText(text);
if (realText.Length() == 0)
return NS_OK; // Don't paint an empty string. XXX What about background/borders? Still paint?
// Resolve style for the text. It contains all the info we need to lay ourselves
// out and to paint.
nsCOMPtr<nsIStyleContext> textContext;
@ -769,6 +990,8 @@ NS_IMETHODIMP nsOutlinerBodyFrame::PaintText(int aRowIndex,
PaintBackgroundLayer(textContext, aPresContext, aRenderingContext, textRect, aDirtyRect);
else {
// Time to paint our text.
// Adjust the rect for its border and padding.
AdjustForBorderPadding(textContext, textRect);
// Compute our text size.
const nsStyleFont* fontStyle = (const nsStyleFont*)textContext->GetStyleData(eStyleStruct_Font);
@ -787,12 +1010,83 @@ NS_IMETHODIMP nsOutlinerBodyFrame::PaintText(int aRowIndex,
textRect.height = height;
}
// XXX Crop if the width is too big!
// Set our font.
aRenderingContext.SetFont(fontMet);
nscoord width;
aRenderingContext.GetWidth(realText, width);
// Set our font.
aRenderingContext.SetFont(fontMet);
if (width > textRect.width) {
// See if the width is even smaller than the ellipsis
// If so, clear the text completely.
nscoord ellipsisWidth;
aRenderingContext.GetWidth(ELLIPSIS, ellipsisWidth);
nsAutoString ellipsis; ellipsis.AssignWithConversion(ELLIPSIS);
nscoord width = textRect.width;
if (ellipsisWidth > width)
realText.SetLength(0);
else if (ellipsisWidth == width)
realText = ellipsis;
else {
// We will be drawing an ellipsis, thank you very much.
// Subtract out the required width of the ellipsis.
// This is the total remaining width we have to play with.
width -= ellipsisWidth;
// Now we crop.
switch (aColumn->GetCropStyle()) {
default:
case 0: {
// Crop right.
nscoord cwidth;
nscoord twidth = 0;
int length = realText.Length();
int i;
for (i = 0; i < length; ++i) {
PRUnichar ch = realText.CharAt(i);
aRenderingContext.GetWidth(ch,cwidth);
if (twidth + cwidth > width)
break;
twidth += cwidth;
}
realText.Truncate(i);
realText += ellipsis;
}
break;
case 2: {
// Crop left.
nscoord cwidth;
nscoord twidth = 0;
int length = realText.Length();
int i;
for (i=length-1; i >= 0; --i) {
PRUnichar ch = realText.CharAt(i);
aRenderingContext.GetWidth(ch,cwidth);
if (twidth + cwidth > width)
break;
twidth += cwidth;
}
nsAutoString copy;
realText.Right(copy, length-1-i);
realText = ellipsis;
realText += copy;
}
break;
case 1:
{
// XXX Not yet implemented.
}
break;
}
}
}
// Set our color.
const nsStyleColor* colorStyle = (const nsStyleColor*)textContext->GetStyleData(eStyleStruct_Color);
@ -832,7 +1126,75 @@ nsOutlinerBodyFrame::PaintBackgroundLayer(nsIStyleContext* aStyleContext, nsIPre
}
// Scrolling
NS_IMETHODIMP nsOutlinerBodyFrame::EnsureRowIsVisible(PRInt32 aRow)
{
if (!mView)
return NS_OK;
if (mTopRowIndex <= aRow && mTopRowIndex+mPageCount > aRow)
return NS_OK;
if (aRow < mTopRowIndex)
ScrollToRow(aRow);
else {
// Bring it just on-screen.
PRInt32 distance = aRow - (mTopRowIndex+mPageCount)+1;
ScrollToRow(mTopRowIndex+distance);
}
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBodyFrame::ScrollToRow(PRInt32 aRow)
{
ScrollInternal(aRow);
UpdateScrollbar();
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBodyFrame::ScrollByLines(PRInt32 aNumLines)
{
if (!mView)
return NS_OK;
PRInt32 newIndex = mTopRowIndex + aNumLines;
if (newIndex < 0)
newIndex = 0;
else {
PRInt32 rowCount;
mView->GetRowCount(&rowCount);
PRInt32 lastPageTopRow = rowCount - mPageCount;
if (newIndex > lastPageTopRow)
newIndex = lastPageTopRow;
}
ScrollToRow(newIndex);
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBodyFrame::ScrollByPages(PRInt32 aNumPages)
{
if (!mView)
return NS_OK;
PRInt32 newIndex = mTopRowIndex + aNumPages * mPageCount;
if (newIndex < 0)
newIndex = 0;
else {
PRInt32 rowCount;
mView->GetRowCount(&rowCount);
PRInt32 lastPageTopRow = rowCount - mPageCount;
if (newIndex > lastPageTopRow)
newIndex = lastPageTopRow;
}
ScrollToRow(newIndex);
return NS_OK;
}
nsresult
nsOutlinerBodyFrame::ScrollInternal(PRInt32 aRow)
{
if (!mView)
return NS_OK;
@ -857,11 +1219,16 @@ NS_IMETHODIMP nsOutlinerBodyFrame::ScrollToRow(PRInt32 aRow)
mPresContext->GetTwipsToPixels(&t2p);
nscoord rowHeightAsPixels = NSToCoordRound((float)mRowHeight*t2p);
// See if we have a background image. If we do, then we cannot blit.
const nsStyleColor* myColor = (const nsStyleColor*)
mStyleContext->GetStyleData(eStyleStruct_Color);
PRBool hasBackground = myColor->mBackgroundImage.Length() > 0;
PRInt32 absDelta = delta > 0 ? delta : -delta;
if (absDelta*mRowHeight >= mRect.height)
if (hasBackground || absDelta*mRowHeight >= mRect.height)
Invalidate();
else if (mOutlinerWidget)
mOutlinerWidget->Scroll(0, delta > 0 ? -delta*rowHeightAsPixels : delta*rowHeightAsPixels, nsnull);
mOutlinerWidget->Scroll(0, -delta*rowHeightAsPixels, nsnull);
return NS_OK;
}
@ -871,19 +1238,8 @@ nsOutlinerBodyFrame::ScrollbarButtonPressed(PRInt32 aOldIndex, PRInt32 aNewIndex
{
if (aNewIndex > aOldIndex)
ScrollToRow(mTopRowIndex+1);
else ScrollToRow(mTopRowIndex-1);
// Update the scrollbar.
nsCOMPtr<nsIContent> scrollbarContent;
mScrollbar->GetContent(getter_AddRefs(scrollbarContent));
float t2p;
mPresContext->GetTwipsToPixels(&t2p);
nscoord rowHeightAsPixels = NSToCoordRound((float)mRowHeight*t2p);
nsAutoString curPos;
curPos.AppendInt(mTopRowIndex*rowHeightAsPixels);
scrollbarContent->SetAttribute(kNameSpaceID_None, nsXULAtoms::curpos, curPos, PR_TRUE);
else if (aNewIndex < aOldIndex)
ScrollToRow(mTopRowIndex-1);
return NS_OK;
}
@ -898,7 +1254,7 @@ nsOutlinerBodyFrame::PositionChanged(PRInt32 aOldIndex, PRInt32& aNewIndex)
nscoord newrow = aNewIndex/rh;
if (oldrow != newrow)
ScrollToRow(newrow);
ScrollInternal(newrow);
// Go exactly where we're supposed to
// Update the scrollbar.
@ -991,4 +1347,5 @@ NS_INTERFACE_MAP_BEGIN(nsOutlinerBodyFrame)
NS_INTERFACE_MAP_ENTRY(nsIOutlinerBoxObject)
NS_INTERFACE_MAP_ENTRY(nsICSSPseudoComparator)
NS_INTERFACE_MAP_ENTRY(nsIScrollbarMediator)
NS_INTERFACE_MAP_END_INHERITING(nsLeafFrame)
NS_INTERFACE_MAP_END_INHERITING(nsLeafFrame)

View File

@ -143,6 +143,11 @@ public:
nscoord GetWidth();
const PRUnichar* GetID() { return mID.GetUnicode(); };
PRBool IsPrimary() { return mIsPrimaryCol; };
PRBool IsCycler() { return mIsCyclerCol; };
PRInt32 GetCropStyle() { return mCropStyle; };
};
// The actual frame that paints the cells and rows.
@ -165,6 +170,11 @@ public:
NS_IMETHOD Init(nsIPresContext* aPresContext, nsIContent* aContent,
nsIFrame* aParent, nsIStyleContext* aContext, nsIFrame* aPrevInFlow);
NS_IMETHOD Destroy(nsIPresContext* aPresContext);
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
nsHTMLReflowMetrics& aReflowMetrics,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
// Painting methods.
// Paint is the generic nsIFrame paint method. We override this method
@ -223,6 +233,9 @@ protected:
// Returns the height of rows in the tree.
PRInt32 GetRowHeight();
// Returns our indentation width.
PRInt32 GetIndentation();
// Returns our width/height once border and padding have been removed.
nsRect GetInnerBox();
@ -233,10 +246,16 @@ protected:
// Builds our cache of column info.
void EnsureColumns();
// Update the curpos of the scrollbar.
void UpdateScrollbar();
// Use to auto-fill some of the common properties without the view having to do it.
// Examples include container, open, selected, and focused.
void PrefillPropertyArray(PRInt32 aRowIndex, const PRUnichar* aColID);
// Our internal scroll method, used by all the public scroll methods.
nsresult ScrollInternal(PRInt32 aRow);
protected: // Data Members
// Our cached pres context.
nsIPresContext* mPresContext;
@ -266,9 +285,10 @@ protected: // Data Members
PRInt32 mTopRowIndex;
PRInt32 mPageCount;
// Cached heights.and info.
// Cached heights.and indent info.
nsRect mInnerBox;
PRInt32 mRowHeight;
PRInt32 mIndentation;
// A scratch array used when looking up cached style contexts.
nsCOMPtr<nsISupportsArray> mScratchArray;

View File

@ -144,11 +144,19 @@ NS_IMETHODIMP nsOutlinerBoxObject::GetSelection(nsIOutlinerSelection * *aSelecti
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBoxObject::GetIndexOfVisibleRow(PRInt32 *_retval)
NS_IMETHODIMP nsOutlinerBoxObject::GetFirstVisibleRow(PRInt32 *_retval)
{
nsIOutlinerBoxObject* body = GetOutlinerBody();
if (body)
return body->GetIndexOfVisibleRow(_retval);
return body->GetFirstVisibleRow(_retval);
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBoxObject::GetLastVisibleRow(PRInt32 *_retval)
{
nsIOutlinerBoxObject* body = GetOutlinerBody();
if (body)
return body->GetLastVisibleRow(_retval);
return NS_OK;
}
@ -160,6 +168,15 @@ NS_IMETHODIMP nsOutlinerBoxObject::GetPageCount(PRInt32 *_retval)
return NS_OK;
}
NS_IMETHODIMP
nsOutlinerBoxObject::EnsureRowIsVisible(PRInt32 aRow)
{
nsIOutlinerBoxObject* body = GetOutlinerBody();
if (body)
return body->EnsureRowIsVisible(aRow);
return NS_OK;
}
NS_IMETHODIMP
nsOutlinerBoxObject::ScrollToRow(PRInt32 aRow)
{
@ -169,6 +186,25 @@ nsOutlinerBoxObject::ScrollToRow(PRInt32 aRow)
return NS_OK;
}
NS_IMETHODIMP
nsOutlinerBoxObject::ScrollByLines(PRInt32 aNumLines)
{
nsIOutlinerBoxObject* body = GetOutlinerBody();
if (body)
return body->ScrollByLines(aNumLines);
return NS_OK;
}
NS_IMETHODIMP
nsOutlinerBoxObject::ScrollByPages(PRInt32 aNumPages)
{
nsIOutlinerBoxObject* body = GetOutlinerBody();
if (body)
return body->ScrollByPages(aNumPages);
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBoxObject::Invalidate()
{
nsIOutlinerBoxObject* body = GetOutlinerBody();
@ -217,27 +253,11 @@ NS_IMETHODIMP nsOutlinerBoxObject::GetCellAt(PRInt32 x, PRInt32 y, PRInt32 *row,
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBoxObject::RowsAppended(PRInt32 count)
NS_IMETHODIMP nsOutlinerBoxObject::RowCountChanged(PRInt32 aIndex, PRInt32 aDelta)
{
nsIOutlinerBoxObject* body = GetOutlinerBody();
if (body)
return body->RowsAppended(count);
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBoxObject::RowsInserted(PRInt32 index, PRInt32 count)
{
nsIOutlinerBoxObject* body = GetOutlinerBody();
if (body)
return body->RowsInserted(index, count);
return NS_OK;
}
NS_IMETHODIMP nsOutlinerBoxObject::RowsRemoved(PRInt32 index, PRInt32 count)
{
nsIOutlinerBoxObject* body = GetOutlinerBody();
if (body)
return body->RowsRemoved(index, count);
return body->RowCountChanged(aIndex, aDelta);
return NS_OK;
}

View File

@ -25,9 +25,14 @@
#include "nsCOMPtr.h"
#include "nsOutlinerColFrame.h"
#include "nsXULAtoms.h"
#include "nsHTMLAtoms.h"
#include "nsIContent.h"
#include "nsIStyleContext.h"
#include "nsINameSpaceManager.h"
#include "nsIDOMNSDocument.h"
#include "nsIDocument.h"
#include "nsIBoxObject.h"
#include "nsIDOMElement.h"
//
// NS_NewOutlinerColFrame
@ -36,13 +41,13 @@
//
nsresult
NS_NewOutlinerColFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRBool aIsRoot,
nsIBoxLayout* aLayoutManager, PRBool aIsHorizontal)
nsIBoxLayout* aLayoutManager)
{
NS_PRECONDITION(aNewFrame, "null OUT ptr");
if (nsnull == aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
nsOutlinerColFrame* it = new (aPresShell) nsOutlinerColFrame(aPresShell, aIsRoot, aLayoutManager, aIsHorizontal);
nsOutlinerColFrame* it = new (aPresShell) nsOutlinerColFrame(aPresShell, aIsRoot, aLayoutManager);
if (!it)
return NS_ERROR_OUT_OF_MEMORY;
@ -70,8 +75,8 @@ NS_INTERFACE_MAP_BEGIN(nsOutlinerColFrame)
NS_INTERFACE_MAP_ENTRY(nsIOutlinerColFrame)
NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame)
// Constructor
nsOutlinerColFrame::nsOutlinerColFrame(nsIPresShell* aPresShell, PRBool aIsRoot, nsIBoxLayout* aLayoutManager, PRBool aIsHorizontal)
:nsBoxFrame(aPresShell, aIsRoot, aLayoutManager, aIsHorizontal)
nsOutlinerColFrame::nsOutlinerColFrame(nsIPresShell* aPresShell, PRBool aIsRoot, nsIBoxLayout* aLayoutManager)
:nsBoxFrame(aPresShell, aIsRoot, aLayoutManager)
{}
// Destructor
@ -144,3 +149,36 @@ nsOutlinerColFrame::GetFrameForPoint(nsIPresContext* aPresContext,
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsOutlinerColFrame::AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aHint)
{
nsresult rv = nsBoxFrame::AttributeChanged(aPresContext, aChild,
aNameSpaceID, aAttribute, aHint);
if (aAttribute == nsHTMLAtoms::width || aAttribute == nsHTMLAtoms::hidden) {
// Invalidate the outliner.
if (!mOutliner) {
// Get our parent node.
nsCOMPtr<nsIContent> parent;
mContent->GetParent(*getter_AddRefs(parent));
nsCOMPtr<nsIDocument> doc;
mContent->GetDocument(*getter_AddRefs(doc));
nsCOMPtr<nsIDOMNSDocument> nsDoc(do_QueryInterface(doc));
nsCOMPtr<nsIDOMElement> elt(do_QueryInterface(parent));
nsCOMPtr<nsIBoxObject> boxObject;
nsDoc->GetBoxObjectFor(elt, getter_AddRefs(boxObject));
mOutliner = do_QueryInterface(boxObject);
}
if (mOutliner)
mOutliner->Invalidate();
}
return rv;
}

View File

@ -24,6 +24,7 @@
#include "nsBoxFrame.h"
#include "nsIOutlinerColFrame.h"
#include "nsIOutlinerBoxObject.h"
class nsSupportsHashtable;
@ -37,16 +38,25 @@ public:
friend nsresult NS_NewOutlinerColFrame(nsIPresShell* aPresShell,
nsIFrame** aNewFrame,
PRBool aIsRoot = PR_FALSE,
nsIBoxLayout* aLayoutManager = nsnull,
PRBool aDefaultHorizontal = PR_TRUE);
nsIBoxLayout* aLayoutManager = nsnull);
NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext,
const nsPoint& aPoint, // Overridden to capture events
nsFramePaintLayer aWhichLayer,
nsIFrame** aFrame);
NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext,
nsIContent* aChild,
PRInt32 aNameSpaceID,
nsIAtom* aAttribute,
PRInt32 aHint);
protected:
nsOutlinerColFrame(nsIPresShell* aPresShell, PRBool aIsRoot = nsnull, nsIBoxLayout* aLayoutManager = nsnull, PRBool aDefaultHorizontal = PR_TRUE);
nsOutlinerColFrame(nsIPresShell* aPresShell, PRBool aIsRoot = nsnull, nsIBoxLayout* aLayoutManager = nsnull);
virtual ~nsOutlinerColFrame();
protected:
// Members.
nsCOMPtr<nsIOutlinerBoxObject> mOutliner;
}; // class nsOutlinerColFrame

View File

@ -136,6 +136,12 @@ struct nsOutlinerRange
mMin++;
else if (aIndex == mMax)
mMax--;
else {
// We have to break this range.
nsOutlinerRange* newRange = new nsOutlinerRange(mSelection, aIndex + 1, mMax);
newRange->Connect(this, mNext);
mMax = aIndex - 1;
}
}
else if (mNext)
mNext->Remove(aIndex);
@ -305,6 +311,8 @@ NS_IMETHODIMP nsOutlinerSelection::Select(PRInt32 aIndex)
{
mShiftSelectPivot = -1;
SetCurrentIndex(aIndex);
if (mFirstRange) {
PRBool alreadySelected = mFirstRange->Contains(aIndex);
@ -324,8 +332,6 @@ NS_IMETHODIMP nsOutlinerSelection::Select(PRInt32 aIndex)
}
}
SetCurrentIndex(aIndex);
// Create our new selection.
mFirstRange = new nsOutlinerRange(this, aIndex);
mFirstRange->Invalidate();
@ -353,9 +359,9 @@ NS_IMETHODIMP nsOutlinerSelection::ToggleSelect(PRInt32 aIndex)
else {
if (!mFirstRange->Contains(aIndex))
mFirstRange->Add(aIndex);
else
else
mFirstRange->Remove(aIndex);
mOutliner->InvalidateRow(aIndex);
FireOnSelectHandler();
@ -368,8 +374,10 @@ NS_IMETHODIMP nsOutlinerSelection::RangedSelect(PRInt32 aStartIndex, PRInt32 aEn
{
if (!aAugment) {
// Clear our selection.
mFirstRange->Invalidate();
delete mFirstRange;
if (mFirstRange) {
mFirstRange->Invalidate();
delete mFirstRange;
}
}
if (aStartIndex == -1) {
@ -384,7 +392,7 @@ NS_IMETHODIMP nsOutlinerSelection::RangedSelect(PRInt32 aStartIndex, PRInt32 aEn
PRInt32 start = aStartIndex < aEndIndex ? aStartIndex : aEndIndex;
PRInt32 end = aStartIndex < aEndIndex ? aEndIndex : aStartIndex;
if (aAugment) {
if (aAugment && mFirstRange) {
// We need to remove all the items within our selected range from the selection,
// and then we insert our new range into the list.
mFirstRange->RemoveRange(start, end);
@ -403,11 +411,29 @@ NS_IMETHODIMP nsOutlinerSelection::RangedSelect(PRInt32 aStartIndex, PRInt32 aEn
return NS_OK;
}
NS_IMETHODIMP nsOutlinerSelection::ClearRange(PRInt32 aStartIndex, PRInt32 aEndIndex)
{
SetCurrentIndex(aEndIndex);
if (mFirstRange) {
PRInt32 start = aStartIndex < aEndIndex ? aStartIndex : aEndIndex;
PRInt32 end = aStartIndex < aEndIndex ? aEndIndex : aStartIndex;
mFirstRange->RemoveRange(start, end);
mOutliner->InvalidateRange(start, end);
}
return NS_OK;
}
NS_IMETHODIMP nsOutlinerSelection::ClearSelection()
{
mFirstRange->Invalidate();
delete mFirstRange;
mFirstRange = nsnull;
if (mFirstRange) {
mFirstRange->Invalidate();
delete mFirstRange;
mFirstRange = nsnull;
}
mShiftSelectPivot = -1;
FireOnSelectHandler();
@ -511,6 +537,12 @@ NS_IMETHODIMP nsOutlinerSelection::SetCurrentIndex(PRInt32 aIndex)
return NS_OK;
}
NS_IMETHODIMP
nsOutlinerSelection::AdjustSelection(PRInt32 aIndex, PRInt32 aCount)
{
return NS_OK;
}
nsresult
nsOutlinerSelection::FireOnSelectHandler()
{

View File

@ -78,6 +78,7 @@ XUL_ATOM(open, "open") // Whether or not a menu, tree, etc. is open
XUL_ATOM(outliner, "outliner")
XUL_ATOM(outlinerbody, "outlinerbody")
XUL_ATOM(outlinercol, "outlinercol")
XUL_ATOM(cycler, "cycler")
XUL_ATOM(primary, "primary")
XUL_ATOM(current, "current")
@ -87,6 +88,7 @@ XUL_ATOM(mozoutlinercolumn, ":-moz-outliner-column")
XUL_ATOM(mozoutlinercelltext, ":-moz-outliner-cell-text")
XUL_ATOM(mozoutlinertwisty, ":-moz-outliner-twisty")
XUL_ATOM(mozoutlinerindentation, ":-moz-outliner-indentation")
XUL_ATOM(mozoutlinerline, ":-moz-outliner-line")
XUL_ATOM(menubar, "menubar") // An XP menu bar.
XUL_ATOM(menu, "menu") // Represents an XP menu