diff --git a/mozilla/extensions/spellcheck/idl/mozISpellCheckingEngine.idl b/mozilla/extensions/spellcheck/idl/mozISpellCheckingEngine.idl index e4e35115952..f88d660a065 100644 --- a/mozilla/extensions/spellcheck/idl/mozISpellCheckingEngine.idl +++ b/mozilla/extensions/spellcheck/idl/mozISpellCheckingEngine.idl @@ -96,3 +96,8 @@ interface mozISpellCheckingEngine : nsISupports { */ void suggest(in wstring word,[array, size_is(count)] out wstring suggestions, out PRUint32 count); }; + +%{C++ +#define DICTIONARY_SEARCH_DIRECTORY "DictD" +#define DICTIONARY_SEARCH_DIRECTORY_LIST "DictDL" +%} diff --git a/mozilla/extensions/spellcheck/locales/Makefile.in b/mozilla/extensions/spellcheck/locales/Makefile.in index 000301c0584..fbb9c5a20bc 100644 --- a/mozilla/extensions/spellcheck/locales/Makefile.in +++ b/mozilla/extensions/spellcheck/locales/Makefile.in @@ -51,8 +51,8 @@ DICTIONARY_FILES = $(strip $(wildcard $(LOCALE_SRCDIR)/myspell/*.dic) $(wildcard ifneq (,$(DICTIONARY_FILES)) libs:: - $(INSTALL) $(DICTIONARY_FILES) $(FINAL_TARGET)/components/myspell + $(INSTALL) $(DICTIONARY_FILES) $(FINAL_TARGET)/dictionaries install:: - $(SYSINSTALL) $(IFLAGS1) $(DICTIONARY_FILES) $(DESTDIR)$(mozappdir)/components/myspell + $(SYSINSTALL) $(IFLAGS1) $(DICTIONARY_FILES) $(DESTDIR)$(mozappdir)/dictionaries endif diff --git a/mozilla/extensions/spellcheck/myspell/src/Makefile.in b/mozilla/extensions/spellcheck/myspell/src/Makefile.in index deea681ea4d..eb65e6bf19a 100644 --- a/mozilla/extensions/spellcheck/myspell/src/Makefile.in +++ b/mozilla/extensions/spellcheck/myspell/src/Makefile.in @@ -57,6 +57,7 @@ REQUIRES = xpcom \ uconv \ unicharutil \ spellchecker \ + xulapp \ $(NULL) CPPSRCS = affentry.cpp \ @@ -69,6 +70,10 @@ CPPSRCS = affentry.cpp \ mozMySpellFactory.cpp \ $(NULL) +ifdef MOZ_XUL_APP +CPPSRCS += mozMySpellDirProvider.cpp +endif + EXTRA_DSO_LDOPTS = \ $(LIBS_DIR) \ $(XPCOM_LIBS) \ diff --git a/mozilla/extensions/spellcheck/myspell/src/mozMySpell.cpp b/mozilla/extensions/spellcheck/myspell/src/mozMySpell.cpp index ab2daf78539..ef44b365e1e 100644 --- a/mozilla/extensions/spellcheck/myspell/src/mozMySpell.cpp +++ b/mozilla/extensions/spellcheck/myspell/src/mozMySpell.cpp @@ -60,8 +60,10 @@ #include "mozMySpell.h" #include "nsReadableUtils.h" #include "nsXPIDLString.h" +#include "nsIObserverService.h" #include "nsISimpleEnumerator.h" -#include "nsDirectoryService.h" +#include "nsIDirectoryEnumerator.h" +#include "nsDirectoryServiceUtils.h" #include "nsDirectoryServiceDefs.h" #include "mozISpellI18NManager.h" #include "nsICharsetConverterManager.h" @@ -70,13 +72,26 @@ #include "nsCRT.h" #include -const PRInt32 kFirstDirSize=8; +NS_IMPL_ISUPPORTS3(mozMySpell, + mozISpellCheckingEngine, + nsIObserver, + nsISupportsWeakReference) -NS_IMPL_ISUPPORTS1(mozMySpell, mozISpellCheckingEngine) - -mozMySpell::mozMySpell() +nsresult +mozMySpell::Init() { - mMySpell = NULL; + if (!mDictionaries.Init()) + return NS_ERROR_OUT_OF_MEMORY; + + LoadDictionaryList(); + + nsCOMPtr obs = + do_GetService("@mozilla.org/observer-service;1"); + if (obs) { + obs->AddObserver(this, "profile-do-change", PR_TRUE); + } + + return NS_OK; } mozMySpell::~mozMySpell() @@ -90,6 +105,9 @@ NS_IMETHODIMP mozMySpell::GetDictionary(PRUnichar **aDictionary) { NS_ENSURE_ARG_POINTER(aDictionary); + if (mDictionary.IsEmpty()) + return NS_ERROR_NOT_INITIALIZED; + *aDictionary = ToNewUnicode(mDictionary); return *aDictionary ? NS_OK : NS_ERROR_OUT_OF_MEMORY; } @@ -101,68 +119,67 @@ NS_IMETHODIMP mozMySpell::SetDictionary(const PRUnichar *aDictionary) { NS_ENSURE_ARG_POINTER(aDictionary); - nsresult rv = NS_OK; - - if (*aDictionary && !mDictionary.Equals(aDictionary)) { - mDictionary = aDictionary; + if (mDictionary.Equals(aDictionary)) + return NS_OK; - nsAutoString affFileName, dictFileName; + nsIFile* affFile = mDictionaries.GetWeak(aDictionary); + if (!affFile) + return NS_ERROR_FILE_NOT_FOUND; - // XXX This isn't really good. nsIFile->Path isn't xp save etc. - // see nsIFile.idl - // A better way would be to QU ti nsILocalFile, and get a filehandle - // from there. Only problem is that myspell wants a path + nsCAutoString dictFileName, affFileName; - nsCOMPtr file; - nsresult rv = NS_GetSpecialDirectory(NS_XPCOM_COMPONENT_DIR, getter_AddRefs(file)); - NS_ENSURE_SUCCESS(rv, rv); - if (!file) - return NS_ERROR_FAILURE; - rv = file->Append(NS_LITERAL_STRING("myspell")); - NS_ENSURE_SUCCESS(rv, rv); - rv = file->Append(mDictionary + NS_LITERAL_STRING(".aff")); - NS_ENSURE_SUCCESS(rv, rv); - file->GetPath(affFileName); + // XXX This isn't really good. nsIFile->NativePath isn't safe for all + // character sets on Windows. + // A better way would be to QI to nsILocalFile, and get a filehandle + // from there. Only problem is that myspell wants a path - rv = NS_GetSpecialDirectory(NS_XPCOM_COMPONENT_DIR, getter_AddRefs(file)); - NS_ENSURE_SUCCESS(rv, rv); - if (!file) - return NS_ERROR_FAILURE; - rv = file->Append(NS_LITERAL_STRING("myspell")); - NS_ENSURE_SUCCESS(rv, rv); - rv = file->Append(mDictionary + NS_LITERAL_STRING(".dic")); - NS_ENSURE_SUCCESS(rv, rv); - file->GetPath(dictFileName); + nsresult rv = affFile->GetNativePath(affFileName); + NS_ENSURE_SUCCESS(rv, rv); - // SetDictionary can be called multiple times, so we might have a valid mMySpell instance - // which needs cleaned up. - if (mMySpell) - delete mMySpell; + dictFileName = affFileName; + PRInt32 dotPos = dictFileName.RFindChar('.'); + if (dotPos == -1) + return NS_ERROR_FAILURE; - mMySpell = new MySpell(NS_ConvertUTF16toUTF8(affFileName).get(), NS_ConvertUTF16toUTF8(dictFileName).get()); - if (!mMySpell) - return NS_ERROR_FAILURE; + dictFileName.SetLength(dotPos); + dictFileName.AppendLiteral(".aff"); - nsCOMPtr ccm = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); + // SetDictionary can be called multiple times, so we might have a + // valid mMySpell instance which needs cleaned up. + delete mMySpell; - rv = ccm->GetUnicodeDecoder(mMySpell->get_dic_encoding(), getter_AddRefs(mDecoder)); - NS_ENSURE_SUCCESS(rv, rv); - rv = ccm->GetUnicodeEncoder(mMySpell->get_dic_encoding(), getter_AddRefs(mEncoder)); - if (mEncoder && NS_SUCCEEDED(rv)) { - mEncoder->SetOutputErrorBehavior(mEncoder->kOnError_Signal, nsnull, '?'); - } + mDictionary = aDictionary; - NS_ENSURE_SUCCESS(rv, rv); + mMySpell = new MySpell(affFileName.get(), + dictFileName.get()); + if (!mMySpell) + return NS_ERROR_OUT_OF_MEMORY; - PRInt32 pos = mDictionary.FindChar('-'); - if (pos == -1) - mLanguage.Assign(NS_LITERAL_STRING("en")); - else - mLanguage = Substring(mDictionary, 0, pos); - } - - return rv; + nsCOMPtr ccm = + do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + rv = ccm->GetUnicodeDecoder(mMySpell->get_dic_encoding(), + getter_AddRefs(mDecoder)); + NS_ENSURE_SUCCESS(rv, rv); + + rv = ccm->GetUnicodeEncoder(mMySpell->get_dic_encoding(), + getter_AddRefs(mEncoder)); + NS_ENSURE_SUCCESS(rv, rv); + + if (mEncoder) + mEncoder->SetOutputErrorBehavior(mEncoder->kOnError_Signal, nsnull, '?'); + + PRInt32 pos = mDictionary.FindChar('-'); + if (pos == -1) + pos = mDictionary.FindChar('_'); + + if (pos == -1) + mLanguage.Assign(mDictionary); + else + mLanguage = Substring(mDictionary, 0, pos); + + return NS_OK; } /* readonly attribute wstring language; */ @@ -170,6 +187,9 @@ NS_IMETHODIMP mozMySpell::GetLanguage(PRUnichar **aLanguage) { NS_ENSURE_ARG_POINTER(aLanguage); + if (mDictionary.IsEmpty()) + return NS_ERROR_NOT_INITIALIZED; + *aLanguage = ToNewUnicode(mLanguage); return *aLanguage ? NS_OK : NS_ERROR_OUT_OF_MEMORY; } @@ -218,72 +238,151 @@ NS_IMETHODIMP mozMySpell::SetPersonalDictionary(mozIPersonalDictionary * aPerson return NS_OK; } +struct AppendNewStruct +{ + PRUnichar **dics; + PRUint32 count; + PRBool failed; +}; + +static PLDHashOperator +AppendNewString(const PRUnichar *aString, nsIFile* aFile, void* aClosure) +{ + AppendNewStruct *ans = (AppendNewStruct*) aClosure; + ans->dics[ans->count] = NS_strdup(aString); + if (!ans->dics[ans->count]) { + ans->failed = PR_TRUE; + return PL_DHASH_STOP; + } + + ++ans->count; + return PL_DHASH_NEXT; +} + /* void GetDictionaryList ([array, size_is (count)] out wstring dictionaries, out PRUint32 count); */ -NS_IMETHODIMP mozMySpell::GetDictionaryList(PRUnichar ***aDictionaries, PRUint32 *aCount) +NS_IMETHODIMP mozMySpell::GetDictionaryList(PRUnichar ***aDictionaries, + PRUint32 *aCount) { if (!aDictionaries || !aCount) return NS_ERROR_NULL_POINTER; - *aDictionaries = 0; - *aCount = 0; - PRInt32 tempCount=0, arraySize = kFirstDirSize; - PRUnichar **newPtr; + AppendNewStruct ans = { + (PRUnichar**) NS_Alloc(sizeof(PRUnichar*) * mDictionaries.Count()), + 0, + PR_FALSE + }; - nsCOMPtr file; - nsresult rv = NS_GetSpecialDirectory(NS_XPCOM_COMPONENT_DIR, getter_AddRefs(file)); - NS_ENSURE_SUCCESS(rv, rv); - if (!file) - return NS_ERROR_FAILURE; + // This pointer is used during enumeration + mDictionaries.EnumerateRead(AppendNewString, &ans); - rv = file->Append(NS_LITERAL_STRING("myspell")); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr dirEntries; - rv = file->GetDirectoryEntries(getter_AddRefs(dirEntries)); - NS_ENSURE_SUCCESS(rv, rv); - if (!dirEntries) - return NS_ERROR_FAILURE; - - PRUnichar **tmpPtr = (PRUnichar **)nsMemory::Alloc(sizeof(PRUnichar *) * kFirstDirSize); - if (!tmpPtr) - return NS_ERROR_OUT_OF_MEMORY; - - PRBool hasMore = PR_FALSE; - while (NS_SUCCEEDED(dirEntries->HasMoreElements(&hasMore)) && hasMore) { - nsCOMPtr nextItem; - - dirEntries->GetNext(getter_AddRefs(nextItem)); - nsCOMPtr theFile = do_QueryInterface(nextItem); - - if (theFile) { - nsAutoString fileName; - theFile->GetLeafName(fileName); - PRInt32 dotLocation = fileName.FindChar('.'); - if ((dotLocation != -1) && - Substring(fileName,dotLocation,4).EqualsLiteral(".dic")) { - if (tempCount >= arraySize) { - arraySize = 2 * tempCount; - newPtr = (PRUnichar **)nsMemory::Alloc(sizeof(PRUnichar *) * arraySize); - if (!newPtr){ - NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(tempCount, tmpPtr); - return NS_ERROR_OUT_OF_MEMORY; - } - for (PRInt32 i = 0; i < tempCount; ++i){ - newPtr[i] = tmpPtr[i]; - } - nsMemory::Free(tmpPtr); - tmpPtr=newPtr; - } - tmpPtr[tempCount++] = ToNewUnicode(Substring(fileName,0,dotLocation)); - } + if (ans.failed) { + while (ans.count) { + --ans.count; + NS_Free(ans.dics[ans.count]); } + NS_Free(ans.dics); + return NS_ERROR_OUT_OF_MEMORY; } - *aDictionaries = tmpPtr; - *aCount = tempCount; + *aDictionaries = ans.dics; + *aCount = ans.count; + return NS_OK; } +void +mozMySpell::LoadDictionaryList() +{ + mDictionaries.Clear(); + + nsresult rv; + + nsCOMPtr dirSvc = + do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID); + if (!dirSvc) + return; + + nsCOMPtr dictDir; + rv = dirSvc->Get(DICTIONARY_SEARCH_DIRECTORY, + NS_GET_IID(nsIFile), getter_AddRefs(dictDir)); + if (NS_FAILED(rv)) { + // default to appdir/dictionaries + rv = dirSvc->Get(NS_XPCOM_CURRENT_PROCESS_DIR, + NS_GET_IID(nsIFile), getter_AddRefs(dictDir)); + if (NS_FAILED(rv)) + return; + + dictDir->AppendNative(NS_LITERAL_CSTRING("dictionaries")); + } + + LoadDictionariesFromDir(dictDir); + + nsCOMPtr dictDirs; + rv = dirSvc->Get(DICTIONARY_SEARCH_DIRECTORY_LIST, + NS_GET_IID(nsISimpleEnumerator), getter_AddRefs(dictDirs)); + if (NS_FAILED(rv)) + return; + + PRBool hasMore; + while (NS_SUCCEEDED(dictDirs->HasMoreElements(&hasMore)) && hasMore) { + nsCOMPtr elem; + dictDirs->GetNext(getter_AddRefs(elem)); + + dictDir = do_QueryInterface(elem); + if (dictDir) + LoadDictionariesFromDir(dictDir); + } +} + +void +mozMySpell::LoadDictionariesFromDir(nsIFile* aDir) +{ + nsresult rv; + + PRBool check = PR_FALSE; + rv = aDir->Exists(&check); + if (NS_FAILED(rv) || !check) + return; + + rv = aDir->IsDirectory(&check); + if (NS_FAILED(rv) || !check) + return; + + nsCOMPtr e; + rv = aDir->GetDirectoryEntries(getter_AddRefs(e)); + if (NS_FAILED(rv)) + return; + + nsCOMPtr files(do_QueryInterface(e)); + if (!files) + return; + + nsCOMPtr file; + while (NS_SUCCEEDED(files->GetNextFile(getter_AddRefs(file))) && file) { + nsAutoString leafName; + file->GetLeafName(leafName); + if (!StringEndsWith(leafName, NS_LITERAL_STRING(".dic"))) + continue; + + nsAutoString dict(leafName); + dict.SetLength(dict.Length() - 4); // magic length of ".dic" + + // check for the presence of the .aff file + leafName = dict; + leafName.AppendLiteral(".aff"); + file->SetLeafName(leafName); + rv = file->Exists(&check); + if (NS_FAILED(rv) || !check) + continue; + +#ifdef DEBUG_bsmedberg + printf("Adding dictionary: %s\n", NS_ConvertUTF16toUTF8(dict).get()); +#endif + + mDictionaries.Put(dict.get(), file); + } +} + nsresult mozMySpell::ConvertCharset(const PRUnichar* aStr, char ** aDst) { NS_ENSURE_ARG_POINTER(aDst); @@ -374,3 +473,15 @@ NS_IMETHODIMP mozMySpell::Suggest(const PRUnichar *aWord, PRUnichar ***aSuggesti NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(*aSuggestionCount, wlst); return rv; } + +NS_IMETHODIMP +mozMySpell::Observe(nsISupports* aSubj, const char *aTopic, + const PRUnichar *aData) +{ + NS_ASSERTION(!strcmp(aTopic, "profile-do-change"), + "Unexpected observer topic"); + + LoadDictionaryList(); + + return NS_OK; +} diff --git a/mozilla/extensions/spellcheck/myspell/src/mozMySpell.h b/mozilla/extensions/spellcheck/myspell/src/mozMySpell.h index 88d3f29a1c6..827bd7fe4a3 100644 --- a/mozilla/extensions/spellcheck/myspell/src/mozMySpell.h +++ b/mozilla/extensions/spellcheck/myspell/src/mozMySpell.h @@ -61,8 +61,11 @@ #include "mozIPersonalDictionary.h" #include "nsString.h" #include "nsCOMPtr.h" +#include "nsIObserver.h" #include "nsIUnicodeEncoder.h" #include "nsIUnicodeDecoder.h" +#include "nsInterfaceHashtable.h" +#include "nsWeakReference.h" #define MOZ_MYSPELL_CONTRACTID "@mozilla.org/spellchecker/myspell;1" #define MOZ_MYSPELL_CID \ @@ -70,15 +73,23 @@ 0xD1EE1205, 0x3F96, 0x4a0f, \ { 0xAB, 0xFE, 0x09, 0xE8, 0xC5, 0x4C, 0x9E, 0x9A} } -class mozMySpell : public mozISpellCheckingEngine +class mozMySpell : public mozISpellCheckingEngine, + public nsIObserver, + public nsSupportsWeakReference { public: NS_DECL_ISUPPORTS NS_DECL_MOZISPELLCHECKINGENGINE + NS_DECL_NSIOBSERVER - mozMySpell(); + mozMySpell() : mMySpell(nsnull) { } virtual ~mozMySpell(); + nsresult Init(); + + void LoadDictionaryList(); + void LoadDictionariesFromDir(nsIFile* aDir); + // helper method for converting a word to the charset of the dictionary nsresult ConvertCharset(const PRUnichar* aStr, char ** aDst); @@ -87,8 +98,12 @@ protected: nsCOMPtr mPersonalDictionary; nsCOMPtr mEncoder; nsCOMPtr mDecoder; + + // Hashtable matches dictionary name to .aff file + nsInterfaceHashtable mDictionaries; nsString mDictionary; nsString mLanguage; + MySpell *mMySpell; }; diff --git a/mozilla/extensions/spellcheck/myspell/src/mozMySpellDirProvider.cpp b/mozilla/extensions/spellcheck/myspell/src/mozMySpellDirProvider.cpp new file mode 100644 index 00000000000..7b3c95b8112 --- /dev/null +++ b/mozilla/extensions/spellcheck/myspell/src/mozMySpellDirProvider.cpp @@ -0,0 +1,180 @@ +/* ***** 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 Firefox. + * + * The Initial Developer of the Original Code is + * the Mozilla Foundation . + * + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Benjamin Smedberg (Original Code) + * + * 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 "mozMySpellDirProvider.h" +#include "nsXULAppAPI.h" +#include "nsString.h" + +#include "mozISpellCheckingEngine.h" +#include "nsICategoryManager.h" + +NS_IMPL_ISUPPORTS2(mozMySpellDirProvider, + nsIDirectoryServiceProvider, + nsIDirectoryServiceProvider2) + +NS_IMETHODIMP +mozMySpellDirProvider::GetFile(const char *aKey, PRBool *aPersist, + nsIFile* *aResult) +{ + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +mozMySpellDirProvider::GetFiles(const char *aKey, + nsISimpleEnumerator* *aResult) +{ + if (strcmp(aKey, DICTIONARY_SEARCH_DIRECTORY_LIST) != 0) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr dirSvc = + do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID); + if (!dirSvc) + return NS_ERROR_FAILURE; + + nsCOMPtr list; + nsresult rv = dirSvc->Get(XRE_EXTENSIONS_DIR_LIST, + NS_GET_IID(nsISimpleEnumerator), + getter_AddRefs(list)); + if (NS_FAILED(rv)) + return rv; + + nsCOMPtr e = new AppendingEnumerator(list); + if (!e) + return NS_ERROR_OUT_OF_MEMORY; + + *aResult = nsnull; + e.swap(*aResult); + return NS_SUCCESS_AGGREGATE_RESULT; +} + +NS_IMPL_ISUPPORTS1(mozMySpellDirProvider::AppendingEnumerator, + nsISimpleEnumerator) + +NS_IMETHODIMP +mozMySpellDirProvider::AppendingEnumerator::HasMoreElements(PRBool *aResult) +{ + *aResult = mNext ? PR_TRUE : PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP +mozMySpellDirProvider::AppendingEnumerator::GetNext(nsISupports* *aResult) +{ + NS_IF_ADDREF(*aResult = mNext); + + mNext = nsnull; + + nsresult rv; + + // Ignore all errors + + PRBool more; + while (NS_SUCCEEDED(mBase->HasMoreElements(&more)) && more) { + nsCOMPtr nextbasesupp; + mBase->GetNext(getter_AddRefs(nextbasesupp)); + + nsCOMPtr nextbase(do_QueryInterface(nextbasesupp)); + if (!nextbase) + continue; + + nextbase->Clone(getter_AddRefs(mNext)); + if (!mNext) + continue; + + mNext->AppendNative(NS_LITERAL_CSTRING("dictionaries")); + + PRBool exists; + rv = mNext->Exists(&exists); + if (NS_SUCCEEDED(rv) && exists) + break; + + mNext = nsnull; + } + + return NS_OK; +} + +mozMySpellDirProvider::AppendingEnumerator::AppendingEnumerator + (nsISimpleEnumerator* aBase) : + mBase(aBase) +{ + // Initialize mNext to begin + GetNext(nsnull); +} + +NS_METHOD +mozMySpellDirProvider::Register(nsIComponentManager* aCompMgr, + nsIFile* aPath, const char *aLoaderStr, + const char *aType, + const nsModuleComponentInfo *aInfo) +{ + nsresult rv; + + nsCOMPtr catMan = + do_GetService(NS_CATEGORYMANAGER_CONTRACTID); + if (!catMan) + return NS_ERROR_FAILURE; + + rv = catMan->AddCategoryEntry(XPCOM_DIRECTORY_PROVIDER_CATEGORY, + "spellcheck-directory-provider", + kContractID, PR_TRUE, PR_TRUE, nsnull); + return rv; +} + +NS_METHOD +mozMySpellDirProvider::Unregister(nsIComponentManager* aCompMgr, + nsIFile* aPath, + const char *aLoaderStr, + const nsModuleComponentInfo *aInfo) +{ + nsresult rv; + + nsCOMPtr catMan = + do_GetService(NS_CATEGORYMANAGER_CONTRACTID); + if (!catMan) + return NS_ERROR_FAILURE; + + rv = catMan->DeleteCategoryEntry(XPCOM_DIRECTORY_PROVIDER_CATEGORY, + "spellcheck-directory-provider", + PR_TRUE); + return rv; +} + +char const *const +mozMySpellDirProvider::kContractID = "@mozilla.org/spellcheck/dir-provider;1"; diff --git a/mozilla/extensions/spellcheck/myspell/src/mozMySpellDirProvider.h b/mozilla/extensions/spellcheck/myspell/src/mozMySpellDirProvider.h new file mode 100644 index 00000000000..e14cea420a9 --- /dev/null +++ b/mozilla/extensions/spellcheck/myspell/src/mozMySpellDirProvider.h @@ -0,0 +1,84 @@ +/* ***** 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 Firefox. + * + * The Initial Developer of the Original Code is + * the Mozilla Foundation . + * + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Benjamin Smedberg (Original Code) + * + * 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 mozMySpellDirProvider_h__ +#define mozMySpellDirProvider_h__ + +#include "nsIDirectoryService.h" +#include "nsIGenericFactory.h" +#include "nsISimpleEnumerator.h" + +class mozMySpellDirProvider : + public nsIDirectoryServiceProvider2 +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIDIRECTORYSERVICEPROVIDER + NS_DECL_NSIDIRECTORYSERVICEPROVIDER2 + + static NS_METHOD Register(nsIComponentManager* aCompMgr, + nsIFile* aPath, const char *aLoaderStr, + const char *aType, + const nsModuleComponentInfo *aInfo); + + static NS_METHOD Unregister(nsIComponentManager* aCompMgr, + nsIFile* aPath, const char *aLoaderStr, + const nsModuleComponentInfo *aInfo); + + static char const *const kContractID; + +private: + class AppendingEnumerator : public nsISimpleEnumerator + { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSISIMPLEENUMERATOR + + AppendingEnumerator(nsISimpleEnumerator* aBase); + + private: + nsCOMPtr mBase; + nsCOMPtr mNext; + }; +}; + +#define MYSPELLDIRPROVIDER_CID \ +{ 0x64d6174c, 0x1496, 0x4ffd, \ + { 0x87, 0xf2, 0xda, 0x26, 0x70, 0xf8, 0x89, 0x34 } } + +#endif // mozMySpellDirProvider diff --git a/mozilla/extensions/spellcheck/myspell/src/mozMySpellFactory.cpp b/mozilla/extensions/spellcheck/myspell/src/mozMySpellFactory.cpp index 33a933cf812..e1828029443 100644 --- a/mozilla/extensions/spellcheck/myspell/src/mozMySpellFactory.cpp +++ b/mozilla/extensions/spellcheck/myspell/src/mozMySpellFactory.cpp @@ -39,13 +39,21 @@ #include "mozMySpell.h" +#ifdef MOZ_XUL_APP +#include "mozMySpellDirProvider.h" +#endif + //////////////////////////////////////////////////////////////////////// // Define the contructor function for the objects // // NOTE: This creates an instance of objects by using the default constructor // -NS_GENERIC_FACTORY_CONSTRUCTOR(mozMySpell) +NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(mozMySpell, Init) + +#ifdef MOZ_XUL_APP +NS_GENERIC_FACTORY_CONSTRUCTOR(mozMySpellDirProvider) +#endif //////////////////////////////////////////////////////////////////////// // Define a table of CIDs implemented by this module along with other @@ -53,7 +61,22 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(mozMySpell) // class name. // static nsModuleComponentInfo components[] = { - { NULL, MOZ_MYSPELL_CID, MOZ_MYSPELL_CONTRACTID, mozMySpellConstructor } + { + "mozMySpell", + MOZ_MYSPELL_CID, + MOZ_MYSPELL_CONTRACTID, + mozMySpellConstructor + } +#ifdef MOZ_XUL_APP + , { + "mozMySpellDirProvider", + MYSPELLDIRPROVIDER_CID, + mozMySpellDirProvider::kContractID, + mozMySpellDirProviderConstructor, + mozMySpellDirProvider::Register, + mozMySpellDirProvider::Unregister + } +#endif }; ////////////////////////////////////////////////////////////////////////