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"
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>
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?>"
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();
88 xRes
= uno::Reference
< XLinguServiceManager
> ( xMgr
->createInstance(
89 OUString( RTL_CONSTASCII_USTRINGPARAM(
90 "com.sun.star.linguistic2.LinguServiceManager" ) ) ), UNO_QUERY
) ;
95 Thesaurus::Thesaurus() :
96 aEvtListeners ( GetLinguMutex() )
109 Thesaurus::~Thesaurus()
113 for (int i
= 0; i
< numthes
; i
++) {
114 if (aThes
[i
]) delete aThes
[i
];
121 for (int i
= 0; i
< numthes
; i
++) {
122 if (aCharSetInfo
[i
]) delete aCharSetInfo
[i
];
123 aCharSetInfo
[i
] = NULL
;
125 delete[] aCharSetInfo
;
129 if (aTEncs
) delete[] aTEncs
;
131 if (aTLocs
) delete[] aTLocs
;
133 if (aTNames
) delete[] aTNames
;
137 pPropHelper
->RemoveAsPropListener();
141 PropertyHelper_Thes
& Thesaurus::GetPropHelper_Impl()
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
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
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();
194 // get supported locales from the dictionaries-to-use...
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
;
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
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
];
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
)
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
;
265 DBG_ASSERT( k
== numthes
, "index mismatch?" );
269 /* no dictionary found so register no dictionaries */
276 aSuppLocales
.realloc(0);
285 sal_Bool SAL_CALL
Thesaurus::hasLocale(const Locale
& rLocale
)
286 throw(RuntimeException
)
288 MutexGuard
aGuard( GetLinguMutex() );
291 if (!aSuppLocales
.getLength())
293 INT32 nLen
= aSuppLocales
.getLength();
294 for (INT32 i
= 0; i
< nLen
; ++i
)
296 const Locale
*pLocale
= aSuppLocales
.getConstArray();
297 if (rLocale
== pLocale
[i
])
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
;
325 INT16 nLanguage
= LocaleToLanguage( rLocale
);
327 if (nLanguage
== LANGUAGE_NONE
|| !rTerm
.getLength())
330 if (!hasLocale( rLocale
))
331 #ifdef LINGU_EXCEPTIONS
332 throw( IllegalArgumentException() );
337 if (prevTerm
== qTerm
&& prevLocale
== nLanguage
) return prevMeanings
;
339 mentry
* pmean
= NULL
;
342 PropertyHelper_Thes
&rHelper
= GetPropHelper();
343 rHelper
.SetTmpPropVals( rProperties
);
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
356 OUString datpath
= aTNames
[i
] + A2OU(".dat");
357 OUString idxpath
= aTNames
[i
] + A2OU(".idx");
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()));
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
);
374 aThes
[i
] = new MyThes(aTmpidx
.getStr(),aTmpdat
.getStr());
376 const char * enc_string
= aThes
[i
]->get_th_encoding();
378 aTEncs
[i
] = rtl_getTextEncodingFromUnixCharset("ISO8859-1");
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
;
393 pCC
= aCharSetInfo
[i
];
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
);
410 OUString codeTerm
= qTerm
;
411 Reference
< XSpellAlternatives
> xTmpRes2
;
414 xTmpRes2
= xSpell
->spell( A2OU("<?xml?><query type='analyze'><word>") +
415 pTerm
+ A2OU("</word></query>"), nLanguage
, rProperties
);
417 Sequence
<OUString
>seq
= xTmpRes2
->getAlternatives();
418 if (seq
.getLength() > 0) {
423 OString o
= OUStringToOString(codeTerm
, rtl_getTextEncodingFromUnixCharset("UTF-8"));
424 fprintf(stderr
, "CODETERM: %s\n", o
.pData
->buffer
);
429 for (int j
= 0; j
< nmean
; j
++) {
430 int count
= pe
->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;
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
449 Reference
< XSpellAlternatives
> xTmpRes
;
450 xTmpRes
= xSpell
->spell( A2OU("<?xml?><query type='generate'><word>") +
451 sTerm
+ A2OU("</word>") + codeTerm
+ A2OU("</query>"), nLanguage
, rProperties
);
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
)
469 cTerm
= makeUpperCase(sTerm
, pCC
);
472 case CAPTYPE_INITCAP
:
474 cTerm
= makeInitCap(sTerm
, pCC
);
483 OUString
aAlt( cTerm
+ catst
);
487 Meaning
* pMn
= new Meaning(rTerm
,nLanguage
,rHelper
);
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();
498 pTH
->CleanUpAfterLookup(&pmean
,nmean
);
502 prevMeanings
= aMeanings
;
503 prevLocale
= nLanguage
;
507 if (stem
|| !xLngSvcMgr
.is()) return noMeanings
;
510 xSpell
= uno::Reference
< XSpellChecker1
>( xLngSvcMgr
->getSpellChecker(), UNO_QUERY
);
511 if (!xSpell
.is() || !xSpell
->isValid( A2OU(SPELLML_SUPPORT
), nLanguage
, rProperties
)) {
514 Reference
< XSpellAlternatives
> xTmpRes
;
515 xTmpRes
= xSpell
->spell( A2OU("<?xml?><query type='stem'><word>") +
516 rTerm
+ A2OU("</word></query>"), nLanguage
, rProperties
);
518 Sequence
<OUString
>seq
= xTmpRes
->getAlternatives();
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
);
525 if (seq
.getLength() > 0) {
526 rTerm
= seq
[0]; // XXX Use only the first stem
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
);
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];
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
);
558 Reference
< XInterface
> SAL_CALL
Thesaurus_CreateInstance(
559 const Reference
< XMultiServiceFactory
> & /*rSMgr*/ )
562 Reference
< XInterface
> xService
= (cppu::OWeakObject
*) new Thesaurus
;
568 Thesaurus::getServiceDisplayName( const Locale
& /*rLocale*/ )
569 throw(RuntimeException
)
571 MutexGuard
aGuard( GetLinguMutex() );
572 return A2OU( "OpenOffice.org New Thesaurus" );
577 Thesaurus::initialize( const Sequence
< Any
>& rArguments
)
578 throw(Exception
, RuntimeException
)
580 MutexGuard
aGuard( GetLinguMutex() );
584 INT32 nLen
= rArguments
.getLength();
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
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
)) {
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
)
634 return pCC
->toLower_rtl(aTerm
, 0, aTerm
.getLength());
639 OUString SAL_CALL
Thesaurus::makeUpperCase(const OUString
& aTerm
, CharClass
* pCC
)
642 return pCC
->toUpper_rtl(aTerm
, 0, aTerm
.getLength());
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);
653 return ( pCC
->toUpper_rtl(bTemp
, 0, 1)
654 + pCC
->toLower_rtl(aTerm
,1,(tlen
-1)) );
656 return pCC
->toUpper_rtl(bTemp
, 0, 1);
665 throw(RuntimeException
)
667 MutexGuard
aGuard( GetLinguMutex() );
672 EventObject
aEvtObj( (XThesaurus
*) this );
673 aEvtListeners
.disposeAndClear( aEvtObj
);
679 Thesaurus::addEventListener( const Reference
< XEventListener
>& rxListener
)
680 throw(RuntimeException
)
682 MutexGuard
aGuard( GetLinguMutex() );
684 if (!bDisposing
&& rxListener
.is())
685 aEvtListeners
.addInterface( rxListener
);
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
)
726 Sequence
< OUString
> SAL_CALL
Thesaurus::getSupportedServiceNames()
727 throw(RuntimeException
)
729 MutexGuard
aGuard( GetLinguMutex() );
730 return getSupportedServiceNames_Static();
734 Sequence
< OUString
> Thesaurus::getSupportedServiceNames_Static()
737 MutexGuard
aGuard( GetLinguMutex() );
739 Sequence
< OUString
> aSNS( 1 ); // auch mehr als 1 Service moeglich
740 aSNS
.getArray()[0] = A2OU( SN_THESAURUS
);
745 sal_Bool SAL_CALL
Thesaurus_writeInfo(
746 void * /*pServiceManager*/, registry::XRegistryKey
* pRegistryKey
)
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
] );
769 void * SAL_CALL
Thesaurus_getFactory( const sal_Char
* pImplName
,
770 XMultiServiceFactory
* pServiceManager
, void * )
773 if ( !Thesaurus::getImplementationName_Static().compareToAscii( pImplName
) )
776 Reference
< XSingleServiceFactory
> xFactory
=
777 cppu::createOneInstanceFactory(
779 Thesaurus::getImplementationName_Static(),
780 Thesaurus_CreateInstance
,
781 Thesaurus::getSupportedServiceNames_Static());
782 // acquire, because we return an interface pointer instead of a reference
784 pRet
= xFactory
.get();
790 ///////////////////////////////////////////////////////////////////////////
793 #undef CAPTYPE_UNKNOWN
795 #undef CAPTYPE_INITCAP
796 #undef CAPTYPE_ALLCAP