sync master with lastest vba changes
[ooovba.git] / lingucomponent / source / thesaurus / libnth / nthesimp.cxx
blobbb6cfd3af5980a15ac6d6a6f61ce359eee42397a
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: nthesimp.cxx,v $
10 * $Revision: 1.15.6.4 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_lingucomponent.hxx"
34 // include <stdio.h>
35 #include <com/sun/star/uno/Reference.h>
37 #include <cppuhelper/factory.hxx> // helper for factories
38 #include <com/sun/star/registry/XRegistryKey.hpp>
39 #include <com/sun/star/beans/XPropertySet.hpp>
40 #include <i18npool/mslangid.hxx>
41 #include <tools/debug.hxx>
42 #include <unotools/processfactory.hxx>
43 #include <osl/mutex.hxx>
44 #include <svtools/pathoptions.hxx>
45 #include <svtools/lingucfg.hxx>
47 #include <rtl/string.hxx>
48 #include <rtl/ustrbuf.hxx>
49 #include "nthesimp.hxx"
50 #include <linguistic/misc.hxx>
51 #include <linguistic/lngprops.hxx>
52 #include "nthesdta.hxx"
53 #include <dictmgr.hxx>
55 #include <list>
56 #include <set>
58 // values asigned to capitalization types
59 #define CAPTYPE_UNKNOWN 0
60 #define CAPTYPE_NOCAP 1
61 #define CAPTYPE_INITCAP 2
62 #define CAPTYPE_ALLCAP 3
63 #define CAPTYPE_MIXED 4
65 // XML-header to query SPELLML support
66 #define SPELLML_SUPPORT "<?xml?>"
68 using namespace utl;
69 using namespace osl;
70 using namespace rtl;
71 using namespace com::sun::star;
72 using namespace com::sun::star::beans;
73 using namespace com::sun::star::lang;
74 using namespace com::sun::star::uno;
75 using namespace com::sun::star::linguistic2;
76 using namespace linguistic;
80 ///////////////////////////////////////////////////////////////////////////
82 static uno::Reference< XLinguServiceManager > GetLngSvcMgr_Impl()
84 uno::Reference< XLinguServiceManager > xRes;
85 uno::Reference< XMultiServiceFactory > xMgr = getProcessServiceFactory();
86 if (xMgr.is())
88 xRes = uno::Reference< XLinguServiceManager > ( xMgr->createInstance(
89 OUString( RTL_CONSTASCII_USTRINGPARAM(
90 "com.sun.star.linguistic2.LinguServiceManager" ) ) ), UNO_QUERY ) ;
92 return xRes;
95 Thesaurus::Thesaurus() :
96 aEvtListeners ( GetLinguMutex() )
98 bDisposing = FALSE;
99 pPropHelper = NULL;
100 aThes = NULL;
101 aCharSetInfo = NULL;
102 aTEncs = NULL;
103 aTLocs = NULL;
104 aTNames = NULL;
105 numthes = 0;
109 Thesaurus::~Thesaurus()
112 if (aThes) {
113 for (int i = 0; i < numthes; i++) {
114 if (aThes[i]) delete aThes[i];
115 aThes[i] = NULL;
117 delete[] aThes;
119 aThes = NULL;
120 if (aCharSetInfo) {
121 for (int i = 0; i < numthes; i++) {
122 if (aCharSetInfo[i]) delete aCharSetInfo[i];
123 aCharSetInfo[i] = NULL;
125 delete[] aCharSetInfo;
127 aCharSetInfo = NULL;
128 numthes = 0;
129 if (aTEncs) delete[] aTEncs;
130 aTEncs = NULL;
131 if (aTLocs) delete[] aTLocs;
132 aTLocs = NULL;
133 if (aTNames) delete[] aTNames;
134 aTNames = NULL;
136 if (pPropHelper)
137 pPropHelper->RemoveAsPropListener();
141 PropertyHelper_Thes & Thesaurus::GetPropHelper_Impl()
143 if (!pPropHelper)
145 Reference< XPropertySet > xPropSet( GetLinguProperties(), UNO_QUERY );
147 pPropHelper = new PropertyHelper_Thes( (XThesaurus *) this, xPropSet );
148 xPropHelper = pPropHelper;
149 pPropHelper->AddAsPropListener(); //! after a reference is established
151 return *pPropHelper;
155 Sequence< Locale > SAL_CALL Thesaurus::getLocales()
156 throw(RuntimeException)
158 MutexGuard aGuard( GetLinguMutex() );
160 // this routine should return the locales supported by the installed
161 // dictionaries.
163 if (!numthes)
165 SvtLinguConfig aLinguCfg;
167 // get list of dictionaries-to-use
168 std::list< SvtLinguConfigDictionaryEntry > aDics;
169 uno::Sequence< rtl::OUString > aFormatList;
170 aLinguCfg.GetSupportedDictionaryFormatsFor( A2OU("Thesauri"),
171 A2OU("org.openoffice.lingu.new.Thesaurus"), aFormatList );
172 sal_Int32 nLen = aFormatList.getLength();
173 for (sal_Int32 i = 0; i < nLen; ++i)
175 std::vector< SvtLinguConfigDictionaryEntry > aTmpDic(
176 aLinguCfg.GetActiveDictionariesByFormat( aFormatList[i] ) );
177 aDics.insert( aDics.end(), aTmpDic.begin(), aTmpDic.end() );
180 //!! for compatibility with old dictionaries (the ones not using extensions
181 //!! or new configuration entries, but still using the dictionary.lst file)
182 //!! Get the list of old style spell checking dictionaries to use...
183 std::vector< SvtLinguConfigDictionaryEntry > aOldStyleDics(
184 GetOldStyleDics( "THES" ) );
186 // to prefer dictionaries with configuration entries we will only
187 // use those old style dictionaries that add a language that
188 // is not yet supported by the list od new style dictionaries
189 MergeNewStyleDicsAndOldStyleDics( aDics, aOldStyleDics );
191 numthes = aDics.size();
192 if (numthes)
194 // get supported locales from the dictionaries-to-use...
195 sal_Int32 k = 0;
196 std::set< rtl::OUString, lt_rtl_OUString > aLocaleNamesSet;
197 std::list< SvtLinguConfigDictionaryEntry >::const_iterator aDictIt;
198 for (aDictIt = aDics.begin(); aDictIt != aDics.end(); ++aDictIt)
200 uno::Sequence< rtl::OUString > aLocaleNames( aDictIt->aLocaleNames );
201 sal_Int32 nLen2 = aLocaleNames.getLength();
202 for (k = 0; k < nLen2; ++k)
204 aLocaleNamesSet.insert( aLocaleNames[k] );
207 // ... and add them to the resulting sequence
208 aSuppLocales.realloc( aLocaleNamesSet.size() );
209 std::set< rtl::OUString, lt_rtl_OUString >::const_iterator aItB;
210 k = 0;
211 for (aItB = aLocaleNamesSet.begin(); aItB != aLocaleNamesSet.end(); ++aItB)
213 Locale aTmp( MsLangId::convertLanguageToLocale(
214 MsLangId::convertIsoStringToLanguage( *aItB )));
215 aSuppLocales[k++] = aTmp;
218 //! For each dictionary and each locale we need a seperate entry.
219 //! If this results in more than one dictionary per locale than (for now)
220 //! it is undefined which dictionary gets used.
221 //! In the future the implementation should support using several dictionaries
222 //! for one locale.
223 numthes = 0;
224 for (aDictIt = aDics.begin(); aDictIt != aDics.end(); ++aDictIt)
225 numthes = numthes + aDictIt->aLocaleNames.getLength();
227 // add dictionary information
228 aThes = new MyThes* [numthes];
229 aTEncs = new rtl_TextEncoding [numthes];
230 aTLocs = new Locale [numthes];
231 aTNames = new OUString [numthes];
232 aCharSetInfo = new CharClass* [numthes];
234 k = 0;
235 for (aDictIt = aDics.begin(); aDictIt != aDics.end(); ++aDictIt)
237 if (aDictIt->aLocaleNames.getLength() > 0 &&
238 aDictIt->aLocations.getLength() > 0)
240 uno::Sequence< rtl::OUString > aLocaleNames( aDictIt->aLocaleNames );
241 sal_Int32 nLocales = aLocaleNames.getLength();
243 // currently only one language per dictionary is supported in the actual implementation...
244 // Thus here we work-around this by adding the same dictionary several times.
245 // Once for each of it's supported locales.
246 for (sal_Int32 i = 0; i < nLocales; ++i)
248 aThes[k] = NULL;
249 aTEncs[k] = 0;
250 aTLocs[k] = MsLangId::convertLanguageToLocale(
251 MsLangId::convertIsoStringToLanguage( aDictIt->aLocaleNames[i] ));
252 aCharSetInfo[k] = new CharClass( aTLocs[k] );
253 // also both files have to be in the same directory and the
254 // file names must only differ in the extension (.aff/.dic).
255 // Thus we use the first location only and strip the extension part.
256 rtl::OUString aLocation = aDictIt->aLocations[0];
257 sal_Int32 nPos = aLocation.lastIndexOf( '.' );
258 aLocation = aLocation.copy( 0, nPos );
259 aTNames[k] = aLocation;
261 ++k;
265 DBG_ASSERT( k == numthes, "index mismatch?" );
267 else
269 /* no dictionary found so register no dictionaries */
270 numthes = 0;
271 aThes = NULL;
272 aTEncs = NULL;
273 aTLocs = NULL;
274 aTNames = NULL;
275 aCharSetInfo = NULL;
276 aSuppLocales.realloc(0);
280 return aSuppLocales;
285 sal_Bool SAL_CALL Thesaurus::hasLocale(const Locale& rLocale)
286 throw(RuntimeException)
288 MutexGuard aGuard( GetLinguMutex() );
290 BOOL bRes = FALSE;
291 if (!aSuppLocales.getLength())
292 getLocales();
293 INT32 nLen = aSuppLocales.getLength();
294 for (INT32 i = 0; i < nLen; ++i)
296 const Locale *pLocale = aSuppLocales.getConstArray();
297 if (rLocale == pLocale[i])
299 bRes = TRUE;
300 break;
303 return bRes;
307 Sequence < Reference < ::com::sun::star::linguistic2::XMeaning > > SAL_CALL
308 Thesaurus::queryMeanings( const OUString& qTerm, const Locale& rLocale,
309 const PropertyValues& rProperties)
310 throw(IllegalArgumentException, RuntimeException)
312 MutexGuard aGuard( GetLinguMutex() );
314 uno::Sequence< Reference< XMeaning > > aMeanings( 1 );
315 uno::Sequence< Reference< XMeaning > > noMeanings( 0 );
316 uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() );
317 uno::Reference< XSpellChecker1 > xSpell;
319 OUString rTerm(qTerm);
320 OUString pTerm(qTerm);
321 sal_uInt16 ct = CAPTYPE_UNKNOWN;
322 sal_Int32 stem = 0;
323 sal_Int32 stem2 = 0;
325 INT16 nLanguage = LocaleToLanguage( rLocale );
327 if (nLanguage == LANGUAGE_NONE || !rTerm.getLength())
328 return noMeanings;
330 if (!hasLocale( rLocale ))
331 #ifdef LINGU_EXCEPTIONS
332 throw( IllegalArgumentException() );
333 #else
334 return noMeanings;
335 #endif
337 if (prevTerm == qTerm && prevLocale == nLanguage) return prevMeanings;
339 mentry * pmean = NULL;
340 sal_Int32 nmean = 0;
342 PropertyHelper_Thes &rHelper = GetPropHelper();
343 rHelper.SetTmpPropVals( rProperties );
345 MyThes * pTH = NULL;
346 rtl_TextEncoding aEnc = 0;
347 CharClass * pCC = NULL;
349 // find the first thesaurus that matches the locale
350 for (int i =0; i < numthes; i++) {
351 if (rLocale == aTLocs[i])
353 // open up and intialize this thesaurus if need be
354 if (!aThes[i])
356 OUString datpath = aTNames[i] + A2OU(".dat");
357 OUString idxpath = aTNames[i] + A2OU(".idx");
358 OUString ndat;
359 OUString nidx;
360 osl::FileBase::getSystemPathFromFileURL(datpath,ndat);
361 osl::FileBase::getSystemPathFromFileURL(idxpath,nidx);
362 OString aTmpidx(OU2ENC(nidx,osl_getThreadTextEncoding()));
363 OString aTmpdat(OU2ENC(ndat,osl_getThreadTextEncoding()));
365 #if defined(WNT)
366 // workaround for Windows specifc problem that the
367 // path length in calls to 'fopen' is limted to somewhat
368 // about 120+ characters which will usually be exceed when
369 // using dictionaries as extensions.
370 aTmpidx = Win_GetShortPathName( nidx );
371 aTmpdat = Win_GetShortPathName( ndat );
372 #endif
374 aThes[i] = new MyThes(aTmpidx.getStr(),aTmpdat.getStr());
375 if (aThes[i]) {
376 const char * enc_string = aThes[i]->get_th_encoding();
377 if (!enc_string) {
378 aTEncs[i] = rtl_getTextEncodingFromUnixCharset("ISO8859-1");
379 } else {
380 aTEncs[i] = rtl_getTextEncodingFromUnixCharset(enc_string);
381 if (aTEncs[i] == RTL_TEXTENCODING_DONTKNOW) {
382 if (strcmp("ISCII-DEVANAGARI", enc_string) == 0) {
383 aTEncs[i] = RTL_TEXTENCODING_ISCII_DEVANAGARI;
384 } else if (strcmp("UTF-8", enc_string) == 0) {
385 aTEncs[i] = RTL_TEXTENCODING_UTF8;
391 pTH = aThes[i];
392 aEnc = aTEncs[i];
393 pCC = aCharSetInfo[i];
395 if (pTH)
396 break;
400 while (pTH) {
401 // convert word to all lower case for searching
402 if (!stem) ct = capitalType(rTerm, pCC);
403 OUString nTerm(makeLowerCase(rTerm, pCC));
404 OString aTmp( OU2ENC(nTerm, aEnc) );
405 nmean = pTH->Lookup(aTmp.getStr(),aTmp.getLength(),&pmean);
407 if (nmean) aMeanings.realloc( nmean );
409 mentry * pe = pmean;
410 OUString codeTerm = qTerm;
411 Reference< XSpellAlternatives > xTmpRes2;
413 if (stem) {
414 xTmpRes2 = xSpell->spell( A2OU("<?xml?><query type='analyze'><word>") +
415 pTerm + A2OU("</word></query>"), nLanguage, rProperties );
416 if (xTmpRes2.is()) {
417 Sequence<OUString>seq = xTmpRes2->getAlternatives();
418 if (seq.getLength() > 0) {
419 codeTerm = seq[0];
420 stem2 = 1;
422 #if 0
423 OString o = OUStringToOString(codeTerm, rtl_getTextEncodingFromUnixCharset("UTF-8"));
424 fprintf(stderr, "CODETERM: %s\n", o.pData->buffer);
425 #endif
429 for (int j = 0; j < nmean; j++) {
430 int count = pe->count;
431 if (count) {
432 Sequence< OUString > aStr( count );
433 OUString *pStr = aStr.getArray();
435 for (int i=0; i < count; i++) {
436 OUString sTerm(pe->psyns[i],strlen(pe->psyns[i]),aEnc );
437 sal_Int32 catpos = sTerm.indexOf('(');
438 sal_Int32 catpos2 = 0;
439 OUString catst;
440 OUString catst2;
441 if (catpos > 2) {
442 // remove category name for affixation and casing
443 catst = A2OU(" ") + sTerm.copy(catpos);
444 sTerm = sTerm.copy(0, catpos);
445 sTerm = sTerm.trim();
447 // generate synonyms with affixes
448 if (stem && stem2) {
449 Reference< XSpellAlternatives > xTmpRes;
450 xTmpRes = xSpell->spell( A2OU("<?xml?><query type='generate'><word>") +
451 sTerm + A2OU("</word>") + codeTerm + A2OU("</query>"), nLanguage, rProperties );
452 if (xTmpRes.is()) {
453 Sequence<OUString>seq = xTmpRes->getAlternatives();
454 for (int k = 0; k < seq.getLength(); k++) {
455 OString o = OUStringToOString(seq[k], rtl_getTextEncodingFromUnixCharset("UTF-8"));
457 if (seq.getLength() > 0) sTerm = seq[0];
460 if (catpos2) sTerm = catst2 + sTerm;
462 sal_uInt16 ct1 = capitalType(sTerm, pCC);
463 if (CAPTYPE_MIXED == ct1)
464 ct = ct1;
465 OUString cTerm;
466 switch (ct) {
467 case CAPTYPE_ALLCAP:
469 cTerm = makeUpperCase(sTerm, pCC);
470 break;
472 case CAPTYPE_INITCAP:
474 cTerm = makeInitCap(sTerm, pCC);
475 break;
477 default:
479 cTerm = sTerm;
480 break;
483 OUString aAlt( cTerm + catst);
484 pStr[i] = aAlt;
486 #if 0
487 Meaning * pMn = new Meaning(rTerm,nLanguage,rHelper);
488 #endif
489 Meaning * pMn = new Meaning(rTerm,nLanguage);
490 OUString dTerm(pe->defn,strlen(pe->defn),aEnc );
491 pMn->SetMeaning(dTerm);
492 pMn->SetSynonyms(aStr);
493 Reference<XMeaning>* pMeaning = aMeanings.getArray();
494 pMeaning[j] = pMn;
496 pe++;
498 pTH->CleanUpAfterLookup(&pmean,nmean);
500 if (nmean) {
501 prevTerm = qTerm;
502 prevMeanings = aMeanings;
503 prevLocale = nLanguage;
504 return aMeanings;
507 if (stem || !xLngSvcMgr.is()) return noMeanings;
508 stem = 1;
510 xSpell = uno::Reference< XSpellChecker1 >( xLngSvcMgr->getSpellChecker(), UNO_QUERY );
511 if (!xSpell.is() || !xSpell->isValid( A2OU(SPELLML_SUPPORT), nLanguage, rProperties )) {
512 return noMeanings;
514 Reference< XSpellAlternatives > xTmpRes;
515 xTmpRes = xSpell->spell( A2OU("<?xml?><query type='stem'><word>") +
516 rTerm + A2OU("</word></query>"), nLanguage, rProperties );
517 if (xTmpRes.is()) {
518 Sequence<OUString>seq = xTmpRes->getAlternatives();
519 #if 0
520 for (int i = 0; i < seq.getLength(); i++) {
521 OString o = OUStringToOString(seq[i], rtl_getTextEncodingFromUnixCharset("UTF-8"));
522 fprintf(stderr, "%d: %s\n", i + 1, o.pData->buffer);
524 #endif
525 if (seq.getLength() > 0) {
526 rTerm = seq[0]; // XXX Use only the first stem
527 continue;
531 // stem the last word of the synonym (for categories after affixation)
532 rTerm = rTerm.trim();
533 sal_Int32 pos = rTerm.lastIndexOf(' ');
534 if (!pos) return noMeanings;
535 xTmpRes = xSpell->spell( A2OU("<?xml?><query type='stem'><word>") +
536 rTerm.copy(pos + 1) + A2OU("</word></query>"), nLanguage, rProperties );
537 if (xTmpRes.is()) {
538 Sequence<OUString>seq = xTmpRes->getAlternatives();
539 if (seq.getLength() > 0) {
540 pTerm = rTerm.copy(pos + 1);
541 rTerm = rTerm.copy(0, pos + 1) + seq[0];
542 #if 0
543 for (int i = 0; i < seq.getLength(); i++) {
544 OString o = OUStringToOString(seq[i], rtl_getTextEncodingFromUnixCharset("UTF-8"));
545 fprintf(stderr, "%d: %s\n", i + 1, o.pData->buffer);
547 #endif
548 continue;
551 break;
553 return noMeanings;
558 Reference< XInterface > SAL_CALL Thesaurus_CreateInstance(
559 const Reference< XMultiServiceFactory > & /*rSMgr*/ )
560 throw(Exception)
562 Reference< XInterface > xService = (cppu::OWeakObject*) new Thesaurus;
563 return xService;
567 OUString SAL_CALL
568 Thesaurus::getServiceDisplayName( const Locale& /*rLocale*/ )
569 throw(RuntimeException)
571 MutexGuard aGuard( GetLinguMutex() );
572 return A2OU( "OpenOffice.org New Thesaurus" );
576 void SAL_CALL
577 Thesaurus::initialize( const Sequence< Any >& rArguments )
578 throw(Exception, RuntimeException)
580 MutexGuard aGuard( GetLinguMutex() );
582 if (!pPropHelper)
584 INT32 nLen = rArguments.getLength();
585 if (1 == nLen)
587 Reference< XPropertySet > xPropSet;
588 rArguments.getConstArray()[0] >>= xPropSet;
590 //! Pointer allows for access of the non-UNO functions.
591 //! And the reference to the UNO-functions while increasing
592 //! the ref-count and will implicitly free the memory
593 //! when the object is not longer used.
594 pPropHelper = new PropertyHelper_Thes( (XThesaurus *) this, xPropSet );
595 xPropHelper = pPropHelper;
596 pPropHelper->AddAsPropListener(); //! after a reference is established
598 else
599 DBG_ERROR( "wrong number of arguments in sequence" );
605 sal_uInt16 SAL_CALL Thesaurus::capitalType(const OUString& aTerm, CharClass * pCC)
607 sal_Int32 tlen = aTerm.getLength();
608 if ((pCC) && (tlen)) {
609 String aStr(aTerm);
610 sal_Int32 nc = 0;
611 for (USHORT tindex = 0; tindex < tlen; tindex++) {
612 if (pCC->getCharacterType(aStr,tindex) &
613 ::com::sun::star::i18n::KCharacterType::UPPER) nc++;
616 if (nc == 0) return (sal_uInt16) CAPTYPE_NOCAP;
618 if (nc == tlen) return (sal_uInt16) CAPTYPE_ALLCAP;
620 if ((nc == 1) && (pCC->getCharacterType(aStr,0) &
621 ::com::sun::star::i18n::KCharacterType::UPPER))
622 return (sal_uInt16) CAPTYPE_INITCAP;
624 return (sal_uInt16) CAPTYPE_MIXED;
626 return (sal_uInt16) CAPTYPE_UNKNOWN;
631 OUString SAL_CALL Thesaurus::makeLowerCase(const OUString& aTerm, CharClass * pCC)
633 if (pCC)
634 return pCC->toLower_rtl(aTerm, 0, aTerm.getLength());
635 return aTerm;
639 OUString SAL_CALL Thesaurus::makeUpperCase(const OUString& aTerm, CharClass * pCC)
641 if (pCC)
642 return pCC->toUpper_rtl(aTerm, 0, aTerm.getLength());
643 return aTerm;
647 OUString SAL_CALL Thesaurus::makeInitCap(const OUString& aTerm, CharClass * pCC)
649 sal_Int32 tlen = aTerm.getLength();
650 if ((pCC) && (tlen)) {
651 OUString bTemp = aTerm.copy(0,1);
652 if (tlen > 1)
653 return ( pCC->toUpper_rtl(bTemp, 0, 1)
654 + pCC->toLower_rtl(aTerm,1,(tlen-1)) );
656 return pCC->toUpper_rtl(bTemp, 0, 1);
658 return aTerm;
663 void SAL_CALL
664 Thesaurus::dispose()
665 throw(RuntimeException)
667 MutexGuard aGuard( GetLinguMutex() );
669 if (!bDisposing)
671 bDisposing = TRUE;
672 EventObject aEvtObj( (XThesaurus *) this );
673 aEvtListeners.disposeAndClear( aEvtObj );
678 void SAL_CALL
679 Thesaurus::addEventListener( const Reference< XEventListener >& rxListener )
680 throw(RuntimeException)
682 MutexGuard aGuard( GetLinguMutex() );
684 if (!bDisposing && rxListener.is())
685 aEvtListeners.addInterface( rxListener );
689 void SAL_CALL
690 Thesaurus::removeEventListener( const Reference< XEventListener >& rxListener )
691 throw(RuntimeException)
693 MutexGuard aGuard( GetLinguMutex() );
695 if (!bDisposing && rxListener.is())
696 aEvtListeners.removeInterface( rxListener );
700 ///////////////////////////////////////////////////////////////////////////
701 // Service specific part
704 OUString SAL_CALL Thesaurus::getImplementationName()
705 throw(RuntimeException)
707 MutexGuard aGuard( GetLinguMutex() );
708 return getImplementationName_Static();
712 sal_Bool SAL_CALL Thesaurus::supportsService( const OUString& ServiceName )
713 throw(RuntimeException)
715 MutexGuard aGuard( GetLinguMutex() );
717 Sequence< OUString > aSNL = getSupportedServiceNames();
718 const OUString * pArray = aSNL.getConstArray();
719 for( INT32 i = 0; i < aSNL.getLength(); i++ )
720 if( pArray[i] == ServiceName )
721 return TRUE;
722 return FALSE;
726 Sequence< OUString > SAL_CALL Thesaurus::getSupportedServiceNames()
727 throw(RuntimeException)
729 MutexGuard aGuard( GetLinguMutex() );
730 return getSupportedServiceNames_Static();
734 Sequence< OUString > Thesaurus::getSupportedServiceNames_Static()
735 throw()
737 MutexGuard aGuard( GetLinguMutex() );
739 Sequence< OUString > aSNS( 1 ); // auch mehr als 1 Service moeglich
740 aSNS.getArray()[0] = A2OU( SN_THESAURUS );
741 return aSNS;
745 sal_Bool SAL_CALL Thesaurus_writeInfo(
746 void * /*pServiceManager*/, registry::XRegistryKey * pRegistryKey )
750 String aImpl( '/' );
751 aImpl += Thesaurus::getImplementationName_Static().getStr();
752 aImpl.AppendAscii( "/UNO/SERVICES" );
753 Reference< registry::XRegistryKey > xNewKey =
754 pRegistryKey->createKey( aImpl );
755 Sequence< OUString > aServices =
756 Thesaurus::getSupportedServiceNames_Static();
757 for( INT32 i = 0; i < aServices.getLength(); i++ )
758 xNewKey->createKey( aServices.getConstArray()[i] );
760 return sal_True;
762 catch(Exception &)
764 return sal_False;
769 void * SAL_CALL Thesaurus_getFactory( const sal_Char * pImplName,
770 XMultiServiceFactory * pServiceManager, void * )
772 void * pRet = 0;
773 if ( !Thesaurus::getImplementationName_Static().compareToAscii( pImplName ) )
776 Reference< XSingleServiceFactory > xFactory =
777 cppu::createOneInstanceFactory(
778 pServiceManager,
779 Thesaurus::getImplementationName_Static(),
780 Thesaurus_CreateInstance,
781 Thesaurus::getSupportedServiceNames_Static());
782 // acquire, because we return an interface pointer instead of a reference
783 xFactory->acquire();
784 pRet = xFactory.get();
786 return pRet;
790 ///////////////////////////////////////////////////////////////////////////
793 #undef CAPTYPE_UNKNOWN
794 #undef CAPTYPE_NOCAP
795 #undef CAPTYPE_INITCAP
796 #undef CAPTYPE_ALLCAP
797 #undef CAPTYPE_MIXED