mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-11-11 05:39:41 +02:00
bug 7243. Rewrote FixedTableLayoutStrategy::AssignPreliminaryColumnWidths
This commit is contained in:
parent
6f5c26fe2a
commit
1046000459
12 changed files with 236 additions and 166 deletions
|
|
@ -233,7 +233,8 @@ BasicTableLayoutStrategy::~BasicTableLayoutStrategy()
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool BasicTableLayoutStrategy::Initialize(nsSize* aMaxElementSize,
|
PRBool BasicTableLayoutStrategy::Initialize(nsSize* aMaxElementSize,
|
||||||
PRInt32 aNumCols)
|
PRInt32 aNumCols,
|
||||||
|
nscoord aMaxWidth)
|
||||||
{
|
{
|
||||||
#ifdef NS_DEBUG
|
#ifdef NS_DEBUG
|
||||||
nsIFrame* tablePIF = nsnull;
|
nsIFrame* tablePIF = nsnull;
|
||||||
|
|
@ -251,7 +252,7 @@ PRBool BasicTableLayoutStrategy::Initialize(nsSize* aMaxElementSize,
|
||||||
mCols = mTableFrame->GetEffectiveCOLSAttribute();
|
mCols = mTableFrame->GetEffectiveCOLSAttribute();
|
||||||
|
|
||||||
// Step 1 - assign the width of all fixed-width columns
|
// Step 1 - assign the width of all fixed-width columns
|
||||||
AssignPreliminaryColumnWidths();
|
AssignPreliminaryColumnWidths(aMaxWidth);
|
||||||
|
|
||||||
// set aMaxElementSize here because we compute mMinTableWidth in AssignPreliminaryColumnWidths
|
// set aMaxElementSize here because we compute mMinTableWidth in AssignPreliminaryColumnWidths
|
||||||
if (nsnull != aMaxElementSize) {
|
if (nsnull != aMaxElementSize) {
|
||||||
|
|
@ -389,7 +390,7 @@ nscoord BasicTableLayoutStrategy::CalcHorizontalPadding(PRInt32 aColX)
|
||||||
|
|
||||||
// Step 1 - assign the width of all fixed-width columns, all other columns get there max,
|
// Step 1 - assign the width of all fixed-width columns, all other columns get there max,
|
||||||
// and calculate min/max table width
|
// and calculate min/max table width
|
||||||
PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
|
PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aMaxWidth)
|
||||||
{
|
{
|
||||||
TDBG_SP("** %p: AssignPreliminaryColumnWidths **\n", mTableFrame);
|
TDBG_SP("** %p: AssignPreliminaryColumnWidths **\n", mTableFrame);
|
||||||
nsVoidArray *spanList = nsnull;
|
nsVoidArray *spanList = nsnull;
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ public:
|
||||||
* @param aMaxElementSize [OUT] if not null, the max element size is computed and returned in this param
|
* @param aMaxElementSize [OUT] if not null, the max element size is computed and returned in this param
|
||||||
* @param aNumCols the total number of columns in the table
|
* @param aNumCols the total number of columns in the table
|
||||||
*/
|
*/
|
||||||
virtual PRBool Initialize(nsSize* aMaxElementSize, PRInt32 aNumCols);
|
virtual PRBool Initialize(nsSize* aMaxElementSize, PRInt32 aNumCols, nscoord aMaxSize);
|
||||||
|
|
||||||
/** compute the max element size of the table.
|
/** compute the max element size of the table.
|
||||||
* assumes that Initialize has been called
|
* assumes that Initialize has been called
|
||||||
|
|
@ -123,10 +123,12 @@ protected:
|
||||||
* Computes the minimum and maximum table widths.
|
* Computes the minimum and maximum table widths.
|
||||||
* Set column width information in each column frame and in the table frame.
|
* Set column width information in each column frame and in the table frame.
|
||||||
*
|
*
|
||||||
|
* @param aMaxWidth - the computed width of the table or
|
||||||
|
* UNCONSTRAINED_SIZE if an auto width table
|
||||||
* @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error
|
* @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
virtual PRBool AssignPreliminaryColumnWidths();
|
virtual PRBool AssignPreliminaryColumnWidths(nscoord aComputedWidth);
|
||||||
|
|
||||||
/** compute the min and max width of this table. Assumes AssignPreliminaryColumnWidths
|
/** compute the min and max width of this table. Assumes AssignPreliminaryColumnWidths
|
||||||
* has been called. Sets mMinTableWidth and mMaxTableWidth as a side effect.
|
* has been called. Sets mMinTableWidth and mMaxTableWidth as a side effect.
|
||||||
|
|
|
||||||
|
|
@ -73,109 +73,135 @@ PRBool FixedTableLayoutStrategy::BalanceColumnWidths(nsIStyleContext *aTableStyl
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* assign the width of all columns
|
/*
|
||||||
|
* assign the width of all columns
|
||||||
* if there is a colframe with a width attribute, use it as the column width
|
* if there is a colframe with a width attribute, use it as the column width
|
||||||
* otherwise if there is a cell in the first row and it has a width attribute, use it
|
* otherwise if there is a cell in the first row and it has a width attribute, use it
|
||||||
* if this cell includes a colspan, width is divided equally among spanned columns
|
* if this cell includes a colspan, width is divided equally among spanned columns
|
||||||
* otherwise the cell get a proportion of the remaining space
|
* otherwise the cell get a proportion of the remaining space
|
||||||
* as determined by the table width attribute. If no table width attribute, it gets 0 width
|
* as determined by the table width attribute. If no table width attribute, it gets 0 width
|
||||||
*/
|
*/
|
||||||
PRBool FixedTableLayoutStrategy::AssignPreliminaryColumnWidths()
|
PRBool FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aComputedWidth)
|
||||||
{
|
{
|
||||||
|
NS_ASSERTION(aComputedWidth != NS_UNCONSTRAINEDSIZE, "bad computed width");
|
||||||
if (gsDebug==PR_TRUE) printf ("** %p: AssignPreliminaryColumnWidths **\n", mTableFrame);
|
if (gsDebug==PR_TRUE) printf ("** %p: AssignPreliminaryColumnWidths **\n", mTableFrame);
|
||||||
|
|
||||||
PRInt32 colIndex;
|
const nsStylePosition* tablePosition;
|
||||||
PRInt32 specifiedColumns=0; // the number of columns whose width is given
|
mTableFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)tablePosition);
|
||||||
nscoord totalWidth = 0; // the sum of the widths of the columns whose width is given
|
PRBool tableIsFixedWidth = eStyleUnit_Coord == tablePosition->mWidth.GetUnit() ||
|
||||||
|
eStyleUnit_Percent == tablePosition->mWidth.GetUnit();
|
||||||
|
|
||||||
PRBool * autoWidthColumns = new PRBool[mNumCols];
|
const nsStyleSpacing* tableSpacing;
|
||||||
nsCRT::memset(autoWidthColumns, PR_TRUE, mNumCols*sizeof(PRBool));
|
mTableFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&)tableSpacing);
|
||||||
|
nsMargin borderPadding;
|
||||||
|
tableSpacing->CalcBorderPaddingFor(mTableFrame, borderPadding);
|
||||||
|
|
||||||
|
PRInt32 colX;
|
||||||
|
// availWidth is used as the basis for percentage width columns. It is aComputedWidth
|
||||||
|
// minus table border, padding, & cellspacing
|
||||||
|
nscoord availWidth = aComputedWidth - borderPadding.left - borderPadding.right -
|
||||||
|
((mNumCols + 1) * mTableFrame->GetCellSpacingX());
|
||||||
|
|
||||||
|
PRInt32 specifiedCols = 0; // the number of columns whose width is given
|
||||||
|
nscoord totalColWidth = 0; // the sum of the widths of the columns
|
||||||
|
|
||||||
|
nscoord* colWidths = new PRBool[mNumCols];
|
||||||
|
nsCRT::memset(colWidths, -1, mNumCols*sizeof(nscoord));
|
||||||
|
|
||||||
// for every column, determine it's specified width
|
// for every column, determine it's specified width
|
||||||
for (colIndex = 0; colIndex<mNumCols; colIndex++)
|
for (colX = 0; colX < mNumCols; colX++) {
|
||||||
{
|
|
||||||
// Get column information
|
// Get column information
|
||||||
nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
|
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||||
NS_ASSERTION(nsnull!=colFrame, "bad col frame");
|
NS_ASSERTION(nsnull != colFrame, "bad col frame");
|
||||||
|
|
||||||
// Get the columns's style
|
// Get the columns's style
|
||||||
const nsStylePosition* colPosition;
|
const nsStylePosition* colPosition;
|
||||||
colFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)colPosition);
|
colFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)colPosition);
|
||||||
|
|
||||||
// Get fixed column width if it has one
|
// get the fixed width if available
|
||||||
if (eStyleUnit_Coord==colPosition->mWidth.GetUnit())
|
if (eStyleUnit_Coord == colPosition->mWidth.GetUnit()) {
|
||||||
{
|
colWidths[colX] = colPosition->mWidth.GetCoordValue();
|
||||||
nscoord colWidth = colPosition->mWidth.GetCoordValue();
|
} // get the percentage width
|
||||||
mTableFrame->SetColumnWidth(colIndex, colWidth);
|
else if (eStyleUnit_Percent == colPosition->mWidth.GetUnit()) {
|
||||||
totalWidth += colWidth;
|
float percent = colPosition->mWidth.GetPercentValue();
|
||||||
specifiedColumns++;
|
colWidths[colX] = NSToCoordRound(percent * (float)availWidth);
|
||||||
autoWidthColumns[colIndex]=PR_FALSE;
|
|
||||||
if (PR_TRUE==gsDebug)
|
|
||||||
printf ("from col, col %d set to width %d\n", colIndex, colWidth);
|
|
||||||
}
|
}
|
||||||
else
|
else { // get width from the cell
|
||||||
{
|
nsTableCellFrame* cellFrame = mTableFrame->GetCellFrameAt(0, colX);
|
||||||
nsTableCellFrame *cellFrame = mTableFrame->GetCellFrameAt(0, colIndex);
|
if (nsnull != cellFrame) {
|
||||||
if (nsnull!=cellFrame)
|
|
||||||
{
|
|
||||||
// Get the cell's style
|
// Get the cell's style
|
||||||
const nsStylePosition* cellPosition;
|
const nsStylePosition* cellPosition;
|
||||||
cellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)cellPosition);
|
cellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)cellPosition);
|
||||||
|
|
||||||
// Get fixed column width if it has one
|
PRInt32 colSpan = mTableFrame->GetEffectiveColSpan(colX, cellFrame);
|
||||||
if (eStyleUnit_Coord==cellPosition->mWidth.GetUnit())
|
// Get fixed cell width if available
|
||||||
{
|
if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit()) {
|
||||||
PRInt32 colSpan = mTableFrame->GetEffectiveColSpan(colIndex, cellFrame);
|
colWidths[colX] = cellPosition->mWidth.GetCoordValue() / colSpan;
|
||||||
nscoord effectiveWidth = cellPosition->mWidth.GetCoordValue()/colSpan;
|
}
|
||||||
mTableFrame->SetColumnWidth(colIndex, effectiveWidth);
|
else if (eStyleUnit_Percent == cellPosition->mWidth.GetUnit()) {
|
||||||
totalWidth += effectiveWidth;
|
float percent = cellPosition->mWidth.GetPercentValue();
|
||||||
specifiedColumns++;
|
colWidths[colX] = NSToCoordRound(percent * (float)availWidth / (float)colSpan);
|
||||||
autoWidthColumns[colIndex]=PR_FALSE;
|
}
|
||||||
if (PR_TRUE==gsDebug)
|
}
|
||||||
printf ("from cell, col %d set to width %d\n", colIndex, effectiveWidth);
|
}
|
||||||
|
if (colWidths[colX] >= 0) {
|
||||||
|
totalColWidth += colWidths[colX];
|
||||||
|
specifiedCols++;
|
||||||
|
if (PR_TRUE==gsDebug) printf ("col %d set to width %d\n", colX, colWidths[colX]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nscoord lastColAllocated = -1;
|
||||||
|
nscoord remainingWidth = availWidth - totalColWidth;
|
||||||
|
if (tableIsFixedWidth && (0 < remainingWidth)) {
|
||||||
|
if (mNumCols > specifiedCols) {
|
||||||
|
// allocate the extra space to the columns which have no width specified
|
||||||
|
if (PR_TRUE == gsDebug) printf ("%p: remainingTW=%d\n", mTableFrame, remainingWidth);
|
||||||
|
nscoord colAlloc = NSToCoordRound( ((float)remainingWidth) / (((float)mNumCols) - ((float)specifiedCols)));
|
||||||
|
for (colX = 0; colX < mNumCols; colX++) {
|
||||||
|
if (-1 == colWidths[colX]) {
|
||||||
|
colWidths[colX] = colAlloc;
|
||||||
|
totalColWidth += colAlloc;
|
||||||
|
lastColAllocated = colX;
|
||||||
|
if (PR_TRUE == gsDebug) printf ("auto col %d set to width %d\n", colX, colAlloc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { // allocate the extra space to the columns which have width specified
|
||||||
|
float divisor = (float)totalColWidth;
|
||||||
|
for (colX = 0; colX < mNumCols; colX++) {
|
||||||
|
if (colWidths[colX] > 0) {
|
||||||
|
nscoord colAlloc = NSToCoordRound(remainingWidth * colWidths[colX] / divisor);
|
||||||
|
colWidths[colX] += colAlloc;
|
||||||
|
totalColWidth += colAlloc;
|
||||||
|
lastColAllocated = colX;
|
||||||
|
if (PR_TRUE == gsDebug) printf ("col %d set to width %d\n", colX, colWidths[colX]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// for every column that did not have a specified width, compute its width from the remaining space
|
nscoord overAllocation = (availWidth >= 0)
|
||||||
if (mNumCols > specifiedColumns)
|
? totalColWidth - availWidth : 0;
|
||||||
{
|
// set the column widths
|
||||||
// Get the table's style
|
for (colX = 0; colX < mNumCols; colX++) {
|
||||||
const nsStylePosition* tablePosition;
|
if (colWidths[colX] < 0)
|
||||||
mTableFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)tablePosition);
|
colWidths[colX] = 0;
|
||||||
if (eStyleUnit_Coord==tablePosition->mWidth.GetUnit())
|
// if there was too much allocated due to rounding, remove it from the last col
|
||||||
{
|
if ((colX == lastColAllocated) && (overAllocation != 0)) {
|
||||||
nscoord specifiedTableWidth = tablePosition->mWidth.GetCoordValue();
|
colWidths[colX] += overAllocation;
|
||||||
nscoord remainingTableWidth = specifiedTableWidth - totalWidth;
|
colWidths[colX] = PR_MAX(0, colWidths[colX]);
|
||||||
if (PR_TRUE==gsDebug)
|
|
||||||
printf ("%p: specifiedTW=%d, remainingTW=%d\n",
|
|
||||||
mTableFrame, specifiedTableWidth, remainingTableWidth);
|
|
||||||
if (0<remainingTableWidth)
|
|
||||||
{
|
|
||||||
nscoord widthPerColumn = remainingTableWidth/(mNumCols-specifiedColumns);
|
|
||||||
for (colIndex = 0; colIndex<mNumCols; colIndex++)
|
|
||||||
{
|
|
||||||
if (PR_TRUE==autoWidthColumns[colIndex])
|
|
||||||
{
|
|
||||||
mTableFrame->SetColumnWidth(colIndex, widthPerColumn);
|
|
||||||
totalWidth += widthPerColumn;
|
|
||||||
if (PR_TRUE==gsDebug)
|
|
||||||
printf ("auto col %d set to width %d\n", colIndex, widthPerColumn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
mTableFrame->SetColumnWidth(colX, colWidths[colX]);
|
||||||
}
|
}
|
||||||
// min/MaxTW is max of (specified table width, sum of specified column(cell) widths)
|
|
||||||
mMinTableWidth = mMaxTableWidth = totalWidth;
|
// min/max TW is min/max of (specified table width, sum of specified column(cell) widths)
|
||||||
if (PR_TRUE==gsDebug)
|
mMinTableWidth = mMaxTableWidth = totalColWidth;
|
||||||
printf ("%p: aMinTW=%d, aMaxTW=%d\n", mTableFrame, mMinTableWidth, mMaxTableWidth);
|
if (PR_TRUE == gsDebug) printf ("%p: aMinTW=%d, aMaxTW=%d\n", mTableFrame, mMinTableWidth, mMaxTableWidth);
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
if (nsnull!=autoWidthColumns)
|
if (nsnull != colWidths) {
|
||||||
{
|
delete [] colWidths;
|
||||||
delete [] autoWidthColumns;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ protected:
|
||||||
* @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error
|
* @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
virtual PRBool AssignPreliminaryColumnWidths();
|
virtual PRBool AssignPreliminaryColumnWidths(nscoord aComputedWidth);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,9 @@ public:
|
||||||
/** call once every time any table thing changes (content, structure, or style)
|
/** call once every time any table thing changes (content, structure, or style)
|
||||||
* @param aMaxElementSize [OUT] if not null, the max element size is computed and returned in this param
|
* @param aMaxElementSize [OUT] if not null, the max element size is computed and returned in this param
|
||||||
* @param aNumCols the total number of columns in the table
|
* @param aNumCols the total number of columns in the table
|
||||||
|
* @param aComputedWidth the computed size of the table
|
||||||
*/
|
*/
|
||||||
virtual PRBool Initialize(nsSize* aMaxElementSize, PRInt32 aNumCols)=0;
|
virtual PRBool Initialize(nsSize* aMaxElementSize, PRInt32 aNumCols, nscoord aComputedWidth)=0;
|
||||||
|
|
||||||
/** compute the max-element-size for the table
|
/** compute the max-element-size for the table
|
||||||
* @param aMaxElementSize [OUT] width field set to the min legal width of the table
|
* @param aMaxElementSize [OUT] width field set to the min legal width of the table
|
||||||
|
|
|
||||||
|
|
@ -2497,7 +2497,7 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext,
|
||||||
if (nsnull!=mTableLayoutStrategy)
|
if (nsnull!=mTableLayoutStrategy)
|
||||||
{
|
{
|
||||||
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TIF Reflow: Re-init layout strategy\n");
|
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TIF Reflow: Re-init layout strategy\n");
|
||||||
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize, GetColCount());
|
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize, GetColCount(), aReflowState.computedWidth);
|
||||||
mColumnWidthsValid=PR_TRUE; //so we don't do this a second time below
|
mColumnWidthsValid=PR_TRUE; //so we don't do this a second time below
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2506,7 +2506,7 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext,
|
||||||
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TIF Reflow: Re-init layout strategy\n");
|
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TIF Reflow: Re-init layout strategy\n");
|
||||||
if (nsnull!=mTableLayoutStrategy)
|
if (nsnull!=mTableLayoutStrategy)
|
||||||
{
|
{
|
||||||
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize, GetColCount());
|
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize, GetColCount(), aReflowState.computedWidth);
|
||||||
mColumnWidthsValid=PR_TRUE;
|
mColumnWidthsValid=PR_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3972,17 +3972,22 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext& aPresContext,
|
||||||
this, maxWidth, aMaxSize.width, aMaxSize.height);
|
this, maxWidth, aMaxSize.width, aMaxSize.height);
|
||||||
|
|
||||||
// based on the compatibility mode, create a table layout strategy
|
// based on the compatibility mode, create a table layout strategy
|
||||||
if (nsnull==mTableLayoutStrategy)
|
if (nsnull == mTableLayoutStrategy) {
|
||||||
{
|
|
||||||
nsCompatibility mode;
|
nsCompatibility mode;
|
||||||
aPresContext.GetCompatibilityMode(&mode);
|
aPresContext.GetCompatibilityMode(&mode);
|
||||||
if (PR_FALSE==RequiresPass1Layout())
|
if (PR_FALSE==RequiresPass1Layout())
|
||||||
mTableLayoutStrategy = new FixedTableLayoutStrategy(this);
|
mTableLayoutStrategy = new FixedTableLayoutStrategy(this);
|
||||||
else
|
else
|
||||||
mTableLayoutStrategy = new BasicTableLayoutStrategy(this, eCompatibility_NavQuirks == mode);
|
mTableLayoutStrategy = new BasicTableLayoutStrategy(this, eCompatibility_NavQuirks == mode);
|
||||||
mTableLayoutStrategy->Initialize(aMaxElementSize, GetColCount());
|
mTableLayoutStrategy->Initialize(aMaxElementSize, GetColCount(), aReflowState.computedWidth);
|
||||||
mColumnWidthsValid=PR_TRUE;
|
mColumnWidthsValid=PR_TRUE;
|
||||||
}
|
}
|
||||||
|
// fixed-layout tables need to reinitialize the layout strategy. When there are scroll bars
|
||||||
|
// reflow gets called twice and the 2nd time has the correct space available.
|
||||||
|
else if (!RequiresPass1Layout()) {
|
||||||
|
mTableLayoutStrategy->Initialize(aMaxElementSize, GetColCount(), aReflowState.computedWidth);
|
||||||
|
}
|
||||||
|
|
||||||
mTableLayoutStrategy->BalanceColumnWidths(mStyleContext, aReflowState, maxWidth);
|
mTableLayoutStrategy->BalanceColumnWidths(mStyleContext, aReflowState, maxWidth);
|
||||||
mColumnWidthsSet=PR_TRUE;
|
mColumnWidthsSet=PR_TRUE;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -233,7 +233,8 @@ BasicTableLayoutStrategy::~BasicTableLayoutStrategy()
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool BasicTableLayoutStrategy::Initialize(nsSize* aMaxElementSize,
|
PRBool BasicTableLayoutStrategy::Initialize(nsSize* aMaxElementSize,
|
||||||
PRInt32 aNumCols)
|
PRInt32 aNumCols,
|
||||||
|
nscoord aMaxWidth)
|
||||||
{
|
{
|
||||||
#ifdef NS_DEBUG
|
#ifdef NS_DEBUG
|
||||||
nsIFrame* tablePIF = nsnull;
|
nsIFrame* tablePIF = nsnull;
|
||||||
|
|
@ -251,7 +252,7 @@ PRBool BasicTableLayoutStrategy::Initialize(nsSize* aMaxElementSize,
|
||||||
mCols = mTableFrame->GetEffectiveCOLSAttribute();
|
mCols = mTableFrame->GetEffectiveCOLSAttribute();
|
||||||
|
|
||||||
// Step 1 - assign the width of all fixed-width columns
|
// Step 1 - assign the width of all fixed-width columns
|
||||||
AssignPreliminaryColumnWidths();
|
AssignPreliminaryColumnWidths(aMaxWidth);
|
||||||
|
|
||||||
// set aMaxElementSize here because we compute mMinTableWidth in AssignPreliminaryColumnWidths
|
// set aMaxElementSize here because we compute mMinTableWidth in AssignPreliminaryColumnWidths
|
||||||
if (nsnull != aMaxElementSize) {
|
if (nsnull != aMaxElementSize) {
|
||||||
|
|
@ -389,7 +390,7 @@ nscoord BasicTableLayoutStrategy::CalcHorizontalPadding(PRInt32 aColX)
|
||||||
|
|
||||||
// Step 1 - assign the width of all fixed-width columns, all other columns get there max,
|
// Step 1 - assign the width of all fixed-width columns, all other columns get there max,
|
||||||
// and calculate min/max table width
|
// and calculate min/max table width
|
||||||
PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths()
|
PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aMaxWidth)
|
||||||
{
|
{
|
||||||
TDBG_SP("** %p: AssignPreliminaryColumnWidths **\n", mTableFrame);
|
TDBG_SP("** %p: AssignPreliminaryColumnWidths **\n", mTableFrame);
|
||||||
nsVoidArray *spanList = nsnull;
|
nsVoidArray *spanList = nsnull;
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ public:
|
||||||
* @param aMaxElementSize [OUT] if not null, the max element size is computed and returned in this param
|
* @param aMaxElementSize [OUT] if not null, the max element size is computed and returned in this param
|
||||||
* @param aNumCols the total number of columns in the table
|
* @param aNumCols the total number of columns in the table
|
||||||
*/
|
*/
|
||||||
virtual PRBool Initialize(nsSize* aMaxElementSize, PRInt32 aNumCols);
|
virtual PRBool Initialize(nsSize* aMaxElementSize, PRInt32 aNumCols, nscoord aMaxSize);
|
||||||
|
|
||||||
/** compute the max element size of the table.
|
/** compute the max element size of the table.
|
||||||
* assumes that Initialize has been called
|
* assumes that Initialize has been called
|
||||||
|
|
@ -123,10 +123,12 @@ protected:
|
||||||
* Computes the minimum and maximum table widths.
|
* Computes the minimum and maximum table widths.
|
||||||
* Set column width information in each column frame and in the table frame.
|
* Set column width information in each column frame and in the table frame.
|
||||||
*
|
*
|
||||||
|
* @param aMaxWidth - the computed width of the table or
|
||||||
|
* UNCONSTRAINED_SIZE if an auto width table
|
||||||
* @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error
|
* @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
virtual PRBool AssignPreliminaryColumnWidths();
|
virtual PRBool AssignPreliminaryColumnWidths(nscoord aComputedWidth);
|
||||||
|
|
||||||
/** compute the min and max width of this table. Assumes AssignPreliminaryColumnWidths
|
/** compute the min and max width of this table. Assumes AssignPreliminaryColumnWidths
|
||||||
* has been called. Sets mMinTableWidth and mMaxTableWidth as a side effect.
|
* has been called. Sets mMinTableWidth and mMaxTableWidth as a side effect.
|
||||||
|
|
|
||||||
|
|
@ -73,109 +73,135 @@ PRBool FixedTableLayoutStrategy::BalanceColumnWidths(nsIStyleContext *aTableStyl
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* assign the width of all columns
|
/*
|
||||||
|
* assign the width of all columns
|
||||||
* if there is a colframe with a width attribute, use it as the column width
|
* if there is a colframe with a width attribute, use it as the column width
|
||||||
* otherwise if there is a cell in the first row and it has a width attribute, use it
|
* otherwise if there is a cell in the first row and it has a width attribute, use it
|
||||||
* if this cell includes a colspan, width is divided equally among spanned columns
|
* if this cell includes a colspan, width is divided equally among spanned columns
|
||||||
* otherwise the cell get a proportion of the remaining space
|
* otherwise the cell get a proportion of the remaining space
|
||||||
* as determined by the table width attribute. If no table width attribute, it gets 0 width
|
* as determined by the table width attribute. If no table width attribute, it gets 0 width
|
||||||
*/
|
*/
|
||||||
PRBool FixedTableLayoutStrategy::AssignPreliminaryColumnWidths()
|
PRBool FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nscoord aComputedWidth)
|
||||||
{
|
{
|
||||||
|
NS_ASSERTION(aComputedWidth != NS_UNCONSTRAINEDSIZE, "bad computed width");
|
||||||
if (gsDebug==PR_TRUE) printf ("** %p: AssignPreliminaryColumnWidths **\n", mTableFrame);
|
if (gsDebug==PR_TRUE) printf ("** %p: AssignPreliminaryColumnWidths **\n", mTableFrame);
|
||||||
|
|
||||||
PRInt32 colIndex;
|
const nsStylePosition* tablePosition;
|
||||||
PRInt32 specifiedColumns=0; // the number of columns whose width is given
|
mTableFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)tablePosition);
|
||||||
nscoord totalWidth = 0; // the sum of the widths of the columns whose width is given
|
PRBool tableIsFixedWidth = eStyleUnit_Coord == tablePosition->mWidth.GetUnit() ||
|
||||||
|
eStyleUnit_Percent == tablePosition->mWidth.GetUnit();
|
||||||
|
|
||||||
PRBool * autoWidthColumns = new PRBool[mNumCols];
|
const nsStyleSpacing* tableSpacing;
|
||||||
nsCRT::memset(autoWidthColumns, PR_TRUE, mNumCols*sizeof(PRBool));
|
mTableFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&)tableSpacing);
|
||||||
|
nsMargin borderPadding;
|
||||||
|
tableSpacing->CalcBorderPaddingFor(mTableFrame, borderPadding);
|
||||||
|
|
||||||
|
PRInt32 colX;
|
||||||
|
// availWidth is used as the basis for percentage width columns. It is aComputedWidth
|
||||||
|
// minus table border, padding, & cellspacing
|
||||||
|
nscoord availWidth = aComputedWidth - borderPadding.left - borderPadding.right -
|
||||||
|
((mNumCols + 1) * mTableFrame->GetCellSpacingX());
|
||||||
|
|
||||||
|
PRInt32 specifiedCols = 0; // the number of columns whose width is given
|
||||||
|
nscoord totalColWidth = 0; // the sum of the widths of the columns
|
||||||
|
|
||||||
|
nscoord* colWidths = new PRBool[mNumCols];
|
||||||
|
nsCRT::memset(colWidths, -1, mNumCols*sizeof(nscoord));
|
||||||
|
|
||||||
// for every column, determine it's specified width
|
// for every column, determine it's specified width
|
||||||
for (colIndex = 0; colIndex<mNumCols; colIndex++)
|
for (colX = 0; colX < mNumCols; colX++) {
|
||||||
{
|
|
||||||
// Get column information
|
// Get column information
|
||||||
nsTableColFrame *colFrame = mTableFrame->GetColFrame(colIndex);
|
nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX);
|
||||||
NS_ASSERTION(nsnull!=colFrame, "bad col frame");
|
NS_ASSERTION(nsnull != colFrame, "bad col frame");
|
||||||
|
|
||||||
// Get the columns's style
|
// Get the columns's style
|
||||||
const nsStylePosition* colPosition;
|
const nsStylePosition* colPosition;
|
||||||
colFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)colPosition);
|
colFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)colPosition);
|
||||||
|
|
||||||
// Get fixed column width if it has one
|
// get the fixed width if available
|
||||||
if (eStyleUnit_Coord==colPosition->mWidth.GetUnit())
|
if (eStyleUnit_Coord == colPosition->mWidth.GetUnit()) {
|
||||||
{
|
colWidths[colX] = colPosition->mWidth.GetCoordValue();
|
||||||
nscoord colWidth = colPosition->mWidth.GetCoordValue();
|
} // get the percentage width
|
||||||
mTableFrame->SetColumnWidth(colIndex, colWidth);
|
else if (eStyleUnit_Percent == colPosition->mWidth.GetUnit()) {
|
||||||
totalWidth += colWidth;
|
float percent = colPosition->mWidth.GetPercentValue();
|
||||||
specifiedColumns++;
|
colWidths[colX] = NSToCoordRound(percent * (float)availWidth);
|
||||||
autoWidthColumns[colIndex]=PR_FALSE;
|
|
||||||
if (PR_TRUE==gsDebug)
|
|
||||||
printf ("from col, col %d set to width %d\n", colIndex, colWidth);
|
|
||||||
}
|
}
|
||||||
else
|
else { // get width from the cell
|
||||||
{
|
nsTableCellFrame* cellFrame = mTableFrame->GetCellFrameAt(0, colX);
|
||||||
nsTableCellFrame *cellFrame = mTableFrame->GetCellFrameAt(0, colIndex);
|
if (nsnull != cellFrame) {
|
||||||
if (nsnull!=cellFrame)
|
|
||||||
{
|
|
||||||
// Get the cell's style
|
// Get the cell's style
|
||||||
const nsStylePosition* cellPosition;
|
const nsStylePosition* cellPosition;
|
||||||
cellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)cellPosition);
|
cellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)cellPosition);
|
||||||
|
|
||||||
// Get fixed column width if it has one
|
PRInt32 colSpan = mTableFrame->GetEffectiveColSpan(colX, cellFrame);
|
||||||
if (eStyleUnit_Coord==cellPosition->mWidth.GetUnit())
|
// Get fixed cell width if available
|
||||||
{
|
if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit()) {
|
||||||
PRInt32 colSpan = mTableFrame->GetEffectiveColSpan(colIndex, cellFrame);
|
colWidths[colX] = cellPosition->mWidth.GetCoordValue() / colSpan;
|
||||||
nscoord effectiveWidth = cellPosition->mWidth.GetCoordValue()/colSpan;
|
}
|
||||||
mTableFrame->SetColumnWidth(colIndex, effectiveWidth);
|
else if (eStyleUnit_Percent == cellPosition->mWidth.GetUnit()) {
|
||||||
totalWidth += effectiveWidth;
|
float percent = cellPosition->mWidth.GetPercentValue();
|
||||||
specifiedColumns++;
|
colWidths[colX] = NSToCoordRound(percent * (float)availWidth / (float)colSpan);
|
||||||
autoWidthColumns[colIndex]=PR_FALSE;
|
}
|
||||||
if (PR_TRUE==gsDebug)
|
}
|
||||||
printf ("from cell, col %d set to width %d\n", colIndex, effectiveWidth);
|
}
|
||||||
|
if (colWidths[colX] >= 0) {
|
||||||
|
totalColWidth += colWidths[colX];
|
||||||
|
specifiedCols++;
|
||||||
|
if (PR_TRUE==gsDebug) printf ("col %d set to width %d\n", colX, colWidths[colX]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nscoord lastColAllocated = -1;
|
||||||
|
nscoord remainingWidth = availWidth - totalColWidth;
|
||||||
|
if (tableIsFixedWidth && (0 < remainingWidth)) {
|
||||||
|
if (mNumCols > specifiedCols) {
|
||||||
|
// allocate the extra space to the columns which have no width specified
|
||||||
|
if (PR_TRUE == gsDebug) printf ("%p: remainingTW=%d\n", mTableFrame, remainingWidth);
|
||||||
|
nscoord colAlloc = NSToCoordRound( ((float)remainingWidth) / (((float)mNumCols) - ((float)specifiedCols)));
|
||||||
|
for (colX = 0; colX < mNumCols; colX++) {
|
||||||
|
if (-1 == colWidths[colX]) {
|
||||||
|
colWidths[colX] = colAlloc;
|
||||||
|
totalColWidth += colAlloc;
|
||||||
|
lastColAllocated = colX;
|
||||||
|
if (PR_TRUE == gsDebug) printf ("auto col %d set to width %d\n", colX, colAlloc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { // allocate the extra space to the columns which have width specified
|
||||||
|
float divisor = (float)totalColWidth;
|
||||||
|
for (colX = 0; colX < mNumCols; colX++) {
|
||||||
|
if (colWidths[colX] > 0) {
|
||||||
|
nscoord colAlloc = NSToCoordRound(remainingWidth * colWidths[colX] / divisor);
|
||||||
|
colWidths[colX] += colAlloc;
|
||||||
|
totalColWidth += colAlloc;
|
||||||
|
lastColAllocated = colX;
|
||||||
|
if (PR_TRUE == gsDebug) printf ("col %d set to width %d\n", colX, colWidths[colX]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// for every column that did not have a specified width, compute its width from the remaining space
|
nscoord overAllocation = (availWidth >= 0)
|
||||||
if (mNumCols > specifiedColumns)
|
? totalColWidth - availWidth : 0;
|
||||||
{
|
// set the column widths
|
||||||
// Get the table's style
|
for (colX = 0; colX < mNumCols; colX++) {
|
||||||
const nsStylePosition* tablePosition;
|
if (colWidths[colX] < 0)
|
||||||
mTableFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)tablePosition);
|
colWidths[colX] = 0;
|
||||||
if (eStyleUnit_Coord==tablePosition->mWidth.GetUnit())
|
// if there was too much allocated due to rounding, remove it from the last col
|
||||||
{
|
if ((colX == lastColAllocated) && (overAllocation != 0)) {
|
||||||
nscoord specifiedTableWidth = tablePosition->mWidth.GetCoordValue();
|
colWidths[colX] += overAllocation;
|
||||||
nscoord remainingTableWidth = specifiedTableWidth - totalWidth;
|
colWidths[colX] = PR_MAX(0, colWidths[colX]);
|
||||||
if (PR_TRUE==gsDebug)
|
|
||||||
printf ("%p: specifiedTW=%d, remainingTW=%d\n",
|
|
||||||
mTableFrame, specifiedTableWidth, remainingTableWidth);
|
|
||||||
if (0<remainingTableWidth)
|
|
||||||
{
|
|
||||||
nscoord widthPerColumn = remainingTableWidth/(mNumCols-specifiedColumns);
|
|
||||||
for (colIndex = 0; colIndex<mNumCols; colIndex++)
|
|
||||||
{
|
|
||||||
if (PR_TRUE==autoWidthColumns[colIndex])
|
|
||||||
{
|
|
||||||
mTableFrame->SetColumnWidth(colIndex, widthPerColumn);
|
|
||||||
totalWidth += widthPerColumn;
|
|
||||||
if (PR_TRUE==gsDebug)
|
|
||||||
printf ("auto col %d set to width %d\n", colIndex, widthPerColumn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
mTableFrame->SetColumnWidth(colX, colWidths[colX]);
|
||||||
}
|
}
|
||||||
// min/MaxTW is max of (specified table width, sum of specified column(cell) widths)
|
|
||||||
mMinTableWidth = mMaxTableWidth = totalWidth;
|
// min/max TW is min/max of (specified table width, sum of specified column(cell) widths)
|
||||||
if (PR_TRUE==gsDebug)
|
mMinTableWidth = mMaxTableWidth = totalColWidth;
|
||||||
printf ("%p: aMinTW=%d, aMaxTW=%d\n", mTableFrame, mMinTableWidth, mMaxTableWidth);
|
if (PR_TRUE == gsDebug) printf ("%p: aMinTW=%d, aMaxTW=%d\n", mTableFrame, mMinTableWidth, mMaxTableWidth);
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
if (nsnull!=autoWidthColumns)
|
if (nsnull != colWidths) {
|
||||||
{
|
delete [] colWidths;
|
||||||
delete [] autoWidthColumns;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ protected:
|
||||||
* @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error
|
* @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
virtual PRBool AssignPreliminaryColumnWidths();
|
virtual PRBool AssignPreliminaryColumnWidths(nscoord aComputedWidth);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,9 @@ public:
|
||||||
/** call once every time any table thing changes (content, structure, or style)
|
/** call once every time any table thing changes (content, structure, or style)
|
||||||
* @param aMaxElementSize [OUT] if not null, the max element size is computed and returned in this param
|
* @param aMaxElementSize [OUT] if not null, the max element size is computed and returned in this param
|
||||||
* @param aNumCols the total number of columns in the table
|
* @param aNumCols the total number of columns in the table
|
||||||
|
* @param aComputedWidth the computed size of the table
|
||||||
*/
|
*/
|
||||||
virtual PRBool Initialize(nsSize* aMaxElementSize, PRInt32 aNumCols)=0;
|
virtual PRBool Initialize(nsSize* aMaxElementSize, PRInt32 aNumCols, nscoord aComputedWidth)=0;
|
||||||
|
|
||||||
/** compute the max-element-size for the table
|
/** compute the max-element-size for the table
|
||||||
* @param aMaxElementSize [OUT] width field set to the min legal width of the table
|
* @param aMaxElementSize [OUT] width field set to the min legal width of the table
|
||||||
|
|
|
||||||
|
|
@ -2497,7 +2497,7 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext,
|
||||||
if (nsnull!=mTableLayoutStrategy)
|
if (nsnull!=mTableLayoutStrategy)
|
||||||
{
|
{
|
||||||
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TIF Reflow: Re-init layout strategy\n");
|
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TIF Reflow: Re-init layout strategy\n");
|
||||||
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize, GetColCount());
|
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize, GetColCount(), aReflowState.computedWidth);
|
||||||
mColumnWidthsValid=PR_TRUE; //so we don't do this a second time below
|
mColumnWidthsValid=PR_TRUE; //so we don't do this a second time below
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2506,7 +2506,7 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext,
|
||||||
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TIF Reflow: Re-init layout strategy\n");
|
if (PR_TRUE==gsDebug || PR_TRUE==gsDebugIR) printf("TIF Reflow: Re-init layout strategy\n");
|
||||||
if (nsnull!=mTableLayoutStrategy)
|
if (nsnull!=mTableLayoutStrategy)
|
||||||
{
|
{
|
||||||
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize, GetColCount());
|
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize, GetColCount(), aReflowState.computedWidth);
|
||||||
mColumnWidthsValid=PR_TRUE;
|
mColumnWidthsValid=PR_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3972,17 +3972,22 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext& aPresContext,
|
||||||
this, maxWidth, aMaxSize.width, aMaxSize.height);
|
this, maxWidth, aMaxSize.width, aMaxSize.height);
|
||||||
|
|
||||||
// based on the compatibility mode, create a table layout strategy
|
// based on the compatibility mode, create a table layout strategy
|
||||||
if (nsnull==mTableLayoutStrategy)
|
if (nsnull == mTableLayoutStrategy) {
|
||||||
{
|
|
||||||
nsCompatibility mode;
|
nsCompatibility mode;
|
||||||
aPresContext.GetCompatibilityMode(&mode);
|
aPresContext.GetCompatibilityMode(&mode);
|
||||||
if (PR_FALSE==RequiresPass1Layout())
|
if (PR_FALSE==RequiresPass1Layout())
|
||||||
mTableLayoutStrategy = new FixedTableLayoutStrategy(this);
|
mTableLayoutStrategy = new FixedTableLayoutStrategy(this);
|
||||||
else
|
else
|
||||||
mTableLayoutStrategy = new BasicTableLayoutStrategy(this, eCompatibility_NavQuirks == mode);
|
mTableLayoutStrategy = new BasicTableLayoutStrategy(this, eCompatibility_NavQuirks == mode);
|
||||||
mTableLayoutStrategy->Initialize(aMaxElementSize, GetColCount());
|
mTableLayoutStrategy->Initialize(aMaxElementSize, GetColCount(), aReflowState.computedWidth);
|
||||||
mColumnWidthsValid=PR_TRUE;
|
mColumnWidthsValid=PR_TRUE;
|
||||||
}
|
}
|
||||||
|
// fixed-layout tables need to reinitialize the layout strategy. When there are scroll bars
|
||||||
|
// reflow gets called twice and the 2nd time has the correct space available.
|
||||||
|
else if (!RequiresPass1Layout()) {
|
||||||
|
mTableLayoutStrategy->Initialize(aMaxElementSize, GetColCount(), aReflowState.computedWidth);
|
||||||
|
}
|
||||||
|
|
||||||
mTableLayoutStrategy->BalanceColumnWidths(mStyleContext, aReflowState, maxWidth);
|
mTableLayoutStrategy->BalanceColumnWidths(mStyleContext, aReflowState, maxWidth);
|
||||||
mColumnWidthsSet=PR_TRUE;
|
mColumnWidthsSet=PR_TRUE;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue