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