168999: Make nsEditorSpellCheck an independant object instead of part of editorshell. r=brade sr=kin a=asa

This commit is contained in:
akkana%netscape.com 2002-10-11 23:46:57 +00:00
Родитель dc1af20c61
Коммит 7224a79a1a
10 изменённых файлов: 536 добавлений и 649 удалений

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

@ -67,9 +67,10 @@ CPPSRCS = \
nsComposerController.cpp \
nsComposerCommands.cpp \
nsComposerRegistration.cpp \
nsEditingSession.cpp \
nsComposerCommandsUpdater.cpp \
nsEditorService.cpp \
nsEditingSession.cpp \
nsComposerCommandsUpdater.cpp \
nsEditorService.cpp \
nsEditorSpellCheck.cpp \
$(NULL)
include $(topsrcdir)/config/rules.mk

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

@ -38,9 +38,10 @@
#include "nsIGenericFactory.h"
#include "nsEditorShell.h" // for the CID
#include "nsEditorShell.h" // for the CID
#include "nsEditingSession.h" // for the CID
#include "nsComposerController.h" // for the CID
#include "nsComposerController.h" // for the CID
#include "nsEditorSpellCheck.h" // for the CID
#include "nsEditorService.h"
////////////////////////////////////////////////////////////////////////
@ -53,6 +54,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsEditorShell)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsEditingSession)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsComposerController)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsEditorService)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsEditorSpellCheck)
////////////////////////////////////////////////////////////////////////
// Define a table of CIDs implemented by this module along with other
@ -71,6 +73,9 @@ static const nsModuleComponentInfo components[] = {
"@mozilla.org/editor/editingsession;1", nsEditingSessionConstructor, },
{ "Editor Service", NS_EDITORSERVICE_CID,
"@mozilla.org/editor/editorservice;1", nsEditorServiceConstructor,},
{ "Editor Spell Checker", NS_EDITORSPELLCHECK_CID,
"@mozilla.org/editor/editorspellchecker;1",
nsEditorSpellCheckConstructor,},
{ "Editor Startup Handler", NS_EDITORSERVICE_CID,
"@mozilla.org/commandlinehandler/general-startup;1?type=editor",
nsEditorServiceConstructor,

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

@ -61,7 +61,6 @@
#include "nsNetUtil.h"
#include "nsIWebNavigation.h"
#include "nsCOMPtr.h"
#include "nsIURL.h"
#include "nsXPIDLString.h"
@ -90,7 +89,10 @@
#include "nsIRefreshURI.h"
#include "nsIPref.h"
#include "nsILookAndFeel.h"
#include "nsIChromeRegistry.h"
#include "nsHTMLTags.h"
#include "nsIDOMEventReceiver.h"
#include "nsIWebBrowserPrint.h"
///////////////////////////////////////
// Editor Includes
@ -108,17 +110,11 @@
#include "nsEditorCID.h"
#include "nsTextServicesCID.h"
#include "nsITextServicesDocument.h"
#include "nsISpellChecker.h"
#include "nsInterfaceState.h"
#include "nsIStringBundle.h"
#include "nsHTMLTags.h"
#include "nsEditorParserObserver.h"
#include "nsIDOMEventReceiver.h"
#include "nsIWebBrowserPrint.h"
///////////////////////////////////////
@ -129,7 +125,6 @@
/* Define Class IDs */
static NS_DEFINE_CID(kHTMLEditorCID, NS_HTMLEDITOR_CID);
static NS_DEFINE_CID(kCTextServicesDocumentCID, NS_TEXTSERVICESDOCUMENT_CID);
static NS_DEFINE_CID(kCStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
@ -252,8 +247,6 @@ nsEditorShell::nsEditorShell()
, mContentMIMEType("text/html")
, mContentTypeKnown(PR_FALSE)
, mWrapColumn(0)
, mSuggestedWordIndex(0)
, mDictionaryIndex(0)
{
//TODO:Save last-used display mode in prefs so new window inherits?
NS_INIT_ISUPPORTS();
@ -268,11 +261,10 @@ nsEditorShell::~nsEditorShell()
// care of themselves.
}
NS_IMPL_ISUPPORTS5(nsEditorShell,
nsIEditorShell,
nsIWebProgressListener,
nsIURIContentListener,
nsIEditorSpellCheck,
NS_IMPL_ISUPPORTS4(nsEditorShell,
nsIEditorShell,
nsIWebProgressListener,
nsIURIContentListener,
nsISupportsWeakReference);
NS_IMETHODIMP
@ -286,10 +278,6 @@ nsEditorShell::Shutdown()
editor->PreDestroy();
}
// Make sure we blow the spellchecker away, just in
// case it hasn't been destroyed already.
mSpellChecker = nsnull;
if (mDocShell)
mDocShell->SetParentURIContentListener(nsnull);
@ -2618,374 +2606,6 @@ nsEditorShell::GetEmbeddedObjects(nsISupportsArray **aObjectArray)
return NS_NOINTERFACE;
}
NS_IMETHODIMP
nsEditorShell::InitSpellChecker()
{
nsresult result = NS_NOINTERFACE;
// We can spell check with any editor type
if (mEditor)
{
nsCOMPtr<nsITextServicesDocument>tsDoc;
result = nsComponentManager::CreateInstance(
kCTextServicesDocumentCID,
nsnull,
NS_GET_IID(nsITextServicesDocument),
(void **)getter_AddRefs(tsDoc));
if (NS_FAILED(result))
return result;
if (!tsDoc)
return NS_ERROR_NULL_POINTER;
// Pass the editor to the text services document
nsCOMPtr<nsIEditor> editor = do_QueryInterface(mEditor);
if (!editor)
return NS_NOINTERFACE;
result = tsDoc->InitWithEditor(editor);
if (NS_FAILED(result))
return result;
result = nsComponentManager::CreateInstance(NS_SPELLCHECKER_CONTRACTID,
nsnull,
NS_GET_IID(nsISpellChecker),
(void **)getter_AddRefs(mSpellChecker));
if (NS_FAILED(result))
return result;
if (!mSpellChecker)
return NS_ERROR_NULL_POINTER;
result = mSpellChecker->SetDocument(tsDoc, PR_TRUE);
if (NS_FAILED(result))
return result;
// Tell the spellchecker what dictionary to use:
nsXPIDLString dictName;
nsCOMPtr<nsIPref> prefs(do_GetService(kPrefServiceCID, &result));
if (NS_SUCCEEDED(result) && prefs)
result = prefs->CopyUnicharPref("spellchecker.dictionary",
getter_Copies(dictName));
if (NS_FAILED(result) || dictName.IsEmpty())
{
// Prefs didn't give us a dictionary name, so just get the current
// locale and use that as the default dictionary name!
nsCOMPtr<nsIXULChromeRegistry> packageRegistry =
do_GetService(NS_CHROMEREGISTRY_CONTRACTID, &result);
if (NS_SUCCEEDED(result) && packageRegistry) {
nsCAutoString utf8DictName;
result = packageRegistry->GetSelectedLocale(NS_LITERAL_CSTRING("navigator"), utf8DictName);
dictName = NS_ConvertUTF8toUCS2(utf8DictName);
}
}
if (NS_SUCCEEDED(result) && !dictName.IsEmpty())
result = SetCurrentDictionary(dictName.get());
// If an error was thrown while checking the dictionary pref, just
// fail silently so that the spellchecker dialog is allowed to come
// up. The user can manually reset the language to their choice on
// the dialog if it is wrong.
result = NS_OK;
DeleteSuggestedWordList();
}
return result;
}
NS_IMETHODIMP
nsEditorShell::GetNextMisspelledWord(PRUnichar **aNextMisspelledWord)
{
nsresult result = NS_NOINTERFACE;
nsAutoString nextMisspelledWord;
// We can spell check with any editor type
if (mEditor && mSpellChecker)
{
DeleteSuggestedWordList();
result = mSpellChecker->NextMisspelledWord(&nextMisspelledWord, &mSuggestedWordList);
}
*aNextMisspelledWord = ToNewUnicode(nextMisspelledWord);
return result;
}
NS_IMETHODIMP
nsEditorShell::GetSuggestedWord(PRUnichar **aSuggestedWord)
{
nsresult result = NS_NOINTERFACE;
nsAutoString word;
// We can spell check with any editor type
if (mEditor)
{
if ( mSuggestedWordIndex < mSuggestedWordList.Count())
{
mSuggestedWordList.StringAt(mSuggestedWordIndex, word);
mSuggestedWordIndex++;
} else {
// A blank string signals that there are no more strings
word.SetLength(0);
}
result = NS_OK;
}
*aSuggestedWord = ToNewUnicode(word);
return result;
}
NS_IMETHODIMP
nsEditorShell::CheckCurrentWord(const PRUnichar *aSuggestedWord, PRBool *aIsMisspelled)
{
nsresult result = NS_NOINTERFACE;
nsAutoString suggestedWord(aSuggestedWord);
// We can spell check with any editor type
if (mEditor && mSpellChecker)
{
DeleteSuggestedWordList();
result = mSpellChecker->CheckWord(&suggestedWord, aIsMisspelled, &mSuggestedWordList);
}
return result;
}
NS_IMETHODIMP
nsEditorShell::ReplaceWord(const PRUnichar *aMisspelledWord, const PRUnichar *aReplaceWord, PRBool allOccurrences)
{
nsresult result = NS_NOINTERFACE;
nsAutoString misspelledWord(aMisspelledWord);
nsAutoString replaceWord(aReplaceWord);
if (mEditor && mSpellChecker)
{
result = mSpellChecker->Replace(&misspelledWord, &replaceWord, allOccurrences);
}
return result;
}
NS_IMETHODIMP
nsEditorShell::IgnoreWordAllOccurrences(const PRUnichar *aWord)
{
nsresult result = NS_NOINTERFACE;
nsAutoString word(aWord);
if (mEditor && mSpellChecker)
{
result = mSpellChecker->IgnoreAll(&word);
}
return result;
}
NS_IMETHODIMP
nsEditorShell::GetPersonalDictionary()
{
nsresult result = NS_NOINTERFACE;
// We can spell check with any editor type
if (mEditor && mSpellChecker)
{
mDictionaryList.Clear();
mDictionaryIndex = 0;
result = mSpellChecker->GetPersonalDictionary(&mDictionaryList);
}
return result;
}
NS_IMETHODIMP
nsEditorShell::GetPersonalDictionaryWord(PRUnichar **aDictionaryWord)
{
nsresult result = NS_NOINTERFACE;
nsAutoString word;
if (mEditor)
{
if ( mDictionaryIndex < mDictionaryList.Count())
{
mDictionaryList.StringAt(mDictionaryIndex, word);
mDictionaryIndex++;
} else {
// A blank string signals that there are no more strings
word.SetLength(0);
}
result = NS_OK;
}
*aDictionaryWord = ToNewUnicode(word);
return result;
}
NS_IMETHODIMP
nsEditorShell::AddWordToDictionary(const PRUnichar *aWord)
{
nsresult result = NS_NOINTERFACE;
nsAutoString word(aWord);
if (mEditor && mSpellChecker)
{
result = mSpellChecker->AddWordToPersonalDictionary(&word);
}
return result;
}
NS_IMETHODIMP
nsEditorShell::RemoveWordFromDictionary(const PRUnichar *aWord)
{
nsresult result = NS_NOINTERFACE;
nsAutoString word(aWord);
if (mEditor && mSpellChecker)
{
result = mSpellChecker->RemoveWordFromPersonalDictionary(&word);
}
return result;
}
NS_IMETHODIMP
nsEditorShell::GetDictionaryList(PRUnichar ***aDictionaryList, PRUint32 *aCount)
{
nsresult result = NS_ERROR_NOT_IMPLEMENTED;
if (!aDictionaryList || !aCount)
return NS_ERROR_NULL_POINTER;
*aDictionaryList = 0;
*aCount = 0;
if (mEditor && mSpellChecker)
{
nsStringArray dictList;
result = mSpellChecker->GetDictionaryList(&dictList);
if (NS_FAILED(result))
return result;
PRUnichar **tmpPtr = 0;
if (dictList.Count() < 1)
{
// If there are no dictionaries, return an array containing
// one element and a count of one.
tmpPtr = (PRUnichar **)nsMemory::Alloc(sizeof(PRUnichar *));
if (!tmpPtr)
return NS_ERROR_OUT_OF_MEMORY;
*tmpPtr = 0;
*aDictionaryList = tmpPtr;
*aCount = 0;
return NS_OK;
}
tmpPtr = (PRUnichar **)nsMemory::Alloc(sizeof(PRUnichar *) * dictList.Count());
if (!tmpPtr)
return NS_ERROR_OUT_OF_MEMORY;
*aDictionaryList = tmpPtr;
*aCount = dictList.Count();
nsAutoString dictStr;
PRUint32 i;
for (i = 0; i < *aCount; i++)
{
dictList.StringAt(i, dictStr);
tmpPtr[i] = ToNewUnicode(dictStr);
}
}
return result;
}
NS_IMETHODIMP
nsEditorShell::GetCurrentDictionary(PRUnichar **aDictionary)
{
nsresult result = NS_ERROR_NOT_INITIALIZED;
if (!aDictionary)
return NS_ERROR_NULL_POINTER;
*aDictionary = 0;
if (mEditor && mSpellChecker)
{
nsAutoString dictStr;
result = mSpellChecker->GetCurrentDictionary(&dictStr);
if (NS_FAILED(result))
return result;
*aDictionary = ToNewUnicode(dictStr);
}
return result;
}
NS_IMETHODIMP
nsEditorShell::SetCurrentDictionary(const PRUnichar *aDictionary)
{
nsresult result = NS_ERROR_NOT_INITIALIZED;
if (!aDictionary)
return NS_ERROR_NULL_POINTER;
if (mEditor && mSpellChecker)
{
nsAutoString dictStr(aDictionary);
result = mSpellChecker->SetCurrentDictionary(&dictStr);
}
return result;
}
NS_IMETHODIMP
nsEditorShell::UninitSpellChecker()
{
nsresult result = NS_NOINTERFACE;
// We can spell check with any editor type
if (mEditor)
{
// Save the last used dictionary to the user's preferences.
nsCOMPtr<nsIPref> prefs(do_GetService(kPrefServiceCID, &result));
if (NS_SUCCEEDED(result) && prefs)
{
PRUnichar *dictName = nsnull;
result = GetCurrentDictionary(&dictName);
if (NS_SUCCEEDED(result) && dictName && *dictName)
result = prefs->SetUnicharPref("spellchecker.dictionary", dictName);
if (dictName)
nsMemory::Free(dictName);
}
// Cleanup - kill the spell checker
DeleteSuggestedWordList();
mDictionaryList.Clear();
mDictionaryIndex = 0;
mSpellChecker = 0;
result = NS_OK;
}
return result;
}
nsresult
nsEditorShell::DeleteSuggestedWordList()
{
mSuggestedWordList.Clear();
mSuggestedWordIndex = 0;
return NS_OK;
}
#ifdef XP_MAC
#pragma mark -
#endif

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

@ -1,250 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsEditorShell_h___
#define nsEditorShell_h___
//#include "nsAppCores.h"
#include "nscore.h"
#include "nsCOMPtr.h"
#include "nsWeakReference.h"//XXX adding weak ref knowledge
#include "nsString.h"
#include "nsISupports.h"
#include "nsIEditorShell.h"
#include "nsIWebProgressListener.h"
#include "nsIDOMEventListener.h"
#include "nsIURIContentListener.h"
#include "nsVoidArray.h"
#include "nsIEditorSpellCheck.h"
#include "nsISpellChecker.h"
#include "nsIHTMLEditor.h"
#include "nsIStringBundle.h"
#include "nsICSSStyleSheet.h"
#include "nsISupportsArray.h"
#include "nsIPrintSettings.h"
class nsIDOMDocument;
class nsIDocShell;
class nsIScriptContext;
class nsIDOMWindow;
class nsIDOMWindowInternal;
class nsIDOMElement;
class nsIDOMNode;
class nsIDOMHTMLDocument;
class nsIURI;
class nsIChannel;
class nsIPresShell;
class nsIOutputStream;
class nsISupportsArray;
class nsIStringBundleService;
class nsIStringBundle;
class nsIStyleSheet;
class nsIEditorController;
class nsIDOMEventReceiver;
class nsIDOMEventListener;
class nsISpellChecker;
class nsInterfaceState;
class nsIHTMLEditor;
class nsICSSStyleSheet;
class nsEditorParserObserver;
class nsStringArray;
#define NS_EDITORSHELL_CID \
{ /* {} */ \
0x9afff72b, 0xca9a, 0x11d2, \
{ 0x96, 0xc9, 0x0, 0x60, 0xb0, 0xfb, 0x99, 0x56 } \
}
////////////////////////////////////////////////////////////////////////////////
// nsEditorShell:
////////////////////////////////////////////////////////////////////////////////
class nsEditorShell : public nsIEditorShell,
public nsIEditorSpellCheck,
public nsIWebProgressListener,
public nsIURIContentListener,
public nsSupportsWeakReference
{
public:
// These must map onto the button-order for nsICommonDialog::Confirm results
// which are rather ugly right now (Cancel in the middle!)
typedef enum {eYes = 0, eCancel = 1, eNo = 2 } EConfirmResult;
nsEditorShell();
virtual ~nsEditorShell();
NS_DECL_ISUPPORTS
/* Declare all methods in the nsIEditorShell interface */
NS_DECL_NSIEDITORSHELL
/* Declare all methods in the nsIEditorSpellCheck interface */
NS_DECL_NSIEDITORSPELLCHECK
// nsIWebProgressListener
NS_DECL_NSIWEBPROGRESSLISTENER
// nsIURIContentListener
NS_DECL_NSIURICONTENTLISTENER
protected:
typedef enum {
eUninitializedEditorType = 0,
ePlainTextEditorType = 1,
eHTMLTextEditorType = 2
} EEditorType;
typedef enum {
eCantEditNoReason = 0,
eCantEditFramesets = 1,
eCantEditMimeType = 2,
eCantEditFileNotFound = 3,
eCantEditOther = 9
} ECantEditReason;
nsresult DoEditorMode(nsIDocShell *aDocShell);
// nuke any existing editor in the editorShell, thus preparing it to edit
// a(nother) document.
nsresult ResetEditingState();
nsresult InstantiateEditor(nsIDOMDocument *aDoc, nsIPresShell *aPresShell);
nsresult PrepareDocumentForEditing(nsIDOMWindow* aDOMWindow, nsIURI *aUrl);
nsresult TransferDocumentStateListeners();
nsresult RemoveOneProperty(const nsString& aProp, const nsString& aAttr);
nsresult DoFind(PRBool aFindNext);
// To allow executing JavaScript commands from C++ via nsIEditorController interface
nsresult DoControllerCommand(const char* aCommand);
void Alert(const nsString& aTitle, const nsString& aMsg);
// Bring up a Yes/No dialog WE REALLY NEED A Yes/No/Cancel dialog and would like to set our own caption as well!
PRBool Confirm(const nsString& aTitle, const nsString& aQuestion);
// Return value: No=0, Yes=1, Cancel=2
// aYesString and aNoString are optional:
// if null, then "Yes" and "No" are used
EConfirmResult ConfirmWithCancel(const nsString& aTitle, const nsString& aQuestion,
const nsString *aYesString, const nsString *aNoString);
// Get a string from the string bundle file. If the string is not found
// this returns an empty string.
void GetBundleString(const nsAString &stringName, nsAString &outString);
// Get the text of the <title> tag
nsresult GetDocumentTitleString(nsString& title);
nsresult DeleteSuggestedWordList();
nsresult GetDocumentURI(nsIDOMDocument *aDoc, nsIURI **aDocumentURI);
// Helper method which is called at the beginning of a new page load
nsresult StartPageLoad(nsIChannel *aChannel);
// Helper method which is called when an entire page load finishes
nsresult EndPageLoad(nsIDOMWindow *aDOMWindow,
nsIChannel *aChannel,
nsresult aStatus);
// helper method which is called each time a document (or frame) starts
// to load.
nsresult StartDocumentLoad(nsIDOMWindow *aDOMWindow);
// helper methods which is called each time a document (or frame) finishes
// loading.
nsresult EndDocumentLoad(nsIDOMWindow *aDOMWindow,
nsIChannel *aChannel,
nsresult aStatus);
// Check a preference and call NormalizeTable if pref is true
// Use after deleting or inserting table cells to automatically
// fix rowspan, colspan, and missing cells problems
nsresult CheckPrefAndNormalizeTable();
nsCOMPtr<nsIHTMLEditor> mEditor; // this can be either an HTML or plain text (or other?) editor
nsCOMPtr<nsISupports> mSearchContext; // context used for search and replace. Owned by the appshell.
nsCOMPtr<nsISpellChecker> mSpellChecker;
nsresult GetDocShellFromContentWindow(nsIDocShell **aDocShell);
PRBool mMailCompose;
// These doc listeners are registered with the editor when that gets
// created. We also keep them in this list so we can register if we have
// to blow away the editor (e.g. URL reload)
nsCOMPtr<nsISupportsArray> mDocStateListeners; // contents are nsISupports
// Pointer to localized strings used for UI
nsCOMPtr<nsIStringBundle> mStringBundle;
PRBool mHTMLSourceMode;
nsIDOMWindowInternal *mWebShellWindow; // weak reference
//nsIDOMWindowInternal *mContentWindow; // weak reference
nsWeakPtr mContentWindow; // weak reference
nsEditorParserObserver *mParserObserver; // we hold the owning ref to this.
nsInterfaceState *mStateMaintainer; // we hold the owning ref to this.
nsIEditorController *mEditorController; // temporary weak ref to the editor controller
nsIEditorController *mComposerController; // temporary weak ref to the nsComposerController
nsIDocShell *mDocShell; // weak reference
// The webshell that contains the document being edited.
// Don't assume that webshell directly contains the document being edited;
// if we are in a frameset, this assumption is false.
nsIDocShell *mContentAreaDocShell; // weak reference
PRPackedBool mCloseWindowWhenLoaded; // error on load. Close window when loaded
ECantEditReason mCantEditReason;
EEditorType mEditorType;
nsString mEditorTypeString; // string which describes which editor type will be instantiated (lowercased)
nsCString mContentMIMEType; // MIME type of the doc we are editing.
PRBool mContentTypeKnown;
PRInt32 mWrapColumn; // can't actually set this 'til the editor is created, so we may have to hold on to it for a while
nsStringArray mSuggestedWordList;
PRInt32 mSuggestedWordIndex;
nsStringArray mDictionaryList;
PRInt32 mDictionaryIndex;
nsCOMPtr<nsIPrintSettings> mPrintSettings;
};
#endif // nsEditorShell_h___

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

@ -0,0 +1,395 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code..
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Kin Blas <kin@netscape.com>
* Akkana Peck <akkana@netscape.com>
* Charley Manske <cmanske@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsEditorSpellCheck.h"
#include "nsTextServicesCID.h"
#include "nsITextServicesDocument.h"
#include "nsISpellChecker.h"
#include "nsIComponentManager.h"
#include "nsXPIDLString.h"
#include "nsIPref.h"
#include "nsIServiceManagerUtils.h"
#include "nsIChromeRegistry.h"
#include "nsString.h"
#include "nsReadableUtils.h"
static NS_DEFINE_CID(kCTextServicesDocumentCID, NS_TEXTSERVICESDOCUMENT_CID);
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
NS_IMPL_ISUPPORTS1(nsEditorSpellCheck, nsIEditorSpellCheck);
nsEditorSpellCheck::nsEditorSpellCheck()
: mSuggestedWordIndex(0)
, mDictionaryIndex(0)
{
}
nsEditorSpellCheck::~nsEditorSpellCheck()
{
// Make sure we blow the spellchecker away, just in
// case it hasn't been destroyed already.
mSpellChecker = nsnull;
}
NS_IMETHODIMP
nsEditorSpellCheck::InitSpellChecker(nsIEditor* editor)
{
nsresult rv;
// We can spell check with any editor type
nsCOMPtr<nsITextServicesDocument>tsDoc;
rv = nsComponentManager::CreateInstance(kCTextServicesDocumentCID,
nsnull,
NS_GET_IID(nsITextServicesDocument),
(void **)getter_AddRefs(tsDoc));
NS_ENSURE_SUCCESS(rv, rv);
if (!tsDoc)
return NS_ERROR_NULL_POINTER;
// Pass the editor to the text services document
rv = tsDoc->InitWithEditor(editor);
NS_ENSURE_SUCCESS(rv, rv);
rv = nsComponentManager::CreateInstance(NS_SPELLCHECKER_CONTRACTID,
nsnull,
NS_GET_IID(nsISpellChecker),
(void **)getter_AddRefs(mSpellChecker));
NS_ENSURE_SUCCESS(rv, rv);
if (!mSpellChecker)
return NS_ERROR_NULL_POINTER;
rv = mSpellChecker->SetDocument(tsDoc, PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
// Tell the spellchecker what dictionary to use:
nsXPIDLString dictName;
nsCOMPtr<nsIPref> prefs(do_GetService(kPrefServiceCID, &rv));
if (NS_SUCCEEDED(rv) && prefs)
rv = prefs->CopyUnicharPref("spellchecker.dictionary",
getter_Copies(dictName));
if (NS_FAILED(rv) || dictName.IsEmpty())
{
// Prefs didn't give us a dictionary name, so just get the current
// locale and use that as the default dictionary name!
nsCOMPtr<nsIXULChromeRegistry> packageRegistry =
do_GetService(NS_CHROMEREGISTRY_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv) && packageRegistry) {
nsCAutoString utf8DictName;
rv = packageRegistry->GetSelectedLocale(NS_LITERAL_CSTRING("navigator"),
utf8DictName);
dictName = NS_ConvertUTF8toUCS2(utf8DictName);
}
}
if (NS_SUCCEEDED(rv) && !dictName.IsEmpty())
SetCurrentDictionary(dictName.get());
// If an error was thrown while checking the dictionary pref, just
// fail silently so that the spellchecker dialog is allowed to come
// up. The user can manually reset the language to their choice on
// the dialog if it is wrong.
DeleteSuggestedWordList();
return NS_OK;
}
NS_IMETHODIMP
nsEditorSpellCheck::GetNextMisspelledWord(PRUnichar **aNextMisspelledWord)
{
if (!mSpellChecker)
return NS_NOINTERFACE;
nsAutoString nextMisspelledWord;
DeleteSuggestedWordList();
nsresult rv = mSpellChecker->NextMisspelledWord(&nextMisspelledWord,
&mSuggestedWordList);
*aNextMisspelledWord = ToNewUnicode(nextMisspelledWord);
return rv;
}
NS_IMETHODIMP
nsEditorSpellCheck::GetSuggestedWord(PRUnichar **aSuggestedWord)
{
nsAutoString word;
if ( mSuggestedWordIndex < mSuggestedWordList.Count())
{
mSuggestedWordList.StringAt(mSuggestedWordIndex, word);
mSuggestedWordIndex++;
} else {
// A blank string signals that there are no more strings
word.SetLength(0);
}
*aSuggestedWord = ToNewUnicode(word);
return NS_OK;
}
NS_IMETHODIMP
nsEditorSpellCheck::CheckCurrentWord(const PRUnichar *aSuggestedWord,
PRBool *aIsMisspelled)
{
if (!mSpellChecker)
return NS_NOINTERFACE;
nsAutoString suggestedWord(aSuggestedWord);
DeleteSuggestedWordList();
return mSpellChecker->CheckWord(&suggestedWord, aIsMisspelled,
&mSuggestedWordList);
}
NS_IMETHODIMP
nsEditorSpellCheck::ReplaceWord(const PRUnichar *aMisspelledWord,
const PRUnichar *aReplaceWord,
PRBool allOccurrences)
{
if (!mSpellChecker)
return NS_NOINTERFACE;
nsAutoString misspelledWord(aMisspelledWord);
nsAutoString replaceWord(aReplaceWord);
return mSpellChecker->Replace(&misspelledWord, &replaceWord, allOccurrences);
}
NS_IMETHODIMP
nsEditorSpellCheck::IgnoreWordAllOccurrences(const PRUnichar *aWord)
{
if (!mSpellChecker)
return NS_NOINTERFACE;
nsAutoString word(aWord);
return mSpellChecker->IgnoreAll(&word);
}
NS_IMETHODIMP
nsEditorSpellCheck::GetPersonalDictionary()
{
if (!mSpellChecker)
return NS_NOINTERFACE;
// We can spell check with any editor type
mDictionaryList.Clear();
mDictionaryIndex = 0;
return mSpellChecker->GetPersonalDictionary(&mDictionaryList);
}
NS_IMETHODIMP
nsEditorSpellCheck::GetPersonalDictionaryWord(PRUnichar **aDictionaryWord)
{
nsAutoString word;
if ( mDictionaryIndex < mDictionaryList.Count())
{
mDictionaryList.StringAt(mDictionaryIndex, word);
mDictionaryIndex++;
} else {
// A blank string signals that there are no more strings
word.SetLength(0);
}
*aDictionaryWord = ToNewUnicode(word);
return NS_OK;
}
NS_IMETHODIMP
nsEditorSpellCheck::AddWordToDictionary(const PRUnichar *aWord)
{
if (!mSpellChecker)
return NS_NOINTERFACE;
nsAutoString word(aWord);
return mSpellChecker->AddWordToPersonalDictionary(&word);
}
NS_IMETHODIMP
nsEditorSpellCheck::RemoveWordFromDictionary(const PRUnichar *aWord)
{
if (!mSpellChecker)
return NS_NOINTERFACE;
nsAutoString word(aWord);
return mSpellChecker->RemoveWordFromPersonalDictionary(&word);
}
NS_IMETHODIMP
nsEditorSpellCheck::GetDictionaryList(PRUnichar ***aDictionaryList, PRUint32 *aCount)
{
if (!mSpellChecker)
return NS_NOINTERFACE;
if (!aDictionaryList || !aCount)
return NS_ERROR_NULL_POINTER;
*aDictionaryList = 0;
*aCount = 0;
nsStringArray dictList;
nsresult rv = mSpellChecker->GetDictionaryList(&dictList);
if (NS_FAILED(rv))
return rv;
PRUnichar **tmpPtr = 0;
if (dictList.Count() < 1)
{
// If there are no dictionaries, return an array containing
// one element and a count of one.
tmpPtr = (PRUnichar **)nsMemory::Alloc(sizeof(PRUnichar *));
if (!tmpPtr)
return NS_ERROR_OUT_OF_MEMORY;
*tmpPtr = 0;
*aDictionaryList = tmpPtr;
*aCount = 0;
return NS_OK;
}
tmpPtr = (PRUnichar **)nsMemory::Alloc(sizeof(PRUnichar *) * dictList.Count());
if (!tmpPtr)
return NS_ERROR_OUT_OF_MEMORY;
*aDictionaryList = tmpPtr;
*aCount = dictList.Count();
nsAutoString dictStr;
PRUint32 i;
for (i = 0; i < *aCount; i++)
{
dictList.StringAt(i, dictStr);
tmpPtr[i] = ToNewUnicode(dictStr);
}
return rv;
}
NS_IMETHODIMP
nsEditorSpellCheck::GetCurrentDictionary(PRUnichar **aDictionary)
{
if (!mSpellChecker)
return NS_NOINTERFACE;
if (!aDictionary)
return NS_ERROR_NULL_POINTER;
*aDictionary = 0;
nsAutoString dictStr;
nsresult rv = mSpellChecker->GetCurrentDictionary(&dictStr);
NS_ENSURE_SUCCESS(rv, rv);
*aDictionary = ToNewUnicode(dictStr);
return rv;
}
NS_IMETHODIMP
nsEditorSpellCheck::SetCurrentDictionary(const PRUnichar *aDictionary)
{
if (!mSpellChecker)
return NS_NOINTERFACE;
if (!aDictionary)
return NS_ERROR_NULL_POINTER;
nsAutoString dictStr(aDictionary);
return mSpellChecker->SetCurrentDictionary(&dictStr);
}
NS_IMETHODIMP
nsEditorSpellCheck::UninitSpellChecker()
{
if (!mSpellChecker)
return NS_NOINTERFACE;
// Save the last used dictionary to the user's preferences.
nsresult rv;
nsCOMPtr<nsIPref> prefs(do_GetService(kPrefServiceCID, &rv));
if (NS_SUCCEEDED(rv) && prefs)
{
PRUnichar *dictName = nsnull;
rv = GetCurrentDictionary(&dictName);
if (NS_SUCCEEDED(rv) && dictName && *dictName)
rv = prefs->SetUnicharPref("spellchecker.dictionary", dictName);
if (dictName)
nsMemory::Free(dictName);
}
// Cleanup - kill the spell checker
DeleteSuggestedWordList();
mDictionaryList.Clear();
mDictionaryIndex = 0;
mSpellChecker = 0;
return NS_OK;
}
nsresult
nsEditorSpellCheck::DeleteSuggestedWordList()
{
mSuggestedWordList.Clear();
mSuggestedWordIndex = 0;
return NS_OK;
}

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

@ -0,0 +1,80 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code..
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Kin Blas <kin@netscape.com>
* Akkana Peck <akkana@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsEditorSpellCheck_h___
#define nsEditorSpellCheck_h___
#include "nsIEditorSpellCheck.h"
#include "nsISpellChecker.h"
#include "nsVoidArray.h"
#include "nsCOMPtr.h"
#define NS_EDITORSPELLCHECK_CID \
{ /* {75656ad9-bd13-4c5d-939a-ec6351eea0cc} */ \
0x75656ad9, 0xbd13, 0x4c5d, \
{ 0x93, 0x9a, 0xec, 0x63, 0x51, 0xee, 0xa0, 0xcc }\
}
class nsEditorSpellCheck : public nsIEditorSpellCheck
{
public:
nsEditorSpellCheck();
virtual ~nsEditorSpellCheck();
NS_DECL_ISUPPORTS
/* Declare all methods in the nsIEditorSpellCheck interface */
NS_DECL_NSIEDITORSPELLCHECK
protected:
nsCOMPtr<nsISpellChecker> mSpellChecker;
nsStringArray mSuggestedWordList;
PRInt32 mSuggestedWordIndex;
nsStringArray mDictionaryList;
PRInt32 mDictionaryIndex;
nsresult DeleteSuggestedWordList();
};
#endif // nsEditorSpellCheck_h___

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

@ -38,11 +38,13 @@
#include "nsISupports.idl"
interface nsIEditor;
[scriptable, uuid(87ce8b81-1cf2-11d3-9ce4-c60a16061e7c)]
interface nsIEditorSpellCheck : nsISupports
{
void InitSpellChecker();
void InitSpellChecker(in nsIEditor editor);
wstring GetNextMisspelledWord();
wstring GetSuggestedWord();
boolean CheckCurrentWord(in wstring suggestedWord);

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

@ -972,6 +972,13 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsEditorSpellCheck.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsInterfaceState.cpp</PATH>
@ -1091,6 +1098,11 @@
<PATH>nsEditorShell.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsEditorSpellCheck.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsInterfaceState.cpp</PATH>
@ -2057,6 +2069,13 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsEditorSpellCheck.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS>Debug</FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsInterfaceState.cpp</PATH>
@ -2176,6 +2195,11 @@
<PATH>nsEditorShell.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsEditorSpellCheck.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsInterfaceState.cpp</PATH>
@ -2256,6 +2280,12 @@
<PATH>nsEditorShell.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>ComposerDebug.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsEditorSpellCheck.cpp</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>ComposerDebug.shlb</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>

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

@ -1,3 +1,4 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
/*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file

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

@ -1,3 +1,4 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
/*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
@ -34,7 +35,7 @@ function Startup()
return;
// Get the spellChecker shell
gSpellChecker = editorShell.QueryInterface(Components.interfaces.nsIEditorSpellCheck);
gSpellChecker = Components.classes['@mozilla.org/editor/editorspellchecker;1'].createInstance(Components.interfaces.nsIEditorSpellCheck);
if (!gSpellChecker) {
dump("SpellChecker not found!!!\n");
window.close();
@ -43,7 +44,7 @@ function Startup()
// Start the spell checker module.
try {
gSpellChecker.InitSpellChecker();
gSpellChecker.InitSpellChecker(GetCurrentEditor());
// XXX: We need to read in a pref here so we can set the
// default language for the spellchecker!
@ -402,7 +403,7 @@ function Recheck()
var curLang = gSpellChecker.GetCurrentDictionary();
gSpellChecker.UninitSpellChecker();
gSpellChecker.InitSpellChecker();
gSpellChecker.InitSpellChecker(GetCurrentEditor());
gSpellChecker.SetCurrentDictionary(curLang);
gMisspelledWord = gSpellChecker.GetNextMisspelledWord();
SetWidgetsForMisspelledWord();
@ -489,7 +490,8 @@ function doDefault()
function CancelSpellCheck()
{
gSpellChecker.UninitSpellChecker();
if (gSpellChecker)
gSpellChecker.UninitSpellChecker();
// Signal to calling window that we canceled
window.opener.cancelSendMessage = true;
@ -498,7 +500,8 @@ function CancelSpellCheck()
function onClose()
{
gSpellChecker.UninitSpellChecker();
if (gSpellChecker)
gSpellChecker.UninitSpellChecker();
window.opener.cancelSendMessage = false;
window.close();
}