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( ) throw (::com::sun::star::uno::RuntimeException);
120 virtual sal_Bool SAL_CALL hasElements( ) throw (::com::sun::star::uno::RuntimeException);
121
122 // XNameAccess
123 virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
124 virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) throw (::com::sun::star::uno::RuntimeException);
125 virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException);
126
127 // XNameReplace
128 virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, const ::com::sun::star::uno::Any& aElement ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
129
130 // XNameContainer
131 virtual void SAL_CALL insertByName( const ::rtl::OUString& aName, const ::com::sun::star::uno::Any& aElement ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
132 virtual void SAL_CALL removeByName( const ::rtl::OUString& Name ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
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 throw (RuntimeException)
213 {
214 MutexGuard aGuard( GetLinguMutex() );
215 return uno::Type( ::getCppuType( (uno::Reference< XConversionDictionary > *) 0) );
216 }
217
218
hasElements()219 sal_Bool SAL_CALL ConvDicNameContainer::hasElements( )
220 throw (RuntimeException)
221 {
222 MutexGuard aGuard( GetLinguMutex() );
223 return aConvDics.getLength() > 0;
224 }
225
226
getByName(const OUString & rName)227 uno::Any SAL_CALL ConvDicNameContainer::getByName( const OUString& rName )
228 throw (NoSuchElementException, WrappedTargetException, RuntimeException)
229 {
230 MutexGuard aGuard( GetLinguMutex() );
231 uno::Reference< XConversionDictionary > xRes( GetByName( rName ) );
232 if (!xRes.is())
233 throw NoSuchElementException();
234 return makeAny( xRes );
235 }
236
237
getElementNames()238 uno::Sequence< OUString > SAL_CALL ConvDicNameContainer::getElementNames( )
239 throw (RuntimeException)
240 {
241 MutexGuard aGuard( GetLinguMutex() );
242
243 sal_Int32 nLen = aConvDics.getLength();
244 uno::Sequence< OUString > aRes( nLen );
245 OUString *pName = aRes.getArray();
246 const uno::Reference< XConversionDictionary > *pDic = aConvDics.getConstArray();
247 for (sal_Int32 i = 0; i < nLen; ++i)
248 pName[i] = pDic[i]->getName();
249 return aRes;
250 }
251
252
hasByName(const OUString & rName)253 sal_Bool SAL_CALL ConvDicNameContainer::hasByName( const OUString& rName )
254 throw (RuntimeException)
255 {
256 MutexGuard aGuard( GetLinguMutex() );
257 return GetByName( rName ).is();
258 }
259
260
replaceByName(const OUString & rName,const uno::Any & rElement)261 void SAL_CALL ConvDicNameContainer::replaceByName(
262 const OUString& rName,
263 const uno::Any& rElement )
264 throw (IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
265 {
266 MutexGuard aGuard( GetLinguMutex() );
267
268 sal_Int32 nRplcIdx = GetIndexByName_Impl( rName );
269 if (nRplcIdx == -1)
270 throw NoSuchElementException();
271 uno::Reference< XConversionDictionary > xNew;
272 rElement >>= xNew;
273 if (!xNew.is() || xNew->getName() != rName)
274 throw IllegalArgumentException();
275 aConvDics.getArray()[ nRplcIdx ] = xNew;
276 }
277
278
insertByName(const OUString & rName,const Any & rElement)279 void SAL_CALL ConvDicNameContainer::insertByName(
280 const OUString& rName,
281 const Any& rElement )
282 throw (IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
283 {
284 MutexGuard aGuard( GetLinguMutex() );
285
286 if (GetByName( rName ).is())
287 throw ElementExistException();
288 uno::Reference< XConversionDictionary > xNew;
289 rElement >>= xNew;
290 if (!xNew.is() || xNew->getName() != rName)
291 throw IllegalArgumentException();
292
293 sal_Int32 nLen = aConvDics.getLength();
294 aConvDics.realloc( nLen + 1 );
295 aConvDics.getArray()[ nLen ] = xNew;
296 }
297
298
removeByName(const OUString & rName)299 void SAL_CALL ConvDicNameContainer::removeByName( const OUString& rName )
300 throw (NoSuchElementException, WrappedTargetException, RuntimeException)
301 {
302 MutexGuard aGuard( GetLinguMutex() );
303
304 sal_Int32 nRplcIdx = GetIndexByName_Impl( rName );
305 if (nRplcIdx == -1)
306 throw NoSuchElementException();
307
308 // physically remove dictionary
309 uno::Reference< XConversionDictionary > xDel = aConvDics.getArray()[nRplcIdx];
310 String aName( xDel->getName() );
311 String aDicMainURL( GetConvDicMainURL( aName, GetDictionaryWriteablePath() ) );
312 INetURLObject aObj( aDicMainURL );
313 DBG_ASSERT( aObj.GetProtocol() == INET_PROT_FILE, "+HangulHanjaOptionsDialog::OkHdl(): non-file URLs cannot be deleted" );
314 if( aObj.GetProtocol() == INET_PROT_FILE )
315 {
316 try
317 {
318 ::ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ),
319 uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () );
320 aCnt.executeCommand( OUString::createFromAscii( "delete" ), makeAny( sal_Bool( sal_True ) ) );
321 }
322 catch( ::com::sun::star::ucb::CommandAbortedException& )
323 {
324 DBG_ERRORFILE( "HangulHanjaOptionsDialog::OkHdl(): CommandAbortedException" );
325 }
326 catch( ... )
327 {
328 DBG_ERRORFILE( "HangulHanjaOptionsDialog::OkHdl(): Any other exception" );
329 }
330 }
331
332 sal_Int32 nLen = aConvDics.getLength();
333 uno::Reference< XConversionDictionary > *pDic = aConvDics.getArray();
334 for (sal_Int32 i = nRplcIdx; i < nLen - 1; ++i)
335 pDic[i] = pDic[i + 1];
336 aConvDics.realloc( nLen - 1 );
337 }
338
339
AddConvDics(const String & rSearchDirPathURL,const String & rExtension)340 void ConvDicNameContainer::AddConvDics(
341 const String &rSearchDirPathURL,
342 const String &rExtension )
343 {
344 const Sequence< OUString > aDirCnt(
345 utl::LocalFileHelper::GetFolderContents( rSearchDirPathURL, sal_False ) );
346 const OUString *pDirCnt = aDirCnt.getConstArray();
347 sal_Int32 nEntries = aDirCnt.getLength();
348
349 for (sal_Int32 i = 0; i < nEntries; ++i)
350 {
351 String aURL( pDirCnt[i] );
352
353 xub_StrLen nPos = aURL.SearchBackward('.');
354 String aExt(aURL.Copy(nPos + 1));
355 aExt.ToLowerAscii();
356 String aSearchExt( rExtension );
357 aSearchExt.ToLowerAscii();
358 if(aExt != aSearchExt)
359 continue; // skip other files
360
361 sal_Int16 nLang;
362 sal_Int16 nConvType;
363 if (IsConvDic( aURL, nLang, nConvType ))
364 {
365 // get decoded dictionary file name
366 INetURLObject aURLObj( aURL );
367 String aDicName = aURLObj.getBase( INetURLObject::LAST_SEGMENT,
368 true, INetURLObject::DECODE_WITH_CHARSET,
369 RTL_TEXTENCODING_UTF8 );
370
371 uno::Reference < XConversionDictionary > xDic;
372 if (nLang == LANGUAGE_KOREAN &&
373 nConvType == ConversionDictionaryType::HANGUL_HANJA)
374 {
375 xDic = new HHConvDic( aDicName, aURL );
376 }
377 else if ((nLang == LANGUAGE_CHINESE_SIMPLIFIED || nLang == LANGUAGE_CHINESE_TRADITIONAL) &&
378 nConvType == ConversionDictionaryType::SCHINESE_TCHINESE)
379 {
380 xDic = new ConvDic( aDicName, nLang, nConvType, sal_False, aURL );
381 }
382
383 if (xDic.is())
384 {
385 uno::Any aAny;
386 aAny <<= xDic;
387 insertByName( xDic->getName(), aAny );
388 }
389 }
390 }
391 }
392
393 ///////////////////////////////////////////////////////////////////////////
394
395 namespace
396 {
397 struct StaticConvDicList : public rtl::StaticWithInit<
398 uno::Reference<XInterface>, StaticConvDicList> {
operator ()__anonf99d38640111::StaticConvDicList399 uno::Reference<XInterface> operator () () {
400 return (cppu::OWeakObject *) new ConvDicList;
401 }
402 };
403 }
404
405
AtExit()406 void ConvDicList::MyAppExitListener::AtExit()
407 {
408 rMyDicList.FlushDics();
409 StaticConvDicList::get().clear();
410 }
411
ConvDicList()412 ConvDicList::ConvDicList() :
413 aEvtListeners( GetLinguMutex() )
414 {
415 pNameContainer = 0;
416 bDisposing = sal_False;
417
418 pExitListener = new MyAppExitListener( *this );
419 xExitListener = pExitListener;
420 pExitListener->Activate();
421 }
422
423
~ConvDicList()424 ConvDicList::~ConvDicList()
425 {
426 // NameContainer will deleted when the reference xNameContainer
427 // is destroyed.
428 // delete pNameContainer;
429
430 if (!bDisposing && pNameContainer)
431 pNameContainer->FlushDics();
432
433 pExitListener->Deactivate();
434 }
435
436
FlushDics()437 void ConvDicList::FlushDics()
438 {
439 // check only pointer to avoid creating the container when
440 // the dictionaries were not accessed yet
441 if (pNameContainer)
442 pNameContainer->FlushDics();
443 }
444
445
GetNameContainer()446 ConvDicNameContainer & ConvDicList::GetNameContainer()
447 {
448 if (!pNameContainer)
449 {
450 pNameContainer = new ConvDicNameContainer( *this );
451 pNameContainer->AddConvDics( GetDictionaryWriteablePath(),
452 A2OU( CONV_DIC_EXT ) );
453 xNameContainer = pNameContainer;
454
455 // access list of text conversion dictionaries to activate
456 SvtLinguOptions aOpt;
457 SvtLinguConfig().GetOptions( aOpt );
458 sal_Int32 nLen = aOpt.aActiveConvDics.getLength();
459 const OUString *pActiveConvDics = aOpt.aActiveConvDics.getConstArray();
460 for (sal_Int32 i = 0; i < nLen; ++i)
461 {
462 uno::Reference< XConversionDictionary > xDic =
463 pNameContainer->GetByName( pActiveConvDics[i] );
464 if (xDic.is())
465 xDic->setActive( sal_True );
466 }
467
468 // since there is no UI to active/deactivate the dictionaries
469 // for chinese text conversion they should be activated by default
470 uno::Reference< XConversionDictionary > xS2TDic(
471 pNameContainer->GetByName( A2OU("ChineseS2T") ), UNO_QUERY );
472 uno::Reference< XConversionDictionary > xT2SDic(
473 pNameContainer->GetByName( A2OU("ChineseT2S") ), UNO_QUERY );
474 if (xS2TDic.is())
475 xS2TDic->setActive( sal_True );
476 if (xT2SDic.is())
477 xT2SDic->setActive( sal_True );
478
479 }
480 return *pNameContainer;
481 }
482
483
getDictionaryContainer()484 uno::Reference< container::XNameContainer > SAL_CALL ConvDicList::getDictionaryContainer( ) throw (RuntimeException)
485 {
486 MutexGuard aGuard( GetLinguMutex() );
487 GetNameContainer();
488 DBG_ASSERT( xNameContainer.is(), "missing name container" );
489 return xNameContainer;
490 }
491
492
addNewDictionary(const OUString & rName,const Locale & rLocale,sal_Int16 nConvDicType)493 uno::Reference< XConversionDictionary > SAL_CALL ConvDicList::addNewDictionary(
494 const OUString& rName,
495 const Locale& rLocale,
496 sal_Int16 nConvDicType )
497 throw (NoSupportException, ElementExistException, RuntimeException)
498 {
499 MutexGuard aGuard( GetLinguMutex() );
500
501 sal_Int16 nLang = LocaleToLanguage( rLocale );
502
503 if (GetNameContainer().hasByName( rName ))
504 throw ElementExistException();
505
506 uno::Reference< XConversionDictionary > xRes;
507 String aDicMainURL( GetConvDicMainURL( rName, GetDictionaryWriteablePath() ) );
508 if (nLang == LANGUAGE_KOREAN &&
509 nConvDicType == ConversionDictionaryType::HANGUL_HANJA)
510 {
511 xRes = new HHConvDic( rName, aDicMainURL );
512 }
513 else if ((nLang == LANGUAGE_CHINESE_SIMPLIFIED || nLang == LANGUAGE_CHINESE_TRADITIONAL) &&
514 nConvDicType == ConversionDictionaryType::SCHINESE_TCHINESE)
515 {
516 xRes = new ConvDic( rName, nLang, nConvDicType, sal_False, aDicMainURL );
517 }
518
519 if (!xRes.is())
520 throw NoSupportException();
521 else
522 {
523 xRes->setActive( sal_True );
524 uno::Any aAny;
525 aAny <<= xRes;
526 GetNameContainer().insertByName( rName, aAny );
527 }
528 return xRes;
529 }
530
531
queryConversions(const OUString & rText,sal_Int32 nStartPos,sal_Int32 nLength,const Locale & rLocale,sal_Int16 nConversionDictionaryType,ConversionDirection eDirection,sal_Int32 nTextConversionOptions)532 uno::Sequence< OUString > SAL_CALL ConvDicList::queryConversions(
533 const OUString& rText,
534 sal_Int32 nStartPos,
535 sal_Int32 nLength,
536 const Locale& rLocale,
537 sal_Int16 nConversionDictionaryType,
538 ConversionDirection eDirection,
539 sal_Int32 nTextConversionOptions )
540 throw (IllegalArgumentException, NoSupportException, RuntimeException)
541 {
542 MutexGuard aGuard( GetLinguMutex() );
543
544 /*sal_Int16 nLang = LocaleToLanguage( rLocale );*/
545
546 sal_Int32 nCount = 0;
547 uno::Sequence< OUString > aRes( 20 );
548 OUString *pRes = aRes.getArray();
549
550 sal_Bool bSupported = sal_False;
551 sal_Int32 nLen = GetNameContainer().GetCount();
552 for (sal_Int32 i = 0; i < nLen; ++i)
553 {
554 const uno::Reference< XConversionDictionary > xDic( GetNameContainer().GetByIndex(i) );
555 sal_Bool bMatch = xDic.is() &&
556 xDic->getLocale() == rLocale &&
557 xDic->getConversionType() == nConversionDictionaryType;
558 bSupported |= bMatch;
559 if (bMatch && xDic->isActive())
560 {
561 Sequence< OUString > aNewConv( xDic->getConversions(
562 rText, nStartPos, nLength,
563 eDirection, nTextConversionOptions ) );
564 sal_Int32 nNewLen = aNewConv.getLength();
565 if (nNewLen > 0)
566 {
567 if (nCount + nNewLen > aRes.getLength())
568 {
569 aRes.realloc( nCount + nNewLen + 20 );
570 pRes = aRes.getArray();
571 }
572 const OUString *pNewConv = aNewConv.getConstArray();
573 for (sal_Int32 k = 0; k < nNewLen; ++k)
574 pRes[nCount++] = pNewConv[k];
575 }
576 }
577 }
578
579 if (!bSupported)
580 throw NoSupportException();
581
582 aRes.realloc( nCount );
583 return aRes;
584 }
585
586
queryMaxCharCount(const Locale & rLocale,sal_Int16 nConversionDictionaryType,ConversionDirection eDirection)587 sal_Int16 SAL_CALL ConvDicList::queryMaxCharCount(
588 const Locale& rLocale,
589 sal_Int16 nConversionDictionaryType,
590 ConversionDirection eDirection )
591 throw (RuntimeException)
592 {
593 MutexGuard aGuard( GetLinguMutex() );
594
595 sal_Int16 nRes = 0;
596 GetNameContainer();
597 sal_Int32 nLen = GetNameContainer().GetCount();
598 for (sal_Int32 i = 0; i < nLen; ++i)
599 {
600 const uno::Reference< XConversionDictionary > xDic( GetNameContainer().GetByIndex(i) );
601 if (xDic.is() &&
602 xDic->getLocale() == rLocale &&
603 xDic->getConversionType() == nConversionDictionaryType)
604 {
605 sal_Int16 nC = xDic->getMaxCharCount( eDirection );
606 if (nC > nRes)
607 nRes = nC;
608 }
609 }
610 return nRes;
611 }
612
613
dispose()614 void SAL_CALL ConvDicList::dispose( )
615 throw (RuntimeException)
616 {
617 MutexGuard aGuard( GetLinguMutex() );
618 if (!bDisposing)
619 {
620 bDisposing = sal_True;
621 EventObject aEvtObj( (XConversionDictionaryList *) this );
622 aEvtListeners.disposeAndClear( aEvtObj );
623
624 FlushDics();
625 }
626 }
627
628
addEventListener(const uno::Reference<XEventListener> & rxListener)629 void SAL_CALL ConvDicList::addEventListener(
630 const uno::Reference< XEventListener >& rxListener )
631 throw (RuntimeException)
632 {
633 MutexGuard aGuard( GetLinguMutex() );
634 if (!bDisposing && rxListener.is())
635 aEvtListeners.addInterface( rxListener );
636 }
637
638
removeEventListener(const uno::Reference<XEventListener> & rxListener)639 void SAL_CALL ConvDicList::removeEventListener(
640 const uno::Reference< XEventListener >& rxListener )
641 throw (RuntimeException)
642 {
643 MutexGuard aGuard( GetLinguMutex() );
644 if (!bDisposing && rxListener.is())
645 aEvtListeners.removeInterface( rxListener );
646 }
647
648
getImplementationName()649 OUString SAL_CALL ConvDicList::getImplementationName( )
650 throw (RuntimeException)
651 {
652 MutexGuard aGuard( GetLinguMutex() );
653 return getImplementationName_Static();
654 }
655
656
supportsService(const OUString & rServiceName)657 sal_Bool SAL_CALL ConvDicList::supportsService( const OUString& rServiceName )
658 throw (RuntimeException)
659 {
660 MutexGuard aGuard( GetLinguMutex() );
661 return rServiceName.equalsAscii( SN_CONV_DICTIONARY_LIST );
662 }
663
664
getSupportedServiceNames()665 uno::Sequence< OUString > SAL_CALL ConvDicList::getSupportedServiceNames( )
666 throw (RuntimeException)
667 {
668 MutexGuard aGuard( GetLinguMutex() );
669 return getSupportedServiceNames_Static();
670 }
671
672
getSupportedServiceNames_Static()673 uno::Sequence< OUString > ConvDicList::getSupportedServiceNames_Static()
674 throw()
675 {
676 uno::Sequence< OUString > aSNS( 1 );
677 aSNS.getArray()[0] = A2OU( SN_CONV_DICTIONARY_LIST );
678 return aSNS;
679 }
680
681
682 ///////////////////////////////////////////////////////////////////////////
683
ConvDicList_CreateInstance(const uno::Reference<XMultiServiceFactory> &)684 uno::Reference< uno::XInterface > SAL_CALL ConvDicList_CreateInstance(
685 const uno::Reference< XMultiServiceFactory > & /*rSMgr*/ )
686 throw(Exception)
687 {
688 return StaticConvDicList::get();
689 }
690
ConvDicList_getFactory(const sal_Char * pImplName,XMultiServiceFactory * pServiceManager,void *)691 void * SAL_CALL ConvDicList_getFactory(
692 const sal_Char * pImplName,
693 XMultiServiceFactory * pServiceManager, void * )
694 {
695 void * pRet = 0;
696 if ( !ConvDicList::getImplementationName_Static().compareToAscii( pImplName ) )
697 {
698 uno::Reference< XSingleServiceFactory > xFactory =
699 cppu::createOneInstanceFactory(
700 pServiceManager,
701 ConvDicList::getImplementationName_Static(),
702 ConvDicList_CreateInstance,
703 ConvDicList::getSupportedServiceNames_Static());
704 // acquire, because we return an interface pointer instead of a reference
705 xFactory->acquire();
706 pRet = xFactory.get();
707 }
708 return pRet;
709 }
710
711 ///////////////////////////////////////////////////////////////////////////
712
713