1b0844812SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3b0844812SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4b0844812SAndrew Rist * or more contributor license agreements. See the NOTICE file
5b0844812SAndrew Rist * distributed with this work for additional information
6b0844812SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7b0844812SAndrew Rist * to you under the Apache License, Version 2.0 (the
8b0844812SAndrew Rist * "License"); you may not use this file except in compliance
9b0844812SAndrew Rist * with the License. You may obtain a copy of the License at
10b0844812SAndrew Rist *
11b0844812SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12b0844812SAndrew Rist *
13b0844812SAndrew Rist * Unless required by applicable law or agreed to in writing,
14b0844812SAndrew Rist * software distributed under the License is distributed on an
15b0844812SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16b0844812SAndrew Rist * KIND, either express or implied. See the License for the
17b0844812SAndrew Rist * specific language governing permissions and limitations
18b0844812SAndrew Rist * under the License.
19b0844812SAndrew Rist *
20b0844812SAndrew Rist *************************************************************/
21b0844812SAndrew Rist
22b0844812SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_lingucomponent.hxx"
26cdf0e10cSrcweir #include <com/sun/star/uno/Reference.h>
27cdf0e10cSrcweir #include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
28cdf0e10cSrcweir
29cdf0e10cSrcweir #include <com/sun/star/linguistic2/SpellFailure.hpp>
30cdf0e10cSrcweir #include <cppuhelper/factory.hxx> // helper for factories
31cdf0e10cSrcweir #include <com/sun/star/registry/XRegistryKey.hpp>
32cdf0e10cSrcweir #include <tools/debug.hxx>
33cdf0e10cSrcweir #include <unotools/processfactory.hxx>
34cdf0e10cSrcweir #include <osl/mutex.hxx>
35cdf0e10cSrcweir
36cdf0e10cSrcweir #include <macspellimp.hxx>
37cdf0e10cSrcweir
38cdf0e10cSrcweir #include <linguistic/spelldta.hxx>
39cdf0e10cSrcweir #include <unotools/pathoptions.hxx>
40cdf0e10cSrcweir #include <unotools/useroptions.hxx>
41cdf0e10cSrcweir #include <osl/file.hxx>
42cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
43cdf0e10cSrcweir
44cdf0e10cSrcweir
45cdf0e10cSrcweir using namespace utl;
46cdf0e10cSrcweir using namespace osl;
47cdf0e10cSrcweir using namespace rtl;
48cdf0e10cSrcweir using namespace com::sun::star;
49cdf0e10cSrcweir using namespace com::sun::star::beans;
50cdf0e10cSrcweir using namespace com::sun::star::lang;
51cdf0e10cSrcweir using namespace com::sun::star::uno;
52cdf0e10cSrcweir using namespace com::sun::star::linguistic2;
53cdf0e10cSrcweir using namespace linguistic;
54cdf0e10cSrcweir
MacSpellChecker()55cdf0e10cSrcweir MacSpellChecker::MacSpellChecker() :
56cdf0e10cSrcweir aEvtListeners ( GetLinguMutex() )
57cdf0e10cSrcweir {
58cdf0e10cSrcweir aDEncs = NULL;
59cdf0e10cSrcweir aDLocs = NULL;
60cdf0e10cSrcweir aDNames = NULL;
61cdf0e10cSrcweir bDisposing = sal_False;
62cdf0e10cSrcweir pPropHelper = NULL;
63cdf0e10cSrcweir numdict = 0;
64cdf0e10cSrcweir NSApplicationLoad();
65cdf0e10cSrcweir NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
66cdf0e10cSrcweir macSpell = [NSSpellChecker sharedSpellChecker];
67cdf0e10cSrcweir macTag = [NSSpellChecker uniqueSpellDocumentTag];
68cdf0e10cSrcweir [pool release];
69cdf0e10cSrcweir }
70cdf0e10cSrcweir
71cdf0e10cSrcweir
~MacSpellChecker()72cdf0e10cSrcweir MacSpellChecker::~MacSpellChecker()
73cdf0e10cSrcweir {
74cdf0e10cSrcweir numdict = 0;
75cdf0e10cSrcweir if (aDEncs) delete[] aDEncs;
76cdf0e10cSrcweir aDEncs = NULL;
77cdf0e10cSrcweir if (aDLocs) delete[] aDLocs;
78cdf0e10cSrcweir aDLocs = NULL;
79cdf0e10cSrcweir if (aDNames) delete[] aDNames;
80cdf0e10cSrcweir aDNames = NULL;
81cdf0e10cSrcweir if (pPropHelper)
82cdf0e10cSrcweir pPropHelper->RemoveAsPropListener();
83cdf0e10cSrcweir }
84cdf0e10cSrcweir
85cdf0e10cSrcweir
GetPropHelper_Impl()86cdf0e10cSrcweir PropertyHelper_Spell & MacSpellChecker::GetPropHelper_Impl()
87cdf0e10cSrcweir {
88cdf0e10cSrcweir if (!pPropHelper)
89cdf0e10cSrcweir {
90cdf0e10cSrcweir Reference< XPropertySet > xPropSet( GetLinguProperties(), UNO_QUERY );
91cdf0e10cSrcweir
92cdf0e10cSrcweir pPropHelper = new PropertyHelper_Spell( (XSpellChecker *) this, xPropSet );
93cdf0e10cSrcweir xPropHelper = pPropHelper;
94cdf0e10cSrcweir pPropHelper->AddAsPropListener(); //! after a reference is established
95cdf0e10cSrcweir }
96cdf0e10cSrcweir return *pPropHelper;
97cdf0e10cSrcweir }
98cdf0e10cSrcweir
99cdf0e10cSrcweir
getLocales()100cdf0e10cSrcweir Sequence< Locale > SAL_CALL MacSpellChecker::getLocales()
101cdf0e10cSrcweir throw(RuntimeException)
102cdf0e10cSrcweir {
103cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() );
104cdf0e10cSrcweir
105cdf0e10cSrcweir // this routine should return the locales supported by the installed
106cdf0e10cSrcweir // dictionaries. So here we need to parse both the user edited
107cdf0e10cSrcweir // dictionary list and the shared dictionary list
108cdf0e10cSrcweir // to see what dictionaries the admin/user has installed
109cdf0e10cSrcweir
110cdf0e10cSrcweir int numusr; // number of user dictionary entries
111cdf0e10cSrcweir int numshr; // number of shared dictionary entries
112c4436845SJürgen Schmidt // dictentry * spdict; // shared dict entry pointer
113c4436845SJürgen Schmidt // dictentry * updict; // user dict entry pointer
114cdf0e10cSrcweir SvtPathOptions aPathOpt;
115cdf0e10cSrcweir rtl_TextEncoding aEnc = RTL_TEXTENCODING_UTF8;
116cdf0e10cSrcweir
117a285f30aSHerbert Dürr std::vector<NSString*> postspdict;
118a285f30aSHerbert Dürr std::vector<NSString*> postupdict;
119cdf0e10cSrcweir
120cdf0e10cSrcweir if (!numdict) {
121cdf0e10cSrcweir
122cdf0e10cSrcweir // invoke a dictionary manager to get the user dictionary list
123cdf0e10cSrcweir // TODO How on Mac OS X?
124cdf0e10cSrcweir
125cdf0e10cSrcweir // invoke a second dictionary manager to get the shared dictionary list
126cdf0e10cSrcweir NSArray *aLocales = [NSLocale availableLocaleIdentifiers];
127cdf0e10cSrcweir
128cdf0e10cSrcweir //Test for existence of the dictionaries
129cdf0e10cSrcweir for (unsigned int i = 0; i < [aLocales count]; i++)
130cdf0e10cSrcweir {
131a285f30aSHerbert Dürr NSString* pLangStr = (NSString*)[aLocales objectAtIndex:i];
132a285f30aSHerbert Dürr if( [macSpell setLanguage:pLangStr ] )
133cdf0e10cSrcweir {
134a285f30aSHerbert Dürr postspdict.push_back( pLangStr );
135cdf0e10cSrcweir }
136cdf0e10cSrcweir }
137cdf0e10cSrcweir
138cdf0e10cSrcweir numusr = postupdict.size();
139cdf0e10cSrcweir numshr = postspdict.size();
140cdf0e10cSrcweir
141cdf0e10cSrcweir // we really should merge these and remove duplicates but since
142cdf0e10cSrcweir // users can name their dictionaries anything they want it would
143cdf0e10cSrcweir // be impossible to know if a real duplication exists unless we
144cdf0e10cSrcweir // add some unique key to each myspell dictionary
145cdf0e10cSrcweir numdict = numshr + numusr;
146cdf0e10cSrcweir
147cdf0e10cSrcweir if (numdict) {
148cdf0e10cSrcweir aDLocs = new Locale [numdict];
149cdf0e10cSrcweir aDEncs = new rtl_TextEncoding [numdict];
150cdf0e10cSrcweir aDNames = new OUString [numdict];
151cdf0e10cSrcweir aSuppLocales.realloc(numdict);
152cdf0e10cSrcweir Locale * pLocale = aSuppLocales.getArray();
153cdf0e10cSrcweir int numlocs = 0;
154cdf0e10cSrcweir int newloc;
155cdf0e10cSrcweir int i,j;
156cdf0e10cSrcweir int k = 0;
157cdf0e10cSrcweir
158cdf0e10cSrcweir //first add the user dictionaries
159cdf0e10cSrcweir //TODO for MAC?
160cdf0e10cSrcweir
161cdf0e10cSrcweir // now add the shared dictionaries
162cdf0e10cSrcweir for (i = 0; i < numshr; i++) {
163cdf0e10cSrcweir NSDictionary *aLocDict = [ NSLocale componentsFromLocaleIdentifier:postspdict[i] ];
164cdf0e10cSrcweir NSString* aLang = [ aLocDict objectForKey:NSLocaleLanguageCode ];
165cdf0e10cSrcweir NSString* aCountry = [ aLocDict objectForKey:NSLocaleCountryCode ];
166cdf0e10cSrcweir OUString lang([aLang cStringUsingEncoding: NSUTF8StringEncoding], [aLang length], aEnc);
167cdf0e10cSrcweir OUString country([ aCountry cStringUsingEncoding: NSUTF8StringEncoding], [aCountry length], aEnc);
168cdf0e10cSrcweir Locale nLoc( lang, country, OUString() );
169cdf0e10cSrcweir newloc = 1;
170cdf0e10cSrcweir //eliminate duplicates (is this needed for MacOS?)
171cdf0e10cSrcweir for (j = 0; j < numlocs; j++) {
172cdf0e10cSrcweir if (nLoc == pLocale[j]) newloc = 0;
173cdf0e10cSrcweir }
174cdf0e10cSrcweir if (newloc) {
175cdf0e10cSrcweir pLocale[numlocs] = nLoc;
176cdf0e10cSrcweir numlocs++;
177cdf0e10cSrcweir }
178cdf0e10cSrcweir aDLocs[k] = nLoc;
179cdf0e10cSrcweir //pointer to Hunspell dictionary - not needed for MAC
180cdf0e10cSrcweir //aDicts[k] = NULL;
181cdf0e10cSrcweir aDEncs[k] = 0;
182cdf0e10cSrcweir // Dictionary file names not valid for Mac Spell
183cdf0e10cSrcweir //aDNames[k] = aPathOpt.GetLinguisticPath() + A2OU("/ooo/") + A2OU(postspdict[i]->filename);
184cdf0e10cSrcweir k++;
185cdf0e10cSrcweir }
186cdf0e10cSrcweir
187cdf0e10cSrcweir aSuppLocales.realloc(numlocs);
188cdf0e10cSrcweir
189cdf0e10cSrcweir } else {
190cdf0e10cSrcweir /* no dictionary.lst found so register no dictionaries */
191cdf0e10cSrcweir numdict = 0;
192cdf0e10cSrcweir //aDicts = NULL;
193cdf0e10cSrcweir aDEncs = NULL;
194cdf0e10cSrcweir aDLocs = NULL;
195cdf0e10cSrcweir aDNames = NULL;
196cdf0e10cSrcweir aSuppLocales.realloc(0);
197cdf0e10cSrcweir }
198cdf0e10cSrcweir
199cdf0e10cSrcweir /* de-allocation of memory is handled inside the DictMgr */
200c4436845SJürgen Schmidt // updict = NULL;
201c4436845SJürgen Schmidt // spdict = NULL;
202cdf0e10cSrcweir
203cdf0e10cSrcweir }
204cdf0e10cSrcweir
205cdf0e10cSrcweir return aSuppLocales;
206cdf0e10cSrcweir }
207cdf0e10cSrcweir
208cdf0e10cSrcweir
209cdf0e10cSrcweir
hasLocale(const Locale & rLocale)210cdf0e10cSrcweir sal_Bool SAL_CALL MacSpellChecker::hasLocale(const Locale& rLocale)
211cdf0e10cSrcweir throw(RuntimeException)
212cdf0e10cSrcweir {
213cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() );
214cdf0e10cSrcweir
215cdf0e10cSrcweir sal_Bool bRes = sal_False;
216cdf0e10cSrcweir if (!aSuppLocales.getLength())
217cdf0e10cSrcweir getLocales();
218cdf0e10cSrcweir
219cdf0e10cSrcweir sal_Int32 nLen = aSuppLocales.getLength();
220cdf0e10cSrcweir for (sal_Int32 i = 0; i < nLen; ++i)
221cdf0e10cSrcweir {
222cdf0e10cSrcweir const Locale *pLocale = aSuppLocales.getConstArray();
223cdf0e10cSrcweir if (rLocale == pLocale[i])
224cdf0e10cSrcweir {
225cdf0e10cSrcweir bRes = sal_True;
226cdf0e10cSrcweir break;
227cdf0e10cSrcweir }
228cdf0e10cSrcweir }
229cdf0e10cSrcweir return bRes;
230cdf0e10cSrcweir }
231cdf0e10cSrcweir
232cdf0e10cSrcweir
GetSpellFailure(const OUString & rWord,const Locale & rLocale)233cdf0e10cSrcweir sal_Int16 MacSpellChecker::GetSpellFailure( const OUString &rWord, const Locale &rLocale )
234cdf0e10cSrcweir {
235cdf0e10cSrcweir rtl_TextEncoding aEnc;
236cdf0e10cSrcweir
237cdf0e10cSrcweir // initialize a myspell object for each dictionary once
238cdf0e10cSrcweir // (note: mutex is held higher up in isValid)
239cdf0e10cSrcweir
240cdf0e10cSrcweir
241cdf0e10cSrcweir sal_Int16 nRes = -1;
242cdf0e10cSrcweir
243cdf0e10cSrcweir // first handle smart quotes both single and double
244cdf0e10cSrcweir OUStringBuffer rBuf(rWord);
245cdf0e10cSrcweir sal_Int32 n = rBuf.getLength();
246cdf0e10cSrcweir sal_Unicode c;
247cdf0e10cSrcweir for (sal_Int32 ix=0; ix < n; ix++) {
248cdf0e10cSrcweir c = rBuf.charAt(ix);
249cdf0e10cSrcweir if ((c == 0x201C) || (c == 0x201D)) rBuf.setCharAt(ix,(sal_Unicode)0x0022);
250cdf0e10cSrcweir if ((c == 0x2018) || (c == 0x2019)) rBuf.setCharAt(ix,(sal_Unicode)0x0027);
251cdf0e10cSrcweir }
252cdf0e10cSrcweir OUString nWord(rBuf.makeStringAndClear());
253cdf0e10cSrcweir
254cdf0e10cSrcweir if (n)
255cdf0e10cSrcweir {
256cdf0e10cSrcweir aEnc = 0;
257cdf0e10cSrcweir NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
258cdf0e10cSrcweir NSString* aNSStr = [[NSString alloc] initWithCharacters: nWord.getStr() length: nWord.getLength()];
259cdf0e10cSrcweir NSString* aLang = [[NSString alloc] initWithCharacters: rLocale.Language.getStr() length: rLocale.Language.getLength()];
260cdf0e10cSrcweir if(rLocale.Country.getLength()>0)
261cdf0e10cSrcweir {
262cdf0e10cSrcweir NSString* aCountry = [[NSString alloc] initWithCharacters: rLocale.Country.getStr() length: rLocale.Country.getLength()];
263cdf0e10cSrcweir NSString* aTag = @"_";
264cdf0e10cSrcweir NSString* aTaggedCountry = [aTag stringByAppendingString:aCountry];
265cdf0e10cSrcweir [aLang autorelease];
266cdf0e10cSrcweir aLang = [aLang stringByAppendingString:aTaggedCountry];
267cdf0e10cSrcweir }
268cdf0e10cSrcweir
269*1e1ac450SHerbert Dürr NSInteger aCount;
270cdf0e10cSrcweir NSRange range = [macSpell checkSpellingOfString:aNSStr startingAt:0 language:aLang wrap:sal_False inSpellDocumentWithTag:macTag wordCount:&aCount];
271cdf0e10cSrcweir int rVal = 0;
272cdf0e10cSrcweir if(range.length>0)
273cdf0e10cSrcweir {
274cdf0e10cSrcweir rVal = -1;
275cdf0e10cSrcweir }
276cdf0e10cSrcweir else
277cdf0e10cSrcweir {
278cdf0e10cSrcweir rVal = 1;
279cdf0e10cSrcweir }
280cdf0e10cSrcweir [pool release];
281cdf0e10cSrcweir if (rVal != 1)
282cdf0e10cSrcweir {
283cdf0e10cSrcweir nRes = SpellFailure::SPELLING_ERROR;
284cdf0e10cSrcweir } else {
285cdf0e10cSrcweir return -1;
286cdf0e10cSrcweir }
287cdf0e10cSrcweir }
288cdf0e10cSrcweir return nRes;
289cdf0e10cSrcweir }
290cdf0e10cSrcweir
291cdf0e10cSrcweir
292cdf0e10cSrcweir
293cdf0e10cSrcweir sal_Bool SAL_CALL
isValid(const OUString & rWord,const Locale & rLocale,const PropertyValues & rProperties)294cdf0e10cSrcweir MacSpellChecker::isValid( const OUString& rWord, const Locale& rLocale,
295cdf0e10cSrcweir const PropertyValues& rProperties )
296cdf0e10cSrcweir throw(IllegalArgumentException, RuntimeException)
297cdf0e10cSrcweir {
298cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() );
299cdf0e10cSrcweir
300cdf0e10cSrcweir if (rLocale == Locale() || !rWord.getLength())
301cdf0e10cSrcweir return sal_True;
302cdf0e10cSrcweir
303cdf0e10cSrcweir if (!hasLocale( rLocale ))
304cdf0e10cSrcweir #ifdef LINGU_EXCEPTIONS
305cdf0e10cSrcweir throw( IllegalArgumentException() );
306cdf0e10cSrcweir #else
307cdf0e10cSrcweir return sal_True;
308cdf0e10cSrcweir #endif
309cdf0e10cSrcweir
310cdf0e10cSrcweir // Get property values to be used.
311cdf0e10cSrcweir // These are be the default values set in the SN_LINGU_PROPERTIES
312cdf0e10cSrcweir // PropertySet which are overridden by the supplied ones from the
313cdf0e10cSrcweir // last argument.
314cdf0e10cSrcweir // You'll probably like to use a simplier solution than the provided
315cdf0e10cSrcweir // one using the PropertyHelper_Spell.
316cdf0e10cSrcweir
317cdf0e10cSrcweir PropertyHelper_Spell &rHelper = GetPropHelper();
318cdf0e10cSrcweir rHelper.SetTmpPropVals( rProperties );
319cdf0e10cSrcweir
320cdf0e10cSrcweir sal_Int16 nFailure = GetSpellFailure( rWord, rLocale );
321cdf0e10cSrcweir if (nFailure != -1)
322cdf0e10cSrcweir {
323cdf0e10cSrcweir sal_Int16 nLang = LocaleToLanguage( rLocale );
324cdf0e10cSrcweir // postprocess result for errors that should be ignored
325cdf0e10cSrcweir if ( (!rHelper.IsSpellUpperCase() && IsUpper( rWord, nLang ))
326cdf0e10cSrcweir || (!rHelper.IsSpellWithDigits() && HasDigits( rWord ))
327cdf0e10cSrcweir || (!rHelper.IsSpellCapitalization()
328cdf0e10cSrcweir && nFailure == SpellFailure::CAPTION_ERROR)
329cdf0e10cSrcweir )
330cdf0e10cSrcweir nFailure = -1;
331cdf0e10cSrcweir }
332cdf0e10cSrcweir
333cdf0e10cSrcweir return (nFailure == -1);
334cdf0e10cSrcweir }
335cdf0e10cSrcweir
336cdf0e10cSrcweir
337cdf0e10cSrcweir Reference< XSpellAlternatives >
GetProposals(const OUString & rWord,const Locale & rLocale)338cdf0e10cSrcweir MacSpellChecker::GetProposals( const OUString &rWord, const Locale &rLocale )
339cdf0e10cSrcweir {
340cdf0e10cSrcweir // Retrieves the return values for the 'spell' function call in case
341cdf0e10cSrcweir // of a misspelled word.
342cdf0e10cSrcweir // Especially it may give a list of suggested (correct) words:
343cdf0e10cSrcweir
344cdf0e10cSrcweir Reference< XSpellAlternatives > xRes;
345cdf0e10cSrcweir // note: mutex is held by higher up by spell which covers both
346cdf0e10cSrcweir
347cdf0e10cSrcweir sal_Int16 nLang = LocaleToLanguage( rLocale );
348cdf0e10cSrcweir int count;
349cdf0e10cSrcweir Sequence< OUString > aStr( 0 );
350cdf0e10cSrcweir
351cdf0e10cSrcweir // first handle smart quotes (single and double)
352cdf0e10cSrcweir OUStringBuffer rBuf(rWord);
353cdf0e10cSrcweir sal_Int32 n = rBuf.getLength();
354cdf0e10cSrcweir sal_Unicode c;
355cdf0e10cSrcweir for (sal_Int32 ix=0; ix < n; ix++) {
356cdf0e10cSrcweir c = rBuf.charAt(ix);
357cdf0e10cSrcweir if ((c == 0x201C) || (c == 0x201D)) rBuf.setCharAt(ix,(sal_Unicode)0x0022);
358cdf0e10cSrcweir if ((c == 0x2018) || (c == 0x2019)) rBuf.setCharAt(ix,(sal_Unicode)0x0027);
359cdf0e10cSrcweir }
360cdf0e10cSrcweir OUString nWord(rBuf.makeStringAndClear());
361cdf0e10cSrcweir
362cdf0e10cSrcweir if (n)
363cdf0e10cSrcweir {
364cdf0e10cSrcweir NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
365cdf0e10cSrcweir NSString* aNSStr = [[NSString alloc] initWithCharacters: nWord.getStr() length: nWord.getLength()];
366cdf0e10cSrcweir NSString* aLang = [[NSString alloc] initWithCharacters: rLocale.Language.getStr() length: rLocale.Language.getLength() ];
367cdf0e10cSrcweir if(rLocale.Country.getLength()>0)
368cdf0e10cSrcweir {
369cdf0e10cSrcweir NSString* aCountry = [[NSString alloc] initWithCharacters: rLocale.Country.getStr() length: rLocale.Country.getLength() ];
370cdf0e10cSrcweir NSString* aTag = @"_";
371cdf0e10cSrcweir NSString* aTaggedCountry = [aTag stringByAppendingString:aCountry];
372cdf0e10cSrcweir [aLang autorelease];
373cdf0e10cSrcweir aLang = [aLang stringByAppendingString:aTaggedCountry];
374cdf0e10cSrcweir }
375cdf0e10cSrcweir [macSpell setLanguage:aLang];
376cdf0e10cSrcweir NSArray *guesses = [macSpell guessesForWord:aNSStr];
377cdf0e10cSrcweir count = [guesses count];
378cdf0e10cSrcweir if (count)
379cdf0e10cSrcweir {
380cdf0e10cSrcweir aStr.realloc( count );
381cdf0e10cSrcweir OUString *pStr = aStr.getArray();
382cdf0e10cSrcweir for (int ii=0; ii < count; ii++)
383cdf0e10cSrcweir {
384cdf0e10cSrcweir // if needed add: if (suglst[ii] == NULL) continue;
385cdf0e10cSrcweir NSString* guess = [guesses objectAtIndex:ii];
386cdf0e10cSrcweir OUString cvtwrd((const sal_Unicode*)[guess cStringUsingEncoding:NSUnicodeStringEncoding], (sal_Int32)[guess length]);
387cdf0e10cSrcweir pStr[ii] = cvtwrd;
388cdf0e10cSrcweir }
389cdf0e10cSrcweir }
390cdf0e10cSrcweir [pool release];
391cdf0e10cSrcweir }
392cdf0e10cSrcweir
393cdf0e10cSrcweir // now return an empty alternative for no suggestions or the list of alternatives if some found
394cdf0e10cSrcweir SpellAlternatives *pAlt = new SpellAlternatives;
395cdf0e10cSrcweir String aTmp(rWord);
396cdf0e10cSrcweir pAlt->SetWordLanguage( aTmp, nLang );
397cdf0e10cSrcweir pAlt->SetFailureType( SpellFailure::SPELLING_ERROR );
398cdf0e10cSrcweir pAlt->SetAlternatives( aStr );
399cdf0e10cSrcweir xRes = pAlt;
400cdf0e10cSrcweir return xRes;
401cdf0e10cSrcweir
402cdf0e10cSrcweir }
403cdf0e10cSrcweir
404cdf0e10cSrcweir
405cdf0e10cSrcweir
406cdf0e10cSrcweir
407cdf0e10cSrcweir Reference< XSpellAlternatives > SAL_CALL
spell(const OUString & rWord,const Locale & rLocale,const PropertyValues & rProperties)408cdf0e10cSrcweir MacSpellChecker::spell( const OUString& rWord, const Locale& rLocale,
409cdf0e10cSrcweir const PropertyValues& rProperties )
410cdf0e10cSrcweir throw(IllegalArgumentException, RuntimeException)
411cdf0e10cSrcweir {
412cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() );
413cdf0e10cSrcweir
414cdf0e10cSrcweir if (rLocale == Locale() || !rWord.getLength())
415cdf0e10cSrcweir return NULL;
416cdf0e10cSrcweir
417cdf0e10cSrcweir if (!hasLocale( rLocale ))
418cdf0e10cSrcweir #ifdef LINGU_EXCEPTIONS
419cdf0e10cSrcweir throw( IllegalArgumentException() );
420cdf0e10cSrcweir #else
421cdf0e10cSrcweir return NULL;
422cdf0e10cSrcweir #endif
423cdf0e10cSrcweir
424cdf0e10cSrcweir Reference< XSpellAlternatives > xAlt;
425cdf0e10cSrcweir if (!isValid( rWord, rLocale, rProperties ))
426cdf0e10cSrcweir {
427cdf0e10cSrcweir xAlt = GetProposals( rWord, rLocale );
428cdf0e10cSrcweir }
429cdf0e10cSrcweir return xAlt;
430cdf0e10cSrcweir }
431cdf0e10cSrcweir
432cdf0e10cSrcweir
MacSpellChecker_CreateInstance(const Reference<XMultiServiceFactory> &)433cdf0e10cSrcweir Reference< XInterface > SAL_CALL MacSpellChecker_CreateInstance(
434cdf0e10cSrcweir const Reference< XMultiServiceFactory > & /*rSMgr*/ )
435cdf0e10cSrcweir throw(Exception)
436cdf0e10cSrcweir {
437cdf0e10cSrcweir
438cdf0e10cSrcweir Reference< XInterface > xService = (cppu::OWeakObject*) new MacSpellChecker;
439cdf0e10cSrcweir return xService;
440cdf0e10cSrcweir }
441cdf0e10cSrcweir
442cdf0e10cSrcweir
443cdf0e10cSrcweir sal_Bool SAL_CALL
addLinguServiceEventListener(const Reference<XLinguServiceEventListener> & rxLstnr)444cdf0e10cSrcweir MacSpellChecker::addLinguServiceEventListener(
445cdf0e10cSrcweir const Reference< XLinguServiceEventListener >& rxLstnr )
446cdf0e10cSrcweir throw(RuntimeException)
447cdf0e10cSrcweir {
448cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() );
449cdf0e10cSrcweir
450cdf0e10cSrcweir sal_Bool bRes = sal_False;
451cdf0e10cSrcweir if (!bDisposing && rxLstnr.is())
452cdf0e10cSrcweir {
453cdf0e10cSrcweir bRes = GetPropHelper().addLinguServiceEventListener( rxLstnr );
454cdf0e10cSrcweir }
455cdf0e10cSrcweir return bRes;
456cdf0e10cSrcweir }
457cdf0e10cSrcweir
458cdf0e10cSrcweir
459cdf0e10cSrcweir sal_Bool SAL_CALL
removeLinguServiceEventListener(const Reference<XLinguServiceEventListener> & rxLstnr)460cdf0e10cSrcweir MacSpellChecker::removeLinguServiceEventListener(
461cdf0e10cSrcweir const Reference< XLinguServiceEventListener >& rxLstnr )
462cdf0e10cSrcweir throw(RuntimeException)
463cdf0e10cSrcweir {
464cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() );
465cdf0e10cSrcweir
466cdf0e10cSrcweir sal_Bool bRes = sal_False;
467cdf0e10cSrcweir if (!bDisposing && rxLstnr.is())
468cdf0e10cSrcweir {
469cdf0e10cSrcweir DBG_ASSERT( xPropHelper.is(), "xPropHelper non existent" );
470cdf0e10cSrcweir bRes = GetPropHelper().removeLinguServiceEventListener( rxLstnr );
471cdf0e10cSrcweir }
472cdf0e10cSrcweir return bRes;
473cdf0e10cSrcweir }
474cdf0e10cSrcweir
475cdf0e10cSrcweir
476cdf0e10cSrcweir OUString SAL_CALL
getServiceDisplayName(const Locale &)477cdf0e10cSrcweir MacSpellChecker::getServiceDisplayName( const Locale& /*rLocale*/ )
478cdf0e10cSrcweir throw(RuntimeException)
479cdf0e10cSrcweir {
480cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() );
481cdf0e10cSrcweir return A2OU( "Mac OS X Spell Checker" );
482cdf0e10cSrcweir }
483cdf0e10cSrcweir
484cdf0e10cSrcweir
485cdf0e10cSrcweir void SAL_CALL
initialize(const Sequence<Any> & rArguments)486cdf0e10cSrcweir MacSpellChecker::initialize( const Sequence< Any >& rArguments )
487cdf0e10cSrcweir throw(Exception, RuntimeException)
488cdf0e10cSrcweir {
489cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() );
490cdf0e10cSrcweir
491cdf0e10cSrcweir if (!pPropHelper)
492cdf0e10cSrcweir {
493cdf0e10cSrcweir sal_Int32 nLen = rArguments.getLength();
494cdf0e10cSrcweir if (2 == nLen)
495cdf0e10cSrcweir {
496cdf0e10cSrcweir Reference< XPropertySet > xPropSet;
497cdf0e10cSrcweir rArguments.getConstArray()[0] >>= xPropSet;
498cdf0e10cSrcweir //rArguments.getConstArray()[1] >>= xDicList;
499cdf0e10cSrcweir
500cdf0e10cSrcweir //! Pointer allows for access of the non-UNO functions.
501cdf0e10cSrcweir //! And the reference to the UNO-functions while increasing
502cdf0e10cSrcweir //! the ref-count and will implicitly free the memory
503cdf0e10cSrcweir //! when the object is not longer used.
504cdf0e10cSrcweir pPropHelper = new PropertyHelper_Spell( (XSpellChecker *) this, xPropSet );
505cdf0e10cSrcweir xPropHelper = pPropHelper;
506cdf0e10cSrcweir pPropHelper->AddAsPropListener(); //! after a reference is established
507cdf0e10cSrcweir }
508cdf0e10cSrcweir else
509cdf0e10cSrcweir DBG_ERROR( "wrong number of arguments in sequence" );
510cdf0e10cSrcweir
511cdf0e10cSrcweir }
512cdf0e10cSrcweir }
513cdf0e10cSrcweir
514cdf0e10cSrcweir
515cdf0e10cSrcweir void SAL_CALL
dispose()516cdf0e10cSrcweir MacSpellChecker::dispose()
517cdf0e10cSrcweir throw(RuntimeException)
518cdf0e10cSrcweir {
519cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() );
520cdf0e10cSrcweir
521cdf0e10cSrcweir if (!bDisposing)
522cdf0e10cSrcweir {
523cdf0e10cSrcweir bDisposing = sal_True;
524cdf0e10cSrcweir EventObject aEvtObj( (XSpellChecker *) this );
525cdf0e10cSrcweir aEvtListeners.disposeAndClear( aEvtObj );
526cdf0e10cSrcweir }
527cdf0e10cSrcweir }
528cdf0e10cSrcweir
529cdf0e10cSrcweir
530cdf0e10cSrcweir void SAL_CALL
addEventListener(const Reference<XEventListener> & rxListener)531cdf0e10cSrcweir MacSpellChecker::addEventListener( const Reference< XEventListener >& rxListener )
532cdf0e10cSrcweir throw(RuntimeException)
533cdf0e10cSrcweir {
534cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() );
535cdf0e10cSrcweir
536cdf0e10cSrcweir if (!bDisposing && rxListener.is())
537cdf0e10cSrcweir aEvtListeners.addInterface( rxListener );
538cdf0e10cSrcweir }
539cdf0e10cSrcweir
540cdf0e10cSrcweir
541cdf0e10cSrcweir void SAL_CALL
removeEventListener(const Reference<XEventListener> & rxListener)542cdf0e10cSrcweir MacSpellChecker::removeEventListener( const Reference< XEventListener >& rxListener )
543cdf0e10cSrcweir throw(RuntimeException)
544cdf0e10cSrcweir {
545cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() );
546cdf0e10cSrcweir
547cdf0e10cSrcweir if (!bDisposing && rxListener.is())
548cdf0e10cSrcweir aEvtListeners.removeInterface( rxListener );
549cdf0e10cSrcweir }
550cdf0e10cSrcweir
551cdf0e10cSrcweir
552cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
553cdf0e10cSrcweir // Service specific part
554cdf0e10cSrcweir //
555cdf0e10cSrcweir
getImplementationName()556cdf0e10cSrcweir OUString SAL_CALL MacSpellChecker::getImplementationName()
557cdf0e10cSrcweir throw(RuntimeException)
558cdf0e10cSrcweir {
559cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() );
560cdf0e10cSrcweir
561cdf0e10cSrcweir return getImplementationName_Static();
562cdf0e10cSrcweir }
563cdf0e10cSrcweir
564cdf0e10cSrcweir
supportsService(const OUString & ServiceName)565cdf0e10cSrcweir sal_Bool SAL_CALL MacSpellChecker::supportsService( const OUString& ServiceName )
566cdf0e10cSrcweir throw(RuntimeException)
567cdf0e10cSrcweir {
568cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() );
569cdf0e10cSrcweir
570cdf0e10cSrcweir Sequence< OUString > aSNL = getSupportedServiceNames();
571cdf0e10cSrcweir const OUString * pArray = aSNL.getConstArray();
572cdf0e10cSrcweir for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
573cdf0e10cSrcweir if( pArray[i] == ServiceName )
574cdf0e10cSrcweir return sal_True;
575cdf0e10cSrcweir return sal_False;
576cdf0e10cSrcweir }
577cdf0e10cSrcweir
578cdf0e10cSrcweir
getSupportedServiceNames()579cdf0e10cSrcweir Sequence< OUString > SAL_CALL MacSpellChecker::getSupportedServiceNames()
580cdf0e10cSrcweir throw(RuntimeException)
581cdf0e10cSrcweir {
582cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() );
583cdf0e10cSrcweir
584cdf0e10cSrcweir return getSupportedServiceNames_Static();
585cdf0e10cSrcweir }
586cdf0e10cSrcweir
587cdf0e10cSrcweir
getSupportedServiceNames_Static()588cdf0e10cSrcweir Sequence< OUString > MacSpellChecker::getSupportedServiceNames_Static()
589cdf0e10cSrcweir throw()
590cdf0e10cSrcweir {
591cdf0e10cSrcweir MutexGuard aGuard( GetLinguMutex() );
592cdf0e10cSrcweir
593cdf0e10cSrcweir Sequence< OUString > aSNS( 1 ); // auch mehr als 1 Service moeglich
594cdf0e10cSrcweir aSNS.getArray()[0] = A2OU( SN_SPELLCHECKER );
595cdf0e10cSrcweir return aSNS;
596cdf0e10cSrcweir }
597cdf0e10cSrcweir
MacSpellChecker_getFactory(const sal_Char * pImplName,XMultiServiceFactory * pServiceManager,void *)598cdf0e10cSrcweir void * SAL_CALL MacSpellChecker_getFactory( const sal_Char * pImplName,
599cdf0e10cSrcweir XMultiServiceFactory * pServiceManager, void * )
600cdf0e10cSrcweir {
601cdf0e10cSrcweir void * pRet = 0;
602cdf0e10cSrcweir if ( !MacSpellChecker::getImplementationName_Static().compareToAscii( pImplName ) )
603cdf0e10cSrcweir {
604cdf0e10cSrcweir Reference< XSingleServiceFactory > xFactory =
605cdf0e10cSrcweir cppu::createOneInstanceFactory(
606cdf0e10cSrcweir pServiceManager,
607cdf0e10cSrcweir MacSpellChecker::getImplementationName_Static(),
608cdf0e10cSrcweir MacSpellChecker_CreateInstance,
609cdf0e10cSrcweir MacSpellChecker::getSupportedServiceNames_Static());
610cdf0e10cSrcweir // acquire, because we return an interface pointer instead of a reference
611cdf0e10cSrcweir xFactory->acquire();
612cdf0e10cSrcweir pRet = xFactory.get();
613cdf0e10cSrcweir }
614cdf0e10cSrcweir return pRet;
615cdf0e10cSrcweir }
616cdf0e10cSrcweir
617cdf0e10cSrcweir
618cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
619