Changes to the cell map to support incremental insertion and removal of rows. Currently

only used by the tree widget.
This commit is contained in:
hyatt%netscape.com 1999-08-30 00:01:09 +00:00
Родитель ef1b8514bd
Коммит 8c3c551001
12 изменённых файлов: 364 добавлений и 16 удалений

Просмотреть файл

@ -54,7 +54,7 @@ nsCellMap::~nsCellMap()
PRInt32 colX;
for (PRInt32 rowX = 0; rowX < mapRowCount; rowX++) {
nsVoidArray* row = (nsVoidArray *)(mRows.ElementAt(rowX));
for (colX = 0; colX <= colCount; colX++) {
for (colX = 0; colX < colCount; colX++) {
CellData* data = (CellData *)(row->ElementAt(colX));
if (data) {
delete data;
@ -137,6 +137,68 @@ void nsCellMap::Grow(PRInt32 aNumMapRows,
}
}
void nsCellMap::InsertRowIntoMap(PRInt32 aRowIndex)
{
// XXX This function does not yet handle spans.
// XXX Does this function need to worry about adjusting the collapsed row/col arrays?
nsVoidArray* row;
PRInt32 origNumCols = mNumCellsOrigInCol.Count();
row = (0 == origNumCols) ? new nsVoidArray() : new nsVoidArray(origNumCols);
if (row) {
mRows.InsertElementAt(row, aRowIndex);
}
PRInt32* val = new PRInt32(0);
if (val) {
mNumCellsOrigInRow.InsertElementAt(val, aRowIndex);
}
mRowCount++;
mNextAvailRowIndex++;
}
void nsCellMap::RemoveRowFromMap(PRInt32 aRowIndex)
{
// XXX This function does not yet handle spans.
// XXX Does this function need to worry about adjusting the collapsed row/col arrays?
PRInt32 colCount = mNumCellsOrigInCol.Count();
for (PRInt32 i = 0; i < colCount; i++) {
// Adjust the column counts.
PRInt32 span;
PRBool originates;
GetCellInfoAt(aRowIndex, i, &originates, &span);
if (originates) {
// Decrement the column count.
PRInt32* cols = (PRInt32*)(mNumCellsOrigInCol.ElementAt(i));
*cols = *cols-1;
}
}
// Delete the originating row info.
PRInt32* numOrig = (PRInt32 *)mNumCellsOrigInRow.ElementAt(aRowIndex);
mNumCellsOrigInRow.RemoveElementAt(aRowIndex);
if (numOrig)
delete numOrig;
// Delete our row information.
nsVoidArray* row = (nsVoidArray *)(mRows.ElementAt(aRowIndex));
for (PRInt32 colX = 0; colX < colCount; colX++) {
CellData* data = (CellData *)(row->ElementAt(colX));
if (data) {
delete data;
}
}
mRows.RemoveElementAt(aRowIndex);
delete row;
// Decrement our row and next available index counts.
mRowCount--;
mNextAvailRowIndex--;
}
PRInt32 nsCellMap::AppendCell(nsTableCellFrame* aCellFrame,
PRInt32 aRowIndex)
{

Просмотреть файл

@ -56,6 +56,15 @@ public:
CellData* GetCellAt(PRInt32 aRowIndex,
PRInt32 aColIndex) const;
/** insert a new row into the map
makes a blank row and adjusts spans
*/
void InsertRowIntoMap(PRInt32 aRowIndex);
/** removes a row from the map and adjusts spans
*/
void RemoveRowFromMap(PRInt32 aRowIndex);
/** append the cellFrame at the end of the row at aRowIndex and return the col index
*/
PRInt32 AppendCell(nsTableCellFrame* aCellFrame,

Просмотреть файл

@ -607,6 +607,80 @@ PRInt32 nsTableFrame::GetEffectiveCOLSAttribute()
return result;
}
NS_IMETHODIMP nsTableFrame::AdjustRowIndices(nsIFrame* aRowGroup,
PRInt32 aRowIndex,
PRInt32 anAdjustment)
{
nsresult rv = NS_OK;
nsIFrame *rowFrame;
aRowGroup->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)
{
PRInt32 index = ((nsTableRowFrame*)rowFrame)->GetRowIndex();
if (index >= aRowIndex)
((nsTableRowFrame *)rowFrame)->SetRowIndex(index+anAdjustment);
}
else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP==rowDisplay->mDisplay)
{
AdjustRowIndices(rowFrame, aRowIndex, anAdjustment);
}
}
return rv;
}
NS_IMETHODIMP nsTableFrame::RemoveRowFromMap(nsTableRowFrame* aRow, PRInt32 aRowIndex)
{
nsresult rv=NS_OK;
// Create a new row in the cell map at the specified index.
mCellMap->RemoveRowFromMap(aRowIndex);
// Iterate over our row groups and increment the row indices of all rows whose index
// is >= aRowIndex.
nsIFrame *rowGroupFrame=mFrames.FirstChild();
for ( ; nsnull!=rowGroupFrame; rowGroupFrame->GetNextSibling(&rowGroupFrame))
{
const nsStyleDisplay *rowGroupDisplay;
rowGroupFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)rowGroupDisplay);
if (PR_TRUE==IsRowGroup(rowGroupDisplay->mDisplay))
{
AdjustRowIndices(rowGroupFrame, aRowIndex, -1);
}
}
return rv;
}
NS_IMETHODIMP nsTableFrame::InsertRowIntoMap(nsTableRowFrame* aRow, PRInt32 aRowIndex)
{
nsresult rv=NS_OK;
// Create a new row in the cell map at the specified index.
mCellMap->InsertRowIntoMap(aRowIndex);
// Iterate over our row groups and increment the row indices of all rows whose index
// is >= aRowIndex.
nsIFrame *rowGroupFrame=mFrames.FirstChild();
for ( ; nsnull!=rowGroupFrame; rowGroupFrame->GetNextSibling(&rowGroupFrame))
{
const nsStyleDisplay *rowGroupDisplay;
rowGroupFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)rowGroupDisplay);
if (PR_TRUE==IsRowGroup(rowGroupDisplay->mDisplay))
{
AdjustRowIndices(rowGroupFrame, aRowIndex, 1);
}
}
// Init the row's index and add its cells to the cell map.
aRow->InitChildrenWithIndex(aRowIndex);
return rv;
}
/** sum the columns represented by all nsTableColGroup objects
* if the cell map says there are more columns than this,
* add extra implicit columns to the content tree.
@ -762,7 +836,6 @@ PRInt32 nsTableFrame::AddCellToTable(nsTableCellFrame* aCellFrame,
NS_ASSERTION(nsnull != mCellMap, "bad cellMap");
// XXX: must be called only on first-in-flow!
return mCellMap->AppendCell(aCellFrame, aRowIndex);
}

Просмотреть файл

@ -736,6 +736,15 @@ public:
virtual void EnsureColumns (nsIPresContext& aPresContext,
PRBool& aCreatedColFrames);
// These methods are used to incrementally insert and remove rows
// from the cell map without having to invalidate the entire map.
NS_IMETHOD InsertRowIntoMap(nsTableRowFrame* aRow, PRInt32 aRowIndex);
NS_IMETHOD RemoveRowFromMap(nsTableRowFrame* aRow, PRInt32 aRowIndex);
NS_IMETHOD AdjustRowIndices(nsIFrame* aRowGroup,
PRInt32 aRowIndex,
PRInt32 anAdjustment);
protected:
/** iterates all child frames and creates a new cell map */
NS_IMETHOD ReBuildCellMap();

Просмотреть файл

@ -235,7 +235,7 @@ nsTableRowFrame::RemoveFrame(nsIPresContext& aPresContext,
}
NS_IMETHODIMP
nsTableRowFrame::InitChildren()
nsTableRowFrame::InitChildrenWithIndex(PRInt32 aRowIndex)
{
nsTableFrame* table = nsnull;
nsresult result=NS_OK;
@ -248,8 +248,8 @@ nsTableRowFrame::InitChildren()
if ((NS_OK==result) && (table != nsnull))
{
mInitializedChildren=PR_TRUE;
PRInt32 rowIndex = table->GetNextAvailRowIndex();
SetRowIndex(rowIndex);
SetRowIndex(aRowIndex);
for (nsIFrame* kidFrame = mFrames.FirstChild(); nsnull != kidFrame; kidFrame->GetNextSibling(&kidFrame))
{
const nsStyleDisplay *kidDisplay;
@ -258,9 +258,9 @@ nsTableRowFrame::InitChildren()
{
// add the cell frame to the table's cell map and get its col index
PRInt32 colIndex;
colIndex = table->AddCellToTable((nsTableCellFrame *)kidFrame, rowIndex);
colIndex = table->AddCellToTable((nsTableCellFrame *)kidFrame, aRowIndex);
// what column does this cell belong to?
// this sets the frame's notion of it's column index
// this sets the frame's notion of its column index
((nsTableCellFrame *)kidFrame)->InitCellFrame(colIndex);
}
}
@ -269,6 +269,26 @@ nsTableRowFrame::InitChildren()
return NS_OK;
}
NS_IMETHODIMP
nsTableRowFrame::InitChildren()
{
nsTableFrame* table = nsnull;
nsresult result=NS_OK;
// each child cell can only be added to the table one time.
// for now, we remember globally whether we've added all or none
if (PR_FALSE==mInitializedChildren)
{
result = nsTableFrame::GetTableFrame(this, table);
if ((NS_OK==result) && (table != nsnull))
{
PRInt32 rowIndex = table->GetNextAvailRowIndex();
InitChildrenWithIndex(rowIndex);
}
}
return NS_OK;
}
/**
* Post-reflow hook. This is where the table row does its post-processing
*/

Просмотреть файл

@ -90,6 +90,7 @@ public:
/** Initialization of data */
NS_IMETHOD InitChildren();
NS_IMETHOD InitChildrenWithIndex(PRInt32 aRowIndex);
void ResetInitChildren();

Просмотреть файл

@ -54,7 +54,7 @@ nsCellMap::~nsCellMap()
PRInt32 colX;
for (PRInt32 rowX = 0; rowX < mapRowCount; rowX++) {
nsVoidArray* row = (nsVoidArray *)(mRows.ElementAt(rowX));
for (colX = 0; colX <= colCount; colX++) {
for (colX = 0; colX < colCount; colX++) {
CellData* data = (CellData *)(row->ElementAt(colX));
if (data) {
delete data;
@ -137,6 +137,68 @@ void nsCellMap::Grow(PRInt32 aNumMapRows,
}
}
void nsCellMap::InsertRowIntoMap(PRInt32 aRowIndex)
{
// XXX This function does not yet handle spans.
// XXX Does this function need to worry about adjusting the collapsed row/col arrays?
nsVoidArray* row;
PRInt32 origNumCols = mNumCellsOrigInCol.Count();
row = (0 == origNumCols) ? new nsVoidArray() : new nsVoidArray(origNumCols);
if (row) {
mRows.InsertElementAt(row, aRowIndex);
}
PRInt32* val = new PRInt32(0);
if (val) {
mNumCellsOrigInRow.InsertElementAt(val, aRowIndex);
}
mRowCount++;
mNextAvailRowIndex++;
}
void nsCellMap::RemoveRowFromMap(PRInt32 aRowIndex)
{
// XXX This function does not yet handle spans.
// XXX Does this function need to worry about adjusting the collapsed row/col arrays?
PRInt32 colCount = mNumCellsOrigInCol.Count();
for (PRInt32 i = 0; i < colCount; i++) {
// Adjust the column counts.
PRInt32 span;
PRBool originates;
GetCellInfoAt(aRowIndex, i, &originates, &span);
if (originates) {
// Decrement the column count.
PRInt32* cols = (PRInt32*)(mNumCellsOrigInCol.ElementAt(i));
*cols = *cols-1;
}
}
// Delete the originating row info.
PRInt32* numOrig = (PRInt32 *)mNumCellsOrigInRow.ElementAt(aRowIndex);
mNumCellsOrigInRow.RemoveElementAt(aRowIndex);
if (numOrig)
delete numOrig;
// Delete our row information.
nsVoidArray* row = (nsVoidArray *)(mRows.ElementAt(aRowIndex));
for (PRInt32 colX = 0; colX < colCount; colX++) {
CellData* data = (CellData *)(row->ElementAt(colX));
if (data) {
delete data;
}
}
mRows.RemoveElementAt(aRowIndex);
delete row;
// Decrement our row and next available index counts.
mRowCount--;
mNextAvailRowIndex--;
}
PRInt32 nsCellMap::AppendCell(nsTableCellFrame* aCellFrame,
PRInt32 aRowIndex)
{

Просмотреть файл

@ -56,6 +56,15 @@ public:
CellData* GetCellAt(PRInt32 aRowIndex,
PRInt32 aColIndex) const;
/** insert a new row into the map
makes a blank row and adjusts spans
*/
void InsertRowIntoMap(PRInt32 aRowIndex);
/** removes a row from the map and adjusts spans
*/
void RemoveRowFromMap(PRInt32 aRowIndex);
/** append the cellFrame at the end of the row at aRowIndex and return the col index
*/
PRInt32 AppendCell(nsTableCellFrame* aCellFrame,

Просмотреть файл

@ -607,6 +607,80 @@ PRInt32 nsTableFrame::GetEffectiveCOLSAttribute()
return result;
}
NS_IMETHODIMP nsTableFrame::AdjustRowIndices(nsIFrame* aRowGroup,
PRInt32 aRowIndex,
PRInt32 anAdjustment)
{
nsresult rv = NS_OK;
nsIFrame *rowFrame;
aRowGroup->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)
{
PRInt32 index = ((nsTableRowFrame*)rowFrame)->GetRowIndex();
if (index >= aRowIndex)
((nsTableRowFrame *)rowFrame)->SetRowIndex(index+anAdjustment);
}
else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP==rowDisplay->mDisplay)
{
AdjustRowIndices(rowFrame, aRowIndex, anAdjustment);
}
}
return rv;
}
NS_IMETHODIMP nsTableFrame::RemoveRowFromMap(nsTableRowFrame* aRow, PRInt32 aRowIndex)
{
nsresult rv=NS_OK;
// Create a new row in the cell map at the specified index.
mCellMap->RemoveRowFromMap(aRowIndex);
// Iterate over our row groups and increment the row indices of all rows whose index
// is >= aRowIndex.
nsIFrame *rowGroupFrame=mFrames.FirstChild();
for ( ; nsnull!=rowGroupFrame; rowGroupFrame->GetNextSibling(&rowGroupFrame))
{
const nsStyleDisplay *rowGroupDisplay;
rowGroupFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)rowGroupDisplay);
if (PR_TRUE==IsRowGroup(rowGroupDisplay->mDisplay))
{
AdjustRowIndices(rowGroupFrame, aRowIndex, -1);
}
}
return rv;
}
NS_IMETHODIMP nsTableFrame::InsertRowIntoMap(nsTableRowFrame* aRow, PRInt32 aRowIndex)
{
nsresult rv=NS_OK;
// Create a new row in the cell map at the specified index.
mCellMap->InsertRowIntoMap(aRowIndex);
// Iterate over our row groups and increment the row indices of all rows whose index
// is >= aRowIndex.
nsIFrame *rowGroupFrame=mFrames.FirstChild();
for ( ; nsnull!=rowGroupFrame; rowGroupFrame->GetNextSibling(&rowGroupFrame))
{
const nsStyleDisplay *rowGroupDisplay;
rowGroupFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)rowGroupDisplay);
if (PR_TRUE==IsRowGroup(rowGroupDisplay->mDisplay))
{
AdjustRowIndices(rowGroupFrame, aRowIndex, 1);
}
}
// Init the row's index and add its cells to the cell map.
aRow->InitChildrenWithIndex(aRowIndex);
return rv;
}
/** sum the columns represented by all nsTableColGroup objects
* if the cell map says there are more columns than this,
* add extra implicit columns to the content tree.
@ -762,7 +836,6 @@ PRInt32 nsTableFrame::AddCellToTable(nsTableCellFrame* aCellFrame,
NS_ASSERTION(nsnull != mCellMap, "bad cellMap");
// XXX: must be called only on first-in-flow!
return mCellMap->AppendCell(aCellFrame, aRowIndex);
}

Просмотреть файл

@ -736,6 +736,15 @@ public:
virtual void EnsureColumns (nsIPresContext& aPresContext,
PRBool& aCreatedColFrames);
// These methods are used to incrementally insert and remove rows
// from the cell map without having to invalidate the entire map.
NS_IMETHOD InsertRowIntoMap(nsTableRowFrame* aRow, PRInt32 aRowIndex);
NS_IMETHOD RemoveRowFromMap(nsTableRowFrame* aRow, PRInt32 aRowIndex);
NS_IMETHOD AdjustRowIndices(nsIFrame* aRowGroup,
PRInt32 aRowIndex,
PRInt32 anAdjustment);
protected:
/** iterates all child frames and creates a new cell map */
NS_IMETHOD ReBuildCellMap();

Просмотреть файл

@ -235,7 +235,7 @@ nsTableRowFrame::RemoveFrame(nsIPresContext& aPresContext,
}
NS_IMETHODIMP
nsTableRowFrame::InitChildren()
nsTableRowFrame::InitChildrenWithIndex(PRInt32 aRowIndex)
{
nsTableFrame* table = nsnull;
nsresult result=NS_OK;
@ -248,8 +248,8 @@ nsTableRowFrame::InitChildren()
if ((NS_OK==result) && (table != nsnull))
{
mInitializedChildren=PR_TRUE;
PRInt32 rowIndex = table->GetNextAvailRowIndex();
SetRowIndex(rowIndex);
SetRowIndex(aRowIndex);
for (nsIFrame* kidFrame = mFrames.FirstChild(); nsnull != kidFrame; kidFrame->GetNextSibling(&kidFrame))
{
const nsStyleDisplay *kidDisplay;
@ -258,9 +258,9 @@ nsTableRowFrame::InitChildren()
{
// add the cell frame to the table's cell map and get its col index
PRInt32 colIndex;
colIndex = table->AddCellToTable((nsTableCellFrame *)kidFrame, rowIndex);
colIndex = table->AddCellToTable((nsTableCellFrame *)kidFrame, aRowIndex);
// what column does this cell belong to?
// this sets the frame's notion of it's column index
// this sets the frame's notion of its column index
((nsTableCellFrame *)kidFrame)->InitCellFrame(colIndex);
}
}
@ -269,6 +269,26 @@ nsTableRowFrame::InitChildren()
return NS_OK;
}
NS_IMETHODIMP
nsTableRowFrame::InitChildren()
{
nsTableFrame* table = nsnull;
nsresult result=NS_OK;
// each child cell can only be added to the table one time.
// for now, we remember globally whether we've added all or none
if (PR_FALSE==mInitializedChildren)
{
result = nsTableFrame::GetTableFrame(this, table);
if ((NS_OK==result) && (table != nsnull))
{
PRInt32 rowIndex = table->GetNextAvailRowIndex();
InitChildrenWithIndex(rowIndex);
}
}
return NS_OK;
}
/**
* Post-reflow hook. This is where the table row does its post-processing
*/

Просмотреть файл

@ -90,6 +90,7 @@ public:
/** Initialization of data */
NS_IMETHOD InitChildren();
NS_IMETHOD InitChildrenWithIndex(PRInt32 aRowIndex);
void ResetInitChildren();