From 5ab9b7f9dfa5fe7b86b17d0166e304355eb57266 Mon Sep 17 00:00:00 2001 From: "cmanske%netscape.com" Date: Thu, 16 Mar 2000 23:45:39 +0000 Subject: [PATCH] Added support for table selection and removed nsIDOMSelectionListener code no longer needed. r=mjudge git-svn-id: svn://10.0.0.236/trunk@63201 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/content/base/src/nsDocumentViewer.cpp | 8 - mozilla/layout/base/nsCaret.cpp | 6 - mozilla/layout/base/nsCaret.h | 1 - mozilla/layout/base/nsDocumentViewer.cpp | 8 - mozilla/layout/base/nsIFrameSelection.h | 26 +- .../layout/base/public/nsIFrameSelection.h | 26 +- mozilla/layout/base/src/nsCaret.cpp | 6 - mozilla/layout/base/src/nsCaret.h | 1 - mozilla/layout/base/src/nsDocumentViewer.cpp | 8 - mozilla/layout/base/src/nsRangeList.cpp | 405 ++++++++++++++++-- mozilla/layout/generic/nsFrame.cpp | 176 +++++--- mozilla/layout/generic/nsFrame.h | 12 +- mozilla/layout/html/base/src/nsFrame.cpp | 176 +++++--- mozilla/layout/html/base/src/nsFrame.h | 12 +- .../html/forms/src/nsGfxTextControlFrame.cpp | 7 - .../html/forms/src/nsGfxTextControlFrame.h | 1 - 16 files changed, 681 insertions(+), 198 deletions(-) diff --git a/mozilla/content/base/src/nsDocumentViewer.cpp b/mozilla/content/base/src/nsDocumentViewer.cpp index a514c04d9c7..220fe5ce1bf 100644 --- a/mozilla/content/base/src/nsDocumentViewer.cpp +++ b/mozilla/content/base/src/nsDocumentViewer.cpp @@ -1687,11 +1687,3 @@ NS_IMETHODIMP nsDocViwerSelectionListener::NotifySelectionChanged() return NS_OK; } - -NS_IMETHODIMP nsDocViwerSelectionListener::TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset) -{ - //stub - return NS_OK; -} - - diff --git a/mozilla/layout/base/nsCaret.cpp b/mozilla/layout/base/nsCaret.cpp index 678869203c8..99cf5fe4f9a 100644 --- a/mozilla/layout/base/nsCaret.cpp +++ b/mozilla/layout/base/nsCaret.cpp @@ -320,12 +320,6 @@ NS_IMETHODIMP nsCaret::NotifySelectionChanged() return NS_OK; } -NS_IMETHODIMP nsCaret::TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset) -{ - //stub - return NS_OK; -} - #ifdef XP_MAC #pragma mark - #endif diff --git a/mozilla/layout/base/nsCaret.h b/mozilla/layout/base/nsCaret.h index d136b8a54b6..56dc183ba89 100644 --- a/mozilla/layout/base/nsCaret.h +++ b/mozilla/layout/base/nsCaret.h @@ -58,7 +58,6 @@ class nsCaret : public nsICaret, //nsIDOMSelectionListener interface NS_IMETHOD NotifySelectionChanged(); - NS_IMETHOD TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset); static void CaretBlinkCallback(nsITimer *aTimer, void *aClosure); diff --git a/mozilla/layout/base/nsDocumentViewer.cpp b/mozilla/layout/base/nsDocumentViewer.cpp index a514c04d9c7..220fe5ce1bf 100644 --- a/mozilla/layout/base/nsDocumentViewer.cpp +++ b/mozilla/layout/base/nsDocumentViewer.cpp @@ -1687,11 +1687,3 @@ NS_IMETHODIMP nsDocViwerSelectionListener::NotifySelectionChanged() return NS_OK; } - -NS_IMETHODIMP nsDocViwerSelectionListener::TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset) -{ - //stub - return NS_OK; -} - - diff --git a/mozilla/layout/base/nsIFrameSelection.h b/mozilla/layout/base/nsIFrameSelection.h index 09470748ee7..daaa67626d0 100644 --- a/mozilla/layout/base/nsIFrameSelection.h +++ b/mozilla/layout/base/nsIFrameSelection.h @@ -97,7 +97,15 @@ struct nsPeekOffsetStruct PRBool mJumpLines; }; - +// Values for aFlag parameter in HandleTableSelection +enum { + TABLESELECTION_CELL=1, + TABLESELECTION_ROW, + TABLESELECTION_COLUMN, + TABLESELECTION_TABLE, + TABLESELECTION_ALLCELLS +}; + class nsIFrameSelection : public nsISupports { public: static const nsIID& GetIID() { static nsIID iid = NS_IFRAMESELECTION_IID; return iid; } @@ -142,10 +150,9 @@ public: * cannot coexist with aContinueSelection * @param aHint will tell the selection which direction geometrically to actually show the caret on. * 1 = end of this line 0 = beggining of this line - * @param aIsCell will tell us if this range describes a Cell. */ NS_IMETHOD HandleClick(nsIContent *aNewFocus, PRUint32 aContentOffset, PRUint32 aContentEndOffset , - PRBool aContinueSelection, PRBool aMultipleSelection, PRBool aHint, PRBool aIsCell) = 0; + PRBool aContinueSelection, PRBool aMultipleSelection, PRBool aHint) = 0; /** HandleDrag extends the selection to contain the frame closest to aPoint. * @param aPresContext is the context to use when figuring out what frame contains the point. @@ -154,6 +161,19 @@ public: */ NS_IMETHOD HandleDrag(nsIPresContext *aPresContext, nsIFrame *aFrame, nsPoint& aPoint) = 0; + /** HandleTableSelection will set selection to a table, cell, etc + * depending on information contained in aFlags + * @param aParentContent is the paretent of either a table or cell that user clicked or dragged the mouse in + * @param aContentOffset is the offset of the table or cell + * @param aTarget indicates what to select: + * TABLESELECTION_CELL We should select a cell (content points to the cell) + * TABLESELECTION_ROW We should select a row (content points to first cell in row) + * TABLESELECTION_COLUMN We should select a row (content points to first cell in column) + * TABLESELECTION_TABLE We should select a table (content points to the table) + * TABLESELECTION_ALLCELLS We should select all cells (content points to first cell in table) + */ + NS_IMETHOD HandleTableSelection(nsIContent *aParentContent, PRInt32 aContentOffset, PRUint32 aTarget) = 0; + /** StartAutoScrollTimer is responsible for scrolling the view so that aPoint is always * visible, and for selecting any frame that contains aPoint. The timer will also reset * itself to fire again if the view has not scrolled to the end of the document. diff --git a/mozilla/layout/base/public/nsIFrameSelection.h b/mozilla/layout/base/public/nsIFrameSelection.h index 09470748ee7..daaa67626d0 100644 --- a/mozilla/layout/base/public/nsIFrameSelection.h +++ b/mozilla/layout/base/public/nsIFrameSelection.h @@ -97,7 +97,15 @@ struct nsPeekOffsetStruct PRBool mJumpLines; }; - +// Values for aFlag parameter in HandleTableSelection +enum { + TABLESELECTION_CELL=1, + TABLESELECTION_ROW, + TABLESELECTION_COLUMN, + TABLESELECTION_TABLE, + TABLESELECTION_ALLCELLS +}; + class nsIFrameSelection : public nsISupports { public: static const nsIID& GetIID() { static nsIID iid = NS_IFRAMESELECTION_IID; return iid; } @@ -142,10 +150,9 @@ public: * cannot coexist with aContinueSelection * @param aHint will tell the selection which direction geometrically to actually show the caret on. * 1 = end of this line 0 = beggining of this line - * @param aIsCell will tell us if this range describes a Cell. */ NS_IMETHOD HandleClick(nsIContent *aNewFocus, PRUint32 aContentOffset, PRUint32 aContentEndOffset , - PRBool aContinueSelection, PRBool aMultipleSelection, PRBool aHint, PRBool aIsCell) = 0; + PRBool aContinueSelection, PRBool aMultipleSelection, PRBool aHint) = 0; /** HandleDrag extends the selection to contain the frame closest to aPoint. * @param aPresContext is the context to use when figuring out what frame contains the point. @@ -154,6 +161,19 @@ public: */ NS_IMETHOD HandleDrag(nsIPresContext *aPresContext, nsIFrame *aFrame, nsPoint& aPoint) = 0; + /** HandleTableSelection will set selection to a table, cell, etc + * depending on information contained in aFlags + * @param aParentContent is the paretent of either a table or cell that user clicked or dragged the mouse in + * @param aContentOffset is the offset of the table or cell + * @param aTarget indicates what to select: + * TABLESELECTION_CELL We should select a cell (content points to the cell) + * TABLESELECTION_ROW We should select a row (content points to first cell in row) + * TABLESELECTION_COLUMN We should select a row (content points to first cell in column) + * TABLESELECTION_TABLE We should select a table (content points to the table) + * TABLESELECTION_ALLCELLS We should select all cells (content points to first cell in table) + */ + NS_IMETHOD HandleTableSelection(nsIContent *aParentContent, PRInt32 aContentOffset, PRUint32 aTarget) = 0; + /** StartAutoScrollTimer is responsible for scrolling the view so that aPoint is always * visible, and for selecting any frame that contains aPoint. The timer will also reset * itself to fire again if the view has not scrolled to the end of the document. diff --git a/mozilla/layout/base/src/nsCaret.cpp b/mozilla/layout/base/src/nsCaret.cpp index 678869203c8..99cf5fe4f9a 100644 --- a/mozilla/layout/base/src/nsCaret.cpp +++ b/mozilla/layout/base/src/nsCaret.cpp @@ -320,12 +320,6 @@ NS_IMETHODIMP nsCaret::NotifySelectionChanged() return NS_OK; } -NS_IMETHODIMP nsCaret::TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset) -{ - //stub - return NS_OK; -} - #ifdef XP_MAC #pragma mark - #endif diff --git a/mozilla/layout/base/src/nsCaret.h b/mozilla/layout/base/src/nsCaret.h index d136b8a54b6..56dc183ba89 100644 --- a/mozilla/layout/base/src/nsCaret.h +++ b/mozilla/layout/base/src/nsCaret.h @@ -58,7 +58,6 @@ class nsCaret : public nsICaret, //nsIDOMSelectionListener interface NS_IMETHOD NotifySelectionChanged(); - NS_IMETHOD TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset); static void CaretBlinkCallback(nsITimer *aTimer, void *aClosure); diff --git a/mozilla/layout/base/src/nsDocumentViewer.cpp b/mozilla/layout/base/src/nsDocumentViewer.cpp index a514c04d9c7..220fe5ce1bf 100644 --- a/mozilla/layout/base/src/nsDocumentViewer.cpp +++ b/mozilla/layout/base/src/nsDocumentViewer.cpp @@ -1687,11 +1687,3 @@ NS_IMETHODIMP nsDocViwerSelectionListener::NotifySelectionChanged() return NS_OK; } - -NS_IMETHODIMP nsDocViwerSelectionListener::TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset) -{ - //stub - return NS_OK; -} - - diff --git a/mozilla/layout/base/src/nsRangeList.cpp b/mozilla/layout/base/src/nsRangeList.cpp index 9a86ac460e1..8207bd54796 100644 --- a/mozilla/layout/base/src/nsRangeList.cpp +++ b/mozilla/layout/base/src/nsRangeList.cpp @@ -35,11 +35,14 @@ #include "nsIComponentManager.h" #include "nsLayoutCID.h" #include "nsIContent.h" +#include "nsIDOMElement.h" #include "nsIDOMNode.h" #include "nsCOMPtr.h" #include "nsRange.h" #include "nsISupportsArray.h" #include "nsIDOMKeyEvent.h" +#include "nsITableLayout.h" +#include "nsITableCellLayout.h" #include "nsIDOMSelectionListener.h" #include "nsIContentIterator.h" @@ -62,6 +65,7 @@ #include "nsITimerCallback.h" #define STATUS_CHECK_RETURN_MACRO() {if (!mTracker) return NS_ERROR_FAILURE;} +//#define DEBUG_TABLE 1 static NS_DEFINE_IID(kCContentIteratorCID, NS_CONTENTITERATOR_CID); static NS_DEFINE_IID(kCSubtreeIteratorCID, NS_SUBTREEITERATOR_CID); @@ -204,6 +208,21 @@ private: nsAutoScrollTimer *mAutoScrollTimer; // timer for autoscrolling. }; +// Stack-class to turn on/off selection batching for table selection +class nsSelectionBatcher +{ +private: + nsCOMPtr mSelection; +public: + nsSelectionBatcher(nsIDOMSelection *aSelection) : mSelection(aSelection) + { + if (mSelection) mSelection->StartBatchChanges(); + } + virtual ~nsSelectionBatcher() + { + if (mSelection) mSelection->EndBatchChanges(); + } +}; class nsRangeList : public nsIFrameSelection @@ -219,8 +238,9 @@ public: NS_IMETHOD HandleTextEvent(nsGUIEvent *aGUIEvent); NS_IMETHOD HandleKeyEvent(nsIPresContext* aPresContext, nsGUIEvent *aGuiEvent); NS_IMETHOD HandleClick(nsIContent *aNewFocus, PRUint32 aContentOffset, PRUint32 aContentEndOffset, - PRBool aContinueSelection, PRBool aMultipleSelection,PRBool aHint, PRBool aIsCell); + PRBool aContinueSelection, PRBool aMultipleSelection,PRBool aHint); NS_IMETHOD HandleDrag(nsIPresContext *aPresContext, nsIFrame *aFrame, nsPoint& aPoint); + NS_IMETHOD HandleTableSelection(nsIContent *aParentContent, PRInt32 aContentOffset, PRUint32 aFlags); NS_IMETHOD StartAutoScrollTimer(nsIPresContext *aPresContext, nsIFrame *aFrame, nsPoint& aPoint, PRUint32 aDelay); NS_IMETHOD StopAutoScrollTimer(); NS_IMETHOD EnableFrameNotification(PRBool aEnable){mNotifyFrames = aEnable; return NS_OK;} @@ -277,13 +297,25 @@ private: void SetDirty(PRBool aDirty=PR_TRUE){if (mBatching) mChangesDuringBatching = aDirty;} nsresult NotifySelectionListeners(); // add parameters to say collapsed etc? - nsresult NotifySelectionListeners(nsIDOMNode *aNode, PRUint32 aCellOffset); NS_IMETHOD SetHint(PRBool aHintRight); NS_IMETHOD GetHint(PRBool *aHintRight); nsDOMSelection *mDomSelections[NUM_SELECTIONTYPES]; + // Table selection support. Unfortunately, we can't get at nsITableCellLayout + // and nsITableLayout through nsIFrame, so we have to duplicate editor code here + nsresult SelectBlockOfCells(nsIContent *aStartNode, nsIContent *aEndNode); + nsresult GetCellIndexes(nsIContent *aCell, PRInt32 &aRowIndex, PRInt32 &aColIndex); + // aTableNode may be null if table isn't needed to be returned + PRBool IsInSameTable(nsIContent *aCell1, nsIContent *aCell2, nsIContent **aTableNode); + nsresult GetParentTable(nsIContent *aCellNode, nsIContent **aTableNode); + nsresult CreateAndAddRange(nsIDOMNode *aParentNode, PRInt32 aOffset); + + nsCOMPtr mStartSelectedCell; + nsCOMPtr mEndSelectedCell; + PRBool mSelectingTableCells; + //batching PRInt32 mBatching; PRBool mChangesDuringBatching; @@ -296,6 +328,7 @@ private: PRInt32 mDesiredX; PRBool mDesiredXSet; enum HINT {HINTLEFT=0,HINTRIGHT=1}mHint;//end of this line or beginning of next + public: static nsIAtom *sTableAtom; static nsIAtom *sCellAtom; @@ -644,6 +677,7 @@ nsRangeList::nsRangeList() } mHint = HINTLEFT; sInstanceCount ++; + mSelectingTableCells = PR_FALSE; } @@ -675,11 +709,6 @@ nsRangeList::~nsRangeList() } - -//END nsRangeList methods - - - NS_IMPL_ADDREF(nsRangeList) NS_IMPL_RELEASE(nsRangeList) @@ -1020,9 +1049,6 @@ nsRangeList::ConstrainFrameAndPointToAnchorSubtree(nsIPresContext *aPresContext, #pragma mark - #endif -//BEGIN nsIFrameSelection methods - - #ifdef PRINT_RANGE void printRange(nsIDOMRange *aDomRange) { @@ -1313,6 +1339,11 @@ nsRangeList::HandleKeyEvent(nsIPresContext* aPresContext, nsGUIEvent *aGuiEvent) return result; } +//END nsRangeList methods + + +//BEGIN nsIFrameSelection methods + NS_IMETHODIMP nsDOMSelection::ToString(nsString& aReturn) { @@ -1377,17 +1408,11 @@ nsDOMSelection::GetHint(PRBool *aHintRight) NS_IMETHODIMP nsRangeList::HandleClick(nsIContent *aNewFocus, PRUint32 aContentOffset, PRUint32 aContentEndOffset, PRBool aContinueSelection, - PRBool aMultipleSelection, PRBool aHint, PRBool aIsCell) + PRBool aMultipleSelection, PRBool aHint) { InvalidateDesiredX(); mHint = HINT(aHint); - if (aIsCell) - { - nsCOMPtr domNode = do_QueryInterface(aNewFocus); - return NotifySelectionListeners(domNode, aContentOffset); - } - nsresult result = TakeFocus(aNewFocus, aContentOffset, aContentEndOffset, aContinueSelection, aMultipleSelection); - return result; + return TakeFocus(aNewFocus, aContentOffset, aContentEndOffset, aContinueSelection, aMultipleSelection); } NS_IMETHODIMP @@ -1425,7 +1450,9 @@ nsRangeList::HandleDrag(nsIPresContext *aPresContext, nsIFrame *aFrame, nsPoint& startPos, contentOffsetEnd,beginOfContent); if (NS_SUCCEEDED(result)) - result = HandleClick(newContent, startPos, contentOffsetEnd , PR_TRUE, PR_FALSE,beginOfContent, PR_FALSE); + { + result = HandleClick(newContent, startPos, contentOffsetEnd , PR_TRUE, PR_FALSE, beginOfContent); + } return result; } @@ -1476,6 +1503,7 @@ nsRangeList::TakeFocus(nsIContent *aNewFocus, PRUint32 aContentOffset, if (aMultipleSelection){ nsCOMPtr newRange; NS_NewRange(getter_AddRefs(newRange)); + newRange->SetStart(domNode,aContentOffset); newRange->SetEnd(domNode,aContentOffset); mDomSelections[SELECTION_NORMAL]->AddRange(newRange); @@ -1534,6 +1562,13 @@ NS_METHOD nsRangeList::SetMouseDownState(PRBool aState) { mMouseDownState = aState; + if (!mMouseDownState) + { + // Mouse up kills table selection + mSelectingTableCells = PR_FALSE; + mStartSelectedCell = nsnull; + mEndSelectedCell = nsnull; + } return NS_OK; } @@ -1828,26 +1863,328 @@ nsRangeList::NotifySelectionListeners() return NS_OK; } +// Start of Table Selection methods nsresult -nsRangeList::NotifySelectionListeners(nsIDOMNode *aNode, PRUint32 aCellOffset) +nsRangeList::HandleTableSelection(nsIContent *aParentContent, PRInt32 aContentOffset, PRUint32 aTarget) { - if (!mSelectionListeners) - return NS_ERROR_FAILURE; - - PRUint32 cnt; - nsresult rv = mSelectionListeners->Count(&cnt); - if (NS_FAILED(rv)) return rv; - for (PRUint32 i = 0; i < cnt;i++) + if (!aParentContent) return NS_ERROR_NULL_POINTER; + if (mSelectingTableCells && (aTarget & TABLESELECTION_TABLE)) { - nsCOMPtr isupports(dont_AddRef(mSelectionListeners->ElementAt(i))); - nsCOMPtr thisListener = do_QueryInterface(isupports); - if (thisListener) - thisListener->TableCellNotification(aNode,aCellOffset); + // We were selecting cells and user drags mouse in table border or inbetween cells, + // just do nothing + return NS_OK; } - return NS_OK; + + nsCOMPtr parentNode = do_QueryInterface(aParentContent); + if (!parentNode) return NS_ERROR_FAILURE; + + nsCOMPtr childContent; + nsresult result = aParentContent->ChildAt(aContentOffset, *getter_AddRefs(childContent)); + if (NS_FAILED(result)) return result; + if (!childContent) return NS_ERROR_FAILURE; + + nsCOMPtr childNode = do_QueryInterface(childContent); + if (!childNode) return NS_ERROR_FAILURE; + + // Stack-class to wrap all table selection changes in + // BeginBatchChanges() / EndBatchChanges() + nsSelectionBatcher selectionBatcher(mDomSelections[SELECTION_NORMAL]); + + if (mSelectingTableCells) + { +#ifdef DEBUG_TABLE + printf("HandleTableSelection: dragging mouse\n"); +#endif + + if (aTarget == TABLESELECTION_CELL) + { + // If dragging in the same cell as last event, do nothing + if (mEndSelectedCell == childContent) + return NS_OK; + +#ifdef DEBUG_TABLE + printf("HandleTableSelection: Dragged into a new cell\n"); +#endif + // Reselect block of cells to new end location + mEndSelectedCell = childContent; + return SelectBlockOfCells(mStartSelectedCell, mEndSelectedCell); + } + } + else + { + // Not dragging -- mouse event is a click +#ifdef DEBUG_TABLE + printf("HandleTableSelection: CLICK event\n"); +#endif + + if (aTarget == TABLESELECTION_TABLE) + { + //TODO: Currently selects when clicked between cells, + // should we restrict to only around border? + // *** How do we get location data for cell and click? + mSelectingTableCells = PR_FALSE; + mStartSelectedCell = nsnull; + mEndSelectedCell = nsnull; +#ifdef DEBUG_TABLE + printf("HandleTableSelection: Selecting Table\n"); +#endif + // Select the table + mDomSelections[SELECTION_NORMAL]->ClearSelection(); + return CreateAndAddRange(parentNode, aContentOffset); + } + + // We are already selecting cells + // Check if cell clicked on is already selected + PRInt32 rangeCount; + result = mDomSelections[SELECTION_NORMAL]->GetRangeCount(&rangeCount); + if (NS_FAILED(result)) return result; + + nsCOMPtr parent; + nsCOMPtr range; + PRInt32 offset; + for( PRInt32 i = 0; i < rangeCount; i++) + { + result = mDomSelections[SELECTION_NORMAL]->GetRangeAt(i, getter_AddRefs(range)); + if (NS_FAILED(result)) return result; + if (!range) return NS_ERROR_NULL_POINTER; + + result = range->GetStartParent(getter_AddRefs(parent)); + if (NS_FAILED(result)) return result; + if (!parent) return NS_ERROR_NULL_POINTER; + + range->GetStartOffset(&offset); + if (parent.get() == parentNode && offset == aContentOffset) + { + // Cell is already selected + if (rangeCount == 1) + { +#ifdef DEBUG_TABLE + printf("HandleTableSelection: Unselecting single selected cell\n"); +#endif + // This was the only cell selected. + // Collapse to "normal" selection inside the cell + mSelectingTableCells = PR_FALSE; + mStartSelectedCell = nsnull; + mEndSelectedCell = nsnull; + //TODO: We need a "Collapse to just before deepest child" routine + // Even better, should we collapse to just after the LAST deepest child + // (i.e., at the end of the cell's contents)? + return mDomSelections[SELECTION_NORMAL]->Collapse(childNode, 0); + } +#ifdef DEBUG_TABLE + printf("HandleTableSelection: Removing cell from multi-cell selection\n"); +#endif + //TODO: Should we try to reassign to a different existing cell? + //mStartSelectedCell = nsnull; + //mEndSelectedCell = nsnull; + // Other cells are selected: + // Deselect cell by removing its range from selection + return mDomSelections[SELECTION_NORMAL]->RemoveRange(range); + } + } + + // If new cell in a different table is selected, clear existing selection + // Content of the last selection range's start parent + nsCOMPtr lastRangeContent = do_QueryInterface(parent); + if (!lastRangeContent) return NS_ERROR_FAILURE; + if (!IsInSameTable(lastRangeContent, childContent, nsnull)) + mDomSelections[SELECTION_NORMAL]->ClearSelection(); + +#ifdef DEBUG_TABLE + printf("HandleTableSelection: Adding new selected cell range\n"); +#endif + // Append a new selection range that surrounds the cell + // It would be nice to make the order of ranges + // map to the order of cells in table, + // but AddRange doesn't allow that + result = CreateAndAddRange(parentNode, aContentOffset); + if (NS_SUCCEEDED(result)) + { + mSelectingTableCells = PR_TRUE; + mStartSelectedCell = childContent; + mEndSelectedCell = childContent; + } + } + return result; } +nsresult +nsRangeList::SelectBlockOfCells(nsIContent *aStartCell, nsIContent *aEndCell) +{ + if (!aStartCell || !aEndCell) return NS_ERROR_NULL_POINTER; + + + // 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); + if(NS_FAILED(result)) return result; + result = GetCellIndexes(aEndCell, endRowIndex, endColIndex); + if(NS_FAILED(result)) return result; + + // Get parent table, and don't allow selection if start + // and end are not in same table + nsCOMPtr table; + if (!IsInSameTable(aStartCell, aEndCell, getter_AddRefs(table))) + return NS_OK; + + // It is now safe to clear the selection + // BE SURE TO RESET IT BEFORE LEAVING! + mDomSelections[SELECTION_NORMAL]->ClearSelection(); + + PRInt32 startColumn = PR_MIN(startColIndex, endColIndex); + PRInt32 startRow = PR_MIN(startRowIndex, endRowIndex); + PRInt32 maxColumn = PR_MAX(startColIndex, endColIndex); + PRInt32 maxRow = PR_MAX(startRowIndex, endRowIndex); + + // frames are not ref counted, so don't use an nsCOMPtr + nsIFrame *frame = nsnull; + result = GetTracker()->GetPrimaryFrameFor(table, &frame); + if (!frame) return NS_ERROR_FAILURE; + + nsITableLayout *tableLayoutObject = nsnull; + result = frame->QueryInterface(NS_GET_IID(nsITableLayout), (void**)(&tableLayoutObject)); + if (NS_FAILED(result)) return result; + if (!tableLayoutObject) return NS_ERROR_FAILURE; + + nsCOMPtr cell; + nsCOMPtr cellNode; + PRBool cellSelected = PR_FALSE; + PRInt32 rowSpan, colSpan, actualRowSpan, actualColSpan; + PRBool isSelected; + + for (PRInt32 row = startRow; row <= maxRow; row++) + { + for(PRInt32 col = startColumn; col <= maxColumn; col += actualColSpan) + { + result = tableLayoutObject->GetCellDataAt(row, col, *getter_AddRefs(cell), + startRowIndex, startColIndex, rowSpan, colSpan, + actualRowSpan, actualColSpan, isSelected); + if (NS_FAILED(result)) return result; + + NS_ASSERTION(actualColSpan, "!actualColSpan is 0!"); + + // Skip cells that are spanned from previous locations or are already selected + if (cell && row == startRowIndex && col == startColIndex && !isSelected) + { + cellNode = do_QueryInterface(cell); + nsCOMPtr parent; + result = cellNode->GetParentNode(getter_AddRefs(parent)); + if (NS_FAILED(result)) return result; + if (!parent) return NS_ERROR_FAILURE; + + //TODO: GET REAL CHILD OFFSET? It is very tempting to use col index as the offset! + result = CreateAndAddRange(parent, col); + if (NS_FAILED(result)) return result; + cellSelected = PR_TRUE; + } + } + } + // Safety code to put selection in starting cell if no cells were selected + if (!cellSelected) + { + cellNode = do_QueryInterface(aStartCell); + result = CreateAndAddRange(cellNode, 0); + } + + return result; +} + +nsresult +nsRangeList::GetCellIndexes(nsIContent *aCell, PRInt32 &aRowIndex, PRInt32 &aColIndex) +{ + if (!aCell) return NS_ERROR_NULL_POINTER; + + aColIndex=0; // initialize out params + aRowIndex=0; + + nsIFrame *frame = nsnull; // frames are not ref counted, so don't use an nsCOMPtr + nsresult result = GetTracker()->GetPrimaryFrameFor(aCell, &frame); + if (!frame) return NS_ERROR_FAILURE; + + nsITableCellLayout *cellLayoutObject=nsnull; // again, frames are not ref-counted + result = frame->QueryInterface(NS_GET_IID(nsITableCellLayout), (void**)(&cellLayoutObject)); + if (NS_FAILED(result)) return result; + if (!cellLayoutObject) return NS_ERROR_FAILURE; + return cellLayoutObject->GetCellIndexes(aRowIndex, aColIndex); +} + +PRBool +nsRangeList::IsInSameTable(nsIContent *aCell1, nsIContent *aCell2, nsIContent **aTable) +{ + if (!aCell1 || !aCell2) return NS_ERROR_NULL_POINTER; + + // aTable is optional: + if(aTable) *aTable = nsnull; + + nsCOMPtr tableNode1; + nsCOMPtr tableNode2; + + nsresult result = GetParentTable(aCell1, getter_AddRefs(tableNode1)); + if (NS_FAILED(result)) return PR_FALSE; + result = GetParentTable(aCell2, getter_AddRefs(tableNode2)); + if (NS_FAILED(result)) return PR_FALSE; + + // Must be in the same table + if (tableNode1 && (tableNode1 == tableNode2)) + { + if (aTable) + { + *aTable = tableNode1; + NS_ADDREF(*aTable); + } + return PR_TRUE;; + } + return NS_ERROR_FAILURE; +} + +nsresult +nsRangeList::GetParentTable(nsIContent *aCell, nsIContent **aTable) +{ + if (!aCell || !aTable) + return NS_ERROR_NULL_POINTER; + + nsCOMPtr parent; + nsresult result = aCell->GetParent(*getter_AddRefs(parent)); + + while (NS_SUCCEEDED(result) && parent) + { + nsIAtom *tag; + parent->GetTag(tag); + if (tag && tag == nsRangeList::sTableAtom) + { + *aTable = parent; + NS_ADDREF(*aTable); + return NS_OK; + } + nsCOMPtr temp; + result = parent->GetParent(*getter_AddRefs(temp)); + parent = temp; + } + return result; +} + +nsresult +nsRangeList::CreateAndAddRange(nsIDOMNode *aParentNode, PRInt32 aOffset) +{ + if (!aParentNode) return NS_ERROR_NULL_POINTER; + nsCOMPtr range; + NS_NewRange(getter_AddRefs(range)); + if (!range) return NS_ERROR_OUT_OF_MEMORY; + + // Set range around child at given offset + nsresult result = range->SetStart(aParentNode, aOffset); + if (NS_FAILED(result)) return result; + result = range->SetEnd(aParentNode, aOffset+1); + if (NS_FAILED(result)) return result; + + return mDomSelections[SELECTION_NORMAL]->AddRange(range); +} + +// End of Table Selection + NS_IMETHODIMP nsRangeList::SetHint(PRBool aHintRight) { @@ -3248,6 +3585,8 @@ nsDOMSelection::FixupSelectionPoints(nsIDOMRange *aRange , nsDirection *aDir, PR nsCOMPtr parent; nsCOMPtr subRange; NS_NewRange(getter_AddRefs(subRange)); + if (!subRange) return NS_ERROR_OUT_OF_MEMORY + result = subRange->SetStart(startNode,startOffset); if (NS_FAILED(result)) return result; @@ -3440,6 +3779,8 @@ nsDOMSelection::SetOriginalAnchorPoint(nsIDOMNode *aNode, PRInt32 aOffset) nsCOMPtr newRange; nsresult result; NS_NewRange(getter_AddRefs(newRange)); + if (!newRange) return NS_ERROR_OUT_OF_MEMORY; + result = newRange->SetStart(aNode,aOffset); if (NS_FAILED(result)) return result; diff --git a/mozilla/layout/generic/nsFrame.cpp b/mozilla/layout/generic/nsFrame.cpp index d415b545e1e..48d07e3f303 100644 --- a/mozilla/layout/generic/nsFrame.cpp +++ b/mozilla/layout/generic/nsFrame.cpp @@ -58,7 +58,8 @@ #include "nsCOMPtr.h" #include "nsStyleChangeList.h" #include "nsIDOMRange.h" -#include "nsITableCellLayout.h"//selection neccesity +#include "nsITableLayout.h" //selection neccesity +#include "nsITableCellLayout.h"// " // Some Misc #defines @@ -793,6 +794,102 @@ nsFrame::HandleEvent(nsIPresContext* aPresContext, return NS_OK; } +NS_IMETHODIMP +nsFrame::GetDataForTableSelection(nsMouseEvent *aMouseEvent, nsIContent **aParentContent, PRInt32 *aContentOffset, PRUint32 *aTarget) +{ + if (!aMouseEvent || !aParentContent || !aContentOffset || !aTarget) + return NS_ERROR_NULL_POINTER; + + *aParentContent = nsnull; + *aContentOffset = 0; + *aTarget = 0; + + // Test if special 'table selection' key is pressed + PRBool doTableSelection; + +#ifdef XP_MAC + doTableSelection = aMouseEvent->isMeta; +#else + doTableSelection = aMouseEvent->isControl; +#endif + + if (!doTableSelection) return NS_OK; + + // Get the cell frame or table frame (or parent) of the current content node + nsIFrame *frame = this; + nsresult result = NS_OK; + PRBool foundCell = PR_FALSE; + PRBool foundTable = PR_FALSE; + +#ifdef DEBUG_cmanske +// Exploring how to get location info for doing table/row/column selection +//printf("*** Mouse event at origin: x=%d, y=%d\n", aMouseEvent->point.x, aMouseEvent->point.y); +//printf("*** Frame rect origin: x=%d, y=%d\n", this->mRect.x, this->mRect.y); +#endif + + while (frame && NS_SUCCEEDED(result)) + { + // Check for a table cell by querying to a known CellFrame interface + nsITableCellLayout *cellElement; + result = (frame)->QueryInterface(nsITableCellLayout::GetIID(), (void **)&cellElement); + if (NS_SUCCEEDED(result) && cellElement) + { + foundCell = PR_TRUE; + break; + } + else + { + // If not a cell, check for table + // This will happen when starting frame is the table or child of a table, + // such as a row (we were inbetween cells or in table border) + nsITableLayout *tableElement; + result = (frame)->QueryInterface(nsITableLayout::GetIID(), (void **)&tableElement); + if (NS_SUCCEEDED(result) && tableElement) + { + foundTable = PR_TRUE; + break; + } + else + result = (frame)->GetParent(&frame); + } + } + // We aren't in a cell or table + if (!foundCell && !foundTable) return NS_OK; + + nsCOMPtr tableOrCellContent; + result = frame->GetContent(getter_AddRefs(tableOrCellContent)); + if (NS_FAILED(result)) return result; + if (!tableOrCellContent) return NS_ERROR_FAILURE; + + nsCOMPtr parentContent; + result = tableOrCellContent->GetParent(*getter_AddRefs(parentContent)); + if (NS_FAILED(result)) return result; + if (!parentContent) return NS_ERROR_FAILURE; + + PRInt32 offset; + result = parentContent->IndexOf(tableOrCellContent, offset); + if (NS_FAILED(result)) return result; + // Not likely? + if (offset < 0) return NS_ERROR_FAILURE; + + // Everything is OK -- set the return values + *aParentContent = parentContent; + NS_ADDREF(*aParentContent); + + *aContentOffset = offset; + + if (foundCell) + *aTarget = TABLESELECTION_CELL; + + if (foundTable) + { + //TODO: Put logic to find "hit" spots for selecting column or row here + *aTarget = TABLESELECTION_TABLE; + } + + return NS_OK; +} + /** * Handles the Mouse Press Event for the frame */ @@ -818,46 +915,22 @@ nsFrame::HandlePress(nsIPresContext* aPresContext, PRBool beginContent; if (NS_SUCCEEDED(GetContentAndOffsetsFromPoint(aPresContext, aEvent->point, getter_AddRefs(newContent), - startPos, contentOffsetEnd, beginContent))){ + startPos, contentOffsetEnd, beginContent))) + { nsCOMPtr frameselection; - if (NS_SUCCEEDED(shell->GetFrameSelection(getter_AddRefs(frameselection))) && frameselection){ + if (NS_SUCCEEDED(shell->GetFrameSelection(getter_AddRefs(frameselection))) && frameselection) + { frameselection->SetMouseDownState(PR_TRUE);//not important if it fails here - PRBool doCellSelection; -#ifdef XP_MAC - doCellSelection = me->isMeta; -#else - doCellSelection = me->isControl; -#endif - nsIFrame *cellFrame; - if (doCellSelection) - { - nsresult result = GrabContainingCell(&cellFrame); - if (NS_SUCCEEDED(result) && cellFrame) - { - nsIContent* cellContent; - result = cellFrame->GetContent(&cellContent); - if (NS_SUCCEEDED(result) && cellContent) - { - nsIContent* parentContent; - result = cellContent->GetParent(parentContent); - if (parentContent){ - PRInt32 newIndex; - result = parentContent->IndexOf(cellContent, newIndex); - if (NS_SUCCEEDED(result) && newIndex >= 0) - { - frameselection->HandleClick(parentContent,newIndex, newIndex+1,me->isShift,PR_FALSE, beginContent, PR_TRUE); - } - NS_IF_RELEASE(parentContent); - } - NS_IF_RELEASE(cellContent); - } - } - } + nsCOMPtrparentContent; + PRInt32 contentOffset; + PRUint32 target; + nsresult result = GetDataForTableSelection(me, getter_AddRefs(parentContent), &contentOffset, &target); + if (NS_SUCCEEDED(result) && parentContent) + frameselection->HandleTableSelection(parentContent, contentOffset, target); else - frameselection->HandleClick(newContent, startPos , contentOffsetEnd , me->isShift, PR_FALSE, beginContent, PR_FALSE); + frameselection->HandleClick(newContent, startPos , contentOffsetEnd , me->isShift, PR_FALSE, beginContent); } - //no release } } return NS_OK; @@ -975,7 +1048,18 @@ NS_IMETHODIMP nsFrame::HandleDrag(nsIPresContext* aPresContext, if (NS_SUCCEEDED(result) && frameselection) { frameselection->StopAutoScrollTimer(); - frameselection->HandleDrag(aPresContext, this, aEvent->point); + + // Check if we are dragging in a table cell + nsCOMPtr parentContent; + PRInt32 contentOffset; + PRUint32 target; + nsMouseEvent *me = (nsMouseEvent *)aEvent; + result = GetDataForTableSelection(me, getter_AddRefs(parentContent), &contentOffset, &target); + if (NS_SUCCEEDED(result) && parentContent) + frameselection->HandleTableSelection(parentContent, contentOffset, target); + else + frameselection->HandleDrag(aPresContext, this, aEvent->point); + frameselection->StartAutoScrollTimer(aPresContext, this, aEvent->point, 30); } @@ -2694,24 +2778,6 @@ nsFrame::GetFirstLeaf(nsIPresContext* aPresContext, nsIFrame **aFrame) } } -NS_IMETHODIMP -nsFrame::GrabContainingCell(nsIFrame **aCellFrame) -{ - *aCellFrame = this; - nsresult result = NS_OK; - while (*aCellFrame && NS_SUCCEEDED(result)) - { - nsITableCellLayout *cellelement; - - result = (*aCellFrame)->QueryInterface(nsITableCellLayout::GetIID(), (void **)&cellelement); - if (NS_SUCCEEDED(result) && cellelement) - return NS_OK; - else - result = (*aCellFrame)->GetParent(aCellFrame); - } - return result?result:NS_ERROR_FAILURE; -} - nsresult nsFrame::CreateAndPostReflowCommand(nsIPresShell* aPresShell, nsIFrame* aTargetFrame, nsIReflowCommand::ReflowType aReflowType, diff --git a/mozilla/layout/generic/nsFrame.h b/mozilla/layout/generic/nsFrame.h index 5e194f9994f..f3f5cc5d99b 100644 --- a/mozilla/layout/generic/nsFrame.h +++ b/mozilla/layout/generic/nsFrame.h @@ -404,8 +404,16 @@ protected: //given a frame five me the first/last leaf available static void GetLastLeaf(nsIPresContext* aPresContext, nsIFrame **aFrame); static void GetFirstLeaf(nsIPresContext* aPresContext, nsIFrame **aFrame); - //grab this as the closest cell or go up the chain till nothing or a cell - NS_IMETHOD GrabContainingCell(nsIFrame **aCellFrame); + + // Test if we are selecting a table object: + // First test if Ctrl (Cmd on Mac) key is down during a mouse click or drag + // If yes, get the parent content node and offset of the frame + // of the enclosing cell or table (if not inside a cell) + // aTarget tells us what table element to select (currently only cell and table supported) + // (enums for this are defined in nsIFrame.h) + NS_IMETHOD GetDataForTableSelection(nsMouseEvent *aMouseEvent, nsIContent **aParentContent, + PRInt32 *aContentOffset, PRUint32 *aTarget); + static void XMLQuote(nsString& aString); virtual PRBool ParentDisablesSelection() const; diff --git a/mozilla/layout/html/base/src/nsFrame.cpp b/mozilla/layout/html/base/src/nsFrame.cpp index d415b545e1e..48d07e3f303 100644 --- a/mozilla/layout/html/base/src/nsFrame.cpp +++ b/mozilla/layout/html/base/src/nsFrame.cpp @@ -58,7 +58,8 @@ #include "nsCOMPtr.h" #include "nsStyleChangeList.h" #include "nsIDOMRange.h" -#include "nsITableCellLayout.h"//selection neccesity +#include "nsITableLayout.h" //selection neccesity +#include "nsITableCellLayout.h"// " // Some Misc #defines @@ -793,6 +794,102 @@ nsFrame::HandleEvent(nsIPresContext* aPresContext, return NS_OK; } +NS_IMETHODIMP +nsFrame::GetDataForTableSelection(nsMouseEvent *aMouseEvent, nsIContent **aParentContent, PRInt32 *aContentOffset, PRUint32 *aTarget) +{ + if (!aMouseEvent || !aParentContent || !aContentOffset || !aTarget) + return NS_ERROR_NULL_POINTER; + + *aParentContent = nsnull; + *aContentOffset = 0; + *aTarget = 0; + + // Test if special 'table selection' key is pressed + PRBool doTableSelection; + +#ifdef XP_MAC + doTableSelection = aMouseEvent->isMeta; +#else + doTableSelection = aMouseEvent->isControl; +#endif + + if (!doTableSelection) return NS_OK; + + // Get the cell frame or table frame (or parent) of the current content node + nsIFrame *frame = this; + nsresult result = NS_OK; + PRBool foundCell = PR_FALSE; + PRBool foundTable = PR_FALSE; + +#ifdef DEBUG_cmanske +// Exploring how to get location info for doing table/row/column selection +//printf("*** Mouse event at origin: x=%d, y=%d\n", aMouseEvent->point.x, aMouseEvent->point.y); +//printf("*** Frame rect origin: x=%d, y=%d\n", this->mRect.x, this->mRect.y); +#endif + + while (frame && NS_SUCCEEDED(result)) + { + // Check for a table cell by querying to a known CellFrame interface + nsITableCellLayout *cellElement; + result = (frame)->QueryInterface(nsITableCellLayout::GetIID(), (void **)&cellElement); + if (NS_SUCCEEDED(result) && cellElement) + { + foundCell = PR_TRUE; + break; + } + else + { + // If not a cell, check for table + // This will happen when starting frame is the table or child of a table, + // such as a row (we were inbetween cells or in table border) + nsITableLayout *tableElement; + result = (frame)->QueryInterface(nsITableLayout::GetIID(), (void **)&tableElement); + if (NS_SUCCEEDED(result) && tableElement) + { + foundTable = PR_TRUE; + break; + } + else + result = (frame)->GetParent(&frame); + } + } + // We aren't in a cell or table + if (!foundCell && !foundTable) return NS_OK; + + nsCOMPtr tableOrCellContent; + result = frame->GetContent(getter_AddRefs(tableOrCellContent)); + if (NS_FAILED(result)) return result; + if (!tableOrCellContent) return NS_ERROR_FAILURE; + + nsCOMPtr parentContent; + result = tableOrCellContent->GetParent(*getter_AddRefs(parentContent)); + if (NS_FAILED(result)) return result; + if (!parentContent) return NS_ERROR_FAILURE; + + PRInt32 offset; + result = parentContent->IndexOf(tableOrCellContent, offset); + if (NS_FAILED(result)) return result; + // Not likely? + if (offset < 0) return NS_ERROR_FAILURE; + + // Everything is OK -- set the return values + *aParentContent = parentContent; + NS_ADDREF(*aParentContent); + + *aContentOffset = offset; + + if (foundCell) + *aTarget = TABLESELECTION_CELL; + + if (foundTable) + { + //TODO: Put logic to find "hit" spots for selecting column or row here + *aTarget = TABLESELECTION_TABLE; + } + + return NS_OK; +} + /** * Handles the Mouse Press Event for the frame */ @@ -818,46 +915,22 @@ nsFrame::HandlePress(nsIPresContext* aPresContext, PRBool beginContent; if (NS_SUCCEEDED(GetContentAndOffsetsFromPoint(aPresContext, aEvent->point, getter_AddRefs(newContent), - startPos, contentOffsetEnd, beginContent))){ + startPos, contentOffsetEnd, beginContent))) + { nsCOMPtr frameselection; - if (NS_SUCCEEDED(shell->GetFrameSelection(getter_AddRefs(frameselection))) && frameselection){ + if (NS_SUCCEEDED(shell->GetFrameSelection(getter_AddRefs(frameselection))) && frameselection) + { frameselection->SetMouseDownState(PR_TRUE);//not important if it fails here - PRBool doCellSelection; -#ifdef XP_MAC - doCellSelection = me->isMeta; -#else - doCellSelection = me->isControl; -#endif - nsIFrame *cellFrame; - if (doCellSelection) - { - nsresult result = GrabContainingCell(&cellFrame); - if (NS_SUCCEEDED(result) && cellFrame) - { - nsIContent* cellContent; - result = cellFrame->GetContent(&cellContent); - if (NS_SUCCEEDED(result) && cellContent) - { - nsIContent* parentContent; - result = cellContent->GetParent(parentContent); - if (parentContent){ - PRInt32 newIndex; - result = parentContent->IndexOf(cellContent, newIndex); - if (NS_SUCCEEDED(result) && newIndex >= 0) - { - frameselection->HandleClick(parentContent,newIndex, newIndex+1,me->isShift,PR_FALSE, beginContent, PR_TRUE); - } - NS_IF_RELEASE(parentContent); - } - NS_IF_RELEASE(cellContent); - } - } - } + nsCOMPtrparentContent; + PRInt32 contentOffset; + PRUint32 target; + nsresult result = GetDataForTableSelection(me, getter_AddRefs(parentContent), &contentOffset, &target); + if (NS_SUCCEEDED(result) && parentContent) + frameselection->HandleTableSelection(parentContent, contentOffset, target); else - frameselection->HandleClick(newContent, startPos , contentOffsetEnd , me->isShift, PR_FALSE, beginContent, PR_FALSE); + frameselection->HandleClick(newContent, startPos , contentOffsetEnd , me->isShift, PR_FALSE, beginContent); } - //no release } } return NS_OK; @@ -975,7 +1048,18 @@ NS_IMETHODIMP nsFrame::HandleDrag(nsIPresContext* aPresContext, if (NS_SUCCEEDED(result) && frameselection) { frameselection->StopAutoScrollTimer(); - frameselection->HandleDrag(aPresContext, this, aEvent->point); + + // Check if we are dragging in a table cell + nsCOMPtr parentContent; + PRInt32 contentOffset; + PRUint32 target; + nsMouseEvent *me = (nsMouseEvent *)aEvent; + result = GetDataForTableSelection(me, getter_AddRefs(parentContent), &contentOffset, &target); + if (NS_SUCCEEDED(result) && parentContent) + frameselection->HandleTableSelection(parentContent, contentOffset, target); + else + frameselection->HandleDrag(aPresContext, this, aEvent->point); + frameselection->StartAutoScrollTimer(aPresContext, this, aEvent->point, 30); } @@ -2694,24 +2778,6 @@ nsFrame::GetFirstLeaf(nsIPresContext* aPresContext, nsIFrame **aFrame) } } -NS_IMETHODIMP -nsFrame::GrabContainingCell(nsIFrame **aCellFrame) -{ - *aCellFrame = this; - nsresult result = NS_OK; - while (*aCellFrame && NS_SUCCEEDED(result)) - { - nsITableCellLayout *cellelement; - - result = (*aCellFrame)->QueryInterface(nsITableCellLayout::GetIID(), (void **)&cellelement); - if (NS_SUCCEEDED(result) && cellelement) - return NS_OK; - else - result = (*aCellFrame)->GetParent(aCellFrame); - } - return result?result:NS_ERROR_FAILURE; -} - nsresult nsFrame::CreateAndPostReflowCommand(nsIPresShell* aPresShell, nsIFrame* aTargetFrame, nsIReflowCommand::ReflowType aReflowType, diff --git a/mozilla/layout/html/base/src/nsFrame.h b/mozilla/layout/html/base/src/nsFrame.h index 5e194f9994f..f3f5cc5d99b 100644 --- a/mozilla/layout/html/base/src/nsFrame.h +++ b/mozilla/layout/html/base/src/nsFrame.h @@ -404,8 +404,16 @@ protected: //given a frame five me the first/last leaf available static void GetLastLeaf(nsIPresContext* aPresContext, nsIFrame **aFrame); static void GetFirstLeaf(nsIPresContext* aPresContext, nsIFrame **aFrame); - //grab this as the closest cell or go up the chain till nothing or a cell - NS_IMETHOD GrabContainingCell(nsIFrame **aCellFrame); + + // Test if we are selecting a table object: + // First test if Ctrl (Cmd on Mac) key is down during a mouse click or drag + // If yes, get the parent content node and offset of the frame + // of the enclosing cell or table (if not inside a cell) + // aTarget tells us what table element to select (currently only cell and table supported) + // (enums for this are defined in nsIFrame.h) + NS_IMETHOD GetDataForTableSelection(nsMouseEvent *aMouseEvent, nsIContent **aParentContent, + PRInt32 *aContentOffset, PRUint32 *aTarget); + static void XMLQuote(nsString& aString); virtual PRBool ParentDisablesSelection() const; diff --git a/mozilla/layout/html/forms/src/nsGfxTextControlFrame.cpp b/mozilla/layout/html/forms/src/nsGfxTextControlFrame.cpp index 565b4699814..4ea35fc795b 100644 --- a/mozilla/layout/html/forms/src/nsGfxTextControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsGfxTextControlFrame.cpp @@ -4272,13 +4272,6 @@ nsEnderEventListener::NotifySelectionChanged() return NS_OK; } -NS_IMETHODIMP -nsEnderEventListener::TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset) -{ - //stub - return NS_OK; -} - NS_IMETHODIMP nsEnderEventListener::WillDo(nsITransactionManager *aManager, nsITransaction *aTransaction, PRBool *aInterrupt) { diff --git a/mozilla/layout/html/forms/src/nsGfxTextControlFrame.h b/mozilla/layout/html/forms/src/nsGfxTextControlFrame.h index 3cdff942194..03eb8468f24 100644 --- a/mozilla/layout/html/forms/src/nsGfxTextControlFrame.h +++ b/mozilla/layout/html/forms/src/nsGfxTextControlFrame.h @@ -252,7 +252,6 @@ public: * @see nsIDOMSelectionListener */ NS_IMETHOD NotifySelectionChanged(); - NS_IMETHOD TableCellNotification(nsIDOMNode* aNode, PRInt32 aOffset); /*END interfaces from nsIDOMSelectionListener*/ /** nsITransactionListener interfaces