xref: /trunk/main/linguistic/source/convdiclist.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_linguistic.hxx"
26 
27 #include <tools/fsys.hxx>
28 #include <tools/stream.hxx>
29 #include <tools/urlobj.hxx>
30 #include <unotools/pathoptions.hxx>
31 #include <unotools/useroptions.hxx>
32 #include <unotools/lingucfg.hxx>
33 #include <rtl/instance.hxx>
34 #include <cppuhelper/factory.hxx>   // helper for factories
35 #include <unotools/localfilehelper.hxx>
36 #include <com/sun/star/linguistic2/XConversionDictionaryList.hpp>
37 #include <com/sun/star/linguistic2/XConversionDictionary.hpp>
38 #include <com/sun/star/linguistic2/ConversionDictionaryType.hpp>
39 #include <com/sun/star/util/XFlushable.hpp>
40 #include <com/sun/star/lang/Locale.hpp>
41 #ifndef _COM_SUN_STAR_UNO_REFERENCE_HPP_
42 #include <com/sun/star/uno/Reference.h>
43 #endif
44 #include <com/sun/star/registry/XRegistryKey.hpp>
45 #include <com/sun/star/container/XNameContainer.hpp>
46 
47 #include <ucbhelper/content.hxx>
48 
49 #include "convdiclist.hxx"
50 #include "convdic.hxx"
51 #include "hhconvdic.hxx"
52 #include "linguistic/misc.hxx"
53 #include "defs.hxx"
54 
55 //using namespace utl;
56 using namespace osl;
57 using namespace rtl;
58 using namespace com::sun::star;
59 using namespace com::sun::star::lang;
60 using namespace com::sun::star::uno;
61 using namespace com::sun::star::container;
62 using namespace com::sun::star::linguistic2;
63 using namespace linguistic;
64 
65 #define SN_CONV_DICTIONARY_LIST  "com.sun.star.linguistic2.ConversionDictionaryList"
66 
67 
68 ///////////////////////////////////////////////////////////////////////////
69 
operator ==(const Locale & r1,const Locale & r2)70 bool operator == ( const Locale &r1, const Locale &r2 )
71 {
72     return  r1.Language == r2.Language &&
73             r1.Country  == r2.Country  &&
74             r1.Variant  == r2.Variant;
75 }
76 
77 ///////////////////////////////////////////////////////////////////////////
78 
GetConvDicMainURL(const String & rDicName,const String & rDirectoryURL)79 String GetConvDicMainURL( const String &rDicName, const String &rDirectoryURL )
80 {
81     // build URL to use for new (persistent) dictionaries
82 
83     String aFullDicName( rDicName );
84     aFullDicName.AppendAscii( CONV_DIC_DOT_EXT );
85 
86     INetURLObject aURLObj;
87     aURLObj.SetSmartProtocol( INET_PROT_FILE );
88     aURLObj.SetSmartURL( rDirectoryURL );
89     aURLObj.Append( aFullDicName, INetURLObject::ENCODE_ALL );
90     DBG_ASSERT(!aURLObj.HasError(), "invalid URL");
91     if (aURLObj.HasError())
92         return String();
93     else
94         return aURLObj.GetMainURL( INetURLObject::DECODE_TO_IURI );
95 }
96 
97 ///////////////////////////////////////////////////////////////////////////
98 
99 class ConvDicNameContainer :
100     public cppu::WeakImplHelper1
101     <
102         ::com::sun::star::container::XNameContainer
103     >
104 {
105     uno::Sequence< uno::Reference< XConversionDictionary > >   aConvDics;
106     ConvDicList     &rConvDicList;
107 
108     // disallow copy-constructor and assignment-operator for now
109     ConvDicNameContainer(const ConvDicNameContainer &);
110     ConvDicNameContainer & operator = (const ConvDicNameContainer &);
111 
112     sal_Int32 GetIndexByName_Impl( const OUString& rName );
113 
114 public:
115     ConvDicNameContainer( ConvDicList &rMyConvDicList );
116     virtual ~ConvDicNameContainer();
117 
118     // XElementAccess
119     virtual ::com::sun::star::uno::Type SAL_CALL getElementType(  );
120     virtual sal_Bool SAL_CALL hasElements(  );
121 
122     // XNameAccess
123     virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName );
124     virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames(  );
125     virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName );
126 
127     // XNameReplace
128     virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const ::com::sun::star::uno::Any& aElement );
129 
130     // XNameContainer
131     virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const ::com::sun::star::uno::Any& aElement );
132     virtual void SAL_CALL removeByName( const ::rtl::OUString& Name );
133 
134 
135     // looks for conversion dictionaries with the specified extension
136     // in the directory and adds them to the container
137     void AddConvDics( const String &rSearchDirPathURL, const String &rExtension );
138 
139     // calls Flush for the dictionaries that support XFlushable
140     void    FlushDics() const;
141 
GetCount() const142     sal_Int32   GetCount() const    { return aConvDics.getLength(); }
143     uno::Reference< XConversionDictionary > GetByName( const OUString& rName );
144 
GetByIndex(sal_Int32 nIdx)145     const uno::Reference< XConversionDictionary >    GetByIndex( sal_Int32 nIdx )
146     {
147         return aConvDics.getConstArray()[nIdx];
148     }
149 };
150 
151 
ConvDicNameContainer(ConvDicList & rMyConvDicList)152 ConvDicNameContainer::ConvDicNameContainer( ConvDicList &rMyConvDicList ) :
153     rConvDicList( rMyConvDicList )
154 {
155 }
156 
157 
~ConvDicNameContainer()158 ConvDicNameContainer::~ConvDicNameContainer()
159 {
160 }
161 
162 
FlushDics() const163 void ConvDicNameContainer::FlushDics() const
164 {
165     sal_Int32 nLen = aConvDics.getLength();
166     const uno::Reference< XConversionDictionary > *pDic = aConvDics.getConstArray();
167     for (sal_Int32 i = 0;  i < nLen;  ++i)
168     {
169         uno::Reference< util::XFlushable > xFlush( pDic[i] , UNO_QUERY );
170         if (xFlush.is())
171         {
172             try
173             {
174                 xFlush->flush();
175             }
176             catch(Exception &)
177             {
178                 DBG_ERROR( "flushing of conversion dictionary failed" );
179             }
180         }
181     }
182 }
183 
184 
GetIndexByName_Impl(const OUString & rName)185 sal_Int32 ConvDicNameContainer::GetIndexByName_Impl(
186         const OUString& rName )
187 {
188     sal_Int32 nRes = -1;
189     sal_Int32 nLen = aConvDics.getLength();
190     const uno::Reference< XConversionDictionary > *pDic = aConvDics.getConstArray();
191     for (sal_Int32 i = 0;  i < nLen && nRes == -1;  ++i)
192     {
193         if (rName == pDic[i]->getName())
194             nRes = i;
195     }
196     return nRes;
197 }
198 
199 
GetByName(const OUString & rName)200 uno::Reference< XConversionDictionary > ConvDicNameContainer::GetByName(
201         const OUString& rName )
202 {
203     uno::Reference< XConversionDictionary > xRes;
204     sal_Int32 nIdx = GetIndexByName_Impl( rName );
205     if ( nIdx != -1)
206         xRes = aConvDics.getArray()[nIdx];
207     return xRes;
208 }
209 
210 
getElementType()211 uno::Type SAL_CALL ConvDicNameContainer::getElementType(  )
212 {
213     MutexGuard  aGuard( GetLinguMutex() );
214     return uno::Type( ::getCppuType( (uno::Reference< XConversionDictionary > *) 0) );
215 }
216 
217 
hasElements()218 sal_Bool SAL_CALL ConvDicNameContainer::hasElements(  )
219 {
220     MutexGuard  aGuard( GetLinguMutex() );
221     return aConvDics.getLength() > 0;
222 }
223 
224 
getByName(const OUString & rName)225 uno::Any SAL_CALL ConvDicNameContainer::getByName( const OUString& rName )
226 {
227     MutexGuard  aGuard( GetLinguMutex() );
228     uno::Reference< XConversionDictionary > xRes( GetByName( rName ) );
229     if (!xRes.is())
230         throw NoSuchElementException();
231     return makeAny( xRes );
232 }
233 
234 
getElementNames()235 uno::Sequence< OUString > SAL_CALL ConvDicNameContainer::getElementNames(  )
236 {
237     MutexGuard  aGuard( GetLinguMutex() );
238 
239     sal_Int32 nLen = aConvDics.getLength();
240     uno::Sequence< OUString > aRes( nLen );
241     OUString *pName = aRes.getArray();
242     const uno::Reference< XConversionDictionary > *pDic = aConvDics.getConstArray();
243     for (sal_Int32 i = 0;  i < nLen;  ++i)
244         pName[i] = pDic[i]->getName();
245     return aRes;
246 }
247 
248 
hasByName(const OUString & rName)249 sal_Bool SAL_CALL ConvDicNameContainer::hasByName( const OUString& rName )
250 {
251     MutexGuard  aGuard( GetLinguMutex() );
252     return GetByName( rName ).is();
253 }
254 
255 
replaceByName(const OUString & rName,const uno::Any & rElement)256 void SAL_CALL ConvDicNameContainer::replaceByName(
257         const OUString& rName,
258         const uno::Any& rElement )
259 {
260     MutexGuard  aGuard( GetLinguMutex() );
261 
262     sal_Int32 nRplcIdx = GetIndexByName_Impl( rName );
263     if (nRplcIdx == -1)
264         throw NoSuchElementException();
265     uno::Reference< XConversionDictionary > xNew;
266     rElement >>= xNew;
267     if (!xNew.is() || xNew->getName() != rName)
268         throw IllegalArgumentException();
269     aConvDics.getArray()[ nRplcIdx ] = xNew;
270 }
271 
272 
insertByName(const OUString & rName,const Any & rElement)273 void SAL_CALL ConvDicNameContainer::insertByName(
274         const OUString& rName,
275         const Any& rElement )
276 {
277     MutexGuard  aGuard( GetLinguMutex() );
278 
279     if (GetByName( rName ).is())
280         throw ElementExistException();
281     uno::Reference< XConversionDictionary > xNew;
282     rElement >>= xNew;
283     if (!xNew.is() || xNew->getName() != rName)
284         throw IllegalArgumentException();
285 
286     sal_Int32 nLen = aConvDics.getLength();
287     aConvDics.realloc( nLen + 1 );
288     aConvDics.getArray()[ nLen ] = xNew;
289 }
290 
291 
removeByName(const OUString & rName)292 void SAL_CALL ConvDicNameContainer::removeByName( const OUString& rName )
293 {
294     MutexGuard  aGuard( GetLinguMutex() );
295 
296     sal_Int32 nRplcIdx = GetIndexByName_Impl( rName );
297     if (nRplcIdx == -1)
298         throw NoSuchElementException();
299 
300     // physically remove dictionary
301     uno::Reference< XConversionDictionary > xDel = aConvDics.getArray()[nRplcIdx];
302     String aName( xDel->getName() );
303     String aDicMainURL( GetConvDicMainURL( aName, GetDictionaryWriteablePath() ) );
304     INetURLObject aObj( aDicMainURL );
305     DBG_ASSERT( aObj.GetProtocol() == INET_PROT_FILE, "+HangulHanjaOptionsDialog::OkHdl(): non-file URLs cannot be deleted" );
306     if( aObj.GetProtocol() == INET_PROT_FILE )
307     {
308         try
309         {
310             ::ucbhelper::Content    aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ),
311                                     uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
312             aCnt.executeCommand( OUString::createFromAscii( "delete" ), makeAny( sal_Bool( sal_True ) ) );
313         }
314         catch( ::com::sun::star::ucb::CommandAbortedException& )
315         {
316             DBG_ERRORFILE( "HangulHanjaOptionsDialog::OkHdl(): CommandAbortedException" );
317         }
318         catch( ... )
319         {
320             DBG_ERRORFILE( "HangulHanjaOptionsDialog::OkHdl(): Any other exception" );
321         }
322     }
323 
324     sal_Int32 nLen = aConvDics.getLength();
325     uno::Reference< XConversionDictionary > *pDic = aConvDics.getArray();
326     for (sal_Int32 i = nRplcIdx;  i < nLen - 1;  ++i)
327         pDic[i] = pDic[i + 1];
328     aConvDics.realloc( nLen - 1 );
329 }
330 
331 
AddConvDics(const String & rSearchDirPathURL,const String & rExtension)332 void ConvDicNameContainer::AddConvDics(
333         const String &rSearchDirPathURL,
334         const String &rExtension )
335 {
336     const Sequence< OUString > aDirCnt(
337                 utl::LocalFileHelper::GetFolderContents( rSearchDirPathURL, sal_False ) );
338     const OUString *pDirCnt = aDirCnt.getConstArray();
339     sal_Int32 nEntries = aDirCnt.getLength();
340 
341     for (sal_Int32 i = 0;  i < nEntries;  ++i)
342     {
343         String  aURL( pDirCnt[i] );
344 
345         xub_StrLen nPos  = aURL.SearchBackward('.');
346         String  aExt(aURL.Copy(nPos + 1));
347         aExt.ToLowerAscii();
348         String  aSearchExt( rExtension );
349         aSearchExt.ToLowerAscii();
350         if(aExt != aSearchExt)
351             continue;          // skip other files
352 
353         sal_Int16 nLang;
354         sal_Int16 nConvType;
355         if (IsConvDic( aURL, nLang, nConvType ))
356         {
357             // get decoded dictionary file name
358             INetURLObject aURLObj( aURL );
359             String aDicName = aURLObj.getBase( INetURLObject::LAST_SEGMENT,
360                         true, INetURLObject::DECODE_WITH_CHARSET,
361                         RTL_TEXTENCODING_UTF8 );
362 
363             uno::Reference < XConversionDictionary > xDic;
364             if (nLang == LANGUAGE_KOREAN &&
365                 nConvType == ConversionDictionaryType::HANGUL_HANJA)
366             {
367                 xDic = new HHConvDic( aDicName, aURL );
368             }
369             else if ((nLang == LANGUAGE_CHINESE_SIMPLIFIED || nLang == LANGUAGE_CHINESE_TRADITIONAL) &&
370                       nConvType == ConversionDictionaryType::SCHINESE_TCHINESE)
371             {
372                 xDic = new ConvDic( aDicName, nLang, nConvType, sal_False, aURL );
373             }
374 
375             if (xDic.is())
376             {
377                 uno::Any aAny;
378                 aAny <<= xDic;
379                 insertByName( xDic->getName(), aAny );
380             }
381         }
382     }
383 }
384 
385 ///////////////////////////////////////////////////////////////////////////
386 
387 namespace
388 {
389     struct StaticConvDicList : public rtl::StaticWithInit<
390         uno::Reference<XInterface>, StaticConvDicList> {
operator ()__anone5a57b430111::StaticConvDicList391         uno::Reference<XInterface> operator () () {
392             return (cppu::OWeakObject *) new ConvDicList;
393         }
394     };
395 }
396 
397 
AtExit()398 void ConvDicList::MyAppExitListener::AtExit()
399 {
400     rMyDicList.FlushDics();
401     StaticConvDicList::get().clear();
402 }
403 
ConvDicList()404 ConvDicList::ConvDicList() :
405     aEvtListeners( GetLinguMutex() )
406 {
407     pNameContainer = 0;
408     bDisposing = sal_False;
409 
410     pExitListener = new MyAppExitListener( *this );
411     xExitListener = pExitListener;
412     pExitListener->Activate();
413 }
414 
415 
~ConvDicList()416 ConvDicList::~ConvDicList()
417 {
418     // NameContainer will deleted when the reference xNameContainer
419     // is destroyed.
420     // delete pNameContainer;
421 
422     if (!bDisposing && pNameContainer)
423         pNameContainer->FlushDics();
424 
425     pExitListener->Deactivate();
426 }
427 
428 
FlushDics()429 void ConvDicList::FlushDics()
430 {
431     // check only pointer to avoid creating the container when
432     // the dictionaries were not accessed yet
433     if (pNameContainer)
434         pNameContainer->FlushDics();
435 }
436 
437 
GetNameContainer()438 ConvDicNameContainer & ConvDicList::GetNameContainer()
439 {
440     if (!pNameContainer)
441     {
442         pNameContainer = new ConvDicNameContainer( *this );
443         pNameContainer->AddConvDics( GetDictionaryWriteablePath(),
444                                      A2OU( CONV_DIC_EXT ) );
445         xNameContainer = pNameContainer;
446 
447         // access list of text conversion dictionaries to activate
448         SvtLinguOptions aOpt;
449         SvtLinguConfig().GetOptions( aOpt );
450         sal_Int32 nLen = aOpt.aActiveConvDics.getLength();
451         const OUString *pActiveConvDics = aOpt.aActiveConvDics.getConstArray();
452         for (sal_Int32 i = 0;  i < nLen;  ++i)
453         {
454             uno::Reference< XConversionDictionary > xDic =
455                     pNameContainer->GetByName( pActiveConvDics[i] );
456             if (xDic.is())
457                 xDic->setActive( sal_True );
458         }
459 
460         // since there is no UI to active/deactivate the dictionaries
461         // for chinese text conversion they should be activated by default
462         uno::Reference< XConversionDictionary > xS2TDic(
463                     pNameContainer->GetByName( A2OU("ChineseS2T") ), UNO_QUERY );
464         uno::Reference< XConversionDictionary > xT2SDic(
465                     pNameContainer->GetByName( A2OU("ChineseT2S") ), UNO_QUERY );
466             if (xS2TDic.is())
467                 xS2TDic->setActive( sal_True );
468             if (xT2SDic.is())
469                 xT2SDic->setActive( sal_True );
470 
471     }
472     return *pNameContainer;
473 }
474 
475 
getDictionaryContainer()476 uno::Reference< container::XNameContainer > SAL_CALL ConvDicList::getDictionaryContainer(  )
477 {
478     MutexGuard  aGuard( GetLinguMutex() );
479     GetNameContainer();
480     DBG_ASSERT( xNameContainer.is(), "missing name container" );
481     return xNameContainer;
482 }
483 
484 
addNewDictionary(const OUString & rName,const Locale & rLocale,sal_Int16 nConvDicType)485 uno::Reference< XConversionDictionary > SAL_CALL ConvDicList::addNewDictionary(
486         const OUString& rName,
487         const Locale& rLocale,
488         sal_Int16 nConvDicType )
489 {
490     MutexGuard  aGuard( GetLinguMutex() );
491 
492     sal_Int16 nLang = LocaleToLanguage( rLocale );
493 
494     if (GetNameContainer().hasByName( rName ))
495         throw ElementExistException();
496 
497     uno::Reference< XConversionDictionary > xRes;
498     String aDicMainURL( GetConvDicMainURL( rName, GetDictionaryWriteablePath() ) );
499     if (nLang == LANGUAGE_KOREAN &&
500         nConvDicType == ConversionDictionaryType::HANGUL_HANJA)
501     {
502         xRes = new HHConvDic( rName, aDicMainURL );
503     }
504     else if ((nLang == LANGUAGE_CHINESE_SIMPLIFIED || nLang == LANGUAGE_CHINESE_TRADITIONAL) &&
505               nConvDicType == ConversionDictionaryType::SCHINESE_TCHINESE)
506     {
507         xRes = new ConvDic( rName, nLang, nConvDicType, sal_False, aDicMainURL );
508     }
509 
510     if (!xRes.is())
511         throw NoSupportException();
512     else
513     {
514         xRes->setActive( sal_True );
515         uno::Any aAny;
516         aAny <<= xRes;
517         GetNameContainer().insertByName( rName, aAny );
518     }
519     return xRes;
520 }
521 
522 
queryConversions(const OUString & rText,sal_Int32 nStartPos,sal_Int32 nLength,const Locale & rLocale,sal_Int16 nConversionDictionaryType,ConversionDirection eDirection,sal_Int32 nTextConversionOptions)523 uno::Sequence< OUString > SAL_CALL ConvDicList::queryConversions(
524         const OUString& rText,
525         sal_Int32 nStartPos,
526         sal_Int32 nLength,
527         const Locale& rLocale,
528         sal_Int16 nConversionDictionaryType,
529         ConversionDirection eDirection,
530         sal_Int32 nTextConversionOptions )
531 {
532     MutexGuard  aGuard( GetLinguMutex() );
533 
534     /*sal_Int16 nLang = LocaleToLanguage( rLocale );*/
535 
536     sal_Int32 nCount = 0;
537     uno::Sequence< OUString > aRes( 20 );
538     OUString *pRes = aRes.getArray();
539 
540     sal_Bool bSupported = sal_False;
541     sal_Int32 nLen = GetNameContainer().GetCount();
542     for (sal_Int32 i = 0;  i < nLen;  ++i)
543     {
544         const uno::Reference< XConversionDictionary > xDic( GetNameContainer().GetByIndex(i) );
545         sal_Bool bMatch =   xDic.is()  &&
546                             xDic->getLocale() == rLocale  &&
547                             xDic->getConversionType() == nConversionDictionaryType;
548         bSupported |= bMatch;
549         if (bMatch  &&  xDic->isActive())
550         {
551             Sequence< OUString > aNewConv( xDic->getConversions(
552                                 rText, nStartPos, nLength,
553                                 eDirection, nTextConversionOptions ) );
554             sal_Int32 nNewLen = aNewConv.getLength();
555             if (nNewLen > 0)
556             {
557                 if (nCount + nNewLen > aRes.getLength())
558                 {
559                     aRes.realloc( nCount + nNewLen + 20 );
560                     pRes = aRes.getArray();
561                 }
562                 const OUString *pNewConv = aNewConv.getConstArray();
563                 for (sal_Int32 k = 0;  k < nNewLen;  ++k)
564                     pRes[nCount++] = pNewConv[k];
565             }
566         }
567     }
568 
569     if (!bSupported)
570         throw NoSupportException();
571 
572     aRes.realloc( nCount );
573     return aRes;
574 }
575 
576 
queryMaxCharCount(const Locale & rLocale,sal_Int16 nConversionDictionaryType,ConversionDirection eDirection)577 sal_Int16 SAL_CALL ConvDicList::queryMaxCharCount(
578         const Locale& rLocale,
579         sal_Int16 nConversionDictionaryType,
580         ConversionDirection eDirection )
581 {
582     MutexGuard  aGuard( GetLinguMutex() );
583 
584     sal_Int16 nRes = 0;
585     GetNameContainer();
586     sal_Int32 nLen = GetNameContainer().GetCount();
587     for (sal_Int32 i = 0;  i < nLen;  ++i)
588     {
589         const uno::Reference< XConversionDictionary > xDic( GetNameContainer().GetByIndex(i) );
590         if (xDic.is()  &&
591             xDic->getLocale() == rLocale  &&
592             xDic->getConversionType() == nConversionDictionaryType)
593         {
594             sal_Int16 nC = xDic->getMaxCharCount( eDirection );
595             if (nC > nRes)
596                 nRes = nC;
597         }
598     }
599     return nRes;
600 }
601 
602 
dispose()603 void SAL_CALL ConvDicList::dispose(  )
604 {
605     MutexGuard  aGuard( GetLinguMutex() );
606     if (!bDisposing)
607     {
608         bDisposing = sal_True;
609         EventObject aEvtObj( (XConversionDictionaryList *) this );
610         aEvtListeners.disposeAndClear( aEvtObj );
611 
612         FlushDics();
613     }
614 }
615 
616 
addEventListener(const uno::Reference<XEventListener> & rxListener)617 void SAL_CALL ConvDicList::addEventListener(
618         const uno::Reference< XEventListener >& rxListener )
619 {
620     MutexGuard  aGuard( GetLinguMutex() );
621     if (!bDisposing && rxListener.is())
622         aEvtListeners.addInterface( rxListener );
623 }
624 
625 
removeEventListener(const uno::Reference<XEventListener> & rxListener)626 void SAL_CALL ConvDicList::removeEventListener(
627         const uno::Reference< XEventListener >& rxListener )
628 {
629     MutexGuard  aGuard( GetLinguMutex() );
630     if (!bDisposing && rxListener.is())
631         aEvtListeners.removeInterface( rxListener );
632 }
633 
634 
getImplementationName()635 OUString SAL_CALL ConvDicList::getImplementationName(  )
636 {
637     MutexGuard  aGuard( GetLinguMutex() );
638     return getImplementationName_Static();
639 }
640 
641 
supportsService(const OUString & rServiceName)642 sal_Bool SAL_CALL ConvDicList::supportsService( const OUString& rServiceName )
643 {
644     MutexGuard  aGuard( GetLinguMutex() );
645     return rServiceName.equalsAscii( SN_CONV_DICTIONARY_LIST );
646 }
647 
648 
getSupportedServiceNames()649 uno::Sequence< OUString > SAL_CALL ConvDicList::getSupportedServiceNames(  )
650 {
651     MutexGuard  aGuard( GetLinguMutex() );
652     return getSupportedServiceNames_Static();
653 }
654 
655 
getSupportedServiceNames_Static()656 uno::Sequence< OUString > ConvDicList::getSupportedServiceNames_Static()
657     throw()
658 {
659     uno::Sequence< OUString > aSNS( 1 );
660     aSNS.getArray()[0] = A2OU( SN_CONV_DICTIONARY_LIST );
661     return aSNS;
662 }
663 
664 
665 ///////////////////////////////////////////////////////////////////////////
666 
ConvDicList_CreateInstance(const uno::Reference<XMultiServiceFactory> &)667 uno::Reference< uno::XInterface > SAL_CALL ConvDicList_CreateInstance(
668         const uno::Reference< XMultiServiceFactory > & /*rSMgr*/ )
669 {
670     return StaticConvDicList::get();
671 }
672 
ConvDicList_getFactory(const sal_Char * pImplName,XMultiServiceFactory * pServiceManager,void *)673 void * SAL_CALL ConvDicList_getFactory(
674         const sal_Char * pImplName,
675         XMultiServiceFactory * pServiceManager, void *  )
676 {
677     void * pRet = 0;
678     if ( !ConvDicList::getImplementationName_Static().compareToAscii( pImplName ) )
679     {
680         uno::Reference< XSingleServiceFactory > xFactory =
681             cppu::createOneInstanceFactory(
682                 pServiceManager,
683                 ConvDicList::getImplementationName_Static(),
684                 ConvDicList_CreateInstance,
685                 ConvDicList::getSupportedServiceNames_Static());
686         // acquire, because we return an interface pointer instead of a reference
687         xFactory->acquire();
688         pRet = xFactory.get();
689     }
690     return pRet;
691 }
692 
693 ///////////////////////////////////////////////////////////////////////////
694