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 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 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 142 sal_Int32 GetCount() const { return aConvDics.getLength(); } 143 uno::Reference< XConversionDictionary > GetByName( const OUString& rName ); 144 145 const uno::Reference< XConversionDictionary > GetByIndex( sal_Int32 nIdx ) 146 { 147 return aConvDics.getConstArray()[nIdx]; 148 } 149 }; 150 151 152 ConvDicNameContainer::ConvDicNameContainer( ConvDicList &rMyConvDicList ) : 153 rConvDicList( rMyConvDicList ) 154 { 155 } 156 157 158 ConvDicNameContainer::~ConvDicNameContainer() 159 { 160 } 161 162 163 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 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 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 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 219 sal_Bool SAL_CALL ConvDicNameContainer::hasElements( ) 220 throw (RuntimeException) 221 { 222 MutexGuard aGuard( GetLinguMutex() ); 223 return aConvDics.getLength() > 0; 224 } 225 226 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 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 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 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 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 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 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> { 399 uno::Reference<XInterface> operator () () { 400 return (cppu::OWeakObject *) new ConvDicList; 401 } 402 }; 403 } 404 405 406 void ConvDicList::MyAppExitListener::AtExit() 407 { 408 rMyDicList.FlushDics(); 409 StaticConvDicList::get().clear(); 410 } 411 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 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 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 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 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 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 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 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 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 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 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 649 OUString SAL_CALL ConvDicList::getImplementationName( ) 650 throw (RuntimeException) 651 { 652 MutexGuard aGuard( GetLinguMutex() ); 653 return getImplementationName_Static(); 654 } 655 656 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 665 uno::Sequence< OUString > SAL_CALL ConvDicList::getSupportedServiceNames( ) 666 throw (RuntimeException) 667 { 668 MutexGuard aGuard( GetLinguMutex() ); 669 return getSupportedServiceNames_Static(); 670 } 671 672 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 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 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