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: lngsvcmgr.cxx,v $
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_linguistic.hxx"
34 #include <com/sun/star/registry/XRegistryKey.hpp>
35 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
36 #include <com/sun/star/container/XEnumeration.hpp>
37 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
38 #include <com/sun/star/linguistic2/XSupportedLocales.hpp>
39 #include <com/sun/star/linguistic2/DictionaryListEventFlags.hpp>
40 #include <com/sun/star/linguistic2/LinguServiceEventFlags.hpp>
42 #include <tools/solar.h>
43 #include <svtools/lingucfg.hxx>
44 #include <unotools/processfactory.hxx>
45 #include <i18npool/lang.h>
46 #include <i18npool/mslangid.hxx>
47 #include <cppuhelper/factory.hxx>
48 #include <cppuhelper/extract.hxx>
49 #include <rtl/logfile.hxx>
51 #include "lngsvcmgr.hxx"
54 #include "spelldsp.hxx"
55 #include "hyphdsp.hxx"
56 #include "thesdsp.hxx"
57 #include "gciterator.hxx"
60 using namespace com::sun::star
;
61 using namespace linguistic
;
62 using ::rtl::OUString
;
64 // forward declarations
65 uno::Sequence
< OUString
> static GetLangSvcList( const uno::Any
&rVal
);
66 uno::Sequence
< OUString
> static GetLangSvc( const uno::Any
&rVal
);
68 ///////////////////////////////////////////////////////////////////////////
70 static BOOL
lcl_SeqHasString( const uno::Sequence
< OUString
> &rSeq
, const OUString
&rText
)
74 INT32 nLen
= rSeq
.getLength();
75 if (nLen
== 0 || rText
.getLength() == 0)
78 const OUString
*pSeq
= rSeq
.getConstArray();
79 for (INT32 i
= 0; i
< nLen
&& !bRes
; ++i
)
87 ///////////////////////////////////////////////////////////////////////////
89 static uno::Sequence
< lang::Locale
> GetAvailLocales(
90 const uno::Sequence
< OUString
> &rSvcImplNames
)
92 uno::Sequence
< lang::Locale
> aRes
;
94 uno::Reference
< lang::XMultiServiceFactory
> xFac( utl::getProcessServiceFactory() );
95 INT32 nNames
= rSvcImplNames
.getLength();
96 if (nNames
&& xFac
.is())
98 std::set
< LanguageType
> aLanguages
;
100 //! since we're going to create one-instance services we have to
101 //! supply their arguments even if we would not need them here...
102 uno::Sequence
< uno::Any
> aArgs(2);
103 aArgs
.getArray()[0] <<= GetLinguProperties();
105 // check all services for the supported languages and new
106 // languages to the result
107 const OUString
*pImplNames
= rSvcImplNames
.getConstArray();
110 for (i
= 0; i
< nNames
; ++i
)
112 uno::Reference
< linguistic2::XSupportedLocales
> xSuppLoc
;
115 xSuppLoc
= uno::Reference
< linguistic2::XSupportedLocales
>(
116 xFac
->createInstanceWithArguments( pImplNames
[i
], aArgs
), uno::UNO_QUERY
);
118 catch (uno::Exception
&)
120 DBG_ASSERT( 0, "createInstanceWithArguments failed" );
125 uno::Sequence
< lang::Locale
> aLoc( xSuppLoc
->getLocales() );
126 INT32 nLoc
= aLoc
.getLength();
127 for (INT32 k
= 0; k
< nLoc
; ++k
)
129 const lang::Locale
*pLoc
= aLoc
.getConstArray();
130 LanguageType nLang
= LocaleToLanguage( pLoc
[k
] );
132 // language not already added?
133 if (aLanguages
.find( nLang
) == aLanguages
.end())
134 aLanguages
.insert( nLang
);
139 DBG_ASSERT( 0, "interface not supported by service" );
143 // build return sequence
144 INT32 nLanguages
= static_cast< INT32
>(aLanguages
.size());
145 aRes
.realloc( nLanguages
);
146 lang::Locale
*pRes
= aRes
.getArray();
147 std::set
< LanguageType
>::const_iterator
aIt( aLanguages
.begin() );
148 for (i
= 0; aIt
!= aLanguages
.end(); ++aIt
, ++i
)
150 LanguageType nLang
= *aIt
;
151 pRes
[i
] = CreateLocale( nLang
);
158 ///////////////////////////////////////////////////////////////////////////
162 const OUString aSvcImplName
;
163 const uno::Sequence
< INT16
> aSuppLanguages
;
165 SvcInfo( const OUString
&rSvcImplName
,
166 const uno::Sequence
< INT16
> &rSuppLanguages
) :
167 aSvcImplName (rSvcImplName
),
168 aSuppLanguages (rSuppLanguages
)
172 BOOL
HasLanguage( INT16 nLanguage
) const;
176 BOOL
SvcInfo::HasLanguage( INT16 nLanguage
) const
178 INT32 nCnt
= aSuppLanguages
.getLength();
179 const INT16
*pLang
= aSuppLanguages
.getConstArray();
182 for ( i
= 0; i
< nCnt
; ++i
)
184 if (nLanguage
== pLang
[i
])
191 ///////////////////////////////////////////////////////////////////////////
194 void LngSvcMgr::SetAvailableCfgServiceLists( LinguDispatcher
&rDispatcher
,
195 const SvcInfoArray
&rAvailSvcs
)
197 // get list of nodenames to look at for their service list
198 const char *pEntryName
= 0;
199 BOOL bHasLangSvcList
= TRUE
;
200 switch (rDispatcher
.GetDspType())
202 case LinguDispatcher::DSP_SPELL
: pEntryName
= "ServiceManager/SpellCheckerList"; break;
203 case LinguDispatcher::DSP_GRAMMAR
: pEntryName
= "ServiceManager/GrammarCheckerList";
204 bHasLangSvcList
= FALSE
;
206 case LinguDispatcher::DSP_HYPH
: pEntryName
= "ServiceManager/HyphenatorList";
207 bHasLangSvcList
= FALSE
;
209 case LinguDispatcher::DSP_THES
: pEntryName
= "ServiceManager/ThesaurusList"; break;
211 DBG_ASSERT( 0, "unexpected case" );
213 String
aNode( String::CreateFromAscii( pEntryName
) );
214 uno::Sequence
< OUString
> aNodeNames( /*aCfg.*/GetNodeNames( aNode
) );
217 INT32 nLen
= aNodeNames
.getLength();
218 const OUString
*pNodeNames
= aNodeNames
.getConstArray();
219 for (INT32 i
= 0; i
< nLen
; ++i
)
221 uno::Sequence
< OUString
> aSvcImplNames
;
223 uno::Sequence
< OUString
> aNames( 1 );
224 OUString
*pNames
= aNames
.getArray();
226 OUString
aPropName( aNode
);
227 aPropName
+= OUString::valueOf( (sal_Unicode
) '/' );
228 aPropName
+= pNodeNames
[i
];
229 pNames
[0] = aPropName
;
231 uno::Sequence
< uno::Any
> aValues
= /*aCfg.*/GetProperties( aNames
);
232 if (aValues
.getLength())
234 // get list of configured service names for the
235 // current node (language)
236 const uno::Any
&rValue
= aValues
.getConstArray()[0];
238 aSvcImplNames
= GetLangSvcList( rValue
);
240 aSvcImplNames
= GetLangSvc( rValue
);
242 INT32 nSvcs
= aSvcImplNames
.getLength();
245 const OUString
*pImplNames
= aSvcImplNames
.getConstArray();
247 LanguageType nLang
= MsLangId::convertIsoStringToLanguage( pNodeNames
[i
] );
249 // build list of available services from those
251 uno::Sequence
< OUString
> aAvailSvcs( nSvcs
);
252 OUString
*pAvailSvcs
= aAvailSvcs
.getArray();
253 for (INT32 k
= 0; k
< nSvcs
; ++k
)
255 // check for availability of the service
256 size_t nAvailSvcs
= rAvailSvcs
.size();
257 for (size_t m
= 0; m
< nAvailSvcs
; ++m
)
259 const SvcInfo
&rSvcInfo
= *rAvailSvcs
[m
];
260 if (rSvcInfo
.aSvcImplName
== pImplNames
[k
] &&
261 rSvcInfo
.HasLanguage( nLang
))
263 pAvailSvcs
[ nCnt
++ ] = rSvcInfo
.aSvcImplName
;
271 aAvailSvcs
.realloc( nCnt
);
272 rDispatcher
.SetServiceList( CreateLocale( nLang
), aAvailSvcs
);
280 ///////////////////////////////////////////////////////////////////////////
283 class LngSvcMgrListenerHelper
:
284 public cppu::WeakImplHelper2
286 linguistic2::XLinguServiceEventListener
,
287 linguistic2::XDictionaryListEventListener
290 LngSvcMgr
&rMyManager
;
293 //cppu::OMultiTypeInterfaceContainerHelper aListeners;
294 ::cppu::OInterfaceContainerHelper aLngSvcMgrListeners
;
295 ::cppu::OInterfaceContainerHelper aLngSvcEvtBroadcasters
;
296 uno::Reference
< linguistic2::XDictionaryList
> xDicList
;
297 uno::Reference
< uno::XInterface
> xMyEvtObj
;
299 INT16 nCombinedLngSvcEvt
;
301 // disallow copy-constructor and assignment-operator for now
302 LngSvcMgrListenerHelper(const LngSvcMgrListenerHelper
&);
303 LngSvcMgrListenerHelper
& operator = (const LngSvcMgrListenerHelper
&);
305 void LaunchEvent( INT16 nLngSvcEvtFlags
);
307 DECL_LINK( TimeOut
, Timer
* );
310 LngSvcMgrListenerHelper( LngSvcMgr
&rLngSvcMgr
,
311 const uno::Reference
< uno::XInterface
> &rxSource
,
312 const uno::Reference
< linguistic2::XDictionaryList
> &rxDicList
);
314 // lang::XEventListener
315 virtual void SAL_CALL
316 disposing( const lang::EventObject
& rSource
)
317 throw(uno::RuntimeException
);
319 // linguistic2::XLinguServiceEventListener
320 virtual void SAL_CALL
321 processLinguServiceEvent( const linguistic2::LinguServiceEvent
& aLngSvcEvent
)
322 throw(uno::RuntimeException
);
324 // linguistic2::XDictionaryListEventListener
325 virtual void SAL_CALL
326 processDictionaryListEvent(
327 const linguistic2::DictionaryListEvent
& rDicListEvent
)
328 throw(uno::RuntimeException
);
330 inline BOOL
AddLngSvcMgrListener(
331 const uno::Reference
< lang::XEventListener
>& rxListener
);
332 inline BOOL
RemoveLngSvcMgrListener(
333 const uno::Reference
< lang::XEventListener
>& rxListener
);
334 void DisposeAndClear( const lang::EventObject
&rEvtObj
);
335 BOOL
AddLngSvcEvtBroadcaster(
336 const uno::Reference
< linguistic2::XLinguServiceEventBroadcaster
> &rxBroadcaster
);
337 BOOL
RemoveLngSvcEvtBroadcaster(
338 const uno::Reference
< linguistic2::XLinguServiceEventBroadcaster
> &rxBroadcaster
);
340 void AddLngSvcEvt( INT16 nLngSvcEvt
);
344 LngSvcMgrListenerHelper::LngSvcMgrListenerHelper(
345 LngSvcMgr
&rLngSvcMgr
,
346 const uno::Reference
< uno::XInterface
> &rxSource
,
347 const uno::Reference
< linguistic2::XDictionaryList
> &rxDicList
) :
348 rMyManager ( rLngSvcMgr
),
349 aLngSvcMgrListeners ( GetLinguMutex() ),
350 aLngSvcEvtBroadcasters ( GetLinguMutex() ),
351 xDicList ( rxDicList
),
352 xMyEvtObj ( rxSource
)
356 xDicList
->addDictionaryListEventListener(
357 (linguistic2::XDictionaryListEventListener
*) this, FALSE
);
360 //! The timer is used to 'sum up' different events in order to reduce the
361 //! number of events forwarded.
362 //! (This may happen already if a property was changed that has several
363 //! listeners, and each of them is launching an event of it's own!)
364 //! Thus this behaviour is necessary to avoid unecessary actions of
365 //! this objects listeners!
366 aLaunchTimer
.SetTimeout( 2000 );
367 aLaunchTimer
.SetTimeoutHdl( LINK( this, LngSvcMgrListenerHelper
, TimeOut
) );
368 nCombinedLngSvcEvt
= 0;
372 void SAL_CALL
LngSvcMgrListenerHelper::disposing( const lang::EventObject
& rSource
)
373 throw(uno::RuntimeException
)
375 osl::MutexGuard
aGuard( GetLinguMutex() );
377 uno::Reference
< uno::XInterface
> xRef( rSource
.Source
);
380 aLngSvcMgrListeners
.removeInterface( xRef
);
381 aLngSvcEvtBroadcasters
.removeInterface( xRef
);
382 if (xDicList
== xRef
)
388 IMPL_LINK( LngSvcMgrListenerHelper
, TimeOut
, Timer
*, pTimer
)
390 osl::MutexGuard
aGuard( GetLinguMutex() );
392 if (&aLaunchTimer
== pTimer
)
394 // change event source to LinguServiceManager since the listeners
395 // probably do not know (and need not to know) about the specific
396 // SpellChecker's or Hyphenator's.
397 linguistic2::LinguServiceEvent
aEvtObj( xMyEvtObj
, nCombinedLngSvcEvt
);
398 nCombinedLngSvcEvt
= 0;
400 if (rMyManager
.pSpellDsp
)
401 rMyManager
.pSpellDsp
->FlushSpellCache();
403 // pass event on to linguistic2::XLinguServiceEventListener's
404 cppu::OInterfaceIteratorHelper
aIt( aLngSvcMgrListeners
);
405 while (aIt
.hasMoreElements())
407 uno::Reference
< linguistic2::XLinguServiceEventListener
> xRef( aIt
.next(), uno::UNO_QUERY
);
409 xRef
->processLinguServiceEvent( aEvtObj
);
416 void LngSvcMgrListenerHelper::AddLngSvcEvt( INT16 nLngSvcEvt
)
418 nCombinedLngSvcEvt
|= nLngSvcEvt
;
419 aLaunchTimer
.Start();
424 LngSvcMgrListenerHelper::processLinguServiceEvent(
425 const linguistic2::LinguServiceEvent
& rLngSvcEvent
)
426 throw(uno::RuntimeException
)
428 osl::MutexGuard
aGuard( GetLinguMutex() );
429 AddLngSvcEvt( rLngSvcEvent
.nEvent
);
434 LngSvcMgrListenerHelper::processDictionaryListEvent(
435 const linguistic2::DictionaryListEvent
& rDicListEvent
)
436 throw(uno::RuntimeException
)
438 osl::MutexGuard
aGuard( GetLinguMutex() );
440 INT16 nDlEvt
= rDicListEvent
.nCondensedEvent
;
444 // we do keep the original event source here though...
446 // pass event on to linguistic2::XDictionaryListEventListener's
447 cppu::OInterfaceIteratorHelper
aIt( aLngSvcMgrListeners
);
448 while (aIt
.hasMoreElements())
450 uno::Reference
< linguistic2::XDictionaryListEventListener
> xRef( aIt
.next(), uno::UNO_QUERY
);
452 xRef
->processDictionaryListEvent( rDicListEvent
);
456 // "translate" DictionaryList event into linguistic2::LinguServiceEvent
458 INT16 nLngSvcEvt
= 0;
460 INT16 nSpellCorrectFlags
=
461 linguistic2::DictionaryListEventFlags::ADD_NEG_ENTRY
|
462 linguistic2::DictionaryListEventFlags::DEL_POS_ENTRY
|
463 linguistic2::DictionaryListEventFlags::ACTIVATE_NEG_DIC
|
464 linguistic2::DictionaryListEventFlags::DEACTIVATE_POS_DIC
;
465 if (0 != (nDlEvt
& nSpellCorrectFlags
))
466 nLngSvcEvt
|= linguistic2::LinguServiceEventFlags::SPELL_CORRECT_WORDS_AGAIN
;
468 INT16 nSpellWrongFlags
=
469 linguistic2::DictionaryListEventFlags::ADD_POS_ENTRY
|
470 linguistic2::DictionaryListEventFlags::DEL_NEG_ENTRY
|
471 linguistic2::DictionaryListEventFlags::ACTIVATE_POS_DIC
|
472 linguistic2::DictionaryListEventFlags::DEACTIVATE_NEG_DIC
;
473 if (0 != (nDlEvt
& nSpellWrongFlags
))
474 nLngSvcEvt
|= linguistic2::LinguServiceEventFlags::SPELL_WRONG_WORDS_AGAIN
;
476 INT16 nHyphenateFlags
=
477 linguistic2::DictionaryListEventFlags::ADD_POS_ENTRY
|
478 linguistic2::DictionaryListEventFlags::DEL_POS_ENTRY
|
479 linguistic2::DictionaryListEventFlags::ACTIVATE_POS_DIC
|
480 linguistic2::DictionaryListEventFlags::ACTIVATE_NEG_DIC
;
481 if (0 != (nDlEvt
& nHyphenateFlags
))
482 nLngSvcEvt
|= linguistic2::LinguServiceEventFlags::HYPHENATE_AGAIN
;
484 if (rMyManager
.pSpellDsp
)
485 rMyManager
.pSpellDsp
->FlushSpellCache();
487 LaunchEvent( nLngSvcEvt
);
491 void LngSvcMgrListenerHelper::LaunchEvent( INT16 nLngSvcEvtFlags
)
493 linguistic2::LinguServiceEvent
aEvt( xMyEvtObj
, nLngSvcEvtFlags
);
495 // pass event on to linguistic2::XLinguServiceEventListener's
496 cppu::OInterfaceIteratorHelper
aIt( aLngSvcMgrListeners
);
497 while (aIt
.hasMoreElements())
499 uno::Reference
< linguistic2::XLinguServiceEventListener
> xRef( aIt
.next(), uno::UNO_QUERY
);
501 xRef
->processLinguServiceEvent( aEvt
);
506 inline BOOL
LngSvcMgrListenerHelper::AddLngSvcMgrListener(
507 const uno::Reference
< lang::XEventListener
>& rxListener
)
509 aLngSvcMgrListeners
.addInterface( rxListener
);
514 inline BOOL
LngSvcMgrListenerHelper::RemoveLngSvcMgrListener(
515 const uno::Reference
< lang::XEventListener
>& rxListener
)
517 aLngSvcMgrListeners
.removeInterface( rxListener
);
522 void LngSvcMgrListenerHelper::DisposeAndClear( const lang::EventObject
&rEvtObj
)
524 // call "disposing" for all listeners and clear list
525 aLngSvcMgrListeners
.disposeAndClear( rEvtObj
);
527 // remove references to this object hold by the broadcasters
528 cppu::OInterfaceIteratorHelper
aIt( aLngSvcEvtBroadcasters
);
529 while (aIt
.hasMoreElements())
531 uno::Reference
< linguistic2::XLinguServiceEventBroadcaster
> xRef( aIt
.next(), uno::UNO_QUERY
);
533 RemoveLngSvcEvtBroadcaster( xRef
);
536 // remove refernce to this object hold by the dictionary-list
539 xDicList
->removeDictionaryListEventListener(
540 (linguistic2::XDictionaryListEventListener
*) this );
546 BOOL
LngSvcMgrListenerHelper::AddLngSvcEvtBroadcaster(
547 const uno::Reference
< linguistic2::XLinguServiceEventBroadcaster
> &rxBroadcaster
)
550 if (rxBroadcaster
.is())
552 aLngSvcEvtBroadcasters
.addInterface( rxBroadcaster
);
553 rxBroadcaster
->addLinguServiceEventListener(
554 (linguistic2::XLinguServiceEventListener
*) this );
560 BOOL
LngSvcMgrListenerHelper::RemoveLngSvcEvtBroadcaster(
561 const uno::Reference
< linguistic2::XLinguServiceEventBroadcaster
> &rxBroadcaster
)
564 if (rxBroadcaster
.is())
566 aLngSvcEvtBroadcasters
.removeInterface( rxBroadcaster
);
567 rxBroadcaster
->removeLinguServiceEventListener(
568 (linguistic2::XLinguServiceEventListener
*) this );
574 ///////////////////////////////////////////////////////////////////////////
577 LngSvcMgr::LngSvcMgr() :
578 utl::ConfigItem( String::CreateFromAscii( "Office.Linguistic" ) ),
579 aEvtListeners ( GetLinguMutex() )
581 bHasAvailSpellLocales
=
582 bHasAvailGrammarLocales
=
583 bHasAvailHyphLocales
=
584 bHasAvailThesLocales
=
593 pAvailGrammarSvcs
= 0;
598 // request notify events when properties (i.e. something in the subtree) changes
599 uno::Sequence
< OUString
> aNames(4);
600 OUString
*pNames
= aNames
.getArray();
601 pNames
[0] = A2OU( "ServiceManager/SpellCheckerList" );
602 pNames
[1] = A2OU( "ServiceManager/GrammarCheckerList" );
603 pNames
[2] = A2OU( "ServiceManager/HyphenatorList" );
604 pNames
[3] = A2OU( "ServiceManager/ThesaurusList" );
605 EnableNotification( aNames
);
609 LngSvcMgr::~LngSvcMgr()
611 // memory for pSpellDsp, pHyphDsp, pThesDsp, pListenerHelper
612 // will be freed in the destructor of the respective Reference's
613 // xSpellDsp, xGrammarDsp, xHyphDsp, xThesDsp
615 delete pAvailSpellSvcs
;
616 delete pAvailGrammarSvcs
;
617 delete pAvailHyphSvcs
;
618 delete pAvailThesSvcs
;
622 void LngSvcMgr::Notify( const uno::Sequence
< OUString
> &rPropertyNames
)
624 const OUString
aSpellCheckerList( A2OU("ServiceManager/SpellCheckerList") );
625 const OUString
aGrammarCheckerList( A2OU("ServiceManager/GrammarCheckerList") );
626 const OUString
aHyphenatorList( A2OU("ServiceManager/HyphenatorList") );
627 const OUString
aThesaurusList( A2OU("ServiceManager/ThesaurusList") );
629 const uno::Sequence
< OUString
> aSpellCheckerListEntries( GetNodeNames( aSpellCheckerList
) );
630 const uno::Sequence
< OUString
> aGrammarCheckerListEntries( GetNodeNames( aGrammarCheckerList
) );
631 const uno::Sequence
< OUString
> aHyphenatorListEntries( GetNodeNames( aHyphenatorList
) );
632 const uno::Sequence
< OUString
> aThesaurusListEntries( GetNodeNames( aThesaurusList
) );
634 uno::Sequence
< uno::Any
> aValues
;
635 uno::Sequence
< OUString
> aNames( 1 );
636 OUString
*pNames
= aNames
.getArray();
638 sal_Int32 nLen
= rPropertyNames
.getLength();
639 const OUString
*pPropertyNames
= rPropertyNames
.getConstArray();
640 for (sal_Int32 i
= 0; i
< nLen
; ++i
)
642 // property names look like
643 // "ServiceManager/ThesaurusList/cfg:any['de-CH']"
645 const OUString
&rName
= pPropertyNames
[i
];
646 sal_Int32 nKeyStart
, nKeyEnd
;
647 nKeyStart
= rName
.indexOf( A2OU("['"), 0 );
648 nKeyEnd
= rName
.indexOf( A2OU("']"), nKeyStart
+ 2);
650 if (nKeyStart
!= -1 && nKeyEnd
!= -1)
651 aKeyText
= rName
.copy( nKeyStart
+ 2, nKeyEnd
- nKeyStart
- 2);
652 DBG_ASSERT( aKeyText
.getLength() != 0, "unexpected key (lang::Locale) string" );
653 if (0 == rName
.compareTo( aSpellCheckerList
, aSpellCheckerList
.getLength() ))
655 // delete old cached data, needs to be acquired new on demand
656 delete pAvailSpellSvcs
; pAvailSpellSvcs
= 0;
658 OUString
aNode( aSpellCheckerList
);
659 if (lcl_SeqHasString( aSpellCheckerListEntries
, aKeyText
))
661 OUString
aPropName( aNode
);
662 aPropName
+= OUString::valueOf( (sal_Unicode
) '/' );
663 aPropName
+= aKeyText
;
664 pNames
[0] = aPropName
;
665 aValues
= /*aCfg.*/GetProperties( aNames
);
666 uno::Sequence
< OUString
> aSvcImplNames
;
667 if (aValues
.getLength())
668 aSvcImplNames
= GetLangSvcList( aValues
.getConstArray()[0] );
670 LanguageType nLang
= LANGUAGE_NONE
;
671 if (0 != aKeyText
.getLength())
672 nLang
= MsLangId::convertIsoStringToLanguage( aKeyText
);
674 GetSpellCheckerDsp_Impl( sal_False
); // don't set service list, it will be done below
675 pSpellDsp
->SetServiceList( CreateLocale(nLang
), aSvcImplNames
);
678 else if (0 == rName
.compareTo( aGrammarCheckerList
, aGrammarCheckerList
.getLength() ))
680 // delete old cached data, needs to be acquired new on demand
681 delete pAvailGrammarSvcs
; pAvailGrammarSvcs
= 0;
683 OUString
aNode( aGrammarCheckerList
);
684 if (lcl_SeqHasString( aGrammarCheckerListEntries
, aKeyText
))
686 OUString
aPropName( aNode
);
687 aPropName
+= OUString::valueOf( (sal_Unicode
) '/' );
688 aPropName
+= aKeyText
;
689 pNames
[0] = aPropName
;
690 aValues
= /*aCfg.*/GetProperties( aNames
);
691 uno::Sequence
< OUString
> aSvcImplNames
;
692 if (aValues
.getLength())
693 aSvcImplNames
= GetLangSvc( aValues
.getConstArray()[0] );
695 LanguageType nLang
= LANGUAGE_NONE
;
696 if (0 != aKeyText
.getLength())
697 nLang
= MsLangId::convertIsoStringToLanguage( aKeyText
);
699 if (SvtLinguConfig().HasGrammarChecker())
701 GetGrammarCheckerDsp_Impl( sal_False
); // don't set service list, it will be done below
702 pGrammarDsp
->SetServiceList( CreateLocale(nLang
), aSvcImplNames
);
706 else if (0 == rName
.compareTo( aHyphenatorList
, aHyphenatorList
.getLength() ))
708 // delete old cached data, needs to be acquired new on demand
709 delete pAvailHyphSvcs
; pAvailHyphSvcs
= 0;
711 OUString
aNode( aHyphenatorList
);
712 if (lcl_SeqHasString( aHyphenatorListEntries
, aKeyText
))
714 OUString
aPropName( aNode
);
715 aPropName
+= OUString::valueOf( (sal_Unicode
) '/' );
716 aPropName
+= aKeyText
;
717 pNames
[0] = aPropName
;
718 aValues
= /*aCfg.*/GetProperties( aNames
);
719 uno::Sequence
< OUString
> aSvcImplNames
;
720 if (aValues
.getLength())
721 aSvcImplNames
= GetLangSvc( aValues
.getConstArray()[0] );
723 LanguageType nLang
= LANGUAGE_NONE
;
724 if (0 != aKeyText
.getLength())
725 nLang
= MsLangId::convertIsoStringToLanguage( aKeyText
);
727 GetHyphenatorDsp_Impl( sal_False
); // don't set service list, it will be done below
728 pHyphDsp
->SetServiceList( CreateLocale(nLang
), aSvcImplNames
);
731 else if (0 == rName
.compareTo( aThesaurusList
, aThesaurusList
.getLength() ))
733 // delete old cached data, needs to be acquired new on demand
734 delete pAvailThesSvcs
; pAvailThesSvcs
= 0;
736 OUString
aNode( aThesaurusList
);
737 if (lcl_SeqHasString( aThesaurusListEntries
, aKeyText
))
739 OUString
aPropName( aNode
);
740 aPropName
+= OUString::valueOf( (sal_Unicode
) '/' );
741 aPropName
+= aKeyText
;
742 pNames
[0] = aPropName
;
743 aValues
= /*aCfg.*/GetProperties( aNames
);
744 uno::Sequence
< OUString
> aSvcImplNames
;
745 if (aValues
.getLength())
746 aSvcImplNames
= GetLangSvcList( aValues
.getConstArray()[0] );
748 LanguageType nLang
= LANGUAGE_NONE
;
749 if (0 != aKeyText
.getLength())
750 nLang
= MsLangId::convertIsoStringToLanguage( aKeyText
);
752 GetThesaurusDsp_Impl( sal_False
); // don't set service list, it will be done below
753 pThesDsp
->SetServiceList( CreateLocale(nLang
), aSvcImplNames
);
758 DBG_ASSERT( 0, "nofified for unexpected property" );
764 void LngSvcMgr::Commit()
766 // everything necessary should have already been done by 'SaveCfgSvcs'
767 // called from within 'setConfiguredServices'.
768 // Also this class usually exits only when the Office i sbeing shutdown.
772 void LngSvcMgr::GetListenerHelper_Impl()
774 if (!pListenerHelper
)
776 pListenerHelper
= new LngSvcMgrListenerHelper( *this,
777 (XLinguServiceManager
*) this, linguistic::GetDictionaryList() );
778 xListenerHelper
= (linguistic2::XLinguServiceEventListener
*) pListenerHelper
;
783 void LngSvcMgr::GetSpellCheckerDsp_Impl( sal_Bool bSetSvcList
)
787 pSpellDsp
= new SpellCheckerDispatcher( *this );
788 xSpellDsp
= pSpellDsp
;
790 SetCfgServiceLists( *pSpellDsp
);
795 void LngSvcMgr::GetGrammarCheckerDsp_Impl( sal_Bool bSetSvcList
)
797 if (!pGrammarDsp
&& SvtLinguConfig().HasGrammarChecker())
799 //! since the grammar checking iterator needs to be a one instance service
800 //! we need to create it the correct way!
801 uno::Reference
< linguistic2::XProofreadingIterator
> xGCI
;
804 uno::Reference
< lang::XMultiServiceFactory
> xMgr(
805 utl::getProcessServiceFactory(), uno::UNO_QUERY_THROW
);
806 xGCI
= uno::Reference
< linguistic2::XProofreadingIterator
>(
807 xMgr
->createInstance( A2OU( SN_GRAMMARCHECKINGITERATOR
) ), uno::UNO_QUERY_THROW
);
809 catch (uno::Exception
&)
812 DBG_ASSERT( xGCI
.is(), "instantiating grammar checking iterator failed" );
816 pGrammarDsp
= dynamic_cast< GrammarCheckingIterator
* >(xGCI
.get());
818 DBG_ASSERT( pGrammarDsp
, "failed to get implementation" );
820 SetCfgServiceLists( *pGrammarDsp
);
826 void LngSvcMgr::GetHyphenatorDsp_Impl( sal_Bool bSetSvcList
)
830 pHyphDsp
= new HyphenatorDispatcher( *this );
833 SetCfgServiceLists( *pHyphDsp
);
838 void LngSvcMgr::GetThesaurusDsp_Impl( sal_Bool bSetSvcList
)
842 pThesDsp
= new ThesaurusDispatcher
;
845 SetCfgServiceLists( *pThesDsp
);
850 void LngSvcMgr::GetAvailableSpellSvcs_Impl()
852 if (!pAvailSpellSvcs
)
854 pAvailSpellSvcs
= new SvcInfoArray
;
856 uno::Reference
< lang::XMultiServiceFactory
> xFac( utl::getProcessServiceFactory() );
859 uno::Reference
< container::XContentEnumerationAccess
> xEnumAccess( xFac
, uno::UNO_QUERY
);
860 uno::Reference
< container::XEnumeration
> xEnum
;
861 if (xEnumAccess
.is())
862 xEnum
= xEnumAccess
->createContentEnumeration(
863 A2OU( SN_SPELLCHECKER
) );
867 while (xEnum
->hasMoreElements())
869 uno::Any aCurrent
= xEnum
->nextElement();
870 uno::Reference
< lang::XSingleComponentFactory
> xCompFactory
;
871 uno::Reference
< lang::XSingleServiceFactory
> xFactory
;
873 uno::Reference
< linguistic2::XSpellChecker
> xSvc
;
874 if ( cppu::extractInterface( xCompFactory
, aCurrent
) || ::cppu::extractInterface( xFactory
, aCurrent
) )
878 uno::Reference
< uno::XComponentContext
> xContext
;
879 uno::Reference
< beans::XPropertySet
> xProps( xFac
, uno::UNO_QUERY
);
881 xProps
->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xContext
;
882 xSvc
= uno::Reference
< linguistic2::XSpellChecker
>( ( xCompFactory
.is() ? xCompFactory
->createInstanceWithContext( xContext
) : xFactory
->createInstance() ), uno::UNO_QUERY
);
884 catch (uno::Exception
&rEx
)
887 DBG_ASSERT( 0, "createInstance failed" );
894 uno::Sequence
< INT16
> aLanguages
;
895 uno::Reference
< XServiceInfo
> xInfo( xSvc
, uno::UNO_QUERY
);
897 aImplName
= xInfo
->getImplementationName();
898 DBG_ASSERT( aImplName
.getLength(),
899 "empty implementation name" );
900 uno::Reference
< linguistic2::XSupportedLocales
> xSuppLoc( xSvc
, uno::UNO_QUERY
);
901 DBG_ASSERT( xSuppLoc
.is(), "interfaces not supported" );
903 uno::Sequence
<lang::Locale
> aLocaleSequence(xSuppLoc
->getLocales());
904 aLanguages
= LocaleSeqToLangSeq( aLocaleSequence
);
907 pAvailSpellSvcs
->push_back( new SvcInfo( aImplName
, aLanguages
) );
916 void LngSvcMgr::GetAvailableGrammarSvcs_Impl()
918 if (!pAvailGrammarSvcs
)
920 pAvailGrammarSvcs
= new SvcInfoArray
;
922 uno::Reference
< lang::XMultiServiceFactory
> xFac( utl::getProcessServiceFactory() );
925 uno::Reference
< container::XContentEnumerationAccess
> xEnumAccess( xFac
, uno::UNO_QUERY
);
926 uno::Reference
< container::XEnumeration
> xEnum
;
927 if (xEnumAccess
.is())
928 xEnum
= xEnumAccess
->createContentEnumeration(
929 A2OU( SN_GRAMMARCHECKER
) );
933 while (xEnum
->hasMoreElements())
935 uno::Any aCurrent
= xEnum
->nextElement();
936 uno::Reference
< lang::XSingleComponentFactory
> xCompFactory
;
937 uno::Reference
< lang::XSingleServiceFactory
> xFactory
;
939 uno::Reference
< linguistic2::XProofreader
> xSvc
;
940 if ( cppu::extractInterface( xCompFactory
, aCurrent
) || ::cppu::extractInterface( xFactory
, aCurrent
) )
944 uno::Reference
< uno::XComponentContext
> xContext
;
945 uno::Reference
< beans::XPropertySet
> xProps( xFac
, uno::UNO_QUERY
);
947 xProps
->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xContext
;
948 xSvc
= uno::Reference
< linguistic2::XProofreader
>( ( xCompFactory
.is() ? xCompFactory
->createInstanceWithContext( xContext
) : xFactory
->createInstance() ), uno::UNO_QUERY
);
950 catch (uno::Exception
&rEx
)
953 DBG_ASSERT( 0, "createInstance failed" );
960 uno::Sequence
< INT16
> aLanguages
;
961 uno::Reference
< XServiceInfo
> xInfo( xSvc
, uno::UNO_QUERY
);
963 aImplName
= xInfo
->getImplementationName();
964 DBG_ASSERT( aImplName
.getLength(),
965 "empty implementation name" );
966 uno::Reference
< linguistic2::XSupportedLocales
> xSuppLoc( xSvc
, uno::UNO_QUERY
);
967 DBG_ASSERT( xSuppLoc
.is(), "interfaces not supported" );
969 uno::Sequence
<lang::Locale
> aLocaleSequence(xSuppLoc
->getLocales());
970 aLanguages
= LocaleSeqToLangSeq( aLocaleSequence
);
973 pAvailGrammarSvcs
->push_back( new SvcInfo( aImplName
, aLanguages
) );
982 void LngSvcMgr::GetAvailableHyphSvcs_Impl()
986 pAvailHyphSvcs
= new SvcInfoArray
;
987 uno::Reference
< lang::XMultiServiceFactory
> xFac( utl::getProcessServiceFactory() );
990 uno::Reference
< container::XContentEnumerationAccess
> xEnumAccess( xFac
, uno::UNO_QUERY
);
991 uno::Reference
< container::XEnumeration
> xEnum
;
992 if (xEnumAccess
.is())
993 xEnum
= xEnumAccess
->createContentEnumeration( A2OU( SN_HYPHENATOR
) );
997 while (xEnum
->hasMoreElements())
999 uno::Any aCurrent
= xEnum
->nextElement();
1000 uno::Reference
< lang::XSingleComponentFactory
> xCompFactory
;
1001 uno::Reference
< lang::XSingleServiceFactory
> xFactory
;
1003 uno::Reference
< linguistic2::XHyphenator
> xSvc
;
1004 if ( cppu::extractInterface( xCompFactory
, aCurrent
) || ::cppu::extractInterface( xFactory
, aCurrent
) )
1008 uno::Reference
< uno::XComponentContext
> xContext
;
1009 uno::Reference
< beans::XPropertySet
> xProps( xFac
, uno::UNO_QUERY
);
1011 xProps
->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xContext
;
1012 xSvc
= uno::Reference
< linguistic2::XHyphenator
>( ( xCompFactory
.is() ? xCompFactory
->createInstanceWithContext( xContext
) : xFactory
->createInstance() ), uno::UNO_QUERY
);
1015 catch (uno::Exception
&rEx
)
1018 DBG_ASSERT( 0, "createInstance failed" );
1025 uno::Sequence
< INT16
> aLanguages
;
1026 uno::Reference
< XServiceInfo
> xInfo( xSvc
, uno::UNO_QUERY
);
1028 aImplName
= xInfo
->getImplementationName();
1029 DBG_ASSERT( aImplName
.getLength(),
1030 "empty implementation name" );
1031 uno::Reference
< linguistic2::XSupportedLocales
> xSuppLoc( xSvc
, uno::UNO_QUERY
);
1032 DBG_ASSERT( xSuppLoc
.is(), "interfaces not supported" );
1033 if (xSuppLoc
.is()) {
1034 uno::Sequence
<lang::Locale
> aLocaleSequence(xSuppLoc
->getLocales());
1035 aLanguages
= LocaleSeqToLangSeq( aLocaleSequence
);
1038 pAvailHyphSvcs
->push_back( new SvcInfo( aImplName
, aLanguages
) );
1047 void LngSvcMgr::GetAvailableThesSvcs_Impl()
1049 if (!pAvailThesSvcs
)
1051 pAvailThesSvcs
= new SvcInfoArray
;
1053 uno::Reference
< lang::XMultiServiceFactory
> xFac( utl::getProcessServiceFactory() );
1056 uno::Reference
< container::XContentEnumerationAccess
> xEnumAccess( xFac
, uno::UNO_QUERY
);
1057 uno::Reference
< container::XEnumeration
> xEnum
;
1058 if (xEnumAccess
.is())
1059 xEnum
= xEnumAccess
->createContentEnumeration(
1060 A2OU( SN_THESAURUS
) );
1064 while (xEnum
->hasMoreElements())
1066 uno::Any aCurrent
= xEnum
->nextElement();
1068 uno::Reference
< lang::XSingleComponentFactory
> xCompFactory
;
1069 uno::Reference
< lang::XSingleServiceFactory
> xFactory
;
1071 uno::Reference
< linguistic2::XThesaurus
> xSvc
;
1072 if ( cppu::extractInterface( xCompFactory
, aCurrent
) || ::cppu::extractInterface( xFactory
, aCurrent
) )
1076 uno::Reference
< uno::XComponentContext
> xContext
;
1077 uno::Reference
< beans::XPropertySet
> xProps( xFac
, uno::UNO_QUERY
);
1079 xProps
->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xContext
;
1080 xSvc
= uno::Reference
< linguistic2::XThesaurus
>( ( xCompFactory
.is() ? xCompFactory
->createInstanceWithContext( xContext
) : xFactory
->createInstance() ), uno::UNO_QUERY
);
1082 catch (uno::Exception
&rEx
)
1085 DBG_ASSERT( 0, "createInstance failed" );
1092 uno::Sequence
< INT16
> aLanguages
;
1093 uno::Reference
< XServiceInfo
> xInfo( xSvc
, uno::UNO_QUERY
);
1095 aImplName
= xInfo
->getImplementationName();
1096 DBG_ASSERT( aImplName
.getLength(),
1097 "empty implementation name" );
1098 uno::Reference
< linguistic2::XSupportedLocales
> xSuppLoc( xSvc
, uno::UNO_QUERY
);
1099 DBG_ASSERT( xSuppLoc
.is(), "interfaces not supported" );
1100 if (xSuppLoc
.is()) {
1101 uno::Sequence
<lang::Locale
> aLocaleSequence(xSuppLoc
->getLocales());
1102 aLanguages
= LocaleSeqToLangSeq( aLocaleSequence
);
1105 pAvailThesSvcs
->push_back( new SvcInfo( aImplName
, aLanguages
) );
1114 void LngSvcMgr::SetCfgServiceLists( SpellCheckerDispatcher
&rSpellDsp
)
1116 RTL_LOGFILE_CONTEXT( aLog
, "linguistic: LngSvcMgr::SetCfgServiceLists - Spell" );
1118 String
aNode( String::CreateFromAscii( "ServiceManager/SpellCheckerList" ) );
1119 uno::Sequence
< OUString
> aNames( /*aCfg.*/GetNodeNames( aNode
) );
1120 OUString
*pNames
= aNames
.getArray();
1121 INT32 nLen
= aNames
.getLength();
1123 // append path prefix need for 'GetProperties' call below
1124 String
aPrefix( aNode
);
1125 aPrefix
.Append( (sal_Unicode
) '/' );
1126 for (int i
= 0; i
< nLen
; ++i
)
1128 OUString
aTmp( aPrefix
);
1133 uno::Sequence
< uno::Any
> aValues( /*aCfg.*/GetProperties( aNames
) );
1134 if (nLen
&& nLen
== aValues
.getLength())
1136 const uno::Any
*pValues
= aValues
.getConstArray();
1137 for (INT32 i
= 0; i
< nLen
; ++i
)
1139 uno::Sequence
< OUString
> aSvcImplNames
;
1140 if (pValues
[i
] >>= aSvcImplNames
)
1142 #if OSL_DEBUG_LEVEL > 1
1143 // INT32 nSvcs = aSvcImplNames.getLength();
1144 // const OUString *pSvcImplNames = aSvcImplNames.getConstArray();
1146 String
aLocaleStr( pNames
[i
] );
1147 xub_StrLen nSeperatorPos
= aLocaleStr
.SearchBackward( sal_Unicode( '/' ) );
1148 aLocaleStr
= aLocaleStr
.Copy( nSeperatorPos
+ 1 );
1149 lang::Locale
aLocale( CreateLocale( MsLangId::convertIsoStringToLanguage(aLocaleStr
) ) );
1150 rSpellDsp
.SetServiceList( aLocale
, aSvcImplNames
);
1157 void LngSvcMgr::SetCfgServiceLists( GrammarCheckingIterator
&rGrammarDsp
)
1159 RTL_LOGFILE_CONTEXT( aLog
, "linguistic: LngSvcMgr::SetCfgServiceLists - Grammar" );
1161 String
aNode( String::CreateFromAscii( "ServiceManager/GrammarCheckerList" ) );
1162 uno::Sequence
< OUString
> aNames( /*aCfg.*/GetNodeNames( aNode
) );
1163 OUString
*pNames
= aNames
.getArray();
1164 INT32 nLen
= aNames
.getLength();
1166 // append path prefix need for 'GetProperties' call below
1167 String
aPrefix( aNode
);
1168 aPrefix
.Append( (sal_Unicode
) '/' );
1169 for (int i
= 0; i
< nLen
; ++i
)
1171 OUString
aTmp( aPrefix
);
1176 uno::Sequence
< uno::Any
> aValues( /*aCfg.*/GetProperties( aNames
) );
1177 if (nLen
&& nLen
== aValues
.getLength())
1179 const uno::Any
*pValues
= aValues
.getConstArray();
1180 for (INT32 i
= 0; i
< nLen
; ++i
)
1182 uno::Sequence
< OUString
> aSvcImplNames
;
1183 if (pValues
[i
] >>= aSvcImplNames
)
1185 // there should only be one grammar checker in use per language...
1186 if (aSvcImplNames
.getLength() > 1)
1187 aSvcImplNames
.realloc(1);
1189 #if OSL_DEBUG_LEVEL > 1
1190 // INT32 nSvcs = aSvcImplNames.getLength();
1191 // const OUString *pSvcImplNames = aSvcImplNames.getConstArray();
1193 String
aLocaleStr( pNames
[i
] );
1194 xub_StrLen nSeperatorPos
= aLocaleStr
.SearchBackward( sal_Unicode( '/' ) );
1195 aLocaleStr
= aLocaleStr
.Copy( nSeperatorPos
+ 1 );
1196 lang::Locale
aLocale( CreateLocale( MsLangId::convertIsoStringToLanguage(aLocaleStr
) ) );
1197 rGrammarDsp
.SetServiceList( aLocale
, aSvcImplNames
);
1204 void LngSvcMgr::SetCfgServiceLists( HyphenatorDispatcher
&rHyphDsp
)
1206 RTL_LOGFILE_CONTEXT( aLog
, "linguistic: LngSvcMgr::SetCfgServiceLists - Hyph" );
1208 String
aNode( String::CreateFromAscii( "ServiceManager/HyphenatorList" ) );
1209 uno::Sequence
< OUString
> aNames( /*aCfg.*/GetNodeNames( aNode
) );
1210 OUString
*pNames
= aNames
.getArray();
1211 INT32 nLen
= aNames
.getLength();
1213 // append path prefix need for 'GetProperties' call below
1214 String
aPrefix( aNode
);
1215 aPrefix
.Append( (sal_Unicode
) '/' );
1216 for (int i
= 0; i
< nLen
; ++i
)
1218 OUString
aTmp( aPrefix
);
1223 uno::Sequence
< uno::Any
> aValues( /*aCfg.*/GetProperties( aNames
) );
1224 if (nLen
&& nLen
== aValues
.getLength())
1226 const uno::Any
*pValues
= aValues
.getConstArray();
1227 for (INT32 i
= 0; i
< nLen
; ++i
)
1229 uno::Sequence
< OUString
> aSvcImplNames
;
1230 if (pValues
[i
] >>= aSvcImplNames
)
1232 // there should only be one hyphenator in use per language...
1233 if (aSvcImplNames
.getLength() > 1)
1234 aSvcImplNames
.realloc(1);
1236 #if OSL_DEBUG_LEVEL > 1
1237 // INT32 nSvcs = aSvcImplNames.getLength();
1238 // const OUString *pSvcImplNames = aSvcImplNames.getConstArray();
1240 String
aLocaleStr( pNames
[i
] );
1241 xub_StrLen nSeperatorPos
= aLocaleStr
.SearchBackward( sal_Unicode( '/' ) );
1242 aLocaleStr
= aLocaleStr
.Copy( nSeperatorPos
+ 1 );
1243 lang::Locale
aLocale( CreateLocale( MsLangId::convertIsoStringToLanguage(aLocaleStr
) ) );
1244 rHyphDsp
.SetServiceList( aLocale
, aSvcImplNames
);
1251 void LngSvcMgr::SetCfgServiceLists( ThesaurusDispatcher
&rThesDsp
)
1253 RTL_LOGFILE_CONTEXT( aLog
, "linguistic: LngSvcMgr::SetCfgServiceLists - Thes" );
1255 String
aNode( String::CreateFromAscii( "ServiceManager/ThesaurusList" ) );
1256 uno::Sequence
< OUString
> aNames( /*aCfg.*/GetNodeNames( aNode
) );
1257 OUString
*pNames
= aNames
.getArray();
1258 INT32 nLen
= aNames
.getLength();
1260 // append path prefix need for 'GetProperties' call below
1261 String
aPrefix( aNode
);
1262 aPrefix
.Append( (sal_Unicode
) '/' );
1263 for (int i
= 0; i
< nLen
; ++i
)
1265 OUString
aTmp( aPrefix
);
1270 uno::Sequence
< uno::Any
> aValues( /*aCfg.*/GetProperties( aNames
) );
1271 if (nLen
&& nLen
== aValues
.getLength())
1273 const uno::Any
*pValues
= aValues
.getConstArray();
1274 for (INT32 i
= 0; i
< nLen
; ++i
)
1276 uno::Sequence
< OUString
> aSvcImplNames
;
1277 if (pValues
[i
] >>= aSvcImplNames
)
1279 #if OSL_DEBUG_LEVEL > 1
1280 // INT32 nSvcs = aSvcImplNames.getLength();
1281 // const OUString *pSvcImplNames = aSvcImplNames.getConstArray();
1283 String
aLocaleStr( pNames
[i
] );
1284 xub_StrLen nSeperatorPos
= aLocaleStr
.SearchBackward( sal_Unicode( '/' ) );
1285 aLocaleStr
= aLocaleStr
.Copy( nSeperatorPos
+ 1 );
1286 lang::Locale
aLocale( CreateLocale( MsLangId::convertIsoStringToLanguage(aLocaleStr
) ) );
1287 rThesDsp
.SetServiceList( aLocale
, aSvcImplNames
);
1294 uno::Reference
< linguistic2::XSpellChecker
> SAL_CALL
1295 LngSvcMgr::getSpellChecker()
1296 throw(uno::RuntimeException
)
1298 osl::MutexGuard
aGuard( GetLinguMutex() );
1299 #if OSL_DEBUG_LEVEL > 1
1300 getAvailableLocales( A2OU( SN_SPELLCHECKER
));
1303 uno::Reference
< linguistic2::XSpellChecker
> xRes
;
1306 if (!xSpellDsp
.is())
1307 GetSpellCheckerDsp_Impl();
1314 uno::Reference
< linguistic2::XHyphenator
> SAL_CALL
1315 LngSvcMgr::getHyphenator()
1316 throw(uno::RuntimeException
)
1318 osl::MutexGuard
aGuard( GetLinguMutex() );
1319 #if OSL_DEBUG_LEVEL > 1
1320 getAvailableLocales( A2OU( SN_HYPHENATOR
));
1323 uno::Reference
< linguistic2::XHyphenator
> xRes
;
1327 GetHyphenatorDsp_Impl();
1334 uno::Reference
< linguistic2::XThesaurus
> SAL_CALL
1335 LngSvcMgr::getThesaurus()
1336 throw(uno::RuntimeException
)
1338 osl::MutexGuard
aGuard( GetLinguMutex() );
1339 #if OSL_DEBUG_LEVEL > 1
1340 getAvailableLocales( A2OU( SN_THESAURUS
));
1343 uno::Reference
< linguistic2::XThesaurus
> xRes
;
1347 GetThesaurusDsp_Impl();
1355 LngSvcMgr::addLinguServiceManagerListener(
1356 const uno::Reference
< lang::XEventListener
>& xListener
)
1357 throw(uno::RuntimeException
)
1359 osl::MutexGuard
aGuard( GetLinguMutex() );
1362 if (!bDisposing
&& xListener
.is())
1364 if (!pListenerHelper
)
1365 GetListenerHelper_Impl();
1366 bRes
= pListenerHelper
->AddLngSvcMgrListener( xListener
);
1373 LngSvcMgr::removeLinguServiceManagerListener(
1374 const uno::Reference
< lang::XEventListener
>& xListener
)
1375 throw(uno::RuntimeException
)
1377 osl::MutexGuard
aGuard( GetLinguMutex() );
1380 if (!bDisposing
&& xListener
.is())
1382 DBG_ASSERT( pListenerHelper
, "listener removed without being added" );
1383 if (!pListenerHelper
)
1384 GetListenerHelper_Impl();
1385 bRes
= pListenerHelper
->RemoveLngSvcMgrListener( xListener
);
1391 uno::Sequence
< OUString
> SAL_CALL
1392 LngSvcMgr::getAvailableServices(
1393 const OUString
& rServiceName
,
1394 const lang::Locale
& rLocale
)
1395 throw(uno::RuntimeException
)
1397 osl::MutexGuard
aGuard( GetLinguMutex() );
1399 uno::Sequence
< OUString
> aRes
;
1400 const SvcInfoArray
*pInfoArray
= 0;
1402 if (0 == rServiceName
.compareToAscii( SN_SPELLCHECKER
))
1404 // don't used cached data here (force re-evaluation in order to have downloaded dictionaries
1405 // already found without the need to restart the office
1406 delete pAvailSpellSvcs
; pAvailSpellSvcs
= 0;
1407 GetAvailableSpellSvcs_Impl();
1408 pInfoArray
= pAvailSpellSvcs
;
1410 else if (0 == rServiceName
.compareToAscii( SN_GRAMMARCHECKER
))
1412 // don't used cached data here (force re-evaluation in order to have downloaded dictionaries
1413 // already found without the need to restart the office
1414 delete pAvailGrammarSvcs
; pAvailGrammarSvcs
= 0;
1415 GetAvailableGrammarSvcs_Impl();
1416 pInfoArray
= pAvailGrammarSvcs
;
1418 else if (0 == rServiceName
.compareToAscii( SN_HYPHENATOR
))
1420 // don't used cached data here (force re-evaluation in order to have downloaded dictionaries
1421 // already found without the need to restart the office
1422 delete pAvailHyphSvcs
; pAvailHyphSvcs
= 0;
1423 GetAvailableHyphSvcs_Impl();
1424 pInfoArray
= pAvailHyphSvcs
;
1426 else if (0 == rServiceName
.compareToAscii( SN_THESAURUS
))
1428 // don't used cached data here (force re-evaluation in order to have downloaded dictionaries
1429 // already found without the need to restart the office
1430 delete pAvailThesSvcs
; pAvailThesSvcs
= 0;
1431 GetAvailableThesSvcs_Impl();
1432 pInfoArray
= pAvailThesSvcs
;
1437 // resize to max number of entries
1438 size_t nMaxCnt
= pInfoArray
->size();
1439 aRes
.realloc( nMaxCnt
);
1440 OUString
*pImplName
= aRes
.getArray();
1443 LanguageType nLanguage
= LocaleToLanguage( rLocale
);
1444 for (size_t i
= 0; i
< nMaxCnt
; ++i
)
1446 const SvcInfo
*pInfo
= (*pInfoArray
)[i
];
1447 if (LANGUAGE_NONE
== nLanguage
1448 || (pInfo
&& pInfo
->HasLanguage( nLanguage
)))
1450 pImplName
[ nCnt
++ ] = pInfo
->aSvcImplName
;
1454 // resize to actual number of entries
1455 if (nCnt
!= nMaxCnt
)
1456 aRes
.realloc( nCnt
);
1463 uno::Sequence
< lang::Locale
> SAL_CALL
1464 LngSvcMgr::getAvailableLocales(
1465 const OUString
& rServiceName
)
1466 throw(uno::RuntimeException
)
1468 osl::MutexGuard
aGuard( GetLinguMutex() );
1470 uno::Sequence
< lang::Locale
> aRes
;
1472 uno::Sequence
< lang::Locale
> *pAvailLocales
= NULL
;
1473 BOOL
*pHasAvailLocales
= NULL
;
1474 if (0 == rServiceName
.compareToAscii( SN_SPELLCHECKER
))
1476 pAvailLocales
= &aAvailSpellLocales
;
1477 pHasAvailLocales
= &bHasAvailSpellLocales
;
1479 else if (0 == rServiceName
.compareToAscii( SN_GRAMMARCHECKER
))
1481 pAvailLocales
= &aAvailGrammarLocales
;
1482 pHasAvailLocales
= &bHasAvailGrammarLocales
;
1484 else if (0 == rServiceName
.compareToAscii( SN_HYPHENATOR
))
1486 pAvailLocales
= &aAvailHyphLocales
;
1487 pHasAvailLocales
= &bHasAvailHyphLocales
;
1489 else if (0 == rServiceName
.compareToAscii( SN_THESAURUS
))
1491 pAvailLocales
= &aAvailThesLocales
;
1492 pHasAvailLocales
= &bHasAvailThesLocales
;
1495 // about pHasAvailLocales: nowadays (with OOo lingu in SO) we want to know immediately about
1496 // new downloaded dictionaries and have them ready right away if the Tools/Options...
1497 // is used to activate them. Thus we can not rely anymore on buffered data.
1498 if (pAvailLocales
/*&& pHasAvailLocales */)
1500 // if (!*pHasAvailLocales)
1502 *pAvailLocales
= GetAvailLocales(
1503 getAvailableServices( rServiceName
, lang::Locale() ) );
1504 // *pHasAvailLocales = TRUE;
1506 aRes
= *pAvailLocales
;
1512 static BOOL
IsEqSvcList( const uno::Sequence
< OUString
> &rList1
,
1513 const uno::Sequence
< OUString
> &rList2
)
1515 // returns TRUE iff both sequences are equal
1518 INT32 nLen
= rList1
.getLength();
1519 if (rList2
.getLength() == nLen
)
1521 const OUString
*pStr1
= rList1
.getConstArray();
1522 const OUString
*pStr2
= rList2
.getConstArray();
1524 for (INT32 i
= 0; i
< nLen
&& bRes
; ++i
)
1526 if (*pStr1
++ != *pStr2
++)
1535 LngSvcMgr::setConfiguredServices(
1536 const OUString
& rServiceName
,
1537 const lang::Locale
& rLocale
,
1538 const uno::Sequence
< OUString
>& rServiceImplNames
)
1539 throw(uno::RuntimeException
)
1541 RTL_LOGFILE_CONTEXT( aLog
, "linguistic: LngSvcMgr::setConfiguredServices" );
1543 osl::MutexGuard
aGuard( GetLinguMutex() );
1545 #if OSL_DEBUG_LEVEL > 1
1546 // const OUString *pImplNames = rServiceImplNames.getConstArray();
1549 LanguageType nLanguage
= LocaleToLanguage( rLocale
);
1550 if (LANGUAGE_NONE
!= nLanguage
)
1552 if (0 == rServiceName
.compareToAscii( SN_SPELLCHECKER
))
1554 if (!xSpellDsp
.is())
1555 GetSpellCheckerDsp_Impl();
1556 BOOL bChanged
= !IsEqSvcList( rServiceImplNames
,
1557 pSpellDsp
->GetServiceList( rLocale
) );
1560 pSpellDsp
->SetServiceList( rLocale
, rServiceImplNames
);
1561 SaveCfgSvcs( A2OU( SN_SPELLCHECKER
) );
1563 if (pListenerHelper
&& bChanged
)
1564 pListenerHelper
->AddLngSvcEvt(
1565 linguistic2::LinguServiceEventFlags::SPELL_CORRECT_WORDS_AGAIN
|
1566 linguistic2::LinguServiceEventFlags::SPELL_WRONG_WORDS_AGAIN
);
1569 else if (0 == rServiceName
.compareToAscii( SN_GRAMMARCHECKER
))
1571 if (!xGrammarDsp
.is())
1572 GetGrammarCheckerDsp_Impl();
1573 BOOL bChanged
= !IsEqSvcList( rServiceImplNames
,
1574 pGrammarDsp
->GetServiceList( rLocale
) );
1577 pGrammarDsp
->SetServiceList( rLocale
, rServiceImplNames
);
1578 SaveCfgSvcs( A2OU( SN_GRAMMARCHECKER
) );
1580 if (pListenerHelper
&& bChanged
)
1581 pListenerHelper
->AddLngSvcEvt(
1582 linguistic2::LinguServiceEventFlags::PROOFREAD_AGAIN
);
1585 else if (0 == rServiceName
.compareToAscii( SN_HYPHENATOR
))
1588 GetHyphenatorDsp_Impl();
1589 BOOL bChanged
= !IsEqSvcList( rServiceImplNames
,
1590 pHyphDsp
->GetServiceList( rLocale
) );
1593 pHyphDsp
->SetServiceList( rLocale
, rServiceImplNames
);
1594 SaveCfgSvcs( A2OU( SN_HYPHENATOR
) );
1596 if (pListenerHelper
&& bChanged
)
1597 pListenerHelper
->AddLngSvcEvt(
1598 linguistic2::LinguServiceEventFlags::HYPHENATE_AGAIN
);
1601 else if (0 == rServiceName
.compareToAscii( SN_THESAURUS
))
1604 GetThesaurusDsp_Impl();
1605 BOOL bChanged
= !IsEqSvcList( rServiceImplNames
,
1606 pThesDsp
->GetServiceList( rLocale
) );
1609 pThesDsp
->SetServiceList( rLocale
, rServiceImplNames
);
1610 SaveCfgSvcs( A2OU( SN_THESAURUS
) );
1617 BOOL
LngSvcMgr::SaveCfgSvcs( const String
&rServiceName
)
1619 RTL_LOGFILE_CONTEXT( aLog
, "linguistic: LngSvcMgr::SaveCfgSvcs" );
1623 LinguDispatcher
*pDsp
= 0;
1624 uno::Sequence
< lang::Locale
> aLocales
;
1626 if (0 == rServiceName
.CompareToAscii( SN_SPELLCHECKER
))
1629 GetSpellCheckerDsp_Impl();
1631 aLocales
= getAvailableLocales( A2OU( SN_SPELLCHECKER
) );
1633 else if (0 == rServiceName
.CompareToAscii( SN_GRAMMARCHECKER
))
1636 GetGrammarCheckerDsp_Impl();
1638 aLocales
= getAvailableLocales( A2OU( SN_GRAMMARCHECKER
) );
1640 else if (0 == rServiceName
.CompareToAscii( SN_HYPHENATOR
))
1643 GetHyphenatorDsp_Impl();
1645 aLocales
= getAvailableLocales( A2OU( SN_HYPHENATOR
) );
1647 else if (0 == rServiceName
.CompareToAscii( SN_THESAURUS
))
1650 GetThesaurusDsp_Impl();
1652 aLocales
= getAvailableLocales( A2OU( SN_THESAURUS
) );
1655 if (pDsp
&& aLocales
.getLength())
1657 INT32 nLen
= aLocales
.getLength();
1658 const lang::Locale
*pLocale
= aLocales
.getConstArray();
1660 uno::Sequence
< beans::PropertyValue
> aValues( nLen
);
1661 beans::PropertyValue
*pValues
= aValues
.getArray();
1662 beans::PropertyValue
*pValue
= pValues
;
1664 // get node name to be used
1665 const char *pNodeName
= NULL
;
1666 if (pDsp
== pSpellDsp
)
1667 pNodeName
= "ServiceManager/SpellCheckerList";
1668 else if (pDsp
== pGrammarDsp
)
1669 pNodeName
= "ServiceManager/GrammarCheckerList";
1670 else if (pDsp
== pHyphDsp
)
1671 pNodeName
= "ServiceManager/HyphenatorList";
1672 else if (pDsp
== pThesDsp
)
1673 pNodeName
= "ServiceManager/ThesaurusList";
1676 DBG_ASSERT( 0, "node name missing" );
1678 OUString
aNodeName( A2OU(pNodeName
) );
1680 for (INT32 i
= 0; i
< nLen
; ++i
)
1682 uno::Sequence
< OUString
> aSvcImplNames
;
1683 aSvcImplNames
= pDsp
->GetServiceList( pLocale
[i
] );
1685 #if OSL_DEBUG_LEVEL > 1
1686 INT32 nSvcs
= aSvcImplNames
.getLength();
1687 const OUString
*pSvcImplName
= aSvcImplNames
.getConstArray();
1688 for (INT32 j
= 0; j
< nSvcs
; ++j
)
1690 OUString
aImplName( pSvcImplName
[j
] );
1693 // build value to be written back to configuration
1695 if ((pDsp
== pHyphDsp
|| pDsp
== pGrammarDsp
) && aSvcImplNames
.getLength() > 1)
1696 aSvcImplNames
.realloc(1); // there should be only one entry for hyphenators or grammar checkers (because they are not chained)
1697 aCfgAny
<<= aSvcImplNames
;
1698 DBG_ASSERT( aCfgAny
.hasValue(), "missing value for 'Any' type" );
1700 OUString
aCfgLocaleStr( MsLangId::convertLanguageToIsoString(
1701 LocaleToLanguage( pLocale
[i
] ) ) );
1702 pValue
->Value
= aCfgAny
;
1703 pValue
->Name
= aNodeName
;
1704 pValue
->Name
+= OUString::valueOf( (sal_Unicode
) '/' );
1705 pValue
->Name
+= aCfgLocaleStr
;
1709 RTL_LOGFILE_CONTEXT( aLog
, "linguistic: LngSvcMgr::SaveCfgSvcs - ReplaceSetProperties" );
1710 // change, add new or replace existing entries.
1711 bRes
|= /*aCfg.*/ReplaceSetProperties( aNodeName
, aValues
);
1719 static uno::Sequence
< OUString
> GetLangSvcList( const uno::Any
&rVal
)
1721 uno::Sequence
< OUString
> aRes
;
1723 if (rVal
.hasValue())
1726 #if OSL_DEBUG_LEVEL > 1
1727 INT32 nSvcs
= aRes
.getLength();
1730 const OUString
*pSvcName
= aRes
.getConstArray();
1731 for (INT32 j
= 0; j
< nSvcs
; ++j
)
1733 OUString
aImplName( pSvcName
[j
] );
1734 DBG_ASSERT( aImplName
.getLength(), "service impl-name missing" );
1744 static uno::Sequence
< OUString
> GetLangSvc( const uno::Any
&rVal
)
1746 uno::Sequence
< OUString
> aRes
;
1747 if (!rVal
.hasValue())
1750 // allowing for a sequence here as well (even though it should only
1751 // be a string) makes coding easier in other places since one needs
1752 // not make a special case for writing a string only and not a
1753 // sequence of strings.
1756 // but only the first string should be used.
1757 if (aRes
.getLength() > 1)
1763 if ((rVal
>>= aImplName
) && aImplName
.getLength() != 0)
1766 aRes
.getArray()[0] = aImplName
;
1770 DBG_ASSERT( 0, "GetLangSvc: unexpected type encountered" );
1778 ///////////////////////////////////////////////////////////////////////////
1780 uno::Sequence
< OUString
> SAL_CALL
1781 LngSvcMgr::getConfiguredServices(
1782 const OUString
& rServiceName
,
1783 const lang::Locale
& rLocale
)
1784 throw(uno::RuntimeException
)
1786 osl::MutexGuard
aGuard( GetLinguMutex() );
1788 uno::Sequence
< OUString
> aSvcImplNames
;
1790 LanguageType nLanguage
= LocaleToLanguage( rLocale
);
1791 OUString
aCfgLocale( MsLangId::convertLanguageToIsoString( nLanguage
) );
1793 uno::Sequence
< uno::Any
> aValues
;
1794 uno::Sequence
< OUString
> aNames( 1 );
1795 OUString
*pNames
= aNames
.getArray();
1796 if ( 0 == rServiceName
.compareToAscii( SN_SPELLCHECKER
) )
1798 OUString
aNode( OUString::createFromAscii( "ServiceManager/SpellCheckerList" ));
1799 const uno::Sequence
< OUString
> aNodeEntries( GetNodeNames( aNode
) );
1800 if (lcl_SeqHasString( aNodeEntries
, aCfgLocale
))
1802 OUString
aPropName( aNode
);
1803 aPropName
+= OUString::valueOf( (sal_Unicode
) '/' );
1804 aPropName
+= aCfgLocale
;
1805 pNames
[0] = aPropName
;
1806 aValues
= /*aCfg.*/GetProperties( aNames
);
1807 if (aValues
.getLength())
1808 aSvcImplNames
= GetLangSvcList( aValues
.getConstArray()[0] );
1811 else if ( 0 == rServiceName
.compareToAscii( SN_GRAMMARCHECKER
) )
1813 OUString
aNode( OUString::createFromAscii( "ServiceManager/GrammarCheckerList" ));
1814 const uno::Sequence
< OUString
> aNodeEntries( GetNodeNames( aNode
) );
1815 if (lcl_SeqHasString( aNodeEntries
, aCfgLocale
))
1817 OUString
aPropName( aNode
);
1818 aPropName
+= OUString::valueOf( (sal_Unicode
) '/' );
1819 aPropName
+= aCfgLocale
;
1820 pNames
[0] = aPropName
;
1821 aValues
= /*aCfg.*/GetProperties( aNames
);
1822 if (aValues
.getLength())
1823 aSvcImplNames
= GetLangSvc( aValues
.getConstArray()[0] );
1826 else if ( 0 == rServiceName
.compareToAscii( SN_HYPHENATOR
) )
1828 OUString
aNode( OUString::createFromAscii( "ServiceManager/HyphenatorList" ));
1829 const uno::Sequence
< OUString
> aNodeEntries( GetNodeNames( aNode
) );
1830 if (lcl_SeqHasString( aNodeEntries
, aCfgLocale
))
1832 OUString
aPropName( aNode
);
1833 aPropName
+= OUString::valueOf( (sal_Unicode
) '/' );
1834 aPropName
+= aCfgLocale
;
1835 pNames
[0] = aPropName
;
1836 aValues
= /*aCfg.*/GetProperties( aNames
);
1837 if (aValues
.getLength())
1838 aSvcImplNames
= GetLangSvc( aValues
.getConstArray()[0] );
1841 else if ( 0 == rServiceName
.compareToAscii( SN_THESAURUS
) )
1843 OUString
aNode( OUString::createFromAscii( "ServiceManager/ThesaurusList" ));
1844 const uno::Sequence
< OUString
> aNodeEntries( GetNodeNames( aNode
) );
1845 if (lcl_SeqHasString( aNodeEntries
, aCfgLocale
))
1847 OUString
aPropName( aNode
);
1848 aPropName
+= OUString::valueOf( (sal_Unicode
) '/' );
1849 aPropName
+= aCfgLocale
;
1850 pNames
[0] = aPropName
;
1851 aValues
= /*aCfg.*/GetProperties( aNames
);
1852 if (aValues
.getLength())
1853 aSvcImplNames
= GetLangSvcList( aValues
.getConstArray()[0] );
1857 #if OSL_DEBUG_LEVEL > 1
1858 const OUString
*pImplNames
= aSvcImplNames
.getConstArray();
1861 return aSvcImplNames
;
1866 LngSvcMgr::dispose()
1867 throw(uno::RuntimeException
)
1869 osl::MutexGuard
aGuard( GetLinguMutex() );
1875 // require listeners to release this object
1876 lang::EventObject
aEvtObj( (XLinguServiceManager
*) this );
1877 aEvtListeners
.disposeAndClear( aEvtObj
);
1879 if (pListenerHelper
)
1880 pListenerHelper
->DisposeAndClear( aEvtObj
);
1886 LngSvcMgr::addEventListener(
1887 const uno::Reference
< lang::XEventListener
>& xListener
)
1888 throw(uno::RuntimeException
)
1890 osl::MutexGuard
aGuard( GetLinguMutex() );
1892 if (!bDisposing
&& xListener
.is())
1894 aEvtListeners
.addInterface( xListener
);
1900 LngSvcMgr::removeEventListener(
1901 const uno::Reference
< lang::XEventListener
>& xListener
)
1902 throw(uno::RuntimeException
)
1904 osl::MutexGuard
aGuard( GetLinguMutex() );
1908 aEvtListeners
.removeInterface( xListener
);
1913 BOOL
LngSvcMgr::AddLngSvcEvtBroadcaster(
1914 const uno::Reference
< linguistic2::XLinguServiceEventBroadcaster
> &rxBroadcaster
)
1917 if (rxBroadcaster
.is())
1919 if (!pListenerHelper
)
1920 GetListenerHelper_Impl();
1921 bRes
= pListenerHelper
->AddLngSvcEvtBroadcaster( rxBroadcaster
);
1927 BOOL
LngSvcMgr::RemoveLngSvcEvtBroadcaster(
1928 const uno::Reference
< linguistic2::XLinguServiceEventBroadcaster
> &rxBroadcaster
)
1931 if (rxBroadcaster
.is())
1933 DBG_ASSERT( pListenerHelper
, "pListenerHelper non existent" );
1934 if (!pListenerHelper
)
1935 GetListenerHelper_Impl();
1936 bRes
= pListenerHelper
->RemoveLngSvcEvtBroadcaster( rxBroadcaster
);
1943 LngSvcMgr::getImplementationName()
1944 throw(uno::RuntimeException
)
1946 osl::MutexGuard
aGuard( GetLinguMutex() );
1947 return getImplementationName_Static();
1952 LngSvcMgr::supportsService( const OUString
& ServiceName
)
1953 throw(uno::RuntimeException
)
1955 osl::MutexGuard
aGuard( GetLinguMutex() );
1957 uno::Sequence
< OUString
> aSNL
= getSupportedServiceNames();
1958 const OUString
* pArray
= aSNL
.getConstArray();
1959 for( INT32 i
= 0; i
< aSNL
.getLength(); i
++ )
1960 if( pArray
[i
] == ServiceName
)
1966 uno::Sequence
< OUString
> SAL_CALL
1967 LngSvcMgr::getSupportedServiceNames()
1968 throw(uno::RuntimeException
)
1970 osl::MutexGuard
aGuard( GetLinguMutex() );
1971 return getSupportedServiceNames_Static();
1975 uno::Sequence
< OUString
> LngSvcMgr::getSupportedServiceNames_Static()
1978 osl::MutexGuard
aGuard( GetLinguMutex() );
1980 uno::Sequence
< OUString
> aSNS( 1 ); // auch mehr als 1 Service moeglich
1981 aSNS
.getArray()[0] = A2OU( SN_LINGU_SERVCICE_MANAGER
);
1986 uno::Reference
< uno::XInterface
> SAL_CALL
LngSvcMgr_CreateInstance(
1987 const uno::Reference
< lang::XMultiServiceFactory
> & /*rSMgr*/ )
1988 throw(uno::Exception
)
1990 uno::Reference
< uno::XInterface
> xService
= (cppu::OWeakObject
*) new LngSvcMgr
;
1996 sal_Bool SAL_CALL
LngSvcMgr_writeInfo(
1997 void * /*pServiceManager*/,
1998 registry::XRegistryKey
* pRegistryKey
)
2002 String
aImpl( '/' );
2003 aImpl
+= LngSvcMgr::getImplementationName_Static().getStr();
2004 aImpl
.AppendAscii( "/UNO/SERVICES" );
2005 uno::Reference
< registry::XRegistryKey
> xNewKey
=
2006 pRegistryKey
->createKey( aImpl
);
2007 uno::Sequence
< OUString
> aServices
= LngSvcMgr::getSupportedServiceNames_Static();
2008 for( INT32 i
= 0; i
< aServices
.getLength(); i
++ )
2009 xNewKey
->createKey( aServices
.getConstArray()[i
] );
2013 catch(uno::Exception
&)
2019 void * SAL_CALL
LngSvcMgr_getFactory(
2020 const sal_Char
* pImplName
,
2021 lang::XMultiServiceFactory
* pServiceManager
,
2022 void * /*pRegistryKey*/ )
2026 if ( !LngSvcMgr::getImplementationName_Static().compareToAscii( pImplName
) )
2028 uno::Reference
< lang::XSingleServiceFactory
> xFactory
=
2029 cppu::createOneInstanceFactory(
2031 LngSvcMgr::getImplementationName_Static(),
2032 LngSvcMgr_CreateInstance
,
2033 LngSvcMgr::getSupportedServiceNames_Static());
2034 // acquire, because we return an interface pointer instead of a reference
2035 xFactory
->acquire();
2036 pRet
= xFactory
.get();
2042 ///////////////////////////////////////////////////////////////////////////