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