From 1b7d75c3dbef3ba75fb16aee41f54af3380ee32e Mon Sep 17 00:00:00 2001 From: "mjudge%netscape.com" Date: Fri, 9 Jun 2000 21:55:50 +0000 Subject: [PATCH] didnt implement selection. bug=34896. r=hyatt git-svn-id: svn://10.0.0.236/trunk@71923 18797224-902f-48f8-a5cc-f745e15eee43 --- .../html/forms/src/nsGfxTextControlFrame2.cpp | 236 +++++++++++++++++- .../html/forms/src/nsGfxTextControlFrame2.h | 12 +- 2 files changed, 237 insertions(+), 11 deletions(-) diff --git a/mozilla/layout/html/forms/src/nsGfxTextControlFrame2.cpp b/mozilla/layout/html/forms/src/nsGfxTextControlFrame2.cpp index 4bdd40f9133..ac4aadc56db 100644 --- a/mozilla/layout/html/forms/src/nsGfxTextControlFrame2.cpp +++ b/mozilla/layout/html/forms/src/nsGfxTextControlFrame2.cpp @@ -79,7 +79,10 @@ #include "nsIDOMKeyEvent.h" #include "nsIPrivateDOMEvent.h" #include "nsIDOMEventReceiver.h" - +#include "nsIDOMCharacterData.h" //for selection setting helper func +#include "nsIDOMNodeList.h" //for selection settting helper func +#include "nsIDOMRange.h" //for selection settting helper func +#include "nsRange.h" //for selection settting helper func (i cant believe this is exported!?) #define DEFAULT_COLUMN_WIDTH 20 @@ -1877,29 +1880,242 @@ nsGfxTextControlFrame2::GetTextLength(PRInt32* aTextLength) NS_IMETHODIMP -nsGfxTextControlFrame2::SetSelectionStart(PRInt32 aSelectionStart) +nsGfxTextControlFrame2::GetFirstTextNode(nsIDOMCharacterData* *aFirstTextNode) { - return NS_ERROR_NOT_IMPLEMENTED; + if (!mEditor) + return NS_ERROR_NOT_INITIALIZED; + nsCOMPtr rootElement; + mEditor->GetRootElement(getter_AddRefs(rootElement)); + *aFirstTextNode = nsnull; + + nsCOMPtr rootNode = do_QueryInterface(rootElement); + if (!rootNode) return NS_ERROR_FAILURE; + + // for a text widget, the text of the document is in a single + // text node under the body. Let's make sure that's true. + nsCOMPtr childNodesList; + rootNode->GetChildNodes(getter_AddRefs(childNodesList)); + if (!childNodesList) + { + NS_WARNING("rootNode has no text node list"); + return NS_ERROR_FAILURE; + } + + PRUint32 numChildNodes = 0; + childNodesList->GetLength(&numChildNodes); + + nsCOMPtr firstChild; + nsresult rv = rootNode->GetFirstChild(getter_AddRefs(firstChild)); + if (NS_FAILED(rv)) return rv; + if (!firstChild) return NS_ERROR_FAILURE; + + nsCOMPtr charDataNode = do_QueryInterface(firstChild, &rv); + if (NS_FAILED(rv)) return rv; + + NS_ADDREF(*aFirstTextNode = charDataNode); + return NS_OK; } +nsresult +nsGfxTextControlFrame2::SelectAllContents() +{ + nsresult rv; + + if (IsSingleLineTextControl()) + { + rv = SetSelectionRange(0, eSelectToEnd); + } + else + { + // we have to select all + if (!mEditor) + return NS_ERROR_NOT_INITIALIZED; + NS_ASSERTION(mEditor, "Should have an editor here"); + rv = mEditor->SelectAll(); + } + + return rv; +} + + +nsresult +nsGfxTextControlFrame2::SetSelectionEndPoints(PRInt32 aSelStart, PRInt32 aSelEnd) +{ + NS_ASSERTION(IsSingleLineTextControl(), "Should only call this on a single line input"); + NS_ASSERTION(mEditor, "Should have an editor here"); + NS_ASSERTION(mTextSelImpl,"selection not found!"); + + nsCOMPtr firstTextNode; + nsresult rv = GetFirstTextNode(getter_AddRefs(firstTextNode)); + if (NS_FAILED(rv) || !firstTextNode) + { + // probably an empty document. not an error + return NS_OK; + } + + nsCOMPtr firstNode = do_QueryInterface(firstTextNode, &rv); + if (!firstNode) return rv; + + // constrain the selection to this node + PRUint32 nodeLengthU; + firstTextNode->GetLength(&nodeLengthU); + PRInt32 nodeLength = (PRInt32)nodeLengthU; + + nsCOMPtr selection; + mTextSelImpl->GetSelection(nsISelectionController::SELECTION_NORMAL,getter_AddRefs(selection)); + if (!selection) return NS_ERROR_FAILURE; + + // are we setting both start and end? + if (aSelStart != eIgnoreSelect && aSelEnd != eIgnoreSelect) + { + if (aSelStart == eSelectToEnd || aSelStart > nodeLength) + aSelStart = nodeLength; + if (aSelStart < 0) + aSelStart = 0; + + if (aSelEnd == eSelectToEnd || aSelEnd > nodeLength) + aSelEnd = nodeLength; + if (aSelEnd < 0) + aSelEnd = 0; + + // remove existing ranges + selection->ClearSelection(); + + nsCOMPtr selectionRange; + NS_NewRange(getter_AddRefs(selectionRange)); + if (!selectionRange) return NS_ERROR_OUT_OF_MEMORY; + + selectionRange->SetStart(firstTextNode, aSelStart); + selectionRange->SetEnd(firstTextNode, aSelEnd); + + selection->AddRange(selectionRange); + } + else // we're setting either start or end but not both + { + // does a range exist? + nsCOMPtr firstRange; + selection->GetRangeAt(0, getter_AddRefs(firstRange)); + PRBool mustAdd = PR_FALSE; + PRInt32 selStart = 0, selEnd = 0; + + if (firstRange) + { + firstRange->GetStartOffset(&selStart); + firstRange->GetEndOffset(&selEnd); + } + else + { + // no range. Make a new one. + NS_NewRange(getter_AddRefs(firstRange)); + if (!firstRange) return NS_ERROR_OUT_OF_MEMORY; + mustAdd = PR_TRUE; + } + + if (aSelStart == eSelectToEnd) + selStart = nodeLength; + else if (aSelStart != eIgnoreSelect) + selStart = aSelStart; + + if (aSelEnd == eSelectToEnd) + selEnd = nodeLength; + else if (aSelEnd != eIgnoreSelect) + selEnd = aSelEnd; + + // swap them + if (selEnd < selStart) + { + PRInt32 temp = selStart; + selStart = selEnd; + selEnd = temp; + } + + firstRange->SetStart(firstTextNode, selStart); + firstRange->SetEnd(firstTextNode, selEnd); + if (mustAdd) + selection->AddRange(firstRange); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsGfxTextControlFrame2::SetSelectionRange(PRInt32 aSelStart, PRInt32 aSelEnd) +{ + if (!IsSingleLineTextControl()) return NS_ERROR_NOT_IMPLEMENTED; + + // make sure we have an editor + if (!mEditor) + return NS_ERROR_NOT_INITIALIZED; + + return SetSelectionEndPoints(aSelStart, aSelEnd); +} + + +NS_IMETHODIMP +nsGfxTextControlFrame2::SetSelectionStart(PRInt32 aSelectionStart) +{ + if (!IsSingleLineTextControl()) return NS_ERROR_NOT_IMPLEMENTED; + + // make sure we have an editor + if (!mEditor) + return NS_ERROR_NOT_INITIALIZED; + + return SetSelectionEndPoints(aSelectionStart, eIgnoreSelect); +} NS_IMETHODIMP nsGfxTextControlFrame2::SetSelectionEnd(PRInt32 aSelectionEnd) { - return NS_ERROR_NOT_IMPLEMENTED; + if (!IsSingleLineTextControl()) return NS_ERROR_NOT_IMPLEMENTED; + + // make sure we have an editor + if (!mEditor) + return NS_ERROR_NOT_INITIALIZED; + + return SetSelectionEndPoints(eIgnoreSelect, aSelectionEnd); } -NS_IMETHODIMP -nsGfxTextControlFrame2::SetSelectionRange(PRInt32 aSelectionStart, PRInt32 aSelectionEnd) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} NS_IMETHODIMP nsGfxTextControlFrame2::GetSelectionRange(PRInt32* aSelectionStart, PRInt32* aSelectionEnd) { - return NS_ERROR_NOT_IMPLEMENTED; + if (!IsSingleLineTextControl()) return NS_ERROR_NOT_IMPLEMENTED; + + NS_ENSURE_ARG_POINTER((aSelectionStart && aSelectionEnd)); + + // make sure we have an editor + if (!mEditor) + return NS_ERROR_NOT_INITIALIZED; + + nsCOMPtr selection; + mTextSelImpl->GetSelection(nsISelectionController::SELECTION_NORMAL,getter_AddRefs(selection)); + if (!selection) return NS_ERROR_FAILURE; + + // we should have only zero or one range + PRInt32 numRanges = 0; + selection->GetRangeCount(&numRanges); + if (numRanges > 1) + { + NS_ASSERTION(0, "Found more than on range in GetSelectionRange"); + } + + if (numRanges == 0) + { + *aSelectionStart = 0; + *aSelectionEnd = 0; + } + else + { + nsCOMPtr firstRange; + selection->GetRangeAt(0, getter_AddRefs(firstRange)); + if (!firstRange) + return NS_ERROR_FAILURE; + firstRange->GetStartOffset(aSelectionStart); + firstRange->GetEndOffset(aSelectionEnd); + } + + return NS_OK; } diff --git a/mozilla/layout/html/forms/src/nsGfxTextControlFrame2.h b/mozilla/layout/html/forms/src/nsGfxTextControlFrame2.h index 0a09a430785..ed228e49f6f 100644 --- a/mozilla/layout/html/forms/src/nsGfxTextControlFrame2.h +++ b/mozilla/layout/html/forms/src/nsGfxTextControlFrame2.h @@ -44,7 +44,7 @@ class nsIEditor; class nsISelectionController; class nsTextAreaSelectionImpl; class nsTextAreaKeyListener; - +class nsIDOMCharacterData; class nsGfxTextControlFrame2 : public nsStackFrame, @@ -215,6 +215,16 @@ protected: NS_IMETHOD RestoreState(nsIPresContext* aPresContext, nsIPresState* aState); +private: + //helper methods + enum { + eIgnoreSelect = -2, + eSelectToEnd = -1 + }; + + NS_IMETHODIMP GetFirstTextNode(nsIDOMCharacterData* *aFirstTextNode); + nsresult SelectAllContents(); + nsresult SetSelectionEndPoints(PRInt32 aSelStart, PRInt32 aSelEnd); private: nsCOMPtr mEditor; nsCOMPtr mSelCon;