Fix for bugzilla 91131(Cannot spellcheck selection)

First pass implementation of spellcheck selection feature:

  editor/composer/src/nsEditorSpellCheck.cpp
  editor/idl/nsIEditorSpellCheck.idl
  editor/txtsvc/public/nsITextServicesDocument.h
  editor/txtsvc/src/Makefile.in
  editor/txtsvc/src/nsTextServicesDocument.cpp
  editor/txtsvc/src/nsTextServicesDocument.h
  editor/ui/composer/content/ComposerCommands.js
  editor/ui/dialogs/content/EdSpellCheck.js
  mailnews/compose/resources/content/MsgComposeCommands.js

r=jfrancis@netscape.com,brade@netscape.com  sr=sfraser@netscape.com


git-svn-id: svn://10.0.0.236/trunk@141315 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
kin%netscape.com 2003-04-17 14:29:08 +00:00
parent a74566cb5d
commit 733361e518
9 changed files with 1020 additions and 342 deletions

View File

@ -43,6 +43,9 @@
#include "nsTextServicesCID.h"
#include "nsITextServicesDocument.h"
#include "nsISpellChecker.h"
#include "nsISelection.h"
#include "nsIDOMRange.h"
#include "nsIEditor.h"
#include "nsIComponentManager.h"
#include "nsXPIDLString.h"
@ -73,7 +76,7 @@ nsEditorSpellCheck::~nsEditorSpellCheck()
}
NS_IMETHODIMP
nsEditorSpellCheck::InitSpellChecker(nsIEditor* editor)
nsEditorSpellCheck::InitSpellChecker(nsIEditor* aEditor, PRBool aEnableSelectionChecking)
{
nsresult rv;
@ -91,9 +94,57 @@ nsEditorSpellCheck::InitSpellChecker(nsIEditor* editor)
tsDoc->SetFilter(mTxtSrvFilter);
// Pass the editor to the text services document
rv = tsDoc->InitWithEditor(editor);
rv = tsDoc->InitWithEditor(aEditor);
NS_ENSURE_SUCCESS(rv, rv);
if (aEnableSelectionChecking) {
// Find out if the section is collapsed or not.
// If it isn't, we want to spellcheck just the selection.
nsCOMPtr<nsISelection> selection;
rv = aEditor->GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
PRInt32 count = 0;
rv = selection->GetRangeCount(&count);
NS_ENSURE_SUCCESS(rv, rv);
if (count > 0) {
nsCOMPtr<nsIDOMRange> range;
rv = selection->GetRangeAt(0, getter_AddRefs(range));
NS_ENSURE_SUCCESS(rv, rv);
PRBool collapsed = PR_FALSE;
rv = range->GetCollapsed(&collapsed);
NS_ENSURE_SUCCESS(rv, rv);
if (!collapsed) {
// We don't want to touch the range in the selection,
// so create a new copy of it.
nsCOMPtr<nsIDOMRange> rangeBounds;
rv = range->CloneRange(getter_AddRefs(rangeBounds));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(rangeBounds, NS_ERROR_FAILURE);
// Make sure the new range spans complete words.
rv = tsDoc->ExpandRangeToWordBoundaries(rangeBounds);
NS_ENSURE_SUCCESS(rv, rv);
// Now tell the text services that you only want
// to iterate over the text in this range.
rv = tsDoc->SetExtent(rangeBounds);
NS_ENSURE_SUCCESS(rv, rv);
}
}
}
rv = nsComponentManager::CreateInstance(NS_SPELLCHECKER_CONTRACTID,
nsnull,
NS_GET_IID(nsISpellChecker),

View File

@ -45,7 +45,7 @@ interface nsITextServicesFilter;
interface nsIEditorSpellCheck : nsISupports
{
void InitSpellChecker(in nsIEditor editor);
void InitSpellChecker(in nsIEditor editor, in boolean enableSelectionChecking);
wstring GetNextMisspelledWord();
wstring GetSuggestedWord();
boolean CheckCurrentWord(in wstring suggestedWord);

View File

@ -42,6 +42,7 @@
#include "nsISupports.h"
class nsIDOMDocument;
class nsIDOMRange;
class nsIPresShell;
class nsIEditor;
class nsString;
@ -101,6 +102,36 @@ public:
*/
NS_IMETHOD InitWithEditor(nsIEditor *aEditor) = 0;
/**
* Sets the range/extent over which the text services document
* will iterate. Note that InitWithDocument() or InitWithEditor()
* should have been called prior to calling this method. If this
* method is never called, the text services defaults to iterating
* over the entire document.
*
* @param aDOMRange is the range to use. aDOMRange must point to a
* valid range object.
*/
NS_IMETHOD SetExtent(nsIDOMRange* aDOMRange) = 0;
/**
* Gets the range that the text services document
* is currently iterating over. If SetExtent() was never
* called, this method will return a range that spans the
* entire body of the document.
*
* @param aDOMRange will contain an AddRef'd pointer to the range.
*/
NS_IMETHOD GetExtent(nsIDOMRange** aDOMRange) = 0;
/**
* Expands the end points of the range so that it spans complete words.
* This call does not change any internal state of the text services document.
*
* @param aDOMRange the range to be expanded/adjusted.
*/
NS_IMETHOD ExpandRangeToWordBoundaries(nsIDOMRange *aRange) = 0;
/**
* Sets the filter to be used while iterating over content.
* @param aFilter filter to be used while iterating over content.

View File

@ -40,6 +40,7 @@ REQUIRES = xpcom \
dom \
widget \
unicharutil \
lwbrk \
$(NULL)
CPPSRCS = \

File diff suppressed because it is too large Load Diff

View File

@ -53,6 +53,8 @@
#include "nsISelectionController.h"
#include "nsITextServicesFilter.h"
class nsIWordBreaker;
/** implementation of a text services object.
*
*/
@ -110,7 +112,9 @@ private:
PRInt32 mSelEndIndex;
PRInt32 mSelEndOffset;
nsCOMPtr<nsITextServicesFilter> mTxtSvcFilter;
nsCOMPtr<nsIDOMRange> mExtent;
nsCOMPtr<nsITextServicesFilter> mTxtSvcFilter;
public:
@ -129,6 +133,9 @@ public:
NS_IMETHOD InitWithDocument(nsIDOMDocument *aDOMDocument, nsIPresShell *aPresShell);
NS_IMETHOD InitWithEditor(nsIEditor *aEditor);
NS_IMETHOD GetDocument(nsIDOMDocument **aDoc);
NS_IMETHOD SetExtent(nsIDOMRange* aDOMRange);
NS_IMETHOD GetExtent(nsIDOMRange** aDOMRange);
NS_IMETHOD ExpandRangeToWordBoundaries(nsIDOMRange *aRange);
NS_IMETHOD SetFilter(nsITextServicesFilter *aFilter);
NS_IMETHOD CanEdit(PRBool *aCanEdit);
NS_IMETHOD GetCurrentTextBlock(nsString *aStr);
@ -175,19 +182,24 @@ private:
nsresult AdjustContentIterator();
nsresult FirstTextNodeInCurrentBlock(nsIContentIterator *aIterator);
nsresult FirstTextNodeInPrevBlock(nsIContentIterator *aIterator);
nsresult FirstTextNodeInNextBlock(nsIContentIterator *aIterator);
static nsresult FirstTextNode(nsIContentIterator *aIterator, TSDIteratorStatus *IteratorStatus);
static nsresult LastTextNode(nsIContentIterator *aIterator, TSDIteratorStatus *IteratorStatus);
static nsresult FirstTextNodeInCurrentBlock(nsIContentIterator *aIterator);
static nsresult FirstTextNodeInPrevBlock(nsIContentIterator *aIterator);
static nsresult FirstTextNodeInNextBlock(nsIContentIterator *aIterator);
nsresult GetFirstTextNodeInPrevBlock(nsIContent **aContent);
nsresult GetFirstTextNodeInNextBlock(nsIContent **aContent);
PRBool IsBlockNode(nsIContent *aContent);
PRBool IsTextNode(nsIContent *aContent);
PRBool IsTextNode(nsIDOMNode *aNode);
PRBool DidSkip(nsIContentIterator* aFilteredIter);
void ClearDidSkip(nsIContentIterator* aFilteredIter);
static PRBool IsBlockNode(nsIContent *aContent);
static PRBool IsTextNode(nsIContent *aContent);
static PRBool IsTextNode(nsIDOMNode *aNode);
PRBool HasSameBlockNodeParent(nsIContent *aContent1, nsIContent *aContent2);
static PRBool DidSkip(nsIContentIterator* aFilteredIter);
static void ClearDidSkip(nsIContentIterator* aFilteredIter);
static PRBool HasSameBlockNodeParent(nsIContent *aContent1, nsIContent *aContent2);
nsresult SetSelectionInternal(PRInt32 aOffset, PRInt32 aLength, PRBool aDoUpdate);
nsresult GetSelection(TSDBlockSelectionStatus *aSelStatus, PRInt32 *aSelOffset, PRInt32 *aSelLength);
@ -197,12 +209,29 @@ private:
PRBool SelectionIsCollapsed();
PRBool SelectionIsValid();
static nsresult CreateOffsetTable(nsVoidArray *aOffsetTable,
nsIContentIterator *aIterator,
TSDIteratorStatus *aIteratorStatus,
nsIDOMRange *aIterRange,
nsString *aStr);
static nsresult ClearOffsetTable(nsVoidArray *aOffsetTable);
static nsresult NodeHasOffsetEntry(nsVoidArray *aOffsetTable,
nsIDOMNode *aNode,
PRBool *aHasEntry,
PRInt32 *aEntryIndex);
nsresult RemoveInvalidOffsetEntries();
nsresult CreateOffsetTable(nsString *aStr=0);
nsresult ClearOffsetTable();
nsresult SplitOffsetEntry(PRInt32 aTableIndex, PRInt32 aOffsetIntoEntry);
nsresult NodeHasOffsetEntry(nsIDOMNode *aNode, PRBool *aHasEntry, PRInt32 *aEntryIndex);
static nsresult GetWordBreaker(nsIWordBreaker **aWordBreaker);
static nsresult FindWordBounds(nsVoidArray *offsetTable, nsString *blockStr,
nsIWordBreaker *aWordBreaker,
nsIDOMNode *aNode, PRInt32 aNodeOffset,
nsIDOMNode **aWordStartNode,
PRInt32 *aWordStartOffset,
nsIDOMNode **aWordEndNode,
PRInt32 *aWordEndOffset);
/* DEBUG */
void PrintOffsetTable();

View File

@ -2424,7 +2424,7 @@ var nsSpellingCommand =
try {
var skipBlockQuotes = (window.document.firstChild.getAttribute("windowtype") == "msgcompose");
window.openDialog("chrome://editor/content/EdSpellCheck.xul", "_blank",
"chrome,close,titlebar,modal", false, skipBlockQuotes);
"chrome,close,titlebar,modal", false, skipBlockQuotes, true);
}
catch(ex) {}
window.content.focus();

View File

@ -54,6 +54,7 @@ function Startup()
var filterContractId;
sendMailMessageMode = window.arguments[0];
var skipBlockQuotes = window.arguments[1];
var enableSelectionChecking = window.arguments[2];
if (skipBlockQuotes)
filterContractId = "@mozilla.org/editor/txtsrvfiltermail;1";
@ -61,7 +62,7 @@ function Startup()
filterContractId = "@mozilla.org/editor/txtsrvfilter;1";
gSpellChecker.setFilter(Components.classes[filterContractId].createInstance(Components.interfaces.nsITextServicesFilter));
gSpellChecker.InitSpellChecker(GetCurrentEditor());
gSpellChecker.InitSpellChecker(GetCurrentEditor(), enableSelectionChecking);
// XXX: We need to read in a pref here so we can set the
// default language for the spellchecker!
@ -424,7 +425,7 @@ function Recheck()
var curLang = gSpellChecker.GetCurrentDictionary();
gSpellChecker.UninitSpellChecker();
gSpellChecker.InitSpellChecker(GetCurrentEditor());
gSpellChecker.InitSpellChecker(GetCurrentEditor(), false);
gSpellChecker.SetCurrentDictionary(curLang);
gMisspelledWord = gSpellChecker.GetNextMisspelledWord();
SetWidgetsForMisspelledWord();

View File

@ -1564,7 +1564,7 @@ function GenericSendMessage( msgType )
window.cancelSendMessage = false;
try {
window.openDialog("chrome://editor/content/EdSpellCheck.xul", "_blank",
"chrome,close,titlebar,modal", true, true);
"chrome,close,titlebar,modal", true, true, false);
}
catch(ex){}
if(window.cancelSendMessage)