Added support for Ctrl+Shift+mouseclick to select block of cells. Rewrote nsITableLayout::nsGetCellData() to be much more efficient, eliminating a method in the process. Implemented nsTableCellFrame::Get[Previous|Next]CellInColumn for cursor key navigation in tables. r=mjudge,karnaze.

This commit is contained in:
cmanske%netscape.com 2000-03-23 04:24:58 +00:00
Родитель a02a62b0ad
Коммит e7d0908c04
15 изменённых файлов: 312 добавлений и 250 удалений

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

@ -1870,6 +1870,13 @@ nsSelection::NotifySelectionListeners()
// Start of Table Selection methods
static PRBool IsCell(nsIContent *aContent)
{
nsIAtom *tag;
aContent->GetTag(tag);
return (tag != 0 && tag == nsSelection::sCellAtom);
}
nsresult
nsSelection::HandleTableSelection(nsIContent *aParentContent, PRInt32 aContentOffset, PRUint32 aTarget, nsMouseEvent *aMouseEvent)
{
@ -1916,8 +1923,7 @@ nsSelection::HandleTableSelection(nsIContent *aParentContent, PRInt32 aContentOf
printf("HandleTableSelection: Dragged into a new cell\n");
#endif
// Reselect block of cells to new end location
mEndSelectedCell = selectedContent;
return SelectBlockOfCells(mStartSelectedCell, mEndSelectedCell);
return SelectBlockOfCells(mStartSelectedCell, selectedContent);
}
}
else
@ -1935,6 +1941,8 @@ nsSelection::HandleTableSelection(nsIContent *aParentContent, PRInt32 aContentOf
mSelectingTableCells = PR_FALSE;
mStartSelectedCell = nsnull;
mEndSelectedCell = nsnull;
#ifdef DEBUG_cmanske
#ifdef DEBUG_TABLE
printf("HandleTableSelection: Selecting Table\n");
{
@ -1949,10 +1957,9 @@ printf("Table frame orgin: x=%d, y=%d\n", rect1.x, rect1.y);
mDomSelections[SELECTION_NORMAL]->GetFrameToRootViewOffset(frame, &rect2.x, &rect2.y);
printf("Translated frame orgin: x=%d, y=%d\n", rect2.x, rect2.y);
printf("Mouse was clicked at: x=%d, y=%d\n", aMouseEvent->point.x, aMouseEvent->point.y);
}
}
#endif
#endif
// Select the table
mDomSelections[SELECTION_NORMAL]->ClearSelection();
@ -1965,6 +1972,12 @@ printf("Mouse was clicked at: x=%d, y=%d\n", aMouseEvent->point.x, aMouseEvent->
result = mDomSelections[SELECTION_NORMAL]->GetRangeCount(&rangeCount);
if (NS_FAILED(result)) return result;
if (rangeCount > 0 && aMouseEvent->isShift && selectedContent != mStartSelectedCell)
{
// If Shift is down as well, do a block selection
return SelectBlockOfCells(mStartSelectedCell, selectedContent);
}
nsCOMPtr<nsIDOMNode> previousCellParent;
nsCOMPtr<nsIDOMRange> range;
PRInt32 offset;
@ -1985,13 +1998,12 @@ printf("Mouse was clicked at: x=%d, y=%d\n", aMouseEvent->point.x, aMouseEvent->
nsCOMPtr<nsIContent> childContent;
result = parentContent->ChildAt(offset, *getter_AddRefs(childContent));
if (NS_FAILED(result)) return result;
if (childContent)
if (childContent && IsCell(childContent))
{
nsIAtom *tag;
childContent->GetTag(tag);
if (tag && tag == nsSelection::sCellAtom)
previousCellParent = parent;
}
// We're done if we didn't find parent of a previously-selected cell
if (!previousCellParent) break;
@ -2056,14 +2068,42 @@ printf("Mouse was clicked at: x=%d, y=%d\n", aMouseEvent->point.x, aMouseEvent->
nsresult
nsSelection::SelectBlockOfCells(nsIContent *aStartCell, nsIContent *aEndCell)
{
if (!aStartCell || !aEndCell) return NS_ERROR_NULL_POINTER;
if (!aEndCell) return NS_ERROR_NULL_POINTER;
mEndSelectedCell = aEndCell;
nsresult result = NS_OK;
if (!aStartCell)
{
// User unselected the origianl start cell
// Try to use the first cell in existing selection
nsCOMPtr<nsIDOMRange> range;
PRInt32 offset;
result = mDomSelections[SELECTION_NORMAL]->GetRangeAt(0, getter_AddRefs(range));
if (NS_FAILED(result)) return result;
if (!range) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNode> parent;
result = range->GetStartParent(getter_AddRefs(parent));
if (NS_FAILED(result)) return result;
if (!parent) return NS_ERROR_NULL_POINTER;
range->GetStartOffset(&offset);
// Be sure previous selection is a table cell
nsCOMPtr<nsIContent> parentContent = do_QueryInterface(parent);
nsCOMPtr<nsIContent> childContent;
result = parentContent->ChildAt(offset, *getter_AddRefs(childContent));
if (NS_FAILED(result)) return result;
if (!childContent) return NS_ERROR_NULL_POINTER;
// We shouldn't be here if selected child isn't a cell!
if (!IsCell(childContent)) return NS_ERROR_FAILURE;
aStartCell = childContent;
}
// Get starting and ending cells' location in the cellmap
PRInt32 startRowIndex, startColIndex, endRowIndex, endColIndex;
// Get starting and ending cells' location in the cellmap
nsresult result = GetCellIndexes(aStartCell, startRowIndex, startColIndex);
result = GetCellIndexes(aStartCell, startRowIndex, startColIndex);
if(NS_FAILED(result)) return result;
result = GetCellIndexes(aEndCell, endRowIndex, endColIndex);
if(NS_FAILED(result)) return result;

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

@ -1870,6 +1870,13 @@ nsSelection::NotifySelectionListeners()
// Start of Table Selection methods
static PRBool IsCell(nsIContent *aContent)
{
nsIAtom *tag;
aContent->GetTag(tag);
return (tag != 0 && tag == nsSelection::sCellAtom);
}
nsresult
nsSelection::HandleTableSelection(nsIContent *aParentContent, PRInt32 aContentOffset, PRUint32 aTarget, nsMouseEvent *aMouseEvent)
{
@ -1916,8 +1923,7 @@ nsSelection::HandleTableSelection(nsIContent *aParentContent, PRInt32 aContentOf
printf("HandleTableSelection: Dragged into a new cell\n");
#endif
// Reselect block of cells to new end location
mEndSelectedCell = selectedContent;
return SelectBlockOfCells(mStartSelectedCell, mEndSelectedCell);
return SelectBlockOfCells(mStartSelectedCell, selectedContent);
}
}
else
@ -1935,6 +1941,8 @@ nsSelection::HandleTableSelection(nsIContent *aParentContent, PRInt32 aContentOf
mSelectingTableCells = PR_FALSE;
mStartSelectedCell = nsnull;
mEndSelectedCell = nsnull;
#ifdef DEBUG_cmanske
#ifdef DEBUG_TABLE
printf("HandleTableSelection: Selecting Table\n");
{
@ -1949,10 +1957,9 @@ printf("Table frame orgin: x=%d, y=%d\n", rect1.x, rect1.y);
mDomSelections[SELECTION_NORMAL]->GetFrameToRootViewOffset(frame, &rect2.x, &rect2.y);
printf("Translated frame orgin: x=%d, y=%d\n", rect2.x, rect2.y);
printf("Mouse was clicked at: x=%d, y=%d\n", aMouseEvent->point.x, aMouseEvent->point.y);
}
}
#endif
#endif
// Select the table
mDomSelections[SELECTION_NORMAL]->ClearSelection();
@ -1965,6 +1972,12 @@ printf("Mouse was clicked at: x=%d, y=%d\n", aMouseEvent->point.x, aMouseEvent->
result = mDomSelections[SELECTION_NORMAL]->GetRangeCount(&rangeCount);
if (NS_FAILED(result)) return result;
if (rangeCount > 0 && aMouseEvent->isShift && selectedContent != mStartSelectedCell)
{
// If Shift is down as well, do a block selection
return SelectBlockOfCells(mStartSelectedCell, selectedContent);
}
nsCOMPtr<nsIDOMNode> previousCellParent;
nsCOMPtr<nsIDOMRange> range;
PRInt32 offset;
@ -1985,13 +1998,12 @@ printf("Mouse was clicked at: x=%d, y=%d\n", aMouseEvent->point.x, aMouseEvent->
nsCOMPtr<nsIContent> childContent;
result = parentContent->ChildAt(offset, *getter_AddRefs(childContent));
if (NS_FAILED(result)) return result;
if (childContent)
if (childContent && IsCell(childContent))
{
nsIAtom *tag;
childContent->GetTag(tag);
if (tag && tag == nsSelection::sCellAtom)
previousCellParent = parent;
}
// We're done if we didn't find parent of a previously-selected cell
if (!previousCellParent) break;
@ -2056,14 +2068,42 @@ printf("Mouse was clicked at: x=%d, y=%d\n", aMouseEvent->point.x, aMouseEvent->
nsresult
nsSelection::SelectBlockOfCells(nsIContent *aStartCell, nsIContent *aEndCell)
{
if (!aStartCell || !aEndCell) return NS_ERROR_NULL_POINTER;
if (!aEndCell) return NS_ERROR_NULL_POINTER;
mEndSelectedCell = aEndCell;
nsresult result = NS_OK;
if (!aStartCell)
{
// User unselected the origianl start cell
// Try to use the first cell in existing selection
nsCOMPtr<nsIDOMRange> range;
PRInt32 offset;
result = mDomSelections[SELECTION_NORMAL]->GetRangeAt(0, getter_AddRefs(range));
if (NS_FAILED(result)) return result;
if (!range) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNode> parent;
result = range->GetStartParent(getter_AddRefs(parent));
if (NS_FAILED(result)) return result;
if (!parent) return NS_ERROR_NULL_POINTER;
range->GetStartOffset(&offset);
// Be sure previous selection is a table cell
nsCOMPtr<nsIContent> parentContent = do_QueryInterface(parent);
nsCOMPtr<nsIContent> childContent;
result = parentContent->ChildAt(offset, *getter_AddRefs(childContent));
if (NS_FAILED(result)) return result;
if (!childContent) return NS_ERROR_NULL_POINTER;
// We shouldn't be here if selected child isn't a cell!
if (!IsCell(childContent)) return NS_ERROR_FAILURE;
aStartCell = childContent;
}
// Get starting and ending cells' location in the cellmap
PRInt32 startRowIndex, startColIndex, endRowIndex, endColIndex;
// Get starting and ending cells' location in the cellmap
nsresult result = GetCellIndexes(aStartCell, startRowIndex, startColIndex);
result = GetCellIndexes(aStartCell, startRowIndex, startColIndex);
if(NS_FAILED(result)) return result;
result = GetCellIndexes(aEndCell, endRowIndex, endColIndex);
if(NS_FAILED(result)) return result;

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

@ -1870,6 +1870,13 @@ nsSelection::NotifySelectionListeners()
// Start of Table Selection methods
static PRBool IsCell(nsIContent *aContent)
{
nsIAtom *tag;
aContent->GetTag(tag);
return (tag != 0 && tag == nsSelection::sCellAtom);
}
nsresult
nsSelection::HandleTableSelection(nsIContent *aParentContent, PRInt32 aContentOffset, PRUint32 aTarget, nsMouseEvent *aMouseEvent)
{
@ -1916,8 +1923,7 @@ nsSelection::HandleTableSelection(nsIContent *aParentContent, PRInt32 aContentOf
printf("HandleTableSelection: Dragged into a new cell\n");
#endif
// Reselect block of cells to new end location
mEndSelectedCell = selectedContent;
return SelectBlockOfCells(mStartSelectedCell, mEndSelectedCell);
return SelectBlockOfCells(mStartSelectedCell, selectedContent);
}
}
else
@ -1935,6 +1941,8 @@ nsSelection::HandleTableSelection(nsIContent *aParentContent, PRInt32 aContentOf
mSelectingTableCells = PR_FALSE;
mStartSelectedCell = nsnull;
mEndSelectedCell = nsnull;
#ifdef DEBUG_cmanske
#ifdef DEBUG_TABLE
printf("HandleTableSelection: Selecting Table\n");
{
@ -1949,10 +1957,9 @@ printf("Table frame orgin: x=%d, y=%d\n", rect1.x, rect1.y);
mDomSelections[SELECTION_NORMAL]->GetFrameToRootViewOffset(frame, &rect2.x, &rect2.y);
printf("Translated frame orgin: x=%d, y=%d\n", rect2.x, rect2.y);
printf("Mouse was clicked at: x=%d, y=%d\n", aMouseEvent->point.x, aMouseEvent->point.y);
}
}
#endif
#endif
// Select the table
mDomSelections[SELECTION_NORMAL]->ClearSelection();
@ -1965,6 +1972,12 @@ printf("Mouse was clicked at: x=%d, y=%d\n", aMouseEvent->point.x, aMouseEvent->
result = mDomSelections[SELECTION_NORMAL]->GetRangeCount(&rangeCount);
if (NS_FAILED(result)) return result;
if (rangeCount > 0 && aMouseEvent->isShift && selectedContent != mStartSelectedCell)
{
// If Shift is down as well, do a block selection
return SelectBlockOfCells(mStartSelectedCell, selectedContent);
}
nsCOMPtr<nsIDOMNode> previousCellParent;
nsCOMPtr<nsIDOMRange> range;
PRInt32 offset;
@ -1985,13 +1998,12 @@ printf("Mouse was clicked at: x=%d, y=%d\n", aMouseEvent->point.x, aMouseEvent->
nsCOMPtr<nsIContent> childContent;
result = parentContent->ChildAt(offset, *getter_AddRefs(childContent));
if (NS_FAILED(result)) return result;
if (childContent)
if (childContent && IsCell(childContent))
{
nsIAtom *tag;
childContent->GetTag(tag);
if (tag && tag == nsSelection::sCellAtom)
previousCellParent = parent;
}
// We're done if we didn't find parent of a previously-selected cell
if (!previousCellParent) break;
@ -2056,14 +2068,42 @@ printf("Mouse was clicked at: x=%d, y=%d\n", aMouseEvent->point.x, aMouseEvent->
nsresult
nsSelection::SelectBlockOfCells(nsIContent *aStartCell, nsIContent *aEndCell)
{
if (!aStartCell || !aEndCell) return NS_ERROR_NULL_POINTER;
if (!aEndCell) return NS_ERROR_NULL_POINTER;
mEndSelectedCell = aEndCell;
nsresult result = NS_OK;
if (!aStartCell)
{
// User unselected the origianl start cell
// Try to use the first cell in existing selection
nsCOMPtr<nsIDOMRange> range;
PRInt32 offset;
result = mDomSelections[SELECTION_NORMAL]->GetRangeAt(0, getter_AddRefs(range));
if (NS_FAILED(result)) return result;
if (!range) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNode> parent;
result = range->GetStartParent(getter_AddRefs(parent));
if (NS_FAILED(result)) return result;
if (!parent) return NS_ERROR_NULL_POINTER;
range->GetStartOffset(&offset);
// Be sure previous selection is a table cell
nsCOMPtr<nsIContent> parentContent = do_QueryInterface(parent);
nsCOMPtr<nsIContent> childContent;
result = parentContent->ChildAt(offset, *getter_AddRefs(childContent));
if (NS_FAILED(result)) return result;
if (!childContent) return NS_ERROR_NULL_POINTER;
// We shouldn't be here if selected child isn't a cell!
if (!IsCell(childContent)) return NS_ERROR_FAILURE;
aStartCell = childContent;
}
// Get starting and ending cells' location in the cellmap
PRInt32 startRowIndex, startColIndex, endRowIndex, endColIndex;
// Get starting and ending cells' location in the cellmap
nsresult result = GetCellIndexes(aStartCell, startRowIndex, startColIndex);
result = GetCellIndexes(aStartCell, startRowIndex, startColIndex);
if(NS_FAILED(result)) return result;
result = GetCellIndexes(aEndCell, endRowIndex, endColIndex);
if(NS_FAILED(result)) return result;

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

@ -49,6 +49,16 @@ public:
/** return the mapped cell's column index (starting at 0 for the first column) */
virtual nsresult GetColIndex(PRInt32 &aColIndex) const = 0;
/** return the previous cell having the same column index as current cell
* returns null if no cell is present (but nsresult is still NS_OK)
*/
NS_IMETHOD GetPreviousCellInColumn(nsITableCellLayout **aCellLayout)=0;
/** return the next cell having the same column index
* returns null if no cell is present (but nsresult is still NS_OK)
*/
NS_IMETHOD GetNextCellInColumn(nsITableCellLayout **aCellLayout)=0;
};

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

@ -423,22 +423,6 @@ nsTableCellMap::Dump() const
}
#endif
nsTableCellFrame*
nsTableCellMap::GetCellFrameOriginatingAt(PRInt32 aRowIndex,
PRInt32 aColIndex)
{
PRInt32 rowIndex = aRowIndex;
nsCellMap* cellMap = mFirstMap;
while (cellMap) {
if (cellMap->GetRowCount() > rowIndex) {
return cellMap->GetCellFrameOriginatingAt(*this, rowIndex, aColIndex);
}
rowIndex -= cellMap->GetRowCount();
cellMap = cellMap->GetNextSibling();
}
return nsnull;
}
nsTableCellFrame*
nsTableCellMap::GetCellInfoAt(PRInt32 aRowIndex,
PRInt32 aColIndex,
@ -1742,18 +1726,6 @@ void nsCellMap::SetMapCellAt(nsTableCellMap& aMap,
else NS_ASSERTION(PR_FALSE, "SetMapCellAt called with row index > num rows");
}
nsTableCellFrame*
nsCellMap::GetCellFrameOriginatingAt(nsTableCellMap& aMap,
PRInt32 aRowX,
PRInt32 aColX)
{
CellData* data = GetCellAt(aMap, aRowX, aColX);
if (data && data->IsOrig()) {
return data->GetCellFrame();
}
return nsnull;
}
nsTableCellFrame*
nsCellMap::GetCellInfoAt(nsTableCellMap& aMap,
PRInt32 aRowX,

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

@ -108,10 +108,6 @@ public:
/** return the actual number of rows in the table represented by this CellMap */
PRInt32 GetRowCount() const;
// temporary until nsTableFrame::GetCellData uses GetCellFrameAt
nsTableCellFrame* GetCellFrameOriginatingAt(PRInt32 aRowX,
PRInt32 aColX);
nsTableCellFrame* GetCellInfoAt(PRInt32 aRowX,
PRInt32 aColX,
PRBool* aOriginates = nsnull,
@ -221,11 +217,6 @@ public:
/** return the actual number of rows in the table represented by this CellMap */
PRInt32 GetRowCount() const;
// temporary until nsTableFrame::GetCellData uses GetCellFrameAt
nsTableCellFrame* GetCellFrameOriginatingAt(nsTableCellMap& aMap,
PRInt32 aRowX,
PRInt32 aColX);
nsTableCellFrame* GetCellInfoAt(nsTableCellMap& aMap,
PRInt32 aRowX,
PRInt32 aColX,

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

@ -1057,6 +1057,54 @@ nsTableCellFrame::GetCellIndexes(PRInt32 &aRowIndex, PRInt32 &aColIndex)
return NS_OK;
}
NS_IMETHODIMP
nsTableCellFrame::GetPreviousCellInColumn(nsITableCellLayout **aCellLayout)
{
if (!aCellLayout) return NS_ERROR_NULL_POINTER;
*aCellLayout = nsnull;
nsTableFrame* tableFrame = nsnull;
nsresult rv = nsTableFrame::GetTableFrame(this, tableFrame);
if (NS_FAILED(rv)) return rv;
if (!tableFrame) return NS_ERROR_FAILURE;
// Get current cell location
PRInt32 rowIndex, colIndex;
GetCellIndexes(rowIndex, colIndex);
if (colIndex > 0)
{
// Get the cellframe at previous colIndex
nsTableCellFrame *cellFrame = tableFrame->GetCellFrameAt(rowIndex, colIndex-1);
if (cellFrame)
cellFrame->QueryInterface(NS_GET_IID(nsITableCellLayout), (void **)aCellLayout);
}
return NS_OK;
}
NS_IMETHODIMP
nsTableCellFrame::GetNextCellInColumn(nsITableCellLayout **aCellLayout)
{
if (!aCellLayout) return NS_ERROR_NULL_POINTER;
*aCellLayout = nsnull;
nsTableFrame* tableFrame = nsnull;
nsresult rv = nsTableFrame::GetTableFrame(this, tableFrame);
if (NS_FAILED(rv)) return rv;
if (!tableFrame) return NS_ERROR_FAILURE;
// Get current cell location
PRInt32 rowIndex, colIndex;
GetCellIndexes(rowIndex, colIndex);
// Get the cellframe at next colIndex
nsTableCellFrame *cellFrame = tableFrame->GetCellFrameAt(rowIndex, colIndex+1);
if (cellFrame)
cellFrame->QueryInterface(NS_GET_IID(nsITableCellLayout), (void **)aCellLayout);
return NS_OK;
}
nsresult
NS_NewTableCellFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
{

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

@ -167,6 +167,18 @@ public:
/** return the mapped cell's row index (starting at 0 for the first row) */
virtual nsresult GetRowIndex(PRInt32 &aRowIndex) const;
/** return the previous cell having the same column index as current cell
* returns null if no cell is present (but nsresult is still NS_OK)
* (When used within layout, you can QI aCellLayout to get an nsIFrame*)
*/
NS_IMETHOD GetPreviousCellInColumn(nsITableCellLayout **aCellLayout);
/** return the next cell having the same column index
* returns null if no cell is present (but nsresult is still NS_OK)
* (When used within layout, you can QI aCellLayout to get an nsIFrame*)
*/
NS_IMETHOD GetNextCellInColumn(nsITableCellLayout **aCellLayout);
/**
* return the cell's specified col span. this is what was specified in the
* content model or in the style info, and is always >= 1.

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

@ -1313,6 +1313,10 @@ nsTableFrame::SetSelected(nsIPresContext* aPresContext,
}
}
#endif
// Must call base class to set mSelected state and trigger repaint of frame
// Note that in current version, aRange and aSpread are ignored,
// only this frame is considered
nsFrame::SetSelected(aPresContext, aRange, aSelected, aSpread);
return NS_OK;//return nsFrame::SetSelected(aRange,aSelected,eSpreadNone);
}
@ -4554,8 +4558,6 @@ nsTableFrame::GetCellDataAt(PRInt32 aRowIndex,
PRInt32& aActualColSpan,
PRBool& aIsSelected)
{
nsresult result;
nsTableCellMap* cellMap = GetCellMap();
// Initialize out params
aCell = nsnull;
aStartRowIndex = 0;
@ -4564,79 +4566,16 @@ nsTableFrame::GetCellDataAt(PRInt32 aRowIndex,
aColSpan = 0;
aIsSelected = PR_FALSE;
nsTableCellMap* cellMap = GetCellMap();
if (!cellMap) { return NS_ERROR_NOT_INITIALIZED;}
// Return a special error value if an index is out of bounds
// This will pass the NS_SUCCEEDED() test
// Thus we can iterate indexes to get all cells in a row or col
// and stop when aCell is returned null.
PRInt32 rowCount = cellMap->GetRowCount();
PRInt32 colCount = cellMap->GetColCount();
PRBool originates;
PRInt32 colSpan; // Is this the "effective" or "html" value?
if (aRowIndex >= rowCount || aColIndex >= colCount)
{
return NS_TABLELAYOUT_CELL_NOT_FOUND;
}
nsTableCellFrame *cellFrame = cellMap->GetCellFrameOriginatingAt(aRowIndex, aColIndex);
if (!cellFrame)
{
PRInt32 rowSpan, colSpan;
PRInt32 row = aStartRowIndex;
PRInt32 col = aStartColIndex;
nsTableCellFrame *cellFrame = cellMap->GetCellInfoAt(aRowIndex, aColIndex, &originates, &colSpan);
if (!cellFrame) return NS_TABLELAYOUT_CELL_NOT_FOUND;
// We didn't find a cell at requested location,
// most probably because of ROWSPAN and/or COLSPAN > 1
// Find the cell that extends into the location we requested,
// starting at the most likely indexes supplied by the caller
// in aStartRowIndex and aStartColIndex;
cellFrame = cellMap->GetCellFrameOriginatingAt(row, col);
if (cellFrame)
{
//The nsTableFrame version returns actual value
// when nsTableCellFrame's return values are "HTML" (i.e., may = 0)
rowSpan = GetEffectiveRowSpan(*cellFrame);
colSpan = GetEffectiveColSpan(*cellFrame);
// Check if this extends into the location we want
if( aRowIndex >= row && aRowIndex < row+rowSpan &&
aColIndex >= col && aColIndex < col+colSpan)
{
CELL_FOUND:
aStartRowIndex = row;
aStartColIndex = col;
aActualRowSpan = rowSpan;
aActualColSpan = colSpan;
aRowSpan = cellFrame->GetRowSpan();
aColSpan = cellFrame->GetColSpan();
// I know jumps aren't cool, but it's efficient!
goto TEST_IF_SELECTED;
} else {
// Suggested indexes didn't work,
// Scan through entire table to find the spanned cell
for (row = 0; row < rowCount; row++ )
{
for (col = 0; col < colCount; col++)
{
cellFrame = cellMap->GetCellFrameOriginatingAt(row, col);
if (cellFrame)
{
rowSpan = GetEffectiveRowSpan(*cellFrame);
colSpan = GetEffectiveColSpan(*cellFrame);
if( aRowIndex >= row && aRowIndex < row+rowSpan &&
aColIndex >= col && aColIndex < col+colSpan)
{
goto CELL_FOUND;
}
}
}
col = 0;
}
}
return NS_TABLELAYOUT_CELL_NOT_FOUND; // We didn't find a cell
}
}
result = cellFrame->GetRowIndex(aStartRowIndex);
nsresult result= cellFrame->GetRowIndex(aStartRowIndex);
if (NS_FAILED(result)) return result;
result = cellFrame->GetColIndex(aStartColIndex);
if (NS_FAILED(result)) return result;
@ -4648,7 +4587,6 @@ CELL_FOUND:
result = cellFrame->GetSelected(&aIsSelected);
if (NS_FAILED(result)) return result;
TEST_IF_SELECTED:
// do this last, because it addrefs,
// and we don't want the caller leaking it on error
nsCOMPtr<nsIContent>content;

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

@ -423,22 +423,6 @@ nsTableCellMap::Dump() const
}
#endif
nsTableCellFrame*
nsTableCellMap::GetCellFrameOriginatingAt(PRInt32 aRowIndex,
PRInt32 aColIndex)
{
PRInt32 rowIndex = aRowIndex;
nsCellMap* cellMap = mFirstMap;
while (cellMap) {
if (cellMap->GetRowCount() > rowIndex) {
return cellMap->GetCellFrameOriginatingAt(*this, rowIndex, aColIndex);
}
rowIndex -= cellMap->GetRowCount();
cellMap = cellMap->GetNextSibling();
}
return nsnull;
}
nsTableCellFrame*
nsTableCellMap::GetCellInfoAt(PRInt32 aRowIndex,
PRInt32 aColIndex,
@ -1742,18 +1726,6 @@ void nsCellMap::SetMapCellAt(nsTableCellMap& aMap,
else NS_ASSERTION(PR_FALSE, "SetMapCellAt called with row index > num rows");
}
nsTableCellFrame*
nsCellMap::GetCellFrameOriginatingAt(nsTableCellMap& aMap,
PRInt32 aRowX,
PRInt32 aColX)
{
CellData* data = GetCellAt(aMap, aRowX, aColX);
if (data && data->IsOrig()) {
return data->GetCellFrame();
}
return nsnull;
}
nsTableCellFrame*
nsCellMap::GetCellInfoAt(nsTableCellMap& aMap,
PRInt32 aRowX,

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

@ -108,10 +108,6 @@ public:
/** return the actual number of rows in the table represented by this CellMap */
PRInt32 GetRowCount() const;
// temporary until nsTableFrame::GetCellData uses GetCellFrameAt
nsTableCellFrame* GetCellFrameOriginatingAt(PRInt32 aRowX,
PRInt32 aColX);
nsTableCellFrame* GetCellInfoAt(PRInt32 aRowX,
PRInt32 aColX,
PRBool* aOriginates = nsnull,
@ -221,11 +217,6 @@ public:
/** return the actual number of rows in the table represented by this CellMap */
PRInt32 GetRowCount() const;
// temporary until nsTableFrame::GetCellData uses GetCellFrameAt
nsTableCellFrame* GetCellFrameOriginatingAt(nsTableCellMap& aMap,
PRInt32 aRowX,
PRInt32 aColX);
nsTableCellFrame* GetCellInfoAt(nsTableCellMap& aMap,
PRInt32 aRowX,
PRInt32 aColX,

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

@ -49,6 +49,16 @@ public:
/** return the mapped cell's column index (starting at 0 for the first column) */
virtual nsresult GetColIndex(PRInt32 &aColIndex) const = 0;
/** return the previous cell having the same column index as current cell
* returns null if no cell is present (but nsresult is still NS_OK)
*/
NS_IMETHOD GetPreviousCellInColumn(nsITableCellLayout **aCellLayout)=0;
/** return the next cell having the same column index
* returns null if no cell is present (but nsresult is still NS_OK)
*/
NS_IMETHOD GetNextCellInColumn(nsITableCellLayout **aCellLayout)=0;
};

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

@ -1057,6 +1057,54 @@ nsTableCellFrame::GetCellIndexes(PRInt32 &aRowIndex, PRInt32 &aColIndex)
return NS_OK;
}
NS_IMETHODIMP
nsTableCellFrame::GetPreviousCellInColumn(nsITableCellLayout **aCellLayout)
{
if (!aCellLayout) return NS_ERROR_NULL_POINTER;
*aCellLayout = nsnull;
nsTableFrame* tableFrame = nsnull;
nsresult rv = nsTableFrame::GetTableFrame(this, tableFrame);
if (NS_FAILED(rv)) return rv;
if (!tableFrame) return NS_ERROR_FAILURE;
// Get current cell location
PRInt32 rowIndex, colIndex;
GetCellIndexes(rowIndex, colIndex);
if (colIndex > 0)
{
// Get the cellframe at previous colIndex
nsTableCellFrame *cellFrame = tableFrame->GetCellFrameAt(rowIndex, colIndex-1);
if (cellFrame)
cellFrame->QueryInterface(NS_GET_IID(nsITableCellLayout), (void **)aCellLayout);
}
return NS_OK;
}
NS_IMETHODIMP
nsTableCellFrame::GetNextCellInColumn(nsITableCellLayout **aCellLayout)
{
if (!aCellLayout) return NS_ERROR_NULL_POINTER;
*aCellLayout = nsnull;
nsTableFrame* tableFrame = nsnull;
nsresult rv = nsTableFrame::GetTableFrame(this, tableFrame);
if (NS_FAILED(rv)) return rv;
if (!tableFrame) return NS_ERROR_FAILURE;
// Get current cell location
PRInt32 rowIndex, colIndex;
GetCellIndexes(rowIndex, colIndex);
// Get the cellframe at next colIndex
nsTableCellFrame *cellFrame = tableFrame->GetCellFrameAt(rowIndex, colIndex+1);
if (cellFrame)
cellFrame->QueryInterface(NS_GET_IID(nsITableCellLayout), (void **)aCellLayout);
return NS_OK;
}
nsresult
NS_NewTableCellFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
{

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

@ -167,6 +167,18 @@ public:
/** return the mapped cell's row index (starting at 0 for the first row) */
virtual nsresult GetRowIndex(PRInt32 &aRowIndex) const;
/** return the previous cell having the same column index as current cell
* returns null if no cell is present (but nsresult is still NS_OK)
* (When used within layout, you can QI aCellLayout to get an nsIFrame*)
*/
NS_IMETHOD GetPreviousCellInColumn(nsITableCellLayout **aCellLayout);
/** return the next cell having the same column index
* returns null if no cell is present (but nsresult is still NS_OK)
* (When used within layout, you can QI aCellLayout to get an nsIFrame*)
*/
NS_IMETHOD GetNextCellInColumn(nsITableCellLayout **aCellLayout);
/**
* return the cell's specified col span. this is what was specified in the
* content model or in the style info, and is always >= 1.

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

@ -1313,6 +1313,10 @@ nsTableFrame::SetSelected(nsIPresContext* aPresContext,
}
}
#endif
// Must call base class to set mSelected state and trigger repaint of frame
// Note that in current version, aRange and aSpread are ignored,
// only this frame is considered
nsFrame::SetSelected(aPresContext, aRange, aSelected, aSpread);
return NS_OK;//return nsFrame::SetSelected(aRange,aSelected,eSpreadNone);
}
@ -4554,8 +4558,6 @@ nsTableFrame::GetCellDataAt(PRInt32 aRowIndex,
PRInt32& aActualColSpan,
PRBool& aIsSelected)
{
nsresult result;
nsTableCellMap* cellMap = GetCellMap();
// Initialize out params
aCell = nsnull;
aStartRowIndex = 0;
@ -4564,79 +4566,16 @@ nsTableFrame::GetCellDataAt(PRInt32 aRowIndex,
aColSpan = 0;
aIsSelected = PR_FALSE;
nsTableCellMap* cellMap = GetCellMap();
if (!cellMap) { return NS_ERROR_NOT_INITIALIZED;}
// Return a special error value if an index is out of bounds
// This will pass the NS_SUCCEEDED() test
// Thus we can iterate indexes to get all cells in a row or col
// and stop when aCell is returned null.
PRInt32 rowCount = cellMap->GetRowCount();
PRInt32 colCount = cellMap->GetColCount();
PRBool originates;
PRInt32 colSpan; // Is this the "effective" or "html" value?
if (aRowIndex >= rowCount || aColIndex >= colCount)
{
return NS_TABLELAYOUT_CELL_NOT_FOUND;
}
nsTableCellFrame *cellFrame = cellMap->GetCellFrameOriginatingAt(aRowIndex, aColIndex);
if (!cellFrame)
{
PRInt32 rowSpan, colSpan;
PRInt32 row = aStartRowIndex;
PRInt32 col = aStartColIndex;
nsTableCellFrame *cellFrame = cellMap->GetCellInfoAt(aRowIndex, aColIndex, &originates, &colSpan);
if (!cellFrame) return NS_TABLELAYOUT_CELL_NOT_FOUND;
// We didn't find a cell at requested location,
// most probably because of ROWSPAN and/or COLSPAN > 1
// Find the cell that extends into the location we requested,
// starting at the most likely indexes supplied by the caller
// in aStartRowIndex and aStartColIndex;
cellFrame = cellMap->GetCellFrameOriginatingAt(row, col);
if (cellFrame)
{
//The nsTableFrame version returns actual value
// when nsTableCellFrame's return values are "HTML" (i.e., may = 0)
rowSpan = GetEffectiveRowSpan(*cellFrame);
colSpan = GetEffectiveColSpan(*cellFrame);
// Check if this extends into the location we want
if( aRowIndex >= row && aRowIndex < row+rowSpan &&
aColIndex >= col && aColIndex < col+colSpan)
{
CELL_FOUND:
aStartRowIndex = row;
aStartColIndex = col;
aActualRowSpan = rowSpan;
aActualColSpan = colSpan;
aRowSpan = cellFrame->GetRowSpan();
aColSpan = cellFrame->GetColSpan();
// I know jumps aren't cool, but it's efficient!
goto TEST_IF_SELECTED;
} else {
// Suggested indexes didn't work,
// Scan through entire table to find the spanned cell
for (row = 0; row < rowCount; row++ )
{
for (col = 0; col < colCount; col++)
{
cellFrame = cellMap->GetCellFrameOriginatingAt(row, col);
if (cellFrame)
{
rowSpan = GetEffectiveRowSpan(*cellFrame);
colSpan = GetEffectiveColSpan(*cellFrame);
if( aRowIndex >= row && aRowIndex < row+rowSpan &&
aColIndex >= col && aColIndex < col+colSpan)
{
goto CELL_FOUND;
}
}
}
col = 0;
}
}
return NS_TABLELAYOUT_CELL_NOT_FOUND; // We didn't find a cell
}
}
result = cellFrame->GetRowIndex(aStartRowIndex);
nsresult result= cellFrame->GetRowIndex(aStartRowIndex);
if (NS_FAILED(result)) return result;
result = cellFrame->GetColIndex(aStartColIndex);
if (NS_FAILED(result)) return result;
@ -4648,7 +4587,6 @@ CELL_FOUND:
result = cellFrame->GetSelected(&aIsSelected);
if (NS_FAILED(result)) return result;
TEST_IF_SELECTED:
// do this last, because it addrefs,
// and we don't want the caller leaking it on error
nsCOMPtr<nsIContent>content;