Removed tableselection listener -- all selection now done in layout. Also added more table selection support for row, col from menu. r=mjudge

This commit is contained in:
cmanske%netscape.com 2000-03-16 23:45:41 +00:00
Родитель 2824049212
Коммит 235ce19d67
21 изменённых файлов: 848 добавлений и 136 удалений

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

@ -56,9 +56,3 @@ NS_IMETHODIMP TypeInState::NotifySelectionChanged()
Reset();
return NS_OK;
};
NS_IMETHODIMP TypeInState::TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset)
{
//stub
return NS_OK;
}

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

@ -38,7 +38,6 @@ public:
virtual ~TypeInState();
NS_IMETHOD NotifySelectionChanged();
NS_IMETHOD TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset);
void GetEnumForName(nsIAtom *aPropName, PRUint32 &aEnum);
void GetPropertyIsString(PRUint32 aProp, PRUint32 &aIsString);

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

@ -211,7 +211,7 @@ nsEditorShell::nsEditorShell()
nsEditorShell::~nsEditorShell()
{
NS_IF_RELEASE(mStateMaintainer);
// the only other references we hold are in nsCOMPtrs, so they'll take
// care of themselves.
}
@ -302,7 +302,6 @@ nsEditorShell::PrepareDocumentForEditing(nsIURI *aUrl)
NS_IF_RELEASE(mStateMaintainer);
}
}
mEditorType = eUninitializedEditorType;
mEditor = 0; // clear out the nsCOMPtr
@ -365,8 +364,8 @@ nsEditorShell::PrepareDocumentForEditing(nsIURI *aUrl)
{
txnMgr->AddListener(NS_STATIC_CAST(nsITransactionListener*, mStateMaintainer));
}
if (NS_SUCCEEDED(rv) && mContentWindow)
{
nsCOMPtr<nsIController> controller;
@ -3149,6 +3148,26 @@ nsEditorShell::SelectTableCell()
return result;
}
NS_IMETHODIMP
nsEditorShell::SelectBlockOfCells(nsIDOMElement *aStartCell, nsIDOMElement *aEndCell)
{
nsresult result = NS_NOINTERFACE;
switch (mEditorType)
{
case eHTMLTextEditorType:
{
nsCOMPtr<nsITableEditor> tableEditor = do_QueryInterface(mEditor);
if (tableEditor)
result = tableEditor->SelectBlockOfCells(aStartCell, aEndCell);
}
break;
default:
result = NS_ERROR_NOT_IMPLEMENTED;
}
return result;
}
NS_IMETHODIMP
nsEditorShell::SelectTableRow()
{

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

@ -138,7 +138,7 @@ class nsEditorShell : public nsIEditorShell,
nsCOMPtr<nsISupports> mSearchContext; // context used for search and replace. Owned by the appshell.
nsInterfaceState* mStateMaintainer; // we hold the owning ref to this.
nsInterfaceState* mStateMaintainer; // we hold the owning ref to this.
PRInt32 mWrapColumn; // can't actually set this 'til the editor is created, so we may have to hold on to it for a while

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

@ -217,6 +217,7 @@ nsHTMLEditor::nsHTMLEditor()
, mRules(nsnull)
, mIsComposing(PR_FALSE)
, mMaxTextLength(-1)
, mSelectingTableCells(PR_FALSE)
{
// Done in nsEditor
// NS_INIT_REFCNT();

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

@ -184,6 +184,7 @@ public:
NS_IMETHOD DeleteTableColumn(PRInt32 aNumber);
NS_IMETHOD DeleteTableRow(PRInt32 aNumber);
NS_IMETHOD SelectTableCell();
NS_IMETHOD SelectBlockOfCells(nsIDOMElement *aStartCell, nsIDOMElement *aEndCell);
NS_IMETHOD SelectTableRow();
NS_IMETHOD SelectTableColumn();
NS_IMETHOD SelectTable();
@ -363,6 +364,8 @@ protected:
// failed to set selection to some other content in the document
NS_IMETHOD SetSelectionAtDocumentStart(nsIDOMSelection *aSelection);
// end of table editing utilities
NS_IMETHOD ReParentContentOfNode(nsIDOMNode *aNode,
nsString &aParentTag,
BlockTransformationType aTranformation);
@ -603,6 +606,14 @@ protected:
PRBool mCachedUnderlineStyle;
nsString mCachedFontName;
// True when selection consists of table cell(s)
PRBool mSelectingTableCells;
// Used to monitor block of cells selected
// by dragging mouse across the table
nsCOMPtr<nsIDOMElement> mStartSelectedCell;
nsCOMPtr<nsIDOMElement> mCurrentSelectedCell;
public:
static nsIAtom *gTypingTxnName;
static nsIAtom *gIMETxnName;

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

@ -90,13 +90,6 @@ nsInterfaceState::NotifyDocumentCreated()
return NS_OK;
}
NS_IMETHODIMP
nsInterfaceState::TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset)
{
//stub
return NS_OK;
}
NS_IMETHODIMP
nsInterfaceState::NotifyDocumentWillBeDestroyed()
{
@ -335,25 +328,89 @@ nsInterfaceState::SelectionIsCollapsed()
nsresult
nsInterfaceState::UpdateParagraphState(const char* observerName, const char* attributeName, nsString& ioParaFormat)
{
nsStringArray tagList;
mEditor->GetParagraphTags(&tagList);
nsCOMPtr<nsIDOMSelection> domSelection;
nsCOMPtr<nsIEditor> editor = do_QueryInterface(mEditor);
// Get the nsIEditor pointer (mEditor is nsIHTMLEditor)
if (!editor) return NS_ERROR_NULL_POINTER;
nsresult rv = editor->GetSelection(getter_AddRefs(domSelection));
if (NS_FAILED(rv)) return rv;
PRInt32 numTags = tagList.Count();
nsAutoString thisTag;
//Note: If numTags == 0, we probably have a text node not in a container
// (directly under <body>). Consider it normal
if (numTags > 0)
PRBool selectionCollapsed = PR_FALSE;
rv = domSelection->GetIsCollapsed(&selectionCollapsed);
if (NS_FAILED(rv)) return rv;
// Get anchor and focus nodes:
nsCOMPtr<nsIDOMNode> anchorNode;
rv = domSelection->GetAnchorNode(getter_AddRefs(anchorNode));
if (NS_FAILED(rv)) return rv;
if (!anchorNode) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNode> focusNode;
rv = domSelection->GetFocusNode(getter_AddRefs(focusNode));
if (NS_FAILED(rv)) return rv;
if (!focusNode) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNode> anchorNodeBlockParent;
PRBool isBlock;
rv = editor->NodeIsBlock(anchorNode, isBlock);
if (NS_FAILED(rv)) return rv;
if (isBlock)
{
// This will never show the "mixed state"
// TODO: Scan list of tags and if any are different, set to "mixed"
tagList.StringAt(0, thisTag);
anchorNodeBlockParent = anchorNode;
}
else
{
// Get block parent of anchorNode node
// We could simply use this if it was in nsIEditor interface!
//rv = editor->GetBlockParent(anchorNode, getter_AddRefs(anchorNodeBlockParent));
// if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIDOMNode>parent;
nsCOMPtr<nsIDOMNode>temp;
rv = anchorNode->GetParentNode(getter_AddRefs(parent));
while (NS_SUCCEEDED(rv) && parent)
{
rv = editor->NodeIsBlock(parent, isBlock);
if (NS_FAILED(rv)) return rv;
if (isBlock)
{
anchorNodeBlockParent = parent;
break;
}
rv = parent->GetParentNode(getter_AddRefs(temp));
parent = do_QueryInterface(temp);
}
}
if (thisTag != mParagraphFormat)
if (!anchorNodeBlockParent) return NS_ERROR_NULL_POINTER;
nsAutoString tagName;
// Check if we have a selection that extends into multiple nodes,
// so we can check for "mixed" selection state
if (selectionCollapsed || focusNode == anchorNode)
{
nsresult rv = SetNodeAttribute(observerName, attributeName, thisTag);
// Entire selection is within one block
anchorNodeBlockParent->GetNodeName(tagName);
}
else
{
// We may have different block parent node types WITHIN the selection,
// even if the anchor and focus parents are the same type.
// Getting the list of all block, e.g., by using GetParagraphTags(&tagList)
// is too inefficient for long documents.
// TODO: Change to use selection iterator to detect each block node in the
// selection and if different from the anchorNodeBlockParent, use "mixed" state
// *** Not doing this now reduces risk for Beta1 -- simply assume mixed state
// Note that "mixed" displays as "normal" in UI as of 3/6.
tagName = "mixed";
}
if (tagName != mParagraphFormat)
{
rv = SetNodeAttribute(observerName, attributeName, tagName);
if (NS_FAILED(rv)) return rv;
mParagraphFormat = thisTag;
mParagraphFormat = tagName;
}
return NS_OK;
}

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

@ -58,7 +58,6 @@ public:
// nsIDOMSelectionListener interface
NS_IMETHOD NotifySelectionChanged();
NS_IMETHOD TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset);
NS_DECL_NSIDOCUMENTSTATELISTENER

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

@ -43,8 +43,11 @@
#include "nsEditorUtils.h"
//#define DEBUG_TABLE 1
static NS_DEFINE_CID(kCContentIteratorCID, NS_CONTENTITERATOR_CID);
/***************************************************************************
* stack based helper class for restoring selection after table edit
*/
@ -75,6 +78,22 @@ class nsSetCaretAfterTableEdit
void CancelSetCaret() {mEd = nsnull; mTable = nsnull;}
};
// Stack-class to turn on/off selection batching for table selection
class nsSelectionBatcher
{
private:
nsCOMPtr<nsIDOMSelection> mSelection;
public:
nsSelectionBatcher(nsIDOMSelection *aSelection) : mSelection(aSelection)
{
if (mSelection) mSelection->StartBatchChanges();
}
virtual ~nsSelectionBatcher()
{
if (mSelection) mSelection->EndBatchChanges();
}
};
// Table Editing helper utilities (not exposed in IDL)
NS_IMETHODIMP
@ -319,7 +338,7 @@ nsHTMLEditor::GetNextRow(nsIDOMElement* aTableElement, nsIDOMElement* &aRow)
}
return NS_OK;
}
#ifdef DEBUG
#ifdef DEBUG_cmanske
printf("GetNextRow: firstChild of row's parent's sibling is not a TR!\n");
#endif
// We arrive here only if a table section has no children
@ -963,8 +982,7 @@ NS_IMETHODIMP
nsHTMLEditor::SelectTableCell()
{
nsCOMPtr<nsIDOMElement> cell;
nsresult res = NS_ERROR_FAILURE;
res = GetElementOrParentByTagName("td", nsnull, getter_AddRefs(cell));
nsresult res = GetElementOrParentByTagName("td", nsnull, getter_AddRefs(cell));
if (NS_FAILED(res)) return res;
// Don't fail if we didn't find a table
if (!cell) return NS_EDITOR_ELEMENT_NOT_FOUND;
@ -979,24 +997,280 @@ nsHTMLEditor::SelectTableCell()
return res;
}
NS_IMETHODIMP
nsHTMLEditor::SelectBlockOfCells(nsIDOMElement *aStartCell, nsIDOMElement *aEndCell)
{
if (!aStartCell || !aEndCell) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMSelection> selection;
nsresult res = nsEditor::GetSelection(getter_AddRefs(selection));
if (NS_FAILED(res)) return res;
if (!selection) return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMElement> table;
res = GetElementOrParentByTagName("table", aStartCell, getter_AddRefs(table));
if (NS_FAILED(res)) return res;
if (!table) return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMElement> endTable;
res = GetElementOrParentByTagName("table", aEndCell, getter_AddRefs(endTable));
if (NS_FAILED(res)) return res;
if (!endTable) return NS_ERROR_FAILURE;
// We can only select a block if within the same table,
// so do nothing if not within one table
if (table != endTable) return NS_OK;
PRInt32 startRowIndex, startColIndex, endRowIndex, endColIndex;
// Get starting and ending cells' location in the cellmap
res = GetCellIndexes(aStartCell, startRowIndex, startColIndex);
if(NS_FAILED(res)) return res;
res = GetCellIndexes(aEndCell, endRowIndex, endColIndex);
if(NS_FAILED(res)) return res;
// Suppress nsIDOMSelectionListener notification
// until all selection changes are finished
nsSelectionBatcher selectionBatcher(selection);
// It is now safe to clear the selection
// BE SURE TO RESET IT BEFORE LEAVING!
selection->ClearSelection();
nsCOMPtr<nsIDOMNode> cellNode;
PRBool cellSelected = PR_FALSE;
PRInt32 startColumn = PR_MIN(startColIndex, endColIndex);
PRInt32 startRow = PR_MIN(startRowIndex, endRowIndex);
PRInt32 maxColumn = PR_MAX(startColIndex, endColIndex);
PRInt32 maxRow = PR_MAX(startRowIndex, endRowIndex);
nsCOMPtr<nsIDOMElement> cell;
PRInt32 rowSpan, colSpan, actualRowSpan, actualColSpan, currentRowIndex, currentColIndex;
PRBool isSelected;
for (PRInt32 row = startRow; row <= maxRow; row++)
{
for(PRInt32 col = startColumn; col <= maxColumn; col += actualColSpan)
{
res = GetCellDataAt(table, row, col, *getter_AddRefs(cell),
currentRowIndex, currentColIndex, rowSpan, colSpan,
actualRowSpan, actualColSpan, isSelected);
if (NS_FAILED(res)) break;
// Skip cells that are spanned from previous locations
if (cell && row == currentRowIndex && col == currentColIndex)
{
cellNode = do_QueryInterface(cell);
res = nsEditor::AppendNodeToSelectionAsRange(cellNode);
if (NS_FAILED(res)) break;
cellSelected = PR_TRUE;
}
}
}
// Safety code to select starting cell if nothing else was selected
if (!cellSelected)
{
cellNode = do_QueryInterface(aStartCell);
return nsEditor::AppendNodeToSelectionAsRange(cellNode);
}
return res;
}
NS_IMETHODIMP
nsHTMLEditor::SelectAllTableCells()
{
nsresult res = NS_OK;
nsCOMPtr<nsIDOMElement> cell;
nsresult res = GetElementOrParentByTagName("td", nsnull, getter_AddRefs(cell));
if (NS_FAILED(res)) return res;
// Don't fail if we didn't find a cell
if (!cell) return NS_EDITOR_ELEMENT_NOT_FOUND;
nsCOMPtr<nsIDOMNode> cellNode = do_QueryInterface(cell);
if (!cellNode) return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMElement> startCell = cell;
// Get location of cell:
nsCOMPtr<nsIDOMSelection> selection;
nsCOMPtr<nsIDOMElement> table;
nsCOMPtr<nsIDOMNode> cellParent;
PRInt32 cellOffset, startRowIndex, startColIndex;
res = GetCellContext(selection, table, cell, cellParent, cellOffset, startRowIndex, startColIndex);
if (NS_FAILED(res)) return res;
if(!cell) return NS_ERROR_NULL_POINTER;
PRInt32 rowCount, colCount;
res = GetTableSize(table, rowCount, colCount);
if (NS_FAILED(res)) return res;
// Suppress nsIDOMSelectionListener notification
// until all selection changes are finished
nsSelectionBatcher selectionBatcher(selection);
// It is now safe to clear the selection
// BE SURE TO RESET IT BEFORE LEAVING!
res = ClearSelection();
// Select all cells in the same column as current cell
PRBool cellSelected = PR_FALSE;
PRInt32 rowSpan, colSpan, actualRowSpan, actualColSpan, currentRowIndex, currentColIndex;
PRBool isSelected;
for(PRInt32 row = 0; row < rowCount; row++)
{
for(PRInt32 col = 0; col < colCount; col += actualColSpan)
{
res = GetCellDataAt(table, row, col, *getter_AddRefs(cell),
currentRowIndex, currentColIndex, rowSpan, colSpan,
actualRowSpan, actualColSpan, isSelected);
if (NS_FAILED(res)) break;
// Skip cells that are spanned from previous rows or columns
if (cell && row == currentRowIndex && col == currentColIndex)
{
cellNode = do_QueryInterface(cell);
res = nsEditor::AppendNodeToSelectionAsRange(cellNode);
if (NS_FAILED(res)) break;
cellSelected = PR_TRUE;
}
}
}
// Safety code to select starting cell if nothing else was selected
if (!cellSelected)
{
cellNode = do_QueryInterface(startCell);
return nsEditor::AppendNodeToSelectionAsRange(cellNode);
}
return res;
}
NS_IMETHODIMP
nsHTMLEditor::SelectTableRow()
{
nsresult res = NS_OK;
nsCOMPtr<nsIDOMElement> cell;
nsresult res = GetElementOrParentByTagName("td", nsnull, getter_AddRefs(cell));
if (NS_FAILED(res)) return res;
// Don't fail if we didn't find a cell
if (!cell) return NS_EDITOR_ELEMENT_NOT_FOUND;
nsCOMPtr<nsIDOMElement> startCell = cell;
nsCOMPtr<nsIDOMNode> cellNode = do_QueryInterface(cell);
if (!cellNode) return NS_ERROR_FAILURE;
// Get location of cell:
nsCOMPtr<nsIDOMSelection> selection;
nsCOMPtr<nsIDOMElement> table;
nsCOMPtr<nsIDOMNode> cellParent;
PRInt32 cellOffset, startRowIndex, startColIndex;
res = GetCellContext(selection, table, cell, cellParent, cellOffset, startRowIndex, startColIndex);
if (NS_FAILED(res)) return res;
if(!cell) return NS_ERROR_NULL_POINTER;
PRInt32 rowCount, colCount;
res = GetTableSize(table, rowCount, colCount);
if (NS_FAILED(res)) return res;
//Note: At this point, we could get first and last cells in row,
// then call SelectBlockOfCells, but that would take just
// a little less code, so the following is more efficient
// Suppress nsIDOMSelectionListener notification
// until all selection changes are finished
nsSelectionBatcher selectionBatcher(selection);
// It is now safe to clear the selection
// BE SURE TO RESET IT BEFORE LEAVING!
res = ClearSelection();
// Select all cells in the same row as current cell
PRBool cellSelected = PR_FALSE;
PRInt32 rowSpan, colSpan, actualRowSpan, actualColSpan, currentRowIndex, currentColIndex;
PRBool isSelected;
for(PRInt32 col = 0; col < colCount; col += actualColSpan)
{
res = GetCellDataAt(table, startRowIndex, col, *getter_AddRefs(cell),
currentRowIndex, currentColIndex, rowSpan, colSpan,
actualRowSpan, actualColSpan, isSelected);
if (NS_FAILED(res)) break;
// Skip cells that are spanned from previous rows or columns
if (cell && currentRowIndex == startRowIndex && currentColIndex == startColIndex)
{
cellNode = do_QueryInterface(cell);
res = nsEditor::AppendNodeToSelectionAsRange(cellNode);
if (NS_FAILED(res)) break;
cellSelected = PR_TRUE;
}
}
// Safety code to select starting cell if nothing else was selected
if (!cellSelected)
{
cellNode = do_QueryInterface(startCell);
return nsEditor::AppendNodeToSelectionAsRange(cellNode);
}
return res;
}
NS_IMETHODIMP
nsHTMLEditor::SelectTableColumn()
{
nsresult res = NS_OK;
nsCOMPtr<nsIDOMElement> cell;
nsresult res = GetElementOrParentByTagName("td", nsnull, getter_AddRefs(cell));
if (NS_FAILED(res)) return res;
// Don't fail if we didn't find a cell
if (!cell) return NS_EDITOR_ELEMENT_NOT_FOUND;
nsCOMPtr<nsIDOMNode> cellNode = do_QueryInterface(cell);
if (!cellNode) return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMElement> startCell = cell;
// Get location of cell:
nsCOMPtr<nsIDOMSelection> selection;
nsCOMPtr<nsIDOMElement> table;
nsCOMPtr<nsIDOMNode> cellParent;
PRInt32 cellOffset, startRowIndex, startColIndex;
res = GetCellContext(selection, table, cell, cellParent, cellOffset, startRowIndex, startColIndex);
if (NS_FAILED(res)) return res;
if(!cell) return NS_ERROR_NULL_POINTER;
PRInt32 rowCount, colCount;
res = GetTableSize(table, rowCount, colCount);
if (NS_FAILED(res)) return res;
// Suppress nsIDOMSelectionListener notification
// until all selection changes are finished
nsSelectionBatcher selectionBatcher(selection);
// It is now safe to clear the selection
// BE SURE TO RESET IT BEFORE LEAVING!
res = ClearSelection();
// Select all cells in the same column as current cell
PRBool cellSelected = PR_FALSE;
PRInt32 rowSpan, colSpan, actualRowSpan, actualColSpan, currentRowIndex, currentColIndex;
PRBool isSelected;
for(PRInt32 row = 0; row < rowCount; row += actualRowSpan)
{
res = GetCellDataAt(table, row, startColIndex, *getter_AddRefs(cell),
currentRowIndex, currentColIndex, rowSpan, colSpan,
actualRowSpan, actualColSpan, isSelected);
if (NS_FAILED(res)) break;
// Skip cells that are spanned from previous rows or columns
if (cell && currentRowIndex == startRowIndex && currentColIndex == startColIndex)
{
cellNode = do_QueryInterface(cell);
res = nsEditor::AppendNodeToSelectionAsRange(cellNode);
if (NS_FAILED(res)) break;
cellSelected = PR_TRUE;
}
}
// Safety code to select starting cell if nothing else was selected
if (!cellSelected)
{
cellNode = do_QueryInterface(startCell);
return nsEditor::AppendNodeToSelectionAsRange(cellNode);
}
return res;
}
@ -1217,22 +1491,16 @@ nsHTMLEditor::GetCellIndexes(nsIDOMElement *aCell, PRInt32 &aRowIndex, PRInt32 &
return NS_ERROR_FAILURE;
}
res = NS_ERROR_FAILURE; // we return an error unless we get the index
nsISupports *layoutObject=nsnull; // frames are not ref counted, so don't use an nsCOMPtr
res = nsHTMLEditor::GetLayoutObject(aCell, &layoutObject);
if (NS_FAILED(res)) return res;
if (!layoutObject) return NS_ERROR_FAILURE;
if ((NS_SUCCEEDED(res)) && (nsnull!=layoutObject))
{ // get the table cell interface from the frame
nsITableCellLayout *cellLayoutObject=nsnull; // again, frames are not ref-counted
res = layoutObject->QueryInterface(NS_GET_IID(nsITableCellLayout), (void**)(&cellLayoutObject));
if ((NS_SUCCEEDED(res)) && (nsnull!=cellLayoutObject))
{
res = cellLayoutObject->GetCellIndexes(aRowIndex, aColIndex);
}
}
return res;
nsITableCellLayout *cellLayoutObject=nsnull; // again, frames are not ref-counted
res = layoutObject->QueryInterface(NS_GET_IID(nsITableCellLayout), (void**)(&cellLayoutObject));
if (NS_FAILED(res)) return res;
if (!cellLayoutObject) return NS_ERROR_FAILURE;
return cellLayoutObject->GetCellIndexes(aRowIndex, aColIndex);
}
NS_IMETHODIMP
@ -1245,13 +1513,10 @@ nsHTMLEditor::GetTableLayoutObject(nsIDOMElement* aTable, nsITableLayout **table
// frames are not ref counted, so don't use an nsCOMPtr
nsISupports *layoutObject=nsnull;
nsresult res = nsHTMLEditor::GetLayoutObject(aTable, &layoutObject);
if ((NS_SUCCEEDED(res)) && (nsnull!=layoutObject))
{ // get the table interface from the frame
res = layoutObject->QueryInterface(NS_GET_IID(nsITableLayout),
(void**)(tableLayoutObject));
}
return res;
if (NS_FAILED(res)) return res;
if (!layoutObject) return NS_ERROR_FAILURE;
return layoutObject->QueryInterface(NS_GET_IID(nsITableLayout),
(void**)(tableLayoutObject));
}
//Return actual number of cells (a cell with colspan > 1 counts as just 1)

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

@ -211,7 +211,7 @@ nsEditorShell::nsEditorShell()
nsEditorShell::~nsEditorShell()
{
NS_IF_RELEASE(mStateMaintainer);
// the only other references we hold are in nsCOMPtrs, so they'll take
// care of themselves.
}
@ -302,7 +302,6 @@ nsEditorShell::PrepareDocumentForEditing(nsIURI *aUrl)
NS_IF_RELEASE(mStateMaintainer);
}
}
mEditorType = eUninitializedEditorType;
mEditor = 0; // clear out the nsCOMPtr
@ -365,8 +364,8 @@ nsEditorShell::PrepareDocumentForEditing(nsIURI *aUrl)
{
txnMgr->AddListener(NS_STATIC_CAST(nsITransactionListener*, mStateMaintainer));
}
if (NS_SUCCEEDED(rv) && mContentWindow)
{
nsCOMPtr<nsIController> controller;
@ -3149,6 +3148,26 @@ nsEditorShell::SelectTableCell()
return result;
}
NS_IMETHODIMP
nsEditorShell::SelectBlockOfCells(nsIDOMElement *aStartCell, nsIDOMElement *aEndCell)
{
nsresult result = NS_NOINTERFACE;
switch (mEditorType)
{
case eHTMLTextEditorType:
{
nsCOMPtr<nsITableEditor> tableEditor = do_QueryInterface(mEditor);
if (tableEditor)
result = tableEditor->SelectBlockOfCells(aStartCell, aEndCell);
}
break;
default:
result = NS_ERROR_NOT_IMPLEMENTED;
}
return result;
}
NS_IMETHODIMP
nsEditorShell::SelectTableRow()
{

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

@ -138,7 +138,7 @@ class nsEditorShell : public nsIEditorShell,
nsCOMPtr<nsISupports> mSearchContext; // context used for search and replace. Owned by the appshell.
nsInterfaceState* mStateMaintainer; // we hold the owning ref to this.
nsInterfaceState* mStateMaintainer; // we hold the owning ref to this.
PRInt32 mWrapColumn; // can't actually set this 'til the editor is created, so we may have to hold on to it for a while

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

@ -90,13 +90,6 @@ nsInterfaceState::NotifyDocumentCreated()
return NS_OK;
}
NS_IMETHODIMP
nsInterfaceState::TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset)
{
//stub
return NS_OK;
}
NS_IMETHODIMP
nsInterfaceState::NotifyDocumentWillBeDestroyed()
{
@ -335,25 +328,89 @@ nsInterfaceState::SelectionIsCollapsed()
nsresult
nsInterfaceState::UpdateParagraphState(const char* observerName, const char* attributeName, nsString& ioParaFormat)
{
nsStringArray tagList;
mEditor->GetParagraphTags(&tagList);
nsCOMPtr<nsIDOMSelection> domSelection;
nsCOMPtr<nsIEditor> editor = do_QueryInterface(mEditor);
// Get the nsIEditor pointer (mEditor is nsIHTMLEditor)
if (!editor) return NS_ERROR_NULL_POINTER;
nsresult rv = editor->GetSelection(getter_AddRefs(domSelection));
if (NS_FAILED(rv)) return rv;
PRInt32 numTags = tagList.Count();
nsAutoString thisTag;
//Note: If numTags == 0, we probably have a text node not in a container
// (directly under <body>). Consider it normal
if (numTags > 0)
PRBool selectionCollapsed = PR_FALSE;
rv = domSelection->GetIsCollapsed(&selectionCollapsed);
if (NS_FAILED(rv)) return rv;
// Get anchor and focus nodes:
nsCOMPtr<nsIDOMNode> anchorNode;
rv = domSelection->GetAnchorNode(getter_AddRefs(anchorNode));
if (NS_FAILED(rv)) return rv;
if (!anchorNode) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNode> focusNode;
rv = domSelection->GetFocusNode(getter_AddRefs(focusNode));
if (NS_FAILED(rv)) return rv;
if (!focusNode) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNode> anchorNodeBlockParent;
PRBool isBlock;
rv = editor->NodeIsBlock(anchorNode, isBlock);
if (NS_FAILED(rv)) return rv;
if (isBlock)
{
// This will never show the "mixed state"
// TODO: Scan list of tags and if any are different, set to "mixed"
tagList.StringAt(0, thisTag);
anchorNodeBlockParent = anchorNode;
}
else
{
// Get block parent of anchorNode node
// We could simply use this if it was in nsIEditor interface!
//rv = editor->GetBlockParent(anchorNode, getter_AddRefs(anchorNodeBlockParent));
// if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIDOMNode>parent;
nsCOMPtr<nsIDOMNode>temp;
rv = anchorNode->GetParentNode(getter_AddRefs(parent));
while (NS_SUCCEEDED(rv) && parent)
{
rv = editor->NodeIsBlock(parent, isBlock);
if (NS_FAILED(rv)) return rv;
if (isBlock)
{
anchorNodeBlockParent = parent;
break;
}
rv = parent->GetParentNode(getter_AddRefs(temp));
parent = do_QueryInterface(temp);
}
}
if (thisTag != mParagraphFormat)
if (!anchorNodeBlockParent) return NS_ERROR_NULL_POINTER;
nsAutoString tagName;
// Check if we have a selection that extends into multiple nodes,
// so we can check for "mixed" selection state
if (selectionCollapsed || focusNode == anchorNode)
{
nsresult rv = SetNodeAttribute(observerName, attributeName, thisTag);
// Entire selection is within one block
anchorNodeBlockParent->GetNodeName(tagName);
}
else
{
// We may have different block parent node types WITHIN the selection,
// even if the anchor and focus parents are the same type.
// Getting the list of all block, e.g., by using GetParagraphTags(&tagList)
// is too inefficient for long documents.
// TODO: Change to use selection iterator to detect each block node in the
// selection and if different from the anchorNodeBlockParent, use "mixed" state
// *** Not doing this now reduces risk for Beta1 -- simply assume mixed state
// Note that "mixed" displays as "normal" in UI as of 3/6.
tagName = "mixed";
}
if (tagName != mParagraphFormat)
{
rv = SetNodeAttribute(observerName, attributeName, tagName);
if (NS_FAILED(rv)) return rv;
mParagraphFormat = thisTag;
mParagraphFormat = tagName;
}
return NS_OK;
}

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

@ -58,7 +58,6 @@ public:
// nsIDOMSelectionListener interface
NS_IMETHOD NotifySelectionChanged();
NS_IMETHOD TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset);
NS_DECL_NSIDOCUMENTSTATELISTENER

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

@ -303,6 +303,11 @@ interface nsIEditorShell : nsISupports
* selects all cells (not TR in the case of rows)
*/
void SelectTableCell();
/** Select a rectangular block of cells:
* all cells falling within the row/column index of startCell
* to through the row/column index of the endCell
*/
void SelectBlockOfCells(in nsIDOMElement startCell, in nsIDOMElement endCell);
void SelectTableRow();
void SelectTableColumn();
void SelectTable();

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

@ -56,9 +56,3 @@ NS_IMETHODIMP TypeInState::NotifySelectionChanged()
Reset();
return NS_OK;
};
NS_IMETHODIMP TypeInState::TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset)
{
//stub
return NS_OK;
}

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

@ -38,7 +38,6 @@ public:
virtual ~TypeInState();
NS_IMETHOD NotifySelectionChanged();
NS_IMETHOD TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset);
void GetEnumForName(nsIAtom *aPropName, PRUint32 &aEnum);
void GetPropertyIsString(PRUint32 aProp, PRUint32 &aIsString);

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

@ -217,6 +217,7 @@ nsHTMLEditor::nsHTMLEditor()
, mRules(nsnull)
, mIsComposing(PR_FALSE)
, mMaxTextLength(-1)
, mSelectingTableCells(PR_FALSE)
{
// Done in nsEditor
// NS_INIT_REFCNT();

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

@ -184,6 +184,7 @@ public:
NS_IMETHOD DeleteTableColumn(PRInt32 aNumber);
NS_IMETHOD DeleteTableRow(PRInt32 aNumber);
NS_IMETHOD SelectTableCell();
NS_IMETHOD SelectBlockOfCells(nsIDOMElement *aStartCell, nsIDOMElement *aEndCell);
NS_IMETHOD SelectTableRow();
NS_IMETHOD SelectTableColumn();
NS_IMETHOD SelectTable();
@ -363,6 +364,8 @@ protected:
// failed to set selection to some other content in the document
NS_IMETHOD SetSelectionAtDocumentStart(nsIDOMSelection *aSelection);
// end of table editing utilities
NS_IMETHOD ReParentContentOfNode(nsIDOMNode *aNode,
nsString &aParentTag,
BlockTransformationType aTranformation);
@ -603,6 +606,14 @@ protected:
PRBool mCachedUnderlineStyle;
nsString mCachedFontName;
// True when selection consists of table cell(s)
PRBool mSelectingTableCells;
// Used to monitor block of cells selected
// by dragging mouse across the table
nsCOMPtr<nsIDOMElement> mStartSelectedCell;
nsCOMPtr<nsIDOMElement> mCurrentSelectedCell;
public:
static nsIAtom *gTypingTxnName;
static nsIAtom *gIMETxnName;

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

@ -43,8 +43,11 @@
#include "nsEditorUtils.h"
//#define DEBUG_TABLE 1
static NS_DEFINE_CID(kCContentIteratorCID, NS_CONTENTITERATOR_CID);
/***************************************************************************
* stack based helper class for restoring selection after table edit
*/
@ -75,6 +78,22 @@ class nsSetCaretAfterTableEdit
void CancelSetCaret() {mEd = nsnull; mTable = nsnull;}
};
// Stack-class to turn on/off selection batching for table selection
class nsSelectionBatcher
{
private:
nsCOMPtr<nsIDOMSelection> mSelection;
public:
nsSelectionBatcher(nsIDOMSelection *aSelection) : mSelection(aSelection)
{
if (mSelection) mSelection->StartBatchChanges();
}
virtual ~nsSelectionBatcher()
{
if (mSelection) mSelection->EndBatchChanges();
}
};
// Table Editing helper utilities (not exposed in IDL)
NS_IMETHODIMP
@ -319,7 +338,7 @@ nsHTMLEditor::GetNextRow(nsIDOMElement* aTableElement, nsIDOMElement* &aRow)
}
return NS_OK;
}
#ifdef DEBUG
#ifdef DEBUG_cmanske
printf("GetNextRow: firstChild of row's parent's sibling is not a TR!\n");
#endif
// We arrive here only if a table section has no children
@ -963,8 +982,7 @@ NS_IMETHODIMP
nsHTMLEditor::SelectTableCell()
{
nsCOMPtr<nsIDOMElement> cell;
nsresult res = NS_ERROR_FAILURE;
res = GetElementOrParentByTagName("td", nsnull, getter_AddRefs(cell));
nsresult res = GetElementOrParentByTagName("td", nsnull, getter_AddRefs(cell));
if (NS_FAILED(res)) return res;
// Don't fail if we didn't find a table
if (!cell) return NS_EDITOR_ELEMENT_NOT_FOUND;
@ -979,24 +997,280 @@ nsHTMLEditor::SelectTableCell()
return res;
}
NS_IMETHODIMP
nsHTMLEditor::SelectBlockOfCells(nsIDOMElement *aStartCell, nsIDOMElement *aEndCell)
{
if (!aStartCell || !aEndCell) return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMSelection> selection;
nsresult res = nsEditor::GetSelection(getter_AddRefs(selection));
if (NS_FAILED(res)) return res;
if (!selection) return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMElement> table;
res = GetElementOrParentByTagName("table", aStartCell, getter_AddRefs(table));
if (NS_FAILED(res)) return res;
if (!table) return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMElement> endTable;
res = GetElementOrParentByTagName("table", aEndCell, getter_AddRefs(endTable));
if (NS_FAILED(res)) return res;
if (!endTable) return NS_ERROR_FAILURE;
// We can only select a block if within the same table,
// so do nothing if not within one table
if (table != endTable) return NS_OK;
PRInt32 startRowIndex, startColIndex, endRowIndex, endColIndex;
// Get starting and ending cells' location in the cellmap
res = GetCellIndexes(aStartCell, startRowIndex, startColIndex);
if(NS_FAILED(res)) return res;
res = GetCellIndexes(aEndCell, endRowIndex, endColIndex);
if(NS_FAILED(res)) return res;
// Suppress nsIDOMSelectionListener notification
// until all selection changes are finished
nsSelectionBatcher selectionBatcher(selection);
// It is now safe to clear the selection
// BE SURE TO RESET IT BEFORE LEAVING!
selection->ClearSelection();
nsCOMPtr<nsIDOMNode> cellNode;
PRBool cellSelected = PR_FALSE;
PRInt32 startColumn = PR_MIN(startColIndex, endColIndex);
PRInt32 startRow = PR_MIN(startRowIndex, endRowIndex);
PRInt32 maxColumn = PR_MAX(startColIndex, endColIndex);
PRInt32 maxRow = PR_MAX(startRowIndex, endRowIndex);
nsCOMPtr<nsIDOMElement> cell;
PRInt32 rowSpan, colSpan, actualRowSpan, actualColSpan, currentRowIndex, currentColIndex;
PRBool isSelected;
for (PRInt32 row = startRow; row <= maxRow; row++)
{
for(PRInt32 col = startColumn; col <= maxColumn; col += actualColSpan)
{
res = GetCellDataAt(table, row, col, *getter_AddRefs(cell),
currentRowIndex, currentColIndex, rowSpan, colSpan,
actualRowSpan, actualColSpan, isSelected);
if (NS_FAILED(res)) break;
// Skip cells that are spanned from previous locations
if (cell && row == currentRowIndex && col == currentColIndex)
{
cellNode = do_QueryInterface(cell);
res = nsEditor::AppendNodeToSelectionAsRange(cellNode);
if (NS_FAILED(res)) break;
cellSelected = PR_TRUE;
}
}
}
// Safety code to select starting cell if nothing else was selected
if (!cellSelected)
{
cellNode = do_QueryInterface(aStartCell);
return nsEditor::AppendNodeToSelectionAsRange(cellNode);
}
return res;
}
NS_IMETHODIMP
nsHTMLEditor::SelectAllTableCells()
{
nsresult res = NS_OK;
nsCOMPtr<nsIDOMElement> cell;
nsresult res = GetElementOrParentByTagName("td", nsnull, getter_AddRefs(cell));
if (NS_FAILED(res)) return res;
// Don't fail if we didn't find a cell
if (!cell) return NS_EDITOR_ELEMENT_NOT_FOUND;
nsCOMPtr<nsIDOMNode> cellNode = do_QueryInterface(cell);
if (!cellNode) return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMElement> startCell = cell;
// Get location of cell:
nsCOMPtr<nsIDOMSelection> selection;
nsCOMPtr<nsIDOMElement> table;
nsCOMPtr<nsIDOMNode> cellParent;
PRInt32 cellOffset, startRowIndex, startColIndex;
res = GetCellContext(selection, table, cell, cellParent, cellOffset, startRowIndex, startColIndex);
if (NS_FAILED(res)) return res;
if(!cell) return NS_ERROR_NULL_POINTER;
PRInt32 rowCount, colCount;
res = GetTableSize(table, rowCount, colCount);
if (NS_FAILED(res)) return res;
// Suppress nsIDOMSelectionListener notification
// until all selection changes are finished
nsSelectionBatcher selectionBatcher(selection);
// It is now safe to clear the selection
// BE SURE TO RESET IT BEFORE LEAVING!
res = ClearSelection();
// Select all cells in the same column as current cell
PRBool cellSelected = PR_FALSE;
PRInt32 rowSpan, colSpan, actualRowSpan, actualColSpan, currentRowIndex, currentColIndex;
PRBool isSelected;
for(PRInt32 row = 0; row < rowCount; row++)
{
for(PRInt32 col = 0; col < colCount; col += actualColSpan)
{
res = GetCellDataAt(table, row, col, *getter_AddRefs(cell),
currentRowIndex, currentColIndex, rowSpan, colSpan,
actualRowSpan, actualColSpan, isSelected);
if (NS_FAILED(res)) break;
// Skip cells that are spanned from previous rows or columns
if (cell && row == currentRowIndex && col == currentColIndex)
{
cellNode = do_QueryInterface(cell);
res = nsEditor::AppendNodeToSelectionAsRange(cellNode);
if (NS_FAILED(res)) break;
cellSelected = PR_TRUE;
}
}
}
// Safety code to select starting cell if nothing else was selected
if (!cellSelected)
{
cellNode = do_QueryInterface(startCell);
return nsEditor::AppendNodeToSelectionAsRange(cellNode);
}
return res;
}
NS_IMETHODIMP
nsHTMLEditor::SelectTableRow()
{
nsresult res = NS_OK;
nsCOMPtr<nsIDOMElement> cell;
nsresult res = GetElementOrParentByTagName("td", nsnull, getter_AddRefs(cell));
if (NS_FAILED(res)) return res;
// Don't fail if we didn't find a cell
if (!cell) return NS_EDITOR_ELEMENT_NOT_FOUND;
nsCOMPtr<nsIDOMElement> startCell = cell;
nsCOMPtr<nsIDOMNode> cellNode = do_QueryInterface(cell);
if (!cellNode) return NS_ERROR_FAILURE;
// Get location of cell:
nsCOMPtr<nsIDOMSelection> selection;
nsCOMPtr<nsIDOMElement> table;
nsCOMPtr<nsIDOMNode> cellParent;
PRInt32 cellOffset, startRowIndex, startColIndex;
res = GetCellContext(selection, table, cell, cellParent, cellOffset, startRowIndex, startColIndex);
if (NS_FAILED(res)) return res;
if(!cell) return NS_ERROR_NULL_POINTER;
PRInt32 rowCount, colCount;
res = GetTableSize(table, rowCount, colCount);
if (NS_FAILED(res)) return res;
//Note: At this point, we could get first and last cells in row,
// then call SelectBlockOfCells, but that would take just
// a little less code, so the following is more efficient
// Suppress nsIDOMSelectionListener notification
// until all selection changes are finished
nsSelectionBatcher selectionBatcher(selection);
// It is now safe to clear the selection
// BE SURE TO RESET IT BEFORE LEAVING!
res = ClearSelection();
// Select all cells in the same row as current cell
PRBool cellSelected = PR_FALSE;
PRInt32 rowSpan, colSpan, actualRowSpan, actualColSpan, currentRowIndex, currentColIndex;
PRBool isSelected;
for(PRInt32 col = 0; col < colCount; col += actualColSpan)
{
res = GetCellDataAt(table, startRowIndex, col, *getter_AddRefs(cell),
currentRowIndex, currentColIndex, rowSpan, colSpan,
actualRowSpan, actualColSpan, isSelected);
if (NS_FAILED(res)) break;
// Skip cells that are spanned from previous rows or columns
if (cell && currentRowIndex == startRowIndex && currentColIndex == startColIndex)
{
cellNode = do_QueryInterface(cell);
res = nsEditor::AppendNodeToSelectionAsRange(cellNode);
if (NS_FAILED(res)) break;
cellSelected = PR_TRUE;
}
}
// Safety code to select starting cell if nothing else was selected
if (!cellSelected)
{
cellNode = do_QueryInterface(startCell);
return nsEditor::AppendNodeToSelectionAsRange(cellNode);
}
return res;
}
NS_IMETHODIMP
nsHTMLEditor::SelectTableColumn()
{
nsresult res = NS_OK;
nsCOMPtr<nsIDOMElement> cell;
nsresult res = GetElementOrParentByTagName("td", nsnull, getter_AddRefs(cell));
if (NS_FAILED(res)) return res;
// Don't fail if we didn't find a cell
if (!cell) return NS_EDITOR_ELEMENT_NOT_FOUND;
nsCOMPtr<nsIDOMNode> cellNode = do_QueryInterface(cell);
if (!cellNode) return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMElement> startCell = cell;
// Get location of cell:
nsCOMPtr<nsIDOMSelection> selection;
nsCOMPtr<nsIDOMElement> table;
nsCOMPtr<nsIDOMNode> cellParent;
PRInt32 cellOffset, startRowIndex, startColIndex;
res = GetCellContext(selection, table, cell, cellParent, cellOffset, startRowIndex, startColIndex);
if (NS_FAILED(res)) return res;
if(!cell) return NS_ERROR_NULL_POINTER;
PRInt32 rowCount, colCount;
res = GetTableSize(table, rowCount, colCount);
if (NS_FAILED(res)) return res;
// Suppress nsIDOMSelectionListener notification
// until all selection changes are finished
nsSelectionBatcher selectionBatcher(selection);
// It is now safe to clear the selection
// BE SURE TO RESET IT BEFORE LEAVING!
res = ClearSelection();
// Select all cells in the same column as current cell
PRBool cellSelected = PR_FALSE;
PRInt32 rowSpan, colSpan, actualRowSpan, actualColSpan, currentRowIndex, currentColIndex;
PRBool isSelected;
for(PRInt32 row = 0; row < rowCount; row += actualRowSpan)
{
res = GetCellDataAt(table, row, startColIndex, *getter_AddRefs(cell),
currentRowIndex, currentColIndex, rowSpan, colSpan,
actualRowSpan, actualColSpan, isSelected);
if (NS_FAILED(res)) break;
// Skip cells that are spanned from previous rows or columns
if (cell && currentRowIndex == startRowIndex && currentColIndex == startColIndex)
{
cellNode = do_QueryInterface(cell);
res = nsEditor::AppendNodeToSelectionAsRange(cellNode);
if (NS_FAILED(res)) break;
cellSelected = PR_TRUE;
}
}
// Safety code to select starting cell if nothing else was selected
if (!cellSelected)
{
cellNode = do_QueryInterface(startCell);
return nsEditor::AppendNodeToSelectionAsRange(cellNode);
}
return res;
}
@ -1217,22 +1491,16 @@ nsHTMLEditor::GetCellIndexes(nsIDOMElement *aCell, PRInt32 &aRowIndex, PRInt32 &
return NS_ERROR_FAILURE;
}
res = NS_ERROR_FAILURE; // we return an error unless we get the index
nsISupports *layoutObject=nsnull; // frames are not ref counted, so don't use an nsCOMPtr
res = nsHTMLEditor::GetLayoutObject(aCell, &layoutObject);
if (NS_FAILED(res)) return res;
if (!layoutObject) return NS_ERROR_FAILURE;
if ((NS_SUCCEEDED(res)) && (nsnull!=layoutObject))
{ // get the table cell interface from the frame
nsITableCellLayout *cellLayoutObject=nsnull; // again, frames are not ref-counted
res = layoutObject->QueryInterface(NS_GET_IID(nsITableCellLayout), (void**)(&cellLayoutObject));
if ((NS_SUCCEEDED(res)) && (nsnull!=cellLayoutObject))
{
res = cellLayoutObject->GetCellIndexes(aRowIndex, aColIndex);
}
}
return res;
nsITableCellLayout *cellLayoutObject=nsnull; // again, frames are not ref-counted
res = layoutObject->QueryInterface(NS_GET_IID(nsITableCellLayout), (void**)(&cellLayoutObject));
if (NS_FAILED(res)) return res;
if (!cellLayoutObject) return NS_ERROR_FAILURE;
return cellLayoutObject->GetCellIndexes(aRowIndex, aColIndex);
}
NS_IMETHODIMP
@ -1245,13 +1513,10 @@ nsHTMLEditor::GetTableLayoutObject(nsIDOMElement* aTable, nsITableLayout **table
// frames are not ref counted, so don't use an nsCOMPtr
nsISupports *layoutObject=nsnull;
nsresult res = nsHTMLEditor::GetLayoutObject(aTable, &layoutObject);
if ((NS_SUCCEEDED(res)) && (nsnull!=layoutObject))
{ // get the table interface from the frame
res = layoutObject->QueryInterface(NS_GET_IID(nsITableLayout),
(void**)(tableLayoutObject));
}
return res;
if (NS_FAILED(res)) return res;
if (!layoutObject) return NS_ERROR_FAILURE;
return layoutObject->QueryInterface(NS_GET_IID(nsITableLayout),
(void**)(tableLayoutObject));
}
//Return actual number of cells (a cell with colspan > 1 counts as just 1)

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

@ -82,6 +82,17 @@ public:
* selects all cells (not TR in the case of rows)
*/
NS_IMETHOD SelectTableCell()=0;
/** Select a rectangular block of cells:
* all cells falling within the row/column index of aStartCell
* to through the row/column index of the aEndCell
* aStartCell can be any location relative to aEndCell,
* as long as they are in the same table
* @param aStartCell starting cell in block
* @param aEndCell ending cell in block
*/
NS_IMETHOD SelectBlockOfCells(nsIDOMElement *aStartCell, nsIDOMElement *aEndCell)=0;
NS_IMETHOD SelectTableRow()=0;
NS_IMETHOD SelectTableColumn()=0;
NS_IMETHOD SelectTable()=0;

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

@ -284,30 +284,37 @@ text.color-caption {
}
div#ColorButtons {
/* Width needs to be >= 2x color button width
(color.gif=14px + 2 for border)
for initial layout.
Then use relative position to move buttons
to desired overlapping locations
/* Width needs to be enough for overlapping
buttons. Note: color.gif=14px + 2 for borders.
We use relative position to move buttons
to desired positions
*/
width: 32px;
max-width: 32px;
height: 19px;
/* This compensates for remaining gap
on right after relative button positioning
width: 30px;
max-width: 30px;
/* Other toolbar buttons are 16px high (+border and margin),
so limit total height of color buttons
region to a compatable height
*/
margin-right: -3px;
height: 22px;
max-height: 22px;
}
/* The initial layout of these buttons is:
BackColorPopupButton appears above TextColorPopupButton.
BackColorPopupButton must be 1st in XUL so that
TextColorPopupButton is on top after relative positioning,
which places TextColorPopupButton button in upper left and
BackColorPopupButton button at lower right of the ColorButtons div
*/
titledbutton#TextColorPopupButton {
list-style-image:url("chrome://editor/skin/images/color.gif");
border: 1px solid #CCCCCC;
padding: 0px;
margin: 0px;
position: relative;
/* Position top left */
top: 1px;
left: -14px;
top: -15px;
left: 1px;
/* TEMP: Set color here. TODO: Set color from page */
background-color: #AA0000;
@ -323,8 +330,7 @@ titledbutton#BackColorPopupButton {
padding: 0px;
margin: 0px;
position: relative;
/* Position lower right */
top: 8px;
top: 7px;
left: 12px;
/* TEMP: Set color here. TODO: Set color from page */