1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/* ***** BEGIN LICENSE BLOCK *****
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public License
6
* as published by the Free Software Foundation; either version 2
7
* of the License, or (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
* Fragments of this code are taken from Mozilla Spellchecker Component:
20
* The Initial Developer of the Original Code of Mozilla Spellchecker Component is
22
* Portions created by the Initial Developer are Copyright (C) 2001
23
* the Initial Developer. All Rights Reserved.
24
* Adapted for use of Voikko by Andris Pavenis <andris.pavenis@iki.fi>
26
* Contributor(s): David Einstein <Deinst@world.std.com>
27
* Kevin Hendricks <kevin.hendricks@sympatico.ca>
28
* Michiel van Leeuwen <mvl@exedo.nl>
29
* Harri Pitkänen <hatapitk@iki.fi>
31
* This spellchecker is based on the MySpell spellchecker made for Open Office
32
* by Kevin Hendricks. Although the algorithms and code, have changed
33
* slightly, the architecture is still the same. The Mozilla implementation
34
* is designed to be compatible with the Open Office dictionaries.
35
* Please do not make changes to the affix or dictionary file formats
36
* without attempting to coordinate with Kevin. For more information
37
* on the original MySpell see
38
* http://whiteboard.openoffice.org/source/browse/whiteboard/lingucomponent/source/spellcheck/myspell/
40
* A special thanks and credit goes to Geoff Kuenning
41
* the creator of ispell. MySpell's affix algorithms were
42
* based on those of ispell which should be noted is
43
* copyright Geoff Kuenning et.al. and now available
44
* under a BSD style license. For more information on ispell
45
* and affix compression in general, please see:
46
* http://www.cs.ucla.edu/ficus-members/geoff/ispell.html
47
* (the home page for ispell)
49
* ***** END LICENSE BLOCK ***** */
51
#include "mozVoikkoSpell.hxx"
52
#include "mozVoikkoUtils.hxx"
53
#include <nsISimpleEnumerator.h>
54
#include <nsServiceManagerUtils.h>
55
#include <nsICategoryManager.h>
56
#include <mozISpellI18NManager.h>
57
#include <nsICharsetConverterManager.h>
58
#include <nsISupportsPrimitives.h>
59
#include <nsUnicharUtilCIID.h>
60
#include <nsUnicharUtils.h>
61
#include <nsStringAPI.h>
62
#include <nsEmbedString.h>
63
#include <nsCRTGlue.h>
67
#define MOZVOIKKO_LANGUAGE_STRING "fi-FI"
69
const PRInt32 kFirstDirSize=8;
70
static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
71
static NS_DEFINE_CID(kUnicharUtilCID, NS_UNICHARUTIL_CID);
73
NS_IMPL_ISUPPORTS1(mozVoikkoSpell, mozISpellCheckingEngine)
75
mozVoikkoSpell::mozVoikkoSpell()
80
mozVoikkoSpell::~mozVoikkoSpell()
82
mPersonalDictionary = nsnull;
86
NS_IMETHODIMP mozVoikkoSpell::LoadDictionariesFromDir(nsIFile* aFile)
88
return NS_ERROR_NOT_IMPLEMENTED;
91
/* attribute wstring dictionary; */
92
NS_IMETHODIMP mozVoikkoSpell::GetDictionary(PRUnichar **aDictionary)
94
NS_ENSURE_ARG_POINTER(aDictionary);
96
*aDictionary = ToNewUnicode(mDictionary);
97
return *aDictionary ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
100
/* set the Dictionary.
101
* This also Loads the dictionary and initializes the converter using the dictionaries converter
103
NS_IMETHODIMP mozVoikkoSpell::SetDictionary(const PRUnichar *aDictionary)
105
NS_ENSURE_ARG_POINTER(aDictionary);
107
nsString newDict(aDictionary);
110
if (!newDict.Equals(NS_LITERAL_STRING(MOZVOIKKO_LANGUAGE_STRING)))
112
logMessage("mozVoikko: dictionary '%s' is not supported",
113
NS_ConvertUTF16toUTF8(newDict).get());
114
return NS_ERROR_FAILURE;
117
if (!mDictionary.Equals(newDict))
119
mDictionary = aDictionary;
120
// FIXME: So we need that?.
123
voikkoSpell = new MozVoikko();
125
return NS_ERROR_FAILURE;
127
mLanguage.Assign(newDict);
137
/* readonly attribute wstring language; */
138
NS_IMETHODIMP mozVoikkoSpell::GetLanguage(PRUnichar **aLanguage)
140
NS_ENSURE_ARG_POINTER(aLanguage);
142
*aLanguage = ToNewUnicode(mLanguage);
143
return *aLanguage ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
146
/* readonly attribute boolean providesPersonalDictionary; */
147
NS_IMETHODIMP mozVoikkoSpell::GetProvidesPersonalDictionary(PRBool *aProvidesPersonalDictionary)
149
NS_ENSURE_ARG_POINTER(aProvidesPersonalDictionary);
151
*aProvidesPersonalDictionary = PR_FALSE;
155
/* readonly attribute boolean providesWordUtils; */
156
NS_IMETHODIMP mozVoikkoSpell::GetProvidesWordUtils(PRBool *aProvidesWordUtils)
158
NS_ENSURE_ARG_POINTER(aProvidesWordUtils);
160
*aProvidesWordUtils = PR_FALSE;
164
/* readonly attribute wstring name; */
165
NS_IMETHODIMP mozVoikkoSpell::GetName(PRUnichar * *aName)
167
return NS_ERROR_NOT_IMPLEMENTED;
170
/* readonly attribute wstring copyright; */
171
NS_IMETHODIMP mozVoikkoSpell::GetCopyright(PRUnichar * *aCopyright)
173
return NS_ERROR_NOT_IMPLEMENTED;
176
/* attribute mozIPersonalDictionary personalDictionary; */
177
NS_IMETHODIMP mozVoikkoSpell::GetPersonalDictionary(mozIPersonalDictionary * *aPersonalDictionary)
179
*aPersonalDictionary = mPersonalDictionary;
180
NS_IF_ADDREF(*aPersonalDictionary);
184
NS_IMETHODIMP mozVoikkoSpell::SetPersonalDictionary(mozIPersonalDictionary * aPersonalDictionary)
186
mPersonalDictionary = aPersonalDictionary;
190
/* void GetDictionaryList ([array, size_is (count)] out wstring dictionaries, out PRUint32 count); */
191
NS_IMETHODIMP mozVoikkoSpell::GetDictionaryList(PRUnichar ***aDictionaries, PRUint32 *aCount)
193
if (!aDictionaries || !aCount)
194
return NS_ERROR_NULL_POINTER;
199
PRUnichar **tmpPtr = (PRUnichar **) NS_Alloc(sizeof(PRUnichar *));
201
return NS_ERROR_OUT_OF_MEMORY;
205
MozVoikko voikkoSpell;
208
nsAutoString voikkoDictName(NS_LITERAL_STRING(MOZVOIKKO_LANGUAGE_STRING).get());
209
tmpPtr[0] = ToNewUnicode(voikkoDictName);
211
*aDictionaries = tmpPtr;
220
nsresult mozVoikkoSpell::ConvertCharset(const PRUnichar* aStr, char ** aDst)
222
NS_ENSURE_ARG_POINTER(aDst);
224
nsString str_u16(aStr);
225
nsCString str_u8 = NS_ConvertUTF16toUTF8(str_u16);
226
const char *str = str_u8.get();
227
*aDst = (char*)NS_Alloc(1 + strlen(str));
233
/* boolean Check (in wstring word); */
234
NS_IMETHODIMP mozVoikkoSpell::Check(const PRUnichar *aWord, PRBool *aResult)
236
NS_ENSURE_ARG_POINTER(aWord);
237
NS_ENSURE_ARG_POINTER(aResult);
238
NS_ENSURE_TRUE(voikkoSpell, NS_ERROR_FAILURE);
241
nsresult rv = ConvertCharset(aWord, &charsetWord);
242
NS_ENSURE_SUCCESS(rv, rv);
244
*aResult = voikkoSpell->spell(charsetWord);
246
NS_Free(charsetWord);
248
if (!*aResult && mPersonalDictionary)
249
rv = mPersonalDictionary->Check(aWord, mLanguage.get(), aResult);
254
/* void Suggest (in wstring word, [array, size_is (count)] out wstring suggestions, out PRUint32 count); */
255
NS_IMETHODIMP mozVoikkoSpell::Suggest(const PRUnichar *aWord, PRUnichar ***aSuggestions, PRUint32 *aSuggestionCount)
257
NS_ENSURE_ARG_POINTER(aSuggestions);
258
NS_ENSURE_ARG_POINTER(aSuggestionCount);
259
NS_ENSURE_TRUE(voikkoSpell, NS_ERROR_FAILURE);
262
*aSuggestionCount = 0;
265
rv = ConvertCharset(aWord, &charsetWord);
266
NS_ENSURE_SUCCESS(rv, rv);
269
*aSuggestionCount = voikkoSpell->suggest(&wlst, charsetWord);
270
NS_Free(charsetWord);
272
// This code is copy/pasted from mySpell (with format changes). Maybe
273
// it can be optimized.
274
if (*aSuggestionCount)
276
*aSuggestions = (PRUnichar **) NS_Alloc(*aSuggestionCount * sizeof(PRUnichar *));
280
for (index = 0; index < *aSuggestionCount && NS_SUCCEEDED(rv); ++index)
282
// Convert the suggestion to utf16
283
nsString str_u16 = NS_ConvertUTF8toUTF16(wlst[index]);
284
PRUint32 len = str_u16.Length();
285
PRUnichar *tmp = (PRUnichar *)NS_Alloc(sizeof(PRUnichar) * (1 + len));
286
memcpy(tmp, str_u16.get(), sizeof(PRUnichar) * (1 + len));
287
(*aSuggestions)[index] = tmp;
291
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(index, *aSuggestions); // free the PRUnichar strings up to the point at which the error occurred
293
else // if (*aSuggestions)
294
rv = NS_ERROR_OUT_OF_MEMORY;
297
voikkoSpell->freeSuggestions(wlst);