xref: /trunk/main/linguistic/workben/sspellimp.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
13b8558fdSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
33b8558fdSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
43b8558fdSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
53b8558fdSAndrew Rist  * distributed with this work for additional information
63b8558fdSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
73b8558fdSAndrew Rist  * to you under the Apache License, Version 2.0 (the
83b8558fdSAndrew Rist  * "License"); you may not use this file except in compliance
93b8558fdSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
113b8558fdSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
133b8558fdSAndrew Rist  * Unless required by applicable law or agreed to in writing,
143b8558fdSAndrew Rist  * software distributed under the License is distributed on an
153b8558fdSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
163b8558fdSAndrew Rist  * KIND, either express or implied.  See the License for the
173b8558fdSAndrew Rist  * specific language governing permissions and limitations
183b8558fdSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
203b8558fdSAndrew Rist  *************************************************************/
213b8558fdSAndrew Rist 
223b8558fdSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_linguistic.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 #ifndef _SPELLIMP_HXX
37cdf0e10cSrcweir #include <sspellimp.hxx>
38cdf0e10cSrcweir #endif
39cdf0e10cSrcweir 
40cdf0e10cSrcweir #include "linguistic/lngprops.hxx"
41cdf0e10cSrcweir #include "linguistic/spelldta.hxx"
42cdf0e10cSrcweir 
43cdf0e10cSrcweir using namespace utl;
44cdf0e10cSrcweir using namespace osl;
45cdf0e10cSrcweir using namespace rtl;
46cdf0e10cSrcweir using namespace com::sun::star;
47cdf0e10cSrcweir using namespace com::sun::star::beans;
48cdf0e10cSrcweir using namespace com::sun::star::lang;
49cdf0e10cSrcweir using namespace com::sun::star::uno;
50cdf0e10cSrcweir using namespace com::sun::star::linguistic2;
51cdf0e10cSrcweir using namespace linguistic;
52cdf0e10cSrcweir 
53cdf0e10cSrcweir 
54cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
55cdf0e10cSrcweir 
operator ==(const Locale & rL1,const Locale & rL2)56cdf0e10cSrcweir BOOL operator == ( const Locale &rL1, const Locale &rL2 )
57cdf0e10cSrcweir {
58cdf0e10cSrcweir     return  rL1.Language ==  rL2.Language   &&
59cdf0e10cSrcweir             rL1.Country  ==  rL2.Country    &&
60cdf0e10cSrcweir             rL1.Variant  ==  rL2.Variant;
61cdf0e10cSrcweir }
62cdf0e10cSrcweir 
63cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
64cdf0e10cSrcweir 
65cdf0e10cSrcweir 
SpellChecker()66cdf0e10cSrcweir SpellChecker::SpellChecker() :
67cdf0e10cSrcweir     aEvtListeners   ( GetLinguMutex() )
68cdf0e10cSrcweir {
69cdf0e10cSrcweir     bDisposing = FALSE;
70cdf0e10cSrcweir     pPropHelper = NULL;
71cdf0e10cSrcweir }
72cdf0e10cSrcweir 
73cdf0e10cSrcweir 
~SpellChecker()74cdf0e10cSrcweir SpellChecker::~SpellChecker()
75cdf0e10cSrcweir {
76cdf0e10cSrcweir     if (pPropHelper)
77cdf0e10cSrcweir         pPropHelper->RemoveAsPropListener();
78cdf0e10cSrcweir }
79cdf0e10cSrcweir 
80cdf0e10cSrcweir 
GetPropHelper_Impl()81cdf0e10cSrcweir PropertyHelper_Spell & SpellChecker::GetPropHelper_Impl()
82cdf0e10cSrcweir {
83cdf0e10cSrcweir     if (!pPropHelper)
84cdf0e10cSrcweir     {
85cdf0e10cSrcweir         Reference< XPropertySet >   xPropSet( GetLinguProperties(), UNO_QUERY );
86cdf0e10cSrcweir 
87cdf0e10cSrcweir         pPropHelper = new PropertyHelper_Spell( (XSpellChecker *) this, xPropSet );
88cdf0e10cSrcweir         xPropHelper = pPropHelper;
89cdf0e10cSrcweir         pPropHelper->AddAsPropListener();   //! after a reference is established
90cdf0e10cSrcweir     }
91cdf0e10cSrcweir     return *pPropHelper;
92cdf0e10cSrcweir }
93cdf0e10cSrcweir 
94cdf0e10cSrcweir 
getLocales()95cdf0e10cSrcweir Sequence< Locale > SAL_CALL SpellChecker::getLocales()
96cdf0e10cSrcweir         throw(RuntimeException)
97cdf0e10cSrcweir {
98cdf0e10cSrcweir     MutexGuard  aGuard( GetLinguMutex() );
99cdf0e10cSrcweir 
100cdf0e10cSrcweir     if (!aSuppLocales.getLength())
101cdf0e10cSrcweir     {
102cdf0e10cSrcweir         aSuppLocales.realloc( 3 );
103cdf0e10cSrcweir         Locale *pLocale = aSuppLocales.getArray();
104cdf0e10cSrcweir         pLocale[0] = Locale( A2OU("en"), A2OU("US"), OUString() );
105cdf0e10cSrcweir         pLocale[1] = Locale( A2OU("de"), A2OU("DE"), OUString() );
106cdf0e10cSrcweir         pLocale[2] = Locale( A2OU("de"), A2OU("CH"), OUString() );
107cdf0e10cSrcweir     }
108cdf0e10cSrcweir 
109cdf0e10cSrcweir     return aSuppLocales;
110cdf0e10cSrcweir }
111cdf0e10cSrcweir 
112cdf0e10cSrcweir 
hasLocale(const Locale & rLocale)113cdf0e10cSrcweir sal_Bool SAL_CALL SpellChecker::hasLocale(const Locale& rLocale)
114cdf0e10cSrcweir         throw(RuntimeException)
115cdf0e10cSrcweir {
116cdf0e10cSrcweir     MutexGuard  aGuard( GetLinguMutex() );
117cdf0e10cSrcweir 
118cdf0e10cSrcweir     BOOL bRes = FALSE;
119cdf0e10cSrcweir     if (!aSuppLocales.getLength())
120cdf0e10cSrcweir         getLocales();
121cdf0e10cSrcweir     INT32 nLen = aSuppLocales.getLength();
122cdf0e10cSrcweir     for (INT32 i = 0;  i < nLen;  ++i)
123cdf0e10cSrcweir     {
124cdf0e10cSrcweir         const Locale *pLocale = aSuppLocales.getConstArray();
125cdf0e10cSrcweir         if (rLocale == pLocale[i])
126cdf0e10cSrcweir         {
127cdf0e10cSrcweir             bRes = TRUE;
128cdf0e10cSrcweir             break;
129cdf0e10cSrcweir         }
130cdf0e10cSrcweir     }
131cdf0e10cSrcweir     return bRes;
132cdf0e10cSrcweir }
133cdf0e10cSrcweir 
134cdf0e10cSrcweir 
GetSpellFailure(const OUString & rWord,const Locale & rLocale)135cdf0e10cSrcweir INT16 SpellChecker::GetSpellFailure( const OUString &rWord, const Locale &rLocale )
136cdf0e10cSrcweir {
137*74cbd1f1SMatthias Seidel     // Checks whether a word is OK in a given language (Locale) or not, and
138cdf0e10cSrcweir     // provides a failure type for the incorrect ones.
139cdf0e10cSrcweir     // - words with "liss" (case sensitiv) as substring will be negative.
140cdf0e10cSrcweir     // - words with 'x' or 'X' will have incorrect spelling.
141cdf0e10cSrcweir     // - words with 's' or 'S' as first letter will have the wrong caption.
142cdf0e10cSrcweir     // - all other words will be OK.
143cdf0e10cSrcweir 
144cdf0e10cSrcweir     INT16 nRes = -1;
145cdf0e10cSrcweir 
146cdf0e10cSrcweir     String aTmp( rWord );
147cdf0e10cSrcweir     if (aTmp.Len())
148cdf0e10cSrcweir     {
149cdf0e10cSrcweir         if (STRING_NOTFOUND != aTmp.SearchAscii( "liss" ))
150cdf0e10cSrcweir         {
151cdf0e10cSrcweir             nRes = SpellFailure::IS_NEGATIVE_WORD;
152cdf0e10cSrcweir         }
153cdf0e10cSrcweir         else if (STRING_NOTFOUND != aTmp.Search( (sal_Unicode) 'x' )  ||
154cdf0e10cSrcweir                  STRING_NOTFOUND != aTmp.Search( (sal_Unicode) 'X' ))
155cdf0e10cSrcweir         {
156cdf0e10cSrcweir             nRes = SpellFailure::SPELLING_ERROR;
157cdf0e10cSrcweir         }
158cdf0e10cSrcweir         else
159cdf0e10cSrcweir         {
160cdf0e10cSrcweir             sal_Unicode cChar = aTmp.GetChar( 0 );
161cdf0e10cSrcweir             if (cChar == (sal_Unicode) 's'  ||  cChar == (sal_Unicode) 'S')
162cdf0e10cSrcweir                 nRes = SpellFailure::CAPTION_ERROR;
163cdf0e10cSrcweir         }
164cdf0e10cSrcweir     }
165cdf0e10cSrcweir 
166cdf0e10cSrcweir     return nRes;
167cdf0e10cSrcweir }
168cdf0e10cSrcweir 
169cdf0e10cSrcweir 
170cdf0e10cSrcweir sal_Bool SAL_CALL
isValid(const OUString & rWord,const Locale & rLocale,const PropertyValues & rProperties)171cdf0e10cSrcweir     SpellChecker::isValid( const OUString& rWord, const Locale& rLocale,
172cdf0e10cSrcweir             const PropertyValues& rProperties )
173cdf0e10cSrcweir         throw(IllegalArgumentException, RuntimeException)
174cdf0e10cSrcweir {
175cdf0e10cSrcweir     MutexGuard  aGuard( GetLinguMutex() );
176cdf0e10cSrcweir 
177cdf0e10cSrcweir     if (rLocale == Locale()  ||  !rWord.getLength())
178cdf0e10cSrcweir         return TRUE;
179cdf0e10cSrcweir 
180cdf0e10cSrcweir     if (!hasLocale( rLocale ))
181cdf0e10cSrcweir #ifdef LINGU_EXCEPTIONS
182cdf0e10cSrcweir         throw( IllegalArgumentException() );
183cdf0e10cSrcweir #else
184cdf0e10cSrcweir         return TRUE;
185cdf0e10cSrcweir #endif
186cdf0e10cSrcweir 
187cdf0e10cSrcweir     // Get property values to be used.
188cdf0e10cSrcweir     // These are be the default values set in the SN_LINGU_PROPERTIES
189cdf0e10cSrcweir     // PropertySet which are overridden by the supplied ones from the
190cdf0e10cSrcweir     // last argument.
191a893be29SPedro Giffuni     // You'll probably like to use a simpler solution than the provided
192cdf0e10cSrcweir     // one using the PropertyHelper_Spell.
193cdf0e10cSrcweir     PropertyHelper_Spell &rHelper = GetPropHelper();
194cdf0e10cSrcweir     rHelper.SetTmpPropVals( rProperties );
195cdf0e10cSrcweir 
196cdf0e10cSrcweir     INT16 nFailure = GetSpellFailure( rWord, rLocale );
197cdf0e10cSrcweir     if (nFailure != -1)
198cdf0e10cSrcweir     {
199cdf0e10cSrcweir         INT16 nLang = LocaleToLanguage( rLocale );
200cdf0e10cSrcweir         // postprocess result for errors that should be ignored
201cdf0e10cSrcweir         if (   (!rHelper.IsSpellUpperCase()  && IsUpper( rWord, nLang ))
202cdf0e10cSrcweir             || (!rHelper.IsSpellWithDigits() && HasDigits( rWord ))
203cdf0e10cSrcweir             || (!rHelper.IsSpellCapitalization()
204cdf0e10cSrcweir                 &&  nFailure == SpellFailure::CAPTION_ERROR)
205cdf0e10cSrcweir         )
206cdf0e10cSrcweir             nFailure = -1;
207cdf0e10cSrcweir     }
208cdf0e10cSrcweir     return nFailure == -1;
209cdf0e10cSrcweir }
210cdf0e10cSrcweir 
211cdf0e10cSrcweir 
212cdf0e10cSrcweir Reference< XSpellAlternatives >
GetProposals(const OUString & rWord,const Locale & rLocale)213cdf0e10cSrcweir     SpellChecker::GetProposals( const OUString &rWord, const Locale &rLocale )
214cdf0e10cSrcweir {
215cdf0e10cSrcweir     // Retrieves the return values for the 'spell' function call in case
216cdf0e10cSrcweir     // of a misspelled word.
217cdf0e10cSrcweir     // Especially it may give a list of suggested (correct) words:
218cdf0e10cSrcweir     // - a "liss" substring will be replaced by "liz".
219cdf0e10cSrcweir     // - 'x' or 'X' will be replaced by 'u' or 'U' for the first proposal
220cdf0e10cSrcweir     //   and they will be removed from the word for the second proposal.
221cdf0e10cSrcweir     // - 's' or 'S' as first letter will be changed to the other caption.
222cdf0e10cSrcweir 
223cdf0e10cSrcweir     Reference< XSpellAlternatives > xRes;
224cdf0e10cSrcweir 
225cdf0e10cSrcweir     String aTmp( rWord );
226cdf0e10cSrcweir     if (aTmp.Len())
227cdf0e10cSrcweir     {
228cdf0e10cSrcweir         INT16 nLang = LocaleToLanguage( rLocale );
229cdf0e10cSrcweir 
230cdf0e10cSrcweir         if (STRING_NOTFOUND != aTmp.SearchAscii( "liss" ))
231cdf0e10cSrcweir         {
232cdf0e10cSrcweir             aTmp.SearchAndReplaceAllAscii( "liss", A2OU("liz") );
233cdf0e10cSrcweir             xRes = new SpellAlternatives( aTmp, nLang,
234cdf0e10cSrcweir                         SpellFailure::IS_NEGATIVE_WORD, aTmp );
235cdf0e10cSrcweir         }
236cdf0e10cSrcweir         else if (STRING_NOTFOUND != aTmp.Search( (sal_Unicode) 'x' )  ||
237cdf0e10cSrcweir                  STRING_NOTFOUND != aTmp.Search( (sal_Unicode) 'X' ))
238cdf0e10cSrcweir         {
239cdf0e10cSrcweir             Sequence< OUString > aStr( 2 );
240cdf0e10cSrcweir             OUString *pStr = aStr.getArray();
241cdf0e10cSrcweir             String  aAlt1( aTmp ),
242cdf0e10cSrcweir                     aAlt2( aTmp );
243cdf0e10cSrcweir             aAlt1.SearchAndReplaceAll( (sal_Unicode) 'x', (sal_Unicode) 'u');
244cdf0e10cSrcweir             aAlt1.SearchAndReplaceAll( (sal_Unicode) 'X', (sal_Unicode) 'U');
245cdf0e10cSrcweir             aAlt2.EraseAllChars( (sal_Unicode) 'x' );
246cdf0e10cSrcweir             aAlt2.EraseAllChars( (sal_Unicode) 'X' );
247cdf0e10cSrcweir             pStr[0] = aAlt1;
248cdf0e10cSrcweir             pStr[1] = aAlt2;
249cdf0e10cSrcweir 
250cdf0e10cSrcweir             SpellAlternatives *pAlt = new SpellAlternatives;
251cdf0e10cSrcweir             pAlt->SetWordLanguage( aTmp, nLang );
252cdf0e10cSrcweir             pAlt->SetFailureType( SpellFailure::SPELLING_ERROR );
253cdf0e10cSrcweir             pAlt->SetAlternatives( aStr );
254cdf0e10cSrcweir 
255cdf0e10cSrcweir             xRes = pAlt;
256cdf0e10cSrcweir         }
257cdf0e10cSrcweir         else
258cdf0e10cSrcweir         {
259cdf0e10cSrcweir             sal_Unicode cChar = aTmp.GetChar( 0 );
260cdf0e10cSrcweir             if (cChar == (sal_Unicode) 's'  ||  cChar == (sal_Unicode) 'S')
261cdf0e10cSrcweir             {
262cdf0e10cSrcweir                 sal_Unicode cNewChar = cChar == (sal_Unicode) 's' ?
263cdf0e10cSrcweir                         (sal_Unicode) 'S': (sal_Unicode) 's';
264cdf0e10cSrcweir                 aTmp.GetBufferAccess()[0] = cNewChar;
265cdf0e10cSrcweir                 xRes = new SpellAlternatives( aTmp, nLang,
266cdf0e10cSrcweir                         SpellFailure::CAPTION_ERROR, aTmp );
267cdf0e10cSrcweir             }
268cdf0e10cSrcweir         }
269cdf0e10cSrcweir     }
270cdf0e10cSrcweir 
271cdf0e10cSrcweir     return xRes;
272cdf0e10cSrcweir }
273cdf0e10cSrcweir 
274cdf0e10cSrcweir 
275cdf0e10cSrcweir Reference< XSpellAlternatives > SAL_CALL
spell(const OUString & rWord,const Locale & rLocale,const PropertyValues & rProperties)276cdf0e10cSrcweir     SpellChecker::spell( const OUString& rWord, const Locale& rLocale,
277cdf0e10cSrcweir             const PropertyValues& rProperties )
278cdf0e10cSrcweir         throw(IllegalArgumentException, RuntimeException)
279cdf0e10cSrcweir {
280cdf0e10cSrcweir     MutexGuard  aGuard( GetLinguMutex() );
281cdf0e10cSrcweir 
282cdf0e10cSrcweir     if (rLocale == Locale()  ||  !rWord.getLength())
283cdf0e10cSrcweir         return NULL;
284cdf0e10cSrcweir 
285cdf0e10cSrcweir     if (!hasLocale( rLocale ))
286cdf0e10cSrcweir #ifdef LINGU_EXCEPTIONS
287cdf0e10cSrcweir         throw( IllegalArgumentException() );
288cdf0e10cSrcweir #else
289cdf0e10cSrcweir         return NULL;
290cdf0e10cSrcweir #endif
291cdf0e10cSrcweir 
292cdf0e10cSrcweir     Reference< XSpellAlternatives > xAlt;
293cdf0e10cSrcweir     if (!isValid( rWord, rLocale, rProperties ))
294cdf0e10cSrcweir     {
295cdf0e10cSrcweir         xAlt =  GetProposals( rWord, rLocale );
296cdf0e10cSrcweir     }
297cdf0e10cSrcweir     return xAlt;
298cdf0e10cSrcweir }
299cdf0e10cSrcweir 
300cdf0e10cSrcweir 
SpellChecker_CreateInstance(const Reference<XMultiServiceFactory> & rSMgr)301cdf0e10cSrcweir Reference< XInterface > SAL_CALL SpellChecker_CreateInstance(
302cdf0e10cSrcweir             const Reference< XMultiServiceFactory > & rSMgr )
303cdf0e10cSrcweir         throw(Exception)
304cdf0e10cSrcweir {
305cdf0e10cSrcweir     Reference< XInterface > xService = (cppu::OWeakObject*) new SpellChecker;
306cdf0e10cSrcweir     return xService;
307cdf0e10cSrcweir }
308cdf0e10cSrcweir 
309cdf0e10cSrcweir 
310cdf0e10cSrcweir sal_Bool SAL_CALL
addLinguServiceEventListener(const Reference<XLinguServiceEventListener> & rxLstnr)311cdf0e10cSrcweir     SpellChecker::addLinguServiceEventListener(
312cdf0e10cSrcweir             const Reference< XLinguServiceEventListener >& rxLstnr )
313cdf0e10cSrcweir         throw(RuntimeException)
314cdf0e10cSrcweir {
315cdf0e10cSrcweir     MutexGuard  aGuard( GetLinguMutex() );
316cdf0e10cSrcweir 
317cdf0e10cSrcweir     BOOL bRes = FALSE;
318cdf0e10cSrcweir     if (!bDisposing && rxLstnr.is())
319cdf0e10cSrcweir     {
320cdf0e10cSrcweir         bRes = GetPropHelper().addLinguServiceEventListener( rxLstnr );
321cdf0e10cSrcweir     }
322cdf0e10cSrcweir     return bRes;
323cdf0e10cSrcweir }
324cdf0e10cSrcweir 
325cdf0e10cSrcweir 
326cdf0e10cSrcweir sal_Bool SAL_CALL
removeLinguServiceEventListener(const Reference<XLinguServiceEventListener> & rxLstnr)327cdf0e10cSrcweir     SpellChecker::removeLinguServiceEventListener(
328cdf0e10cSrcweir             const Reference< XLinguServiceEventListener >& rxLstnr )
329cdf0e10cSrcweir         throw(RuntimeException)
330cdf0e10cSrcweir {
331cdf0e10cSrcweir     MutexGuard  aGuard( GetLinguMutex() );
332cdf0e10cSrcweir 
333cdf0e10cSrcweir     BOOL bRes = FALSE;
334cdf0e10cSrcweir     if (!bDisposing && rxLstnr.is())
335cdf0e10cSrcweir     {
336cdf0e10cSrcweir         DBG_ASSERT( xPropHelper.is(), "xPropHelper non existent" );
337cdf0e10cSrcweir         bRes = GetPropHelper().removeLinguServiceEventListener( rxLstnr );
338cdf0e10cSrcweir     }
339cdf0e10cSrcweir     return bRes;
340cdf0e10cSrcweir }
341cdf0e10cSrcweir 
342cdf0e10cSrcweir 
343cdf0e10cSrcweir OUString SAL_CALL
getServiceDisplayName(const Locale & rLocale)344cdf0e10cSrcweir     SpellChecker::getServiceDisplayName( const Locale& rLocale )
345cdf0e10cSrcweir         throw(RuntimeException)
346cdf0e10cSrcweir {
347cdf0e10cSrcweir     MutexGuard  aGuard( GetLinguMutex() );
348cdf0e10cSrcweir     return A2OU( "OpenOffice example spellchecker" );
349cdf0e10cSrcweir }
350cdf0e10cSrcweir 
351cdf0e10cSrcweir 
352cdf0e10cSrcweir void SAL_CALL
initialize(const Sequence<Any> & rArguments)353cdf0e10cSrcweir     SpellChecker::initialize( const Sequence< Any >& rArguments )
354cdf0e10cSrcweir         throw(Exception, RuntimeException)
355cdf0e10cSrcweir {
356cdf0e10cSrcweir     MutexGuard  aGuard( GetLinguMutex() );
357cdf0e10cSrcweir 
358cdf0e10cSrcweir     if (!pPropHelper)
359cdf0e10cSrcweir     {
360cdf0e10cSrcweir         INT32 nLen = rArguments.getLength();
361cdf0e10cSrcweir         if (2 == nLen)
362cdf0e10cSrcweir         {
363cdf0e10cSrcweir             Reference< XPropertySet >   xPropSet;
364cdf0e10cSrcweir             rArguments.getConstArray()[0] >>= xPropSet;
365cdf0e10cSrcweir             //rArguments.getConstArray()[1] >>= xDicList;
366cdf0e10cSrcweir 
367cdf0e10cSrcweir             //! Pointer allows for access of the non-UNO functions.
368cdf0e10cSrcweir             //! And the reference to the UNO-functions while increasing
369cdf0e10cSrcweir             //! the ref-count and will implicitly free the memory
370cdf0e10cSrcweir             //! when the object is not longer used.
371cdf0e10cSrcweir             pPropHelper = new PropertyHelper_Spell( (XSpellChecker *) this, xPropSet );
372cdf0e10cSrcweir             xPropHelper = pPropHelper;
373cdf0e10cSrcweir             pPropHelper->AddAsPropListener();   //! after a reference is established
374cdf0e10cSrcweir         }
375cdf0e10cSrcweir         else
376cdf0e10cSrcweir             DBG_ERROR( "wrong number of arguments in sequence" );
377cdf0e10cSrcweir     }
378cdf0e10cSrcweir }
379cdf0e10cSrcweir 
380cdf0e10cSrcweir 
381cdf0e10cSrcweir void SAL_CALL
dispose()382cdf0e10cSrcweir     SpellChecker::dispose()
383cdf0e10cSrcweir         throw(RuntimeException)
384cdf0e10cSrcweir {
385cdf0e10cSrcweir     MutexGuard  aGuard( GetLinguMutex() );
386cdf0e10cSrcweir 
387cdf0e10cSrcweir     if (!bDisposing)
388cdf0e10cSrcweir     {
389cdf0e10cSrcweir         bDisposing = TRUE;
390cdf0e10cSrcweir         EventObject aEvtObj( (XSpellChecker *) this );
391cdf0e10cSrcweir         aEvtListeners.disposeAndClear( aEvtObj );
392cdf0e10cSrcweir     }
393cdf0e10cSrcweir }
394cdf0e10cSrcweir 
395cdf0e10cSrcweir 
396cdf0e10cSrcweir void SAL_CALL
addEventListener(const Reference<XEventListener> & rxListener)397cdf0e10cSrcweir     SpellChecker::addEventListener( const Reference< XEventListener >& rxListener )
398cdf0e10cSrcweir         throw(RuntimeException)
399cdf0e10cSrcweir {
400cdf0e10cSrcweir     MutexGuard  aGuard( GetLinguMutex() );
401cdf0e10cSrcweir 
402cdf0e10cSrcweir     if (!bDisposing && rxListener.is())
403cdf0e10cSrcweir         aEvtListeners.addInterface( rxListener );
404cdf0e10cSrcweir }
405cdf0e10cSrcweir 
406cdf0e10cSrcweir 
407cdf0e10cSrcweir void SAL_CALL
removeEventListener(const Reference<XEventListener> & rxListener)408cdf0e10cSrcweir     SpellChecker::removeEventListener( const Reference< XEventListener >& rxListener )
409cdf0e10cSrcweir         throw(RuntimeException)
410cdf0e10cSrcweir {
411cdf0e10cSrcweir     MutexGuard  aGuard( GetLinguMutex() );
412cdf0e10cSrcweir 
413cdf0e10cSrcweir     if (!bDisposing && rxListener.is())
414cdf0e10cSrcweir         aEvtListeners.removeInterface( rxListener );
415cdf0e10cSrcweir }
416cdf0e10cSrcweir 
417cdf0e10cSrcweir 
418cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
419cdf0e10cSrcweir // Service specific part
420cdf0e10cSrcweir //
421cdf0e10cSrcweir 
getImplementationName()422cdf0e10cSrcweir OUString SAL_CALL SpellChecker::getImplementationName()
423cdf0e10cSrcweir         throw(RuntimeException)
424cdf0e10cSrcweir {
425cdf0e10cSrcweir     MutexGuard  aGuard( GetLinguMutex() );
426cdf0e10cSrcweir     return getImplementationName_Static();
427cdf0e10cSrcweir }
428cdf0e10cSrcweir 
429cdf0e10cSrcweir 
supportsService(const OUString & ServiceName)430cdf0e10cSrcweir sal_Bool SAL_CALL SpellChecker::supportsService( const OUString& ServiceName )
431cdf0e10cSrcweir         throw(RuntimeException)
432cdf0e10cSrcweir {
433cdf0e10cSrcweir     MutexGuard  aGuard( GetLinguMutex() );
434cdf0e10cSrcweir 
435cdf0e10cSrcweir     Sequence< OUString > aSNL = getSupportedServiceNames();
436cdf0e10cSrcweir     const OUString * pArray = aSNL.getConstArray();
437cdf0e10cSrcweir     for( INT32 i = 0; i < aSNL.getLength(); i++ )
438cdf0e10cSrcweir         if( pArray[i] == ServiceName )
439cdf0e10cSrcweir             return TRUE;
440cdf0e10cSrcweir     return FALSE;
441cdf0e10cSrcweir }
442cdf0e10cSrcweir 
443cdf0e10cSrcweir 
getSupportedServiceNames()444cdf0e10cSrcweir Sequence< OUString > SAL_CALL SpellChecker::getSupportedServiceNames()
445cdf0e10cSrcweir         throw(RuntimeException)
446cdf0e10cSrcweir {
447cdf0e10cSrcweir     MutexGuard  aGuard( GetLinguMutex() );
448cdf0e10cSrcweir     return getSupportedServiceNames_Static();
449cdf0e10cSrcweir }
450cdf0e10cSrcweir 
451cdf0e10cSrcweir 
getSupportedServiceNames_Static()452cdf0e10cSrcweir Sequence< OUString > SpellChecker::getSupportedServiceNames_Static()
453cdf0e10cSrcweir         throw()
454cdf0e10cSrcweir {
455cdf0e10cSrcweir     MutexGuard  aGuard( GetLinguMutex() );
456cdf0e10cSrcweir 
457cdf0e10cSrcweir     Sequence< OUString > aSNS( 1 ); // auch mehr als 1 Service moeglich
458cdf0e10cSrcweir     aSNS.getArray()[0] = A2OU( SN_SPELLCHECKER );
459cdf0e10cSrcweir     return aSNS;
460cdf0e10cSrcweir }
461cdf0e10cSrcweir 
462cdf0e10cSrcweir 
SpellChecker_writeInfo(void *,registry::XRegistryKey * pRegistryKey)463cdf0e10cSrcweir sal_Bool SAL_CALL SpellChecker_writeInfo(
464cdf0e10cSrcweir             void * /*pServiceManager*/, registry::XRegistryKey * pRegistryKey )
465cdf0e10cSrcweir {
466cdf0e10cSrcweir     try
467cdf0e10cSrcweir     {
468cdf0e10cSrcweir         String aImpl( '/' );
469cdf0e10cSrcweir         aImpl += SpellChecker::getImplementationName_Static().getStr();
470cdf0e10cSrcweir         aImpl.AppendAscii( "/UNO/SERVICES" );
471cdf0e10cSrcweir         Reference< registry::XRegistryKey > xNewKey =
472cdf0e10cSrcweir                 pRegistryKey->createKey( aImpl );
473cdf0e10cSrcweir         Sequence< OUString > aServices =
474cdf0e10cSrcweir                 SpellChecker::getSupportedServiceNames_Static();
475cdf0e10cSrcweir         for( INT32 i = 0; i < aServices.getLength(); i++ )
476cdf0e10cSrcweir             xNewKey->createKey( aServices.getConstArray()[i] );
477cdf0e10cSrcweir 
478cdf0e10cSrcweir         return sal_True;
479cdf0e10cSrcweir     }
480cdf0e10cSrcweir     catch(Exception &)
481cdf0e10cSrcweir     {
482cdf0e10cSrcweir         return sal_False;
483cdf0e10cSrcweir     }
484cdf0e10cSrcweir }
485cdf0e10cSrcweir 
486cdf0e10cSrcweir 
SpellChecker_getFactory(const sal_Char * pImplName,XMultiServiceFactory * pServiceManager,void *)487cdf0e10cSrcweir void * SAL_CALL SpellChecker_getFactory( const sal_Char * pImplName,
488cdf0e10cSrcweir             XMultiServiceFactory * pServiceManager, void *  )
489cdf0e10cSrcweir {
490cdf0e10cSrcweir     void * pRet = 0;
491cdf0e10cSrcweir     if ( !SpellChecker::getImplementationName_Static().compareToAscii( pImplName ) )
492cdf0e10cSrcweir     {
493cdf0e10cSrcweir         Reference< XSingleServiceFactory > xFactory =
494cdf0e10cSrcweir             cppu::createOneInstanceFactory(
495cdf0e10cSrcweir                 pServiceManager,
496cdf0e10cSrcweir                 SpellChecker::getImplementationName_Static(),
497cdf0e10cSrcweir                 SpellChecker_CreateInstance,
498cdf0e10cSrcweir                 SpellChecker::getSupportedServiceNames_Static());
499cdf0e10cSrcweir         // acquire, because we return an interface pointer instead of a reference
500cdf0e10cSrcweir         xFactory->acquire();
501cdf0e10cSrcweir         pRet = xFactory.get();
502cdf0e10cSrcweir     }
503cdf0e10cSrcweir     return pRet;
504cdf0e10cSrcweir }
505cdf0e10cSrcweir 
506cdf0e10cSrcweir 
507cdf0e10cSrcweir ///////////////////////////////////////////////////////////////////////////
508