More changes to allow tables to support nested row groups.

This commit is contained in:
hyatt@netscape.com
1999-06-14 08:01:00 +00:00
parent 1775c24f8b
commit c180aa1dcf
8 changed files with 370 additions and 206 deletions

View File

@@ -414,6 +414,12 @@ NS_IMETHODIMP nsTableFrame::DidAppendRowGroup(nsTableRowGroupFrame *aRowGroupFra
return rv;
}
}
else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP==rowDisplay->mDisplay) {
rv = DidAppendRowGroup((nsTableRowGroupFrame*)nextRow);
if (NS_FAILED(rv)) {
return rv;
}
}
}
return rv;
@@ -961,6 +967,29 @@ void nsTableFrame::AddCellToTable (nsTableRowFrame *aRowFrame,
#endif
}
static nsresult BuildCellMapForRowGroup(nsIFrame* rowGroupFrame)
{
nsresult rv = NS_OK;
nsIFrame *rowFrame;
rowGroupFrame->FirstChild(nsnull, &rowFrame);
for ( ; nsnull!=rowFrame; rowFrame->GetNextSibling(&rowFrame))
{
const nsStyleDisplay *rowDisplay;
rowFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)rowDisplay);
if (NS_STYLE_DISPLAY_TABLE_ROW==rowDisplay->mDisplay)
{
rv = ((nsTableRowFrame *)rowFrame)->InitChildren();
if (NS_FAILED(rv))
return rv;
}
else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP==rowDisplay->mDisplay)
{
BuildCellMapForRowGroup(rowFrame);
}
}
return rv;
}
NS_METHOD nsTableFrame::ReBuildCellMap()
{
if (PR_TRUE==gsDebugIR) printf("TIF: ReBuildCellMap.\n");
@@ -972,19 +1001,7 @@ NS_METHOD nsTableFrame::ReBuildCellMap()
rowGroupFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)rowGroupDisplay);
if (PR_TRUE==IsRowGroup(rowGroupDisplay->mDisplay))
{
nsIFrame *rowFrame;
rowGroupFrame->FirstChild(nsnull, &rowFrame);
for ( ; nsnull!=rowFrame; rowFrame->GetNextSibling(&rowFrame))
{
const nsStyleDisplay *rowDisplay;
rowFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)rowDisplay);
if (NS_STYLE_DISPLAY_TABLE_ROW==rowDisplay->mDisplay)
{
rv = ((nsTableRowFrame *)rowFrame)->InitChildren();
if (NS_FAILED(rv))
return rv;
}
}
BuildCellMapForRowGroup(rowGroupFrame);
}
}
mCellMapValid=PR_TRUE;
@@ -2917,32 +2934,122 @@ NS_METHOD nsTableFrame::ResizeReflowPass2(nsIPresContext& aPresContext,
// collapsing row groups, rows, col groups and cols are accounted for after both passes of
// reflow so that it has no effect on the calculations of reflow.
NS_METHOD nsTableFrame::AdjustForCollapsingRowGroup(nsIFrame* aRowGroupFrame,
PRInt32& aRowX)
{
const nsStyleDisplay* groupDisplay;
aRowGroupFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)groupDisplay));
PRBool groupIsCollapsed = (NS_STYLE_VISIBILITY_COLLAPSE == groupDisplay->mVisible);
nsTableRowFrame* rowFrame = nsnull;
aRowGroupFrame->FirstChild(nsnull, (nsIFrame**)&rowFrame);
while (nsnull != rowFrame) {
const nsStyleDisplay *rowDisplay;
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)rowDisplay));
if (NS_STYLE_DISPLAY_TABLE_ROW == rowDisplay->mDisplay) {
if (groupIsCollapsed || (NS_STYLE_VISIBILITY_COLLAPSE == rowDisplay->mVisible)) {
mCellMap->SetRowCollapsedAt(aRowX, PR_TRUE);
}
aRowX++;
}
else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == rowDisplay->mDisplay) {
AdjustForCollapsingRowGroup(rowFrame, aRowX);
}
rowFrame->GetNextSibling((nsIFrame**)&rowFrame);
}
return NS_OK;
}
NS_METHOD nsTableFrame::CollapseRowGroup(nsIFrame* aRowGroupFrame,
const nscoord& aYTotalOffset,
nscoord& aYGroupOffset, PRInt32& aRowX)
{
const nsStyleDisplay* groupDisplay;
aRowGroupFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)groupDisplay));
PRBool collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE == groupDisplay->mVisible);
nsIFrame* rowFrame;
aRowGroupFrame->FirstChild(nsnull, &rowFrame);
while (nsnull != rowFrame) {
const nsStyleDisplay* rowDisplay;
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)rowDisplay));
if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == rowDisplay->mDisplay) {
CollapseRowGroup(rowFrame, aYTotalOffset, aYGroupOffset, aRowX);
}
else if (NS_STYLE_DISPLAY_TABLE_ROW == rowDisplay->mDisplay) {
nsRect rowRect;
rowFrame->GetRect(rowRect);
if (collapseGroup || (NS_STYLE_VISIBILITY_COLLAPSE == rowDisplay->mVisible)) {
aYGroupOffset += rowRect.height;
rowRect.height = 0;
rowFrame->SetRect(rowRect);
nsIFrame* cellFrame;
rowFrame->FirstChild(nsnull, &cellFrame);
while (nsnull != cellFrame) {
const nsStyleDisplay* cellDisplay;
cellFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)cellDisplay));
if (NS_STYLE_DISPLAY_TABLE_CELL == cellDisplay->mDisplay) {
nsTableCellFrame* cFrame = (nsTableCellFrame*)cellFrame;
nsRect cRect;
cFrame->GetRect(cRect);
cRect.height -= rowRect.height;
cFrame->SetCollapseOffsetY(-aYGroupOffset);
cFrame->SetRect(cRect);
}
cellFrame->GetNextSibling(&cellFrame);
}
// check if a cell above spans into here
//if (!collapseGroup) {
PRInt32 numCols = mCellMap->GetColCount();
nsTableCellFrame* lastCell = nsnull;
for (int colX = 0; colX < numCols; colX++) {
CellData* cellData = mCellMap->GetCellAt(aRowX, colX);
if (cellData && !cellData->mCell) { // a cell above is spanning into here
// adjust the real cell's rect only once
nsTableCellFrame* realCell = cellData->mRealCell->mCell;
if (realCell != lastCell) {
nsRect realRect;
realCell->GetRect(realRect);
realRect.height -= rowRect.height;
realCell->SetRect(realRect);
}
lastCell = realCell;
}
}
//}
} else { // row is not collapsed but needs to be adjusted by those that are
rowRect.y -= aYGroupOffset;
rowFrame->SetRect(rowRect);
}
aRowX++;
}
rowFrame->GetNextSibling(&rowFrame);
} // end row frame while
nsRect groupRect;
aRowGroupFrame->GetRect(groupRect);
groupRect.height -= aYGroupOffset;
groupRect.y -= aYTotalOffset;
aRowGroupFrame->SetRect(groupRect);
return NS_OK;
}
NS_METHOD nsTableFrame::AdjustForCollapsingRows(nsIPresContext& aPresContext,
nscoord& aHeight)
{
// determine which row groups and rows are collapsed
PRInt32 rowX = 0;
nsIFrame* childFrame;
FirstChild(nsnull, &childFrame);
while (nsnull != childFrame) {
const nsStyleDisplay* groupDisplay;
childFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)groupDisplay));
if (IsRowGroup(groupDisplay->mDisplay)) {
PRBool groupIsCollapsed = (NS_STYLE_VISIBILITY_COLLAPSE == groupDisplay->mVisible);
nsTableRowFrame* rowFrame = nsnull;
childFrame->FirstChild(nsnull, (nsIFrame**)&rowFrame);
PRInt32 rowX = 0;
while (nsnull != rowFrame) {
const nsStyleDisplay *rowDisplay;
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)rowDisplay));
if (NS_STYLE_DISPLAY_TABLE_ROW == rowDisplay->mDisplay) {
if (groupIsCollapsed || (NS_STYLE_VISIBILITY_COLLAPSE == rowDisplay->mVisible)) {
mCellMap->SetRowCollapsedAt(rowX, PR_TRUE);
}
}
rowFrame->GetNextSibling((nsIFrame**)&rowFrame);
rowX++;
}
AdjustForCollapsingRowGroup(childFrame, rowX);
}
childFrame->GetNextSibling(&childFrame);
}
@@ -2955,76 +3062,14 @@ NS_METHOD nsTableFrame::AdjustForCollapsingRows(nsIPresContext& aPresContext,
nsIFrame* groupFrame = mFrames.FirstChild();
nscoord yGroupOffset = 0; // total offset among rows within a single row group
nscoord yTotalOffset = 0; // total offset among all rows in all row groups
PRInt32 rowX = 0;
PRBool collapseGroup;
rowX = 0;
while (nsnull != groupFrame) {
const nsStyleDisplay* groupDisplay;
groupFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)groupDisplay));
if (IsRowGroup(groupDisplay->mDisplay)) {
collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE == groupDisplay->mVisible);
nsIFrame* rowFrame;
groupFrame->FirstChild(nsnull, &rowFrame);
while (nsnull != rowFrame) {
const nsStyleDisplay* rowDisplay;
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)rowDisplay));
if (NS_STYLE_DISPLAY_TABLE_ROW == rowDisplay->mDisplay) {
nsRect rowRect;
rowFrame->GetRect(rowRect);
if (collapseGroup || (NS_STYLE_VISIBILITY_COLLAPSE == rowDisplay->mVisible)) {
yGroupOffset += rowRect.height;
rowRect.height = 0;
rowFrame->SetRect(rowRect);
nsIFrame* cellFrame;
rowFrame->FirstChild(nsnull, &cellFrame);
while (nsnull != cellFrame) {
const nsStyleDisplay* cellDisplay;
cellFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)cellDisplay));
if (NS_STYLE_DISPLAY_TABLE_CELL == cellDisplay->mDisplay) {
nsTableCellFrame* cFrame = (nsTableCellFrame*)cellFrame;
nsRect cRect;
cFrame->GetRect(cRect);
cRect.height -= rowRect.height;
cFrame->SetCollapseOffsetY(-yGroupOffset);
cFrame->SetRect(cRect);
}
cellFrame->GetNextSibling(&cellFrame);
}
// check if a cell above spans into here
//if (!collapseGroup) {
PRInt32 numCols = mCellMap->GetColCount();
nsTableCellFrame* lastCell = nsnull;
for (int colX = 0; colX < numCols; colX++) {
CellData* cellData = mCellMap->GetCellAt(rowX, colX);
if (cellData && !cellData->mCell) { // a cell above is spanning into here
// adjust the real cell's rect only once
nsTableCellFrame* realCell = cellData->mRealCell->mCell;
if (realCell != lastCell) {
nsRect realRect;
realCell->GetRect(realRect);
realRect.height -= rowRect.height;
realCell->SetRect(realRect);
}
lastCell = realCell;
}
}
//}
} else { // row is not collapsed but needs to be adjusted by those that are
rowRect.y -= yGroupOffset;
rowFrame->SetRect(rowRect);
}
rowX++;
}
rowFrame->GetNextSibling(&rowFrame);
} // end row frame while
if (IsRowGroup(groupDisplay->mDisplay)) {
CollapseRowGroup(groupFrame, yTotalOffset, yGroupOffset, rowX);
}
nsRect groupRect;
groupFrame->GetRect(groupRect);
groupRect.height -= yGroupOffset;
groupRect.y -= yTotalOffset;
groupFrame->SetRect(groupRect);
yTotalOffset += yGroupOffset;
yGroupOffset = 0;
groupFrame->GetNextSibling(&groupFrame);

View File

@@ -575,6 +575,13 @@ protected:
nsIFrame* aKidFrame,
nscoord aDeltaY);
NS_METHOD AdjustForCollapsingRowGroup(nsIFrame* aRowGroupFrame,
PRInt32& aRowX);
NS_METHOD CollapseRowGroup(nsIFrame* aRowGroupFrame,
const nscoord& aYTotalOffset,
nscoord& aYGroupOffset, PRInt32& aRowX);
NS_METHOD AdjustForCollapsingRows(nsIPresContext& aPresContext,
nscoord& aHeight);

View File

@@ -110,7 +110,7 @@ nsTableRowGroupFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
}
}
NS_METHOD nsTableRowGroupFrame::GetRowCount(PRInt32 &aCount)
NS_METHOD nsTableRowGroupFrame::GetRowCount(PRInt32 &aCount, PRBool aDeepCount)
{
// init out-param
aCount=0;
@@ -125,6 +125,11 @@ NS_METHOD nsTableRowGroupFrame::GetRowCount(PRInt32 &aCount)
childFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
aCount++;
else if (aDeepCount && NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay) {
PRInt32 childRowGroupCount;
((nsTableRowGroupFrame*)childFrame)->GetRowCount(childRowGroupCount);
aCount += childRowGroupCount;
}
childFrame->GetNextSibling(&childFrame);
}
return NS_OK;
@@ -145,6 +150,12 @@ PRInt32 nsTableRowGroupFrame::GetStartRowIndex()
result = ((nsTableRowFrame *)childFrame)->GetRowIndex();
break;
}
else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay) {
result = ((nsTableRowGroupFrame*)childFrame)->GetStartRowIndex();
if (result != -1)
break;
}
childFrame->GetNextSibling(&childFrame);
}
return result;
@@ -166,6 +177,12 @@ NS_METHOD nsTableRowGroupFrame::GetMaxColumns(PRInt32 &aMaxColumns) const
PRInt32 colCount = ((nsTableRowFrame *)childFrame)->GetMaxColumns();
aMaxColumns = PR_MAX(aMaxColumns, colCount);
}
else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay) {
PRInt32 rgColCount;
((nsTableRowGroupFrame*)childFrame)->GetMaxColumns(rgColCount);
aMaxColumns = PR_MAX(aMaxColumns, rgColCount);
}
childFrame->GetNextSibling(&childFrame);
}
return NS_OK;
@@ -349,6 +366,10 @@ nsTableRowGroupFrame::GetFrameForPoint(const nsPoint& aPoint, nsIFrame** aFrame)
return kid->GetFrameForPoint(tmp, aFrame);
}
}
else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay) {
return kid->GetFrameForPoint(aPoint, aFrame);
}
kid->GetNextSibling(&kid);
}
return NS_ERROR_FAILURE;
@@ -571,7 +592,7 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext& aPresContext,
// iterate children and for each row get its height
PRInt32 numRows;
GetRowCount(numRows);
GetRowCount(numRows, PR_FALSE);
PRInt32 *rowHeights = new PRInt32[numRows];
nsCRT::memset (rowHeights, 0, numRows*sizeof(PRInt32));
@@ -583,16 +604,18 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext& aPresContext,
// For row groups that are split across pages, the first row frame won't
// necessarily be index 0
PRInt32 startRowIndex;
if (rowFrame) {
startRowIndex = ((nsTableRowFrame*)rowFrame)->GetRowIndex();
}
PRInt32 startRowIndex = -1;
while (nsnull != rowFrame)
{
const nsStyleDisplay *childDisplay;
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
{
if (startRowIndex == -1) {
startRowIndex = ((nsTableRowFrame*)rowFrame)->GetRowIndex();
}
// get the height of the tallest cell in the row (excluding cells that span rows)
// XXX GetChildMaxTopMargin and GetChildMaxBottomMargin should be removed/simplified because
// according to CSS, all table cells must have the same top/bottom and left/right margins.
@@ -612,6 +635,7 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext& aPresContext,
// Get the next row
rowFrame->GetNextSibling(&rowFrame);
}
/* Step 2: Now account for cells that span rows.
* A spanning cell's height is the sum of the heights of the rows it spans,
@@ -640,7 +664,13 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext& aPresContext,
{
const nsStyleDisplay *childDisplay;
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay) {
// Only for the tree widget does this code fire.
nsSize rowGroupSize;
rowFrame->GetSize(rowGroupSize);
rowGroupHeight += rowGroupSize.height;
}
else if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
{
if (gsDebug) printf("TRGF CalcRowH: Step 2 for row %d (%p)...\n",
rowIndex + startRowIndex, rowFrame);

View File

@@ -102,7 +102,7 @@ public:
NS_IMETHOD GetFrameName(nsString& aResult) const;
/** set aCount to the number of child rows (not necessarily == number of child frames) */
NS_METHOD GetRowCount(PRInt32 &aCount);
NS_METHOD GetRowCount(PRInt32 &aCount, PRBool aDeepCount = PR_TRUE);
/** return the table-relative row index of the first row in this rowgroup.
* if there are no rows, -1 is returned.

View File

@@ -414,6 +414,12 @@ NS_IMETHODIMP nsTableFrame::DidAppendRowGroup(nsTableRowGroupFrame *aRowGroupFra
return rv;
}
}
else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP==rowDisplay->mDisplay) {
rv = DidAppendRowGroup((nsTableRowGroupFrame*)nextRow);
if (NS_FAILED(rv)) {
return rv;
}
}
}
return rv;
@@ -961,6 +967,29 @@ void nsTableFrame::AddCellToTable (nsTableRowFrame *aRowFrame,
#endif
}
static nsresult BuildCellMapForRowGroup(nsIFrame* rowGroupFrame)
{
nsresult rv = NS_OK;
nsIFrame *rowFrame;
rowGroupFrame->FirstChild(nsnull, &rowFrame);
for ( ; nsnull!=rowFrame; rowFrame->GetNextSibling(&rowFrame))
{
const nsStyleDisplay *rowDisplay;
rowFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)rowDisplay);
if (NS_STYLE_DISPLAY_TABLE_ROW==rowDisplay->mDisplay)
{
rv = ((nsTableRowFrame *)rowFrame)->InitChildren();
if (NS_FAILED(rv))
return rv;
}
else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP==rowDisplay->mDisplay)
{
BuildCellMapForRowGroup(rowFrame);
}
}
return rv;
}
NS_METHOD nsTableFrame::ReBuildCellMap()
{
if (PR_TRUE==gsDebugIR) printf("TIF: ReBuildCellMap.\n");
@@ -972,19 +1001,7 @@ NS_METHOD nsTableFrame::ReBuildCellMap()
rowGroupFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)rowGroupDisplay);
if (PR_TRUE==IsRowGroup(rowGroupDisplay->mDisplay))
{
nsIFrame *rowFrame;
rowGroupFrame->FirstChild(nsnull, &rowFrame);
for ( ; nsnull!=rowFrame; rowFrame->GetNextSibling(&rowFrame))
{
const nsStyleDisplay *rowDisplay;
rowFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)rowDisplay);
if (NS_STYLE_DISPLAY_TABLE_ROW==rowDisplay->mDisplay)
{
rv = ((nsTableRowFrame *)rowFrame)->InitChildren();
if (NS_FAILED(rv))
return rv;
}
}
BuildCellMapForRowGroup(rowGroupFrame);
}
}
mCellMapValid=PR_TRUE;
@@ -2917,32 +2934,122 @@ NS_METHOD nsTableFrame::ResizeReflowPass2(nsIPresContext& aPresContext,
// collapsing row groups, rows, col groups and cols are accounted for after both passes of
// reflow so that it has no effect on the calculations of reflow.
NS_METHOD nsTableFrame::AdjustForCollapsingRowGroup(nsIFrame* aRowGroupFrame,
PRInt32& aRowX)
{
const nsStyleDisplay* groupDisplay;
aRowGroupFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)groupDisplay));
PRBool groupIsCollapsed = (NS_STYLE_VISIBILITY_COLLAPSE == groupDisplay->mVisible);
nsTableRowFrame* rowFrame = nsnull;
aRowGroupFrame->FirstChild(nsnull, (nsIFrame**)&rowFrame);
while (nsnull != rowFrame) {
const nsStyleDisplay *rowDisplay;
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)rowDisplay));
if (NS_STYLE_DISPLAY_TABLE_ROW == rowDisplay->mDisplay) {
if (groupIsCollapsed || (NS_STYLE_VISIBILITY_COLLAPSE == rowDisplay->mVisible)) {
mCellMap->SetRowCollapsedAt(aRowX, PR_TRUE);
}
aRowX++;
}
else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == rowDisplay->mDisplay) {
AdjustForCollapsingRowGroup(rowFrame, aRowX);
}
rowFrame->GetNextSibling((nsIFrame**)&rowFrame);
}
return NS_OK;
}
NS_METHOD nsTableFrame::CollapseRowGroup(nsIFrame* aRowGroupFrame,
const nscoord& aYTotalOffset,
nscoord& aYGroupOffset, PRInt32& aRowX)
{
const nsStyleDisplay* groupDisplay;
aRowGroupFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)groupDisplay));
PRBool collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE == groupDisplay->mVisible);
nsIFrame* rowFrame;
aRowGroupFrame->FirstChild(nsnull, &rowFrame);
while (nsnull != rowFrame) {
const nsStyleDisplay* rowDisplay;
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)rowDisplay));
if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == rowDisplay->mDisplay) {
CollapseRowGroup(rowFrame, aYTotalOffset, aYGroupOffset, aRowX);
}
else if (NS_STYLE_DISPLAY_TABLE_ROW == rowDisplay->mDisplay) {
nsRect rowRect;
rowFrame->GetRect(rowRect);
if (collapseGroup || (NS_STYLE_VISIBILITY_COLLAPSE == rowDisplay->mVisible)) {
aYGroupOffset += rowRect.height;
rowRect.height = 0;
rowFrame->SetRect(rowRect);
nsIFrame* cellFrame;
rowFrame->FirstChild(nsnull, &cellFrame);
while (nsnull != cellFrame) {
const nsStyleDisplay* cellDisplay;
cellFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)cellDisplay));
if (NS_STYLE_DISPLAY_TABLE_CELL == cellDisplay->mDisplay) {
nsTableCellFrame* cFrame = (nsTableCellFrame*)cellFrame;
nsRect cRect;
cFrame->GetRect(cRect);
cRect.height -= rowRect.height;
cFrame->SetCollapseOffsetY(-aYGroupOffset);
cFrame->SetRect(cRect);
}
cellFrame->GetNextSibling(&cellFrame);
}
// check if a cell above spans into here
//if (!collapseGroup) {
PRInt32 numCols = mCellMap->GetColCount();
nsTableCellFrame* lastCell = nsnull;
for (int colX = 0; colX < numCols; colX++) {
CellData* cellData = mCellMap->GetCellAt(aRowX, colX);
if (cellData && !cellData->mCell) { // a cell above is spanning into here
// adjust the real cell's rect only once
nsTableCellFrame* realCell = cellData->mRealCell->mCell;
if (realCell != lastCell) {
nsRect realRect;
realCell->GetRect(realRect);
realRect.height -= rowRect.height;
realCell->SetRect(realRect);
}
lastCell = realCell;
}
}
//}
} else { // row is not collapsed but needs to be adjusted by those that are
rowRect.y -= aYGroupOffset;
rowFrame->SetRect(rowRect);
}
aRowX++;
}
rowFrame->GetNextSibling(&rowFrame);
} // end row frame while
nsRect groupRect;
aRowGroupFrame->GetRect(groupRect);
groupRect.height -= aYGroupOffset;
groupRect.y -= aYTotalOffset;
aRowGroupFrame->SetRect(groupRect);
return NS_OK;
}
NS_METHOD nsTableFrame::AdjustForCollapsingRows(nsIPresContext& aPresContext,
nscoord& aHeight)
{
// determine which row groups and rows are collapsed
PRInt32 rowX = 0;
nsIFrame* childFrame;
FirstChild(nsnull, &childFrame);
while (nsnull != childFrame) {
const nsStyleDisplay* groupDisplay;
childFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)groupDisplay));
if (IsRowGroup(groupDisplay->mDisplay)) {
PRBool groupIsCollapsed = (NS_STYLE_VISIBILITY_COLLAPSE == groupDisplay->mVisible);
nsTableRowFrame* rowFrame = nsnull;
childFrame->FirstChild(nsnull, (nsIFrame**)&rowFrame);
PRInt32 rowX = 0;
while (nsnull != rowFrame) {
const nsStyleDisplay *rowDisplay;
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)rowDisplay));
if (NS_STYLE_DISPLAY_TABLE_ROW == rowDisplay->mDisplay) {
if (groupIsCollapsed || (NS_STYLE_VISIBILITY_COLLAPSE == rowDisplay->mVisible)) {
mCellMap->SetRowCollapsedAt(rowX, PR_TRUE);
}
}
rowFrame->GetNextSibling((nsIFrame**)&rowFrame);
rowX++;
}
AdjustForCollapsingRowGroup(childFrame, rowX);
}
childFrame->GetNextSibling(&childFrame);
}
@@ -2955,76 +3062,14 @@ NS_METHOD nsTableFrame::AdjustForCollapsingRows(nsIPresContext& aPresContext,
nsIFrame* groupFrame = mFrames.FirstChild();
nscoord yGroupOffset = 0; // total offset among rows within a single row group
nscoord yTotalOffset = 0; // total offset among all rows in all row groups
PRInt32 rowX = 0;
PRBool collapseGroup;
rowX = 0;
while (nsnull != groupFrame) {
const nsStyleDisplay* groupDisplay;
groupFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)groupDisplay));
if (IsRowGroup(groupDisplay->mDisplay)) {
collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE == groupDisplay->mVisible);
nsIFrame* rowFrame;
groupFrame->FirstChild(nsnull, &rowFrame);
while (nsnull != rowFrame) {
const nsStyleDisplay* rowDisplay;
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)rowDisplay));
if (NS_STYLE_DISPLAY_TABLE_ROW == rowDisplay->mDisplay) {
nsRect rowRect;
rowFrame->GetRect(rowRect);
if (collapseGroup || (NS_STYLE_VISIBILITY_COLLAPSE == rowDisplay->mVisible)) {
yGroupOffset += rowRect.height;
rowRect.height = 0;
rowFrame->SetRect(rowRect);
nsIFrame* cellFrame;
rowFrame->FirstChild(nsnull, &cellFrame);
while (nsnull != cellFrame) {
const nsStyleDisplay* cellDisplay;
cellFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)cellDisplay));
if (NS_STYLE_DISPLAY_TABLE_CELL == cellDisplay->mDisplay) {
nsTableCellFrame* cFrame = (nsTableCellFrame*)cellFrame;
nsRect cRect;
cFrame->GetRect(cRect);
cRect.height -= rowRect.height;
cFrame->SetCollapseOffsetY(-yGroupOffset);
cFrame->SetRect(cRect);
}
cellFrame->GetNextSibling(&cellFrame);
}
// check if a cell above spans into here
//if (!collapseGroup) {
PRInt32 numCols = mCellMap->GetColCount();
nsTableCellFrame* lastCell = nsnull;
for (int colX = 0; colX < numCols; colX++) {
CellData* cellData = mCellMap->GetCellAt(rowX, colX);
if (cellData && !cellData->mCell) { // a cell above is spanning into here
// adjust the real cell's rect only once
nsTableCellFrame* realCell = cellData->mRealCell->mCell;
if (realCell != lastCell) {
nsRect realRect;
realCell->GetRect(realRect);
realRect.height -= rowRect.height;
realCell->SetRect(realRect);
}
lastCell = realCell;
}
}
//}
} else { // row is not collapsed but needs to be adjusted by those that are
rowRect.y -= yGroupOffset;
rowFrame->SetRect(rowRect);
}
rowX++;
}
rowFrame->GetNextSibling(&rowFrame);
} // end row frame while
if (IsRowGroup(groupDisplay->mDisplay)) {
CollapseRowGroup(groupFrame, yTotalOffset, yGroupOffset, rowX);
}
nsRect groupRect;
groupFrame->GetRect(groupRect);
groupRect.height -= yGroupOffset;
groupRect.y -= yTotalOffset;
groupFrame->SetRect(groupRect);
yTotalOffset += yGroupOffset;
yGroupOffset = 0;
groupFrame->GetNextSibling(&groupFrame);

View File

@@ -575,6 +575,13 @@ protected:
nsIFrame* aKidFrame,
nscoord aDeltaY);
NS_METHOD AdjustForCollapsingRowGroup(nsIFrame* aRowGroupFrame,
PRInt32& aRowX);
NS_METHOD CollapseRowGroup(nsIFrame* aRowGroupFrame,
const nscoord& aYTotalOffset,
nscoord& aYGroupOffset, PRInt32& aRowX);
NS_METHOD AdjustForCollapsingRows(nsIPresContext& aPresContext,
nscoord& aHeight);

View File

@@ -110,7 +110,7 @@ nsTableRowGroupFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
}
}
NS_METHOD nsTableRowGroupFrame::GetRowCount(PRInt32 &aCount)
NS_METHOD nsTableRowGroupFrame::GetRowCount(PRInt32 &aCount, PRBool aDeepCount)
{
// init out-param
aCount=0;
@@ -125,6 +125,11 @@ NS_METHOD nsTableRowGroupFrame::GetRowCount(PRInt32 &aCount)
childFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
aCount++;
else if (aDeepCount && NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay) {
PRInt32 childRowGroupCount;
((nsTableRowGroupFrame*)childFrame)->GetRowCount(childRowGroupCount);
aCount += childRowGroupCount;
}
childFrame->GetNextSibling(&childFrame);
}
return NS_OK;
@@ -145,6 +150,12 @@ PRInt32 nsTableRowGroupFrame::GetStartRowIndex()
result = ((nsTableRowFrame *)childFrame)->GetRowIndex();
break;
}
else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay) {
result = ((nsTableRowGroupFrame*)childFrame)->GetStartRowIndex();
if (result != -1)
break;
}
childFrame->GetNextSibling(&childFrame);
}
return result;
@@ -166,6 +177,12 @@ NS_METHOD nsTableRowGroupFrame::GetMaxColumns(PRInt32 &aMaxColumns) const
PRInt32 colCount = ((nsTableRowFrame *)childFrame)->GetMaxColumns();
aMaxColumns = PR_MAX(aMaxColumns, colCount);
}
else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay) {
PRInt32 rgColCount;
((nsTableRowGroupFrame*)childFrame)->GetMaxColumns(rgColCount);
aMaxColumns = PR_MAX(aMaxColumns, rgColCount);
}
childFrame->GetNextSibling(&childFrame);
}
return NS_OK;
@@ -349,6 +366,10 @@ nsTableRowGroupFrame::GetFrameForPoint(const nsPoint& aPoint, nsIFrame** aFrame)
return kid->GetFrameForPoint(tmp, aFrame);
}
}
else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay) {
return kid->GetFrameForPoint(aPoint, aFrame);
}
kid->GetNextSibling(&kid);
}
return NS_ERROR_FAILURE;
@@ -571,7 +592,7 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext& aPresContext,
// iterate children and for each row get its height
PRInt32 numRows;
GetRowCount(numRows);
GetRowCount(numRows, PR_FALSE);
PRInt32 *rowHeights = new PRInt32[numRows];
nsCRT::memset (rowHeights, 0, numRows*sizeof(PRInt32));
@@ -583,16 +604,18 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext& aPresContext,
// For row groups that are split across pages, the first row frame won't
// necessarily be index 0
PRInt32 startRowIndex;
if (rowFrame) {
startRowIndex = ((nsTableRowFrame*)rowFrame)->GetRowIndex();
}
PRInt32 startRowIndex = -1;
while (nsnull != rowFrame)
{
const nsStyleDisplay *childDisplay;
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
{
if (startRowIndex == -1) {
startRowIndex = ((nsTableRowFrame*)rowFrame)->GetRowIndex();
}
// get the height of the tallest cell in the row (excluding cells that span rows)
// XXX GetChildMaxTopMargin and GetChildMaxBottomMargin should be removed/simplified because
// according to CSS, all table cells must have the same top/bottom and left/right margins.
@@ -612,6 +635,7 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext& aPresContext,
// Get the next row
rowFrame->GetNextSibling(&rowFrame);
}
/* Step 2: Now account for cells that span rows.
* A spanning cell's height is the sum of the heights of the rows it spans,
@@ -640,7 +664,13 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext& aPresContext,
{
const nsStyleDisplay *childDisplay;
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay) {
// Only for the tree widget does this code fire.
nsSize rowGroupSize;
rowFrame->GetSize(rowGroupSize);
rowGroupHeight += rowGroupSize.height;
}
else if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
{
if (gsDebug) printf("TRGF CalcRowH: Step 2 for row %d (%p)...\n",
rowIndex + startRowIndex, rowFrame);

View File

@@ -102,7 +102,7 @@ public:
NS_IMETHOD GetFrameName(nsString& aResult) const;
/** set aCount to the number of child rows (not necessarily == number of child frames) */
NS_METHOD GetRowCount(PRInt32 &aCount);
NS_METHOD GetRowCount(PRInt32 &aCount, PRBool aDeepCount = PR_TRUE);
/** return the table-relative row index of the first row in this rowgroup.
* if there are no rows, -1 is returned.