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_editeng.hxx" 30 31 #include <map> 32 #include <set> 33 #include <vector> 34 #include <slist> 35 #include <memory> 36 #include <editeng/unolingu.hxx> 37 #include <tools/debug.hxx> 38 #include <tools/urlobj.hxx> 39 #include <rtl/logfile.hxx> 40 #include <unotools/pathoptions.hxx> 41 #include <com/sun/star/frame/XModel.hpp> 42 #include <com/sun/star/frame/XStorable.hpp> 43 #include <com/sun/star/lang/XEventListener.hpp> 44 #include <com/sun/star/linguistic2/XAvailableLocales.hpp> 45 #include <com/sun/star/ucb/XAnyCompareFactory.hpp> 46 #include <com/sun/star/ucb/XContentAccess.hpp> 47 #include <com/sun/star/ucb/XSortedDynamicResultSetFactory.hpp> 48 #include <com/sun/star/ucb/NumberedSortingInfo.hpp> 49 #include <com/sun/star/ucb/XContentAccess.hpp> 50 #include <com/sun/star/sdbc/XResultSet.hpp> 51 #include <com/sun/star/sdbc/XRow.hpp> 52 #include <com/sun/star/util/DateTime.hpp> 53 54 #include <comphelper/processfactory.hxx> 55 #include <cppuhelper/implbase1.hxx> // helper for implementations 56 #include <i18npool/mslangid.hxx> 57 #include <unotools/lingucfg.hxx> 58 #include <unotools/ucbhelper.hxx> 59 #include <unotools/localfilehelper.hxx> 60 #include <ucbhelper/commandenvironment.hxx> 61 #include <ucbhelper/content.hxx> 62 #include <comphelper/processfactory.hxx> 63 #include <vcl/msgbox.hxx> 64 #include <tools/shl.hxx> 65 #include <linguistic/misc.hxx> 66 #include <editeng/eerdll.hxx> 67 #include <editeng/editrids.hrc> 68 69 using namespace ::rtl; 70 using namespace ::comphelper; 71 using namespace ::linguistic; 72 using namespace ::com::sun::star; 73 using namespace ::com::sun::star::util; 74 using namespace ::com::sun::star::uno; 75 using namespace ::com::sun::star::lang; 76 using namespace ::com::sun::star::beans; 77 using namespace ::com::sun::star::frame; 78 using namespace ::com::sun::star::linguistic2; 79 80 #define CSS com::sun::star 81 82 /////////////////////////////////////////////////////////////////////////// 83 84 85 static uno::Reference< XLinguServiceManager > GetLngSvcMgr_Impl() 86 { 87 uno::Reference< XLinguServiceManager > xRes; 88 uno::Reference< XMultiServiceFactory > xMgr = getProcessServiceFactory(); 89 if (xMgr.is()) 90 { 91 xRes = uno::Reference< XLinguServiceManager > ( xMgr->createInstance( 92 OUString( RTL_CONSTASCII_USTRINGPARAM( 93 "com.sun.star.linguistic2.LinguServiceManager" ) ) ), UNO_QUERY ) ; 94 } 95 return xRes; 96 } 97 98 /////////////////////////////////////////////////////////////////////////// 99 100 sal_Bool lcl_FindEntry( const OUString &rEntry, const Sequence< OUString > &rCfgSvcs ) 101 { 102 sal_Int32 nRes = -1; 103 sal_Int32 nEntries = rCfgSvcs.getLength(); 104 const OUString *pEntry = rCfgSvcs.getConstArray(); 105 for (sal_Int32 i = 0; i < nEntries && nRes == -1; ++i) 106 { 107 if (rEntry == pEntry[i]) 108 nRes = i; 109 } 110 return nRes != -1; 111 } 112 113 114 Sequence< OUString > lcl_RemoveMissingEntries( 115 const Sequence< OUString > &rCfgSvcs, 116 const Sequence< OUString > &rAvailSvcs ) 117 { 118 Sequence< OUString > aRes( rCfgSvcs.getLength() ); 119 OUString *pRes = aRes.getArray(); 120 sal_Int32 nCnt = 0; 121 122 sal_Int32 nEntries = rCfgSvcs.getLength(); 123 const OUString *pEntry = rCfgSvcs.getConstArray(); 124 for (sal_Int32 i = 0; i < nEntries; ++i) 125 { 126 if (pEntry[i].getLength() && lcl_FindEntry( pEntry[i], rAvailSvcs )) 127 pRes[ nCnt++ ] = pEntry[i]; 128 } 129 130 aRes.realloc( nCnt ); 131 return aRes; 132 } 133 134 135 Sequence< OUString > lcl_GetLastFoundSvcs( 136 SvtLinguConfig &rCfg, 137 const OUString &rLastFoundList , 138 const Locale &rAvailLocale ) 139 { 140 Sequence< OUString > aRes; 141 142 OUString aCfgLocaleStr( MsLangId::convertLanguageToIsoString( 143 SvxLocaleToLanguage( rAvailLocale ) ) ); 144 145 Sequence< OUString > aNodeNames( rCfg.GetNodeNames(rLastFoundList) ); 146 sal_Bool bFound = lcl_FindEntry( aCfgLocaleStr, aNodeNames); 147 148 if (bFound) 149 { 150 Sequence< OUString > aNames(1); 151 OUString &rNodeName = aNames.getArray()[0]; 152 rNodeName = rLastFoundList; 153 rNodeName += OUString::valueOf( (sal_Unicode)'/' ); 154 rNodeName += aCfgLocaleStr; 155 Sequence< Any > aValues( rCfg.GetProperties( aNames ) ); 156 #if OSL_DEBUG_LEVEL > 1 157 const Any *pValue; 158 pValue = aValues.getConstArray(); 159 #endif 160 if (aValues.getLength()) 161 { 162 DBG_ASSERT( aValues.getLength() == 1, "unexpected length of sequence" ); 163 Sequence< OUString > aSvcImplNames; 164 if (aValues.getConstArray()[0] >>= aSvcImplNames) 165 aRes = aSvcImplNames; 166 else 167 { 168 DBG_ERROR( "type mismatch" ); 169 } 170 } 171 } 172 173 return aRes; 174 } 175 176 177 Sequence< OUString > lcl_GetNewEntries( 178 const Sequence< OUString > &rLastFoundSvcs, 179 const Sequence< OUString > &rAvailSvcs ) 180 { 181 sal_Int32 nLen = rAvailSvcs.getLength(); 182 Sequence< OUString > aRes( nLen ); 183 OUString *pRes = aRes.getArray(); 184 sal_Int32 nCnt = 0; 185 186 const OUString *pEntry = rAvailSvcs.getConstArray(); 187 for (sal_Int32 i = 0; i < nLen; ++i) 188 { 189 if (pEntry[i].getLength() && !lcl_FindEntry( pEntry[i], rLastFoundSvcs )) 190 pRes[ nCnt++ ] = pEntry[i]; 191 } 192 193 aRes.realloc( nCnt ); 194 return aRes; 195 } 196 197 198 Sequence< OUString > lcl_MergeSeq( 199 const Sequence< OUString > &rCfgSvcs, 200 const Sequence< OUString > &rNewSvcs ) 201 { 202 Sequence< OUString > aRes( rCfgSvcs.getLength() + rNewSvcs.getLength() ); 203 OUString *pRes = aRes.getArray(); 204 sal_Int32 nCnt = 0; 205 206 for (sal_Int32 k = 0; k < 2; ++k) 207 { 208 // add previously configuerd service first and append 209 // new found services at the end 210 const Sequence< OUString > &rSeq = k == 0 ? rCfgSvcs : rNewSvcs; 211 212 sal_Int32 nLen = rSeq.getLength(); 213 const OUString *pEntry = rSeq.getConstArray(); 214 for (sal_Int32 i = 0; i < nLen; ++i) 215 { 216 if (pEntry[i].getLength() && !lcl_FindEntry( pEntry[i], aRes )) 217 pRes[ nCnt++ ] = pEntry[i]; 218 } 219 } 220 221 aRes.realloc( nCnt ); 222 return aRes; 223 } 224 225 /////////////////////////////////////////////////////////////////////////// 226 227 // static member initialization 228 sal_Int16 SvxLinguConfigUpdate::nNeedUpdating = -1; 229 sal_Int32 SvxLinguConfigUpdate::nCurrentDataFilesChangedCheckValue = -1; 230 231 void SvxLinguConfigUpdate::UpdateAll( sal_Bool bForceCheck ) 232 { 233 RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::UpdateAll" ); 234 235 if (IsNeedUpdateAll( bForceCheck )) 236 { 237 typedef OUString OUstring_t; 238 typedef Sequence< OUString > Sequence_OUString_t; 239 typedef std::vector< OUstring_t > OUString_vector_t; 240 typedef std::set< OUstring_t > OUString_set_t; 241 std::vector< OUString_vector_t > aVector; 242 typedef std::map< OUstring_t, Sequence_OUString_t > list_entry_map_t; 243 244 RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::UpdateAll - updating..." ); 245 246 DBG_ASSERT( nNeedUpdating == 1, "SvxLinguConfigUpdate::UpdateAll already updated!" ); 247 248 uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() ); 249 DBG_ASSERT( xLngSvcMgr.is(), "service manager missing"); 250 if (!xLngSvcMgr.is()) 251 return; 252 253 SvtLinguConfig aCfg; 254 255 const int nNumServices = 4; 256 const sal_Char * apServices[nNumServices] = { SN_SPELLCHECKER, SN_GRAMMARCHECKER, SN_HYPHENATOR, SN_THESAURUS }; 257 const sal_Char * apCurLists[nNumServices] = { "ServiceManager/SpellCheckerList", "ServiceManager/GrammarCheckerList", "ServiceManager/HyphenatorList", "ServiceManager/ThesaurusList" }; 258 const sal_Char * apLastFoundLists[nNumServices] = { "ServiceManager/LastFoundSpellCheckers", "ServiceManager/LastFoundGrammarCheckers", "ServiceManager/LastFoundHyphenators", "ServiceManager/LastFoundThesauri" }; 259 260 // usage of indices as above: 0 = spell checker, 1 = grammar checker, 2 = hyphenator, 3 = thesaurus 261 std::vector< list_entry_map_t > aLastFoundSvcs(nNumServices); 262 std::vector< list_entry_map_t > aCurSvcs(nNumServices); 263 264 for (int k = 0; k < nNumServices; ++k) 265 { 266 OUString aService( A2OU( apServices[k] ) ); 267 OUString aActiveList( A2OU( apCurLists[k] ) ); 268 OUString aLastFoundList( A2OU( apLastFoundLists[k] ) ); 269 sal_Int32 i; 270 271 // 272 // remove configured but not available language/services entries 273 // 274 Sequence< OUString > aNodeNames( aCfg.GetNodeNames( aActiveList ) ); // list of configured locales 275 sal_Int32 nNodeNames = aNodeNames.getLength(); 276 const OUString *pNodeName = aNodeNames.getConstArray(); 277 for (i = 0; i < nNodeNames; ++i) 278 { 279 Locale aLocale( SvxCreateLocale( MsLangId::convertIsoStringToLanguage(pNodeName[i]) ) ); 280 Sequence< OUString > aCfgSvcs( 281 xLngSvcMgr->getConfiguredServices( aService, aLocale )); 282 Sequence< OUString > aAvailSvcs( 283 xLngSvcMgr->getAvailableServices( aService, aLocale )); 284 #if OSL_DEBUG_LEVEL > 1 285 const OUString * pCfgSvcs = aCfgSvcs.getConstArray();; 286 const OUString * pAvailSvcs = aAvailSvcs.getConstArray();; 287 (void) pCfgSvcs; 288 (void) pAvailSvcs; 289 #endif 290 aCfgSvcs = lcl_RemoveMissingEntries( aCfgSvcs, aAvailSvcs ); 291 292 aCurSvcs[k][ pNodeName[i] ] = aCfgSvcs; 293 } 294 295 // 296 // add new available language/servcice entries 297 // 298 uno::Reference< XAvailableLocales > xAvail( xLngSvcMgr, UNO_QUERY ); 299 Sequence< Locale > aAvailLocales( xAvail->getAvailableLocales(aService) ); 300 sal_Int32 nAvailLocales = aAvailLocales.getLength(); 301 const Locale *pAvailLocale = aAvailLocales.getConstArray(); 302 for (i = 0; i < nAvailLocales; ++i) 303 { 304 Sequence< OUString > aAvailSvcs( 305 xLngSvcMgr->getAvailableServices( aService, pAvailLocale[i] )); 306 Sequence< OUString > aLastSvcs( 307 lcl_GetLastFoundSvcs( aCfg, aLastFoundList , pAvailLocale[i] )); 308 Sequence< OUString > aNewSvcs = 309 lcl_GetNewEntries( aLastSvcs, aAvailSvcs ); 310 #if OSL_DEBUG_LEVEL > 1 311 const OUString * pAvailSvcs = aAvailSvcs.getConstArray(); 312 const OUString * pLastSvcs = aLastSvcs.getConstArray(); 313 const OUString * pNewSvcs = aNewSvcs.getConstArray(); 314 (void) pAvailSvcs; 315 (void) pLastSvcs; 316 (void) pNewSvcs; 317 #endif 318 319 OUString aCfgLocaleStr( MsLangId::convertLanguageToIsoString( 320 SvxLocaleToLanguage( pAvailLocale[i] ) ) ); 321 Sequence< OUString > aCfgSvcs( aCurSvcs[k][ aCfgLocaleStr ] ); 322 323 // merge services list (previously configured to be listed first). 324 aCfgSvcs = lcl_MergeSeq( aCfgSvcs, aNewSvcs ); 325 326 /* 327 // there is at most one Hyphenator per language allowed 328 // to be configured, thus we only use the first one found. 329 if (k == 2 && aCfgSvcs.getLength() > 1) 330 aCfgSvcs.realloc(1); 331 */ 332 aCurSvcs[k][ aCfgLocaleStr ] = aCfgSvcs; 333 } 334 335 // 336 // set last found services to currently available ones 337 // 338 for (i = 0; i < nAvailLocales; ++i) 339 { 340 Sequence< OUString > aSvcImplNames( 341 xLngSvcMgr->getAvailableServices( aService, pAvailLocale[i] ) ); 342 343 #if OSL_DEBUG_LEVEL > 1 344 sal_Int32 nSvcs = aSvcImplNames.getLength(); 345 const OUString *pSvcImplName = aSvcImplNames.getConstArray(); 346 for (sal_Int32 j = 0; j < nSvcs; ++j) 347 { 348 OUString aImplName( pSvcImplName[j] ); 349 } 350 #endif 351 352 OUString aCfgLocaleStr( MsLangId::convertLanguageToIsoString( 353 SvxLocaleToLanguage( pAvailLocale[i] ) ) ); 354 aLastFoundSvcs[k][ aCfgLocaleStr ] = aSvcImplNames; 355 } 356 } 357 358 // 359 // write new data back to configuration 360 // 361 for (int k = 0; k < nNumServices; ++k) 362 { 363 for (int i = 0; i < 2; ++i) 364 { 365 const sal_Char *pSubNodeName = (i == 0) ? apCurLists[k] : apLastFoundLists[k]; 366 OUString aSubNodeName( A2OU(pSubNodeName) ); 367 368 list_entry_map_t &rCurMap = (i == 0) ? aCurSvcs[k] : aLastFoundSvcs[k]; 369 list_entry_map_t::const_iterator aIt( rCurMap.begin() ); 370 sal_Int32 nVals = static_cast< sal_Int32 >( rCurMap.size() ); 371 Sequence< PropertyValue > aNewValues( nVals ); 372 PropertyValue *pNewValue = aNewValues.getArray(); 373 while (aIt != rCurMap.end()) 374 { 375 OUString aCfgEntryName( aSubNodeName ); 376 aCfgEntryName += OUString::valueOf( (sal_Unicode) '/' ); 377 aCfgEntryName += (*aIt).first; 378 379 #if OSL_DEBUG_LEVEL > 1 380 Sequence< OUString > aSvcImplNames( (*aIt).second ); 381 sal_Int32 nSvcs = aSvcImplNames.getLength(); 382 const OUString *pSvcImplName = aSvcImplNames.getConstArray(); 383 for (sal_Int32 j = 0; j < nSvcs; ++j) 384 { 385 OUString aImplName( pSvcImplName[j] ); 386 } 387 #endif 388 pNewValue->Name = aCfgEntryName; 389 pNewValue->Value <<= (*aIt).second; 390 ++pNewValue; 391 ++aIt; 392 } 393 DBG_ASSERT( pNewValue - aNewValues.getArray() == nVals, 394 "possible mismatch of sequence size and property number" ); 395 396 { 397 RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::UpdateAll - ReplaceSetProperties" ); 398 // add new or replace existing entries. 399 sal_Bool bRes = aCfg.ReplaceSetProperties( aSubNodeName, aNewValues ); 400 if (!bRes) 401 { 402 #if OSL_DEBUG_LEVEL > 1 403 DBG_ERROR( "failed to set new configuration values" ); 404 #endif 405 } 406 } 407 } 408 } 409 DBG_ASSERT( nCurrentDataFilesChangedCheckValue != -1, "SvxLinguConfigUpdate::UpdateAll DataFilesChangedCheckValue not yet calculated!" ); 410 Any aAny; 411 412 // for the time being (developer builds until OOo 3.0) 413 // we should always check for everything available 414 // otherwise we may miss a new installed extension dicitonary 415 // just because e.g. the spellchecker is not asked what 416 // languages it does support currently... 417 // Since the check is on-demand occuring and executed once it should 418 // not be too troublesome. 419 // In OOo 3.0 we will not need the respective code anymore at all. 420 // aAny <<= nCurrentDataFilesChangedCheckValue; 421 aAny <<= (sal_Int32) -1; // keep the value set to 'need to check' 422 423 aCfg.SetProperty( A2OU( "DataFilesChangedCheckValue" ), aAny ); 424 425 //! Note 1: the new values are commited when the 'aCfg' object 426 //! gets destroyed. 427 //! Note 2: the new settings in the configuration get applied 428 //! because the 'LngSvcMgr' (in linguistic/source/lngsvcmgr.hxx) 429 //! listens to the configuration for changes of the relevant 430 //! properties and then applies the new settings. 431 432 // nothing needs to be done anymore 433 nNeedUpdating = 0; 434 } 435 } 436 437 438 sal_Int32 SvxLinguConfigUpdate::CalcDataFilesChangedCheckValue() 439 { 440 RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::CalcDataFilesChangedCheckValue" ); 441 442 sal_Int32 nHashVal = 0; 443 // nothing to be checked anymore since those old directory paths are gone by now 444 return nHashVal; 445 } 446 447 448 sal_Bool SvxLinguConfigUpdate::IsNeedUpdateAll( sal_Bool bForceCheck ) 449 { 450 RTL_LOGFILE_CONTEXT( aLog, "svx: SvxLinguConfigUpdate::IsNeedUpdateAll" ); 451 if (nNeedUpdating == -1 || bForceCheck ) // need to check if updating is necessary 452 { 453 // calculate hash value for current data files 454 nCurrentDataFilesChangedCheckValue = CalcDataFilesChangedCheckValue(); 455 456 // compare hash value and check value to see if anything has changed 457 // and thus the configuration needs to be updated 458 SvtLinguOptions aLinguOpt; 459 SvtLinguConfig aCfg; 460 aCfg.GetOptions( aLinguOpt ); 461 nNeedUpdating = (nCurrentDataFilesChangedCheckValue == aLinguOpt.nDataFilesChangedCheckValue) ? 0 : 1; 462 } 463 DBG_ASSERT( nNeedUpdating != -1, 464 "need for linguistic configuration update should have been already checked." ); 465 466 return nNeedUpdating == 1; 467 } 468 469 /////////////////////////////////////////////////////////////////////////// 470 471 472 //! Dummy implementation in order to avoid loading of lingu DLL 473 //! when only the XSupportedLocales interface is used. 474 //! The dummy accesses the real implementation (and thus loading the DLL) 475 //! when "real" work needs to be done only. 476 class ThesDummy_Impl : 477 public cppu::WeakImplHelper1< XThesaurus > 478 { 479 uno::Reference< XThesaurus > xThes; // the real one... 480 Sequence< Locale > *pLocaleSeq; 481 482 void GetCfgLocales(); 483 484 void GetThes_Impl(); 485 486 public: 487 ThesDummy_Impl() : pLocaleSeq(0) {} 488 ~ThesDummy_Impl(); 489 490 // XSupportedLocales 491 virtual ::com::sun::star::uno::Sequence< 492 ::com::sun::star::lang::Locale > SAL_CALL 493 getLocales() 494 throw(::com::sun::star::uno::RuntimeException); 495 virtual sal_Bool SAL_CALL 496 hasLocale( const ::com::sun::star::lang::Locale& rLocale ) 497 throw(::com::sun::star::uno::RuntimeException); 498 499 // XThesaurus 500 virtual ::com::sun::star::uno::Sequence< 501 ::com::sun::star::uno::Reference< 502 ::com::sun::star::linguistic2::XMeaning > > SAL_CALL 503 queryMeanings( const ::rtl::OUString& rTerm, 504 const ::com::sun::star::lang::Locale& rLocale, 505 const ::com::sun::star::beans::PropertyValues& rProperties ) 506 throw(::com::sun::star::lang::IllegalArgumentException, 507 ::com::sun::star::uno::RuntimeException); 508 }; 509 510 511 ThesDummy_Impl::~ThesDummy_Impl() 512 { 513 delete pLocaleSeq; 514 } 515 516 517 void ThesDummy_Impl::GetCfgLocales() 518 { 519 if (!pLocaleSeq) 520 { 521 SvtLinguConfig aCfg; 522 String aNode( A2OU( "ServiceManager/ThesaurusList" ) ); 523 Sequence < OUString > aNodeNames( aCfg.GetNodeNames( aNode ) ); 524 const OUString *pNodeNames = aNodeNames.getConstArray(); 525 sal_Int32 nLen = aNodeNames.getLength(); 526 pLocaleSeq = new Sequence< Locale >( nLen ); 527 Locale *pLocale = pLocaleSeq->getArray(); 528 for (sal_Int32 i = 0; i < nLen; ++i) 529 { 530 pLocale[i] = SvxCreateLocale( 531 MsLangId::convertIsoStringToLanguage( pNodeNames[i] ) ); 532 } 533 } 534 } 535 536 537 void ThesDummy_Impl::GetThes_Impl() 538 { 539 // update configuration before accessing the service 540 if (SvxLinguConfigUpdate::IsNeedUpdateAll()) 541 SvxLinguConfigUpdate::UpdateAll(); 542 543 if (!xThes.is()) 544 { 545 uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() ); 546 if (xLngSvcMgr.is()) 547 xThes = xLngSvcMgr->getThesaurus(); 548 549 if (xThes.is()) 550 { 551 // no longer needed... 552 delete pLocaleSeq; pLocaleSeq = 0; 553 } 554 } 555 } 556 557 558 uno::Sequence< lang::Locale > SAL_CALL 559 ThesDummy_Impl::getLocales() 560 throw(uno::RuntimeException) 561 { 562 if (!SvxLinguConfigUpdate::IsNeedUpdateAll()) // configuration already update and thus lingu DLL's already loaded ? 563 GetThes_Impl(); 564 if (xThes.is()) 565 return xThes->getLocales(); 566 else if (!pLocaleSeq) // if not already loaded save startup time by avoiding loading them now 567 GetCfgLocales(); 568 return *pLocaleSeq; 569 } 570 571 572 sal_Bool SAL_CALL 573 ThesDummy_Impl::hasLocale( const lang::Locale& rLocale ) 574 throw(uno::RuntimeException) 575 { 576 if (!SvxLinguConfigUpdate::IsNeedUpdateAll()) // configuration already update and thus lingu DLL's already loaded ? 577 GetThes_Impl(); 578 if (xThes.is()) 579 return xThes->hasLocale( rLocale ); 580 else if (!pLocaleSeq) // if not already loaded save startup time by avoiding loading them now 581 GetCfgLocales(); 582 GetCfgLocales(); 583 sal_Bool bFound = sal_False; 584 sal_Int32 nLen = pLocaleSeq->getLength(); 585 const Locale *pLocale = pLocaleSeq->getConstArray(); 586 const Locale *pEnd = pLocale + nLen; 587 for ( ; pLocale < pEnd && !bFound; ++pLocale) 588 { 589 bFound = pLocale->Language == rLocale.Language && 590 pLocale->Country == rLocale.Country && 591 pLocale->Variant == rLocale.Variant; 592 } 593 return bFound; 594 } 595 596 597 uno::Sequence< uno::Reference< linguistic2::XMeaning > > SAL_CALL 598 ThesDummy_Impl::queryMeanings( 599 const rtl::OUString& rTerm, 600 const lang::Locale& rLocale, 601 const beans::PropertyValues& rProperties ) 602 throw(lang::IllegalArgumentException, 603 uno::RuntimeException) 604 { 605 GetThes_Impl(); 606 uno::Sequence< uno::Reference< linguistic2::XMeaning > > aRes; 607 DBG_ASSERT( xThes.is(), "Thesaurus missing" ); 608 if (xThes.is()) 609 aRes = xThes->queryMeanings( rTerm, rLocale, rProperties ); 610 return aRes; 611 } 612 613 614 /////////////////////////////////////////////////////////////////////////// 615 616 617 //! Dummy implementation in order to avoid loading of lingu DLL. 618 //! The dummy accesses the real implementation (and thus loading the DLL) 619 //! when it needs to be done only. 620 class SpellDummy_Impl : 621 public cppu::WeakImplHelper1< XSpellChecker1 > 622 { 623 uno::Reference< XSpellChecker1 > xSpell; // the real one... 624 625 void GetSpell_Impl(); 626 627 public: 628 629 // XSupportedLanguages (for XSpellChecker1) 630 virtual ::com::sun::star::uno::Sequence< sal_Int16 > SAL_CALL 631 getLanguages() 632 throw(::com::sun::star::uno::RuntimeException); 633 virtual sal_Bool SAL_CALL 634 hasLanguage( sal_Int16 nLanguage ) 635 throw(::com::sun::star::uno::RuntimeException); 636 637 // XSpellChecker1 (same as XSpellChecker but sal_Int16 for language) 638 virtual sal_Bool SAL_CALL 639 isValid( const ::rtl::OUString& rWord, sal_Int16 nLanguage, 640 const ::com::sun::star::beans::PropertyValues& rProperties ) 641 throw(::com::sun::star::lang::IllegalArgumentException, 642 ::com::sun::star::uno::RuntimeException); 643 virtual ::com::sun::star::uno::Reference< 644 ::com::sun::star::linguistic2::XSpellAlternatives > SAL_CALL 645 spell( const ::rtl::OUString& rWord, sal_Int16 nLanguage, 646 const ::com::sun::star::beans::PropertyValues& rProperties ) 647 throw(::com::sun::star::lang::IllegalArgumentException, 648 ::com::sun::star::uno::RuntimeException); 649 }; 650 651 652 void SpellDummy_Impl::GetSpell_Impl() 653 { 654 // update configuration before accessing the service 655 if (SvxLinguConfigUpdate::IsNeedUpdateAll()) 656 SvxLinguConfigUpdate::UpdateAll(); 657 658 if (!xSpell.is()) 659 { 660 uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() ); 661 if (xLngSvcMgr.is()) 662 xSpell = uno::Reference< XSpellChecker1 >( xLngSvcMgr->getSpellChecker(), UNO_QUERY ); 663 } 664 } 665 666 667 uno::Sequence< sal_Int16 > SAL_CALL 668 SpellDummy_Impl::getLanguages() 669 throw(uno::RuntimeException) 670 { 671 GetSpell_Impl(); 672 if (xSpell.is()) 673 return xSpell->getLanguages(); 674 else 675 return uno::Sequence< sal_Int16 >(); 676 } 677 678 679 sal_Bool SAL_CALL 680 SpellDummy_Impl::hasLanguage( sal_Int16 nLanguage ) 681 throw(uno::RuntimeException) 682 { 683 GetSpell_Impl(); 684 sal_Bool bRes = sal_False; 685 if (xSpell.is()) 686 bRes = xSpell->hasLanguage( nLanguage ); 687 return bRes; 688 } 689 690 691 sal_Bool SAL_CALL 692 SpellDummy_Impl::isValid( const rtl::OUString& rWord, sal_Int16 nLanguage, 693 const beans::PropertyValues& rProperties ) 694 throw(lang::IllegalArgumentException, 695 uno::RuntimeException) 696 { 697 GetSpell_Impl(); 698 sal_Bool bRes = sal_True; 699 if (xSpell.is()) 700 bRes = xSpell->isValid( rWord, nLanguage, rProperties ); 701 return bRes; 702 } 703 704 705 uno::Reference< linguistic2::XSpellAlternatives > SAL_CALL 706 SpellDummy_Impl::spell( const rtl::OUString& rWord, sal_Int16 nLanguage, 707 const beans::PropertyValues& rProperties ) 708 throw(lang::IllegalArgumentException, 709 uno::RuntimeException) 710 { 711 GetSpell_Impl(); 712 uno::Reference< linguistic2::XSpellAlternatives > xRes; 713 if (xSpell.is()) 714 xRes = xSpell->spell( rWord, nLanguage, rProperties ); 715 return xRes; 716 } 717 718 719 /////////////////////////////////////////////////////////////////////////// 720 721 722 //! Dummy implementation in order to avoid loading of lingu DLL. 723 //! The dummy accesses the real implementation (and thus loading the DLL) 724 //! when it needs to be done only. 725 class HyphDummy_Impl : 726 public cppu::WeakImplHelper1< XHyphenator > 727 { 728 uno::Reference< XHyphenator > xHyph; // the real one... 729 730 void GetHyph_Impl(); 731 732 public: 733 734 // XSupportedLocales 735 virtual ::com::sun::star::uno::Sequence< 736 ::com::sun::star::lang::Locale > SAL_CALL 737 getLocales() 738 throw(::com::sun::star::uno::RuntimeException); 739 virtual sal_Bool SAL_CALL 740 hasLocale( const ::com::sun::star::lang::Locale& rLocale ) 741 throw(::com::sun::star::uno::RuntimeException); 742 743 // XHyphenator 744 virtual ::com::sun::star::uno::Reference< 745 ::com::sun::star::linguistic2::XHyphenatedWord > SAL_CALL 746 hyphenate( const ::rtl::OUString& rWord, 747 const ::com::sun::star::lang::Locale& rLocale, 748 sal_Int16 nMaxLeading, 749 const ::com::sun::star::beans::PropertyValues& rProperties ) 750 throw(::com::sun::star::lang::IllegalArgumentException, 751 ::com::sun::star::uno::RuntimeException); 752 virtual ::com::sun::star::uno::Reference< 753 ::com::sun::star::linguistic2::XHyphenatedWord > SAL_CALL 754 queryAlternativeSpelling( const ::rtl::OUString& rWord, 755 const ::com::sun::star::lang::Locale& rLocale, 756 sal_Int16 nIndex, 757 const ::com::sun::star::beans::PropertyValues& rProperties ) 758 throw(::com::sun::star::lang::IllegalArgumentException, 759 ::com::sun::star::uno::RuntimeException); 760 virtual ::com::sun::star::uno::Reference< 761 ::com::sun::star::linguistic2::XPossibleHyphens > SAL_CALL 762 createPossibleHyphens( 763 const ::rtl::OUString& rWord, 764 const ::com::sun::star::lang::Locale& rLocale, 765 const ::com::sun::star::beans::PropertyValues& rProperties ) 766 throw(::com::sun::star::lang::IllegalArgumentException, 767 ::com::sun::star::uno::RuntimeException); 768 }; 769 770 771 void HyphDummy_Impl::GetHyph_Impl() 772 { 773 // update configuration before accessing the service 774 if (SvxLinguConfigUpdate::IsNeedUpdateAll()) 775 SvxLinguConfigUpdate::UpdateAll(); 776 777 if (!xHyph.is()) 778 { 779 uno::Reference< XLinguServiceManager > xLngSvcMgr( GetLngSvcMgr_Impl() ); 780 if (xLngSvcMgr.is()) 781 xHyph = xLngSvcMgr->getHyphenator(); 782 } 783 } 784 785 786 uno::Sequence< lang::Locale > SAL_CALL 787 HyphDummy_Impl::getLocales() 788 throw(uno::RuntimeException) 789 { 790 GetHyph_Impl(); 791 if (xHyph.is()) 792 return xHyph->getLocales(); 793 else 794 return uno::Sequence< lang::Locale >(); 795 } 796 797 798 sal_Bool SAL_CALL 799 HyphDummy_Impl::hasLocale( const lang::Locale& rLocale ) 800 throw(uno::RuntimeException) 801 { 802 GetHyph_Impl(); 803 sal_Bool bRes = sal_False; 804 if (xHyph.is()) 805 bRes = xHyph->hasLocale( rLocale ); 806 return bRes; 807 } 808 809 810 uno::Reference< linguistic2::XHyphenatedWord > SAL_CALL 811 HyphDummy_Impl::hyphenate( 812 const rtl::OUString& rWord, 813 const lang::Locale& rLocale, 814 sal_Int16 nMaxLeading, 815 const beans::PropertyValues& rProperties ) 816 throw(lang::IllegalArgumentException, 817 uno::RuntimeException) 818 { 819 GetHyph_Impl(); 820 uno::Reference< linguistic2::XHyphenatedWord > xRes; 821 if (xHyph.is()) 822 xRes = xHyph->hyphenate( rWord, rLocale, nMaxLeading, rProperties ); 823 return xRes; 824 } 825 826 827 uno::Reference< linguistic2::XHyphenatedWord > SAL_CALL 828 HyphDummy_Impl::queryAlternativeSpelling( 829 const rtl::OUString& rWord, 830 const lang::Locale& rLocale, 831 sal_Int16 nIndex, 832 const PropertyValues& rProperties ) 833 throw(lang::IllegalArgumentException, 834 uno::RuntimeException) 835 { 836 GetHyph_Impl(); 837 uno::Reference< linguistic2::XHyphenatedWord > xRes; 838 if (xHyph.is()) 839 xRes = xHyph->queryAlternativeSpelling( rWord, rLocale, nIndex, rProperties ); 840 return xRes; 841 } 842 843 844 uno::Reference< linguistic2::XPossibleHyphens > SAL_CALL 845 HyphDummy_Impl::createPossibleHyphens( 846 const rtl::OUString& rWord, 847 const lang::Locale& rLocale, 848 const beans::PropertyValues& rProperties ) 849 throw(lang::IllegalArgumentException, 850 uno::RuntimeException) 851 { 852 GetHyph_Impl(); 853 uno::Reference< linguistic2::XPossibleHyphens > xRes; 854 if (xHyph.is()) 855 xRes = xHyph->createPossibleHyphens( rWord, rLocale, rProperties ); 856 return xRes; 857 } 858 859 860 /////////////////////////////////////////////////////////////////////////// 861 862 863 typedef cppu::WeakImplHelper1 < XEventListener > LinguMgrAppExitLstnrBaseClass; 864 865 class LinguMgrAppExitLstnr : public LinguMgrAppExitLstnrBaseClass 866 { 867 uno::Reference< XComponent > xDesktop; 868 869 public: 870 LinguMgrAppExitLstnr(); 871 virtual ~LinguMgrAppExitLstnr(); 872 873 virtual void AtExit() = 0; 874 875 876 // lang::XEventListener 877 virtual void SAL_CALL disposing(const EventObject& rSource) 878 throw( RuntimeException ); 879 }; 880 881 LinguMgrAppExitLstnr::LinguMgrAppExitLstnr() 882 { 883 // add object to frame::Desktop EventListeners in order to properly call 884 // the AtExit function at appliction exit. 885 886 uno::Reference< XMultiServiceFactory > xMgr = getProcessServiceFactory(); 887 if ( xMgr.is() ) 888 { 889 xDesktop = uno::Reference< XComponent > ( xMgr->createInstance( 890 OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.frame.Desktop" ) ) ), UNO_QUERY ) ; 891 if (xDesktop.is()) 892 xDesktop->addEventListener( this ); 893 } 894 } 895 896 LinguMgrAppExitLstnr::~LinguMgrAppExitLstnr() 897 { 898 if (xDesktop.is()) 899 { 900 xDesktop->removeEventListener( this ); 901 xDesktop = NULL; //! release reference to desktop 902 } 903 DBG_ASSERT(!xDesktop.is(), "reference to desktop should be realeased"); 904 } 905 906 void LinguMgrAppExitLstnr::disposing(const EventObject& rSource) 907 throw( RuntimeException ) 908 { 909 if (xDesktop.is() && rSource.Source == xDesktop) 910 { 911 xDesktop->removeEventListener( this ); 912 xDesktop = NULL; //! release reference to desktop 913 914 AtExit(); 915 } 916 } 917 918 /////////////////////////////////////////////////////////////////////////// 919 920 class LinguMgrExitLstnr : public LinguMgrAppExitLstnr 921 { 922 public: 923 virtual void AtExit(); 924 }; 925 926 void LinguMgrExitLstnr::AtExit() 927 { 928 // release references 929 LinguMgr::xLngSvcMgr = 0; 930 LinguMgr::xSpell = 0; 931 LinguMgr::xHyph = 0; 932 LinguMgr::xThes = 0; 933 LinguMgr::xDicList = 0; 934 LinguMgr::xProp = 0; 935 LinguMgr::xIgnoreAll = 0; 936 LinguMgr::xChangeAll = 0; 937 938 LinguMgr::bExiting = sal_True; 939 940 //TL:TODO: MBA fragen wie ich ohne Absturz hier meinen Speicher 941 // wieder freibekomme... 942 //delete LinguMgr::pExitLstnr; 943 LinguMgr::pExitLstnr = 0; 944 } 945 946 /////////////////////////////////////////////////////////////////////////// 947 948 949 // static member initialization 950 LinguMgrExitLstnr * LinguMgr::pExitLstnr = 0; 951 sal_Bool LinguMgr::bExiting = sal_False; 952 uno::Reference< XLinguServiceManager > LinguMgr::xLngSvcMgr = 0; 953 uno::Reference< XSpellChecker1 > LinguMgr::xSpell = 0; 954 uno::Reference< XHyphenator > LinguMgr::xHyph = 0; 955 uno::Reference< XThesaurus > LinguMgr::xThes = 0; 956 uno::Reference< XDictionaryList > LinguMgr::xDicList = 0; 957 uno::Reference< XPropertySet > LinguMgr::xProp = 0; 958 uno::Reference< XDictionary > LinguMgr::xIgnoreAll = 0; 959 uno::Reference< XDictionary > LinguMgr::xChangeAll = 0; 960 961 962 uno::Reference< XLinguServiceManager > LinguMgr::GetLngSvcMgr() 963 { 964 if (bExiting) 965 return 0; 966 967 if (!pExitLstnr) 968 pExitLstnr = new LinguMgrExitLstnr; 969 970 if (!xLngSvcMgr.is()) 971 xLngSvcMgr = GetLngSvcMgr_Impl(); 972 973 return xLngSvcMgr; 974 } 975 976 977 uno::Reference< XSpellChecker1 > LinguMgr::GetSpellChecker() 978 { 979 return xSpell.is() ? xSpell : GetSpell(); 980 } 981 982 uno::Reference< XHyphenator > LinguMgr::GetHyphenator() 983 { 984 return xHyph.is() ? xHyph : GetHyph(); 985 } 986 987 uno::Reference< XThesaurus > LinguMgr::GetThesaurus() 988 { 989 return xThes.is() ? xThes : GetThes(); 990 } 991 992 uno::Reference< XDictionaryList > LinguMgr::GetDictionaryList() 993 { 994 return xDicList.is() ? xDicList : GetDicList(); 995 } 996 997 uno::Reference< XPropertySet > LinguMgr::GetLinguPropertySet() 998 { 999 return xProp.is() ? xProp : GetProp(); 1000 } 1001 1002 uno::Reference< XDictionary > LinguMgr::GetStandardDic() 1003 { 1004 //! don't hold reference to this 1005 //! (it may be removed from dictionary list and needs to be 1006 //! created empty if accessed again) 1007 return GetStandard(); 1008 } 1009 1010 uno::Reference< XDictionary > LinguMgr::GetIgnoreAllList() 1011 { 1012 return xIgnoreAll.is() ? xIgnoreAll : GetIgnoreAll(); 1013 } 1014 1015 uno::Reference< XDictionary > LinguMgr::GetChangeAllList() 1016 { 1017 return xChangeAll.is() ? xChangeAll : GetChangeAll(); 1018 } 1019 1020 uno::Reference< XSpellChecker1 > LinguMgr::GetSpell() 1021 { 1022 if (bExiting) 1023 return 0; 1024 1025 if (!pExitLstnr) 1026 pExitLstnr = new LinguMgrExitLstnr; 1027 1028 //! use dummy implementation in order to avoid loading of lingu DLL 1029 xSpell = new SpellDummy_Impl; 1030 1031 /* if (!xLngSvcMgr.is()) 1032 xLngSvcMgr = GetLngSvcMgr_Impl(); 1033 1034 if (xLngSvcMgr.is()) 1035 { 1036 xSpell = uno::Reference< XSpellChecker1 > ( 1037 xLngSvcMgr->getSpellChecker(), UNO_QUERY ); 1038 } 1039 */ 1040 return xSpell; 1041 } 1042 1043 uno::Reference< XHyphenator > LinguMgr::GetHyph() 1044 { 1045 if (bExiting) 1046 return 0; 1047 1048 if (!pExitLstnr) 1049 pExitLstnr = new LinguMgrExitLstnr; 1050 1051 //! use dummy implementation in order to avoid loading of lingu DLL 1052 xHyph = new HyphDummy_Impl; 1053 1054 /* 1055 if (!xLngSvcMgr.is()) 1056 xLngSvcMgr = GetLngSvcMgr_Impl(); 1057 1058 if (xLngSvcMgr.is()) 1059 { 1060 xHyph = xLngSvcMgr->getHyphenator(); 1061 } 1062 */ 1063 return xHyph; 1064 } 1065 1066 uno::Reference< XThesaurus > LinguMgr::GetThes() 1067 { 1068 if (bExiting) 1069 return 0; 1070 1071 if (!pExitLstnr) 1072 pExitLstnr = new LinguMgrExitLstnr; 1073 1074 //! use dummy implementation in order to avoid loading of lingu DLL 1075 //! when only the XSupportedLocales interface is used. 1076 //! The dummy accesses the real implementation (and thus loading the DLL) 1077 //! when "real" work needs to be done only. 1078 xThes = new ThesDummy_Impl; 1079 /* 1080 if (!xLngSvcMgr.is()) 1081 xLngSvcMgr = GetLngSvcMgr_Impl(); 1082 1083 if (xLngSvcMgr.is()) 1084 { 1085 xThes = xLngSvcMgr->getThesaurus(); 1086 } 1087 */ 1088 return xThes; 1089 } 1090 1091 1092 void LinguMgr::UpdateAll() 1093 { 1094 } 1095 1096 1097 uno::Reference< XDictionaryList > LinguMgr::GetDicList() 1098 { 1099 if (bExiting) 1100 return 0; 1101 1102 if (!pExitLstnr) 1103 pExitLstnr = new LinguMgrExitLstnr; 1104 1105 uno::Reference< XMultiServiceFactory > xMgr( getProcessServiceFactory() ); 1106 if (xMgr.is()) 1107 { 1108 xDicList = uno::Reference< XDictionaryList > ( xMgr->createInstance( 1109 A2OU("com.sun.star.linguistic2.DictionaryList") ), UNO_QUERY ); 1110 } 1111 return xDicList; 1112 } 1113 1114 uno::Reference< XPropertySet > LinguMgr::GetProp() 1115 { 1116 if (bExiting) 1117 return 0; 1118 1119 if (!pExitLstnr) 1120 pExitLstnr = new LinguMgrExitLstnr; 1121 1122 uno::Reference< XMultiServiceFactory > xMgr( getProcessServiceFactory() ); 1123 if (xMgr.is()) 1124 { 1125 xProp = uno::Reference< XPropertySet > ( xMgr->createInstance( 1126 A2OU("com.sun.star.linguistic2.LinguProperties") ), UNO_QUERY ); 1127 } 1128 return xProp; 1129 } 1130 1131 uno::Reference< XDictionary > LinguMgr::GetIgnoreAll() 1132 { 1133 if (bExiting) 1134 return 0; 1135 1136 if (!pExitLstnr) 1137 pExitLstnr = new LinguMgrExitLstnr; 1138 1139 uno::Reference< XDictionaryList > xTmpDicList( GetDictionaryList() ); 1140 if (xTmpDicList.is()) 1141 { 1142 xIgnoreAll = uno::Reference< XDictionary > ( xTmpDicList->getDictionaryByName( 1143 A2OU("IgnoreAllList") ), UNO_QUERY ); 1144 } 1145 return xIgnoreAll; 1146 } 1147 1148 uno::Reference< XDictionary > LinguMgr::GetChangeAll() 1149 { 1150 if (bExiting) 1151 return 0; 1152 1153 if (!pExitLstnr) 1154 pExitLstnr = new LinguMgrExitLstnr; 1155 1156 uno::Reference< XDictionaryList > _xDicList( GetDictionaryList() , UNO_QUERY ); 1157 if (_xDicList.is()) 1158 { 1159 xChangeAll = uno::Reference< XDictionary > ( 1160 _xDicList->createDictionary( 1161 A2OU("ChangeAllList"), 1162 SvxCreateLocale( LANGUAGE_NONE ), 1163 DictionaryType_NEGATIVE, String() ), UNO_QUERY ); 1164 } 1165 return xChangeAll; 1166 } 1167 1168 uno::Reference< XDictionary > LinguMgr::GetStandard() 1169 { 1170 // Tries to return a dictionary which may hold positive entries is 1171 // persistent and not read-only. 1172 1173 if (bExiting) 1174 return 0; 1175 1176 uno::Reference< XDictionaryList > xTmpDicList( GetDictionaryList() ); 1177 if (!xTmpDicList.is()) 1178 return NULL; 1179 1180 const OUString aDicName( RTL_CONSTASCII_USTRINGPARAM( "standard.dic" ) ); 1181 uno::Reference< XDictionary > xDic( xTmpDicList->getDictionaryByName( aDicName ), 1182 UNO_QUERY ); 1183 if (!xDic.is()) 1184 { 1185 // try to create standard dictionary 1186 uno::Reference< XDictionary > xTmp; 1187 try 1188 { 1189 xTmp = xTmpDicList->createDictionary( aDicName, 1190 SvxCreateLocale( LANGUAGE_NONE ), 1191 DictionaryType_POSITIVE, 1192 linguistic::GetWritableDictionaryURL( aDicName ) ); 1193 } 1194 catch(com::sun::star::uno::Exception &) 1195 { 1196 } 1197 1198 // add new dictionary to list 1199 if (xTmp.is()) 1200 { 1201 xTmpDicList->addDictionary( xTmp ); 1202 xTmp->setActive( sal_True ); 1203 } 1204 xDic = uno::Reference< XDictionary > ( xTmp, UNO_QUERY ); 1205 } 1206 #if OSL_DEBUG_LEVEL > 1 1207 uno::Reference< XStorable > xStor( xDic, UNO_QUERY ); 1208 DBG_ASSERT( xDic.is() && xDic->getDictionaryType() == DictionaryType_POSITIVE, 1209 "wrong dictionary type"); 1210 DBG_ASSERT( xDic.is() && SvxLocaleToLanguage( xDic->getLocale() ) == LANGUAGE_NONE, 1211 "wrong dictionary language"); 1212 DBG_ASSERT( !xStor.is() || (xStor->hasLocation() && !xStor->isReadonly()), 1213 "dictionary not editable" ); 1214 #endif 1215 1216 return xDic; 1217 } 1218 1219 /////////////////////////////////////////////////////////////////////////// 1220 1221 uno::Reference< XSpellChecker1 > SvxGetSpellChecker() 1222 { 1223 return LinguMgr::GetSpellChecker(); 1224 } 1225 1226 uno::Reference< XHyphenator > SvxGetHyphenator() 1227 { 1228 return LinguMgr::GetHyphenator(); 1229 } 1230 1231 uno::Reference< XThesaurus > SvxGetThesaurus() 1232 { 1233 return LinguMgr::GetThesaurus(); 1234 } 1235 1236 uno::Reference< XDictionaryList > SvxGetDictionaryList() 1237 { 1238 return LinguMgr::GetDictionaryList(); 1239 } 1240 1241 uno::Reference< XPropertySet > SvxGetLinguPropertySet() 1242 { 1243 return LinguMgr::GetLinguPropertySet(); 1244 } 1245 1246 //TL:TODO: remove argument or provide SvxGetIgnoreAllList with the same one 1247 uno::Reference< XDictionary > SvxGetOrCreatePosDic( 1248 uno::Reference< XDictionaryList > /* xDicList */ ) 1249 { 1250 return LinguMgr::GetStandardDic(); 1251 } 1252 1253 uno::Reference< XDictionary > SvxGetIgnoreAllList() 1254 { 1255 return LinguMgr::GetIgnoreAllList(); 1256 } 1257 1258 uno::Reference< XDictionary > SvxGetChangeAllList() 1259 { 1260 return LinguMgr::GetChangeAllList(); 1261 } 1262 1263 /////////////////////////////////////////////////////////////////////////// 1264 1265 1266 #include <com/sun/star/linguistic2/XHyphenatedWord.hpp> 1267 1268 SvxAlternativeSpelling SvxGetAltSpelling( 1269 const ::com::sun::star::uno::Reference< 1270 ::com::sun::star::linguistic2::XHyphenatedWord > & rHyphWord ) 1271 { 1272 SvxAlternativeSpelling aRes; 1273 if (rHyphWord.is() && rHyphWord->isAlternativeSpelling()) 1274 { 1275 OUString aWord( rHyphWord->getWord() ), 1276 aAltWord( rHyphWord->getHyphenatedWord() ); 1277 sal_Int16 nHyphenationPos = rHyphWord->getHyphenationPos(), 1278 nHyphenPos = rHyphWord->getHyphenPos(); 1279 sal_Int16 nLen = (sal_Int16)aWord.getLength(); 1280 sal_Int16 nAltLen = (sal_Int16)aAltWord.getLength(); 1281 const sal_Unicode *pWord = aWord.getStr(), 1282 *pAltWord = aAltWord.getStr(); 1283 1284 // count number of chars from the left to the 1285 // hyphenation pos / hyphen pos that are equal 1286 sal_Int16 nL = 0; 1287 while (nL <= nHyphenationPos && nL <= nHyphenPos 1288 && pWord[ nL ] == pAltWord[ nL ]) 1289 ++nL; 1290 // count number of chars from the right to the 1291 // hyphenation pos / hyphen pos that are equal 1292 sal_Int16 nR = 0; 1293 sal_Int32 nIdx = nLen - 1; 1294 sal_Int32 nAltIdx = nAltLen - 1; 1295 while (nIdx > nHyphenationPos && nAltIdx > nHyphenPos 1296 && pWord[ nIdx-- ] == pAltWord[ nAltIdx-- ]) 1297 ++nR; 1298 1299 aRes.aReplacement = OUString( aAltWord.copy( nL, nAltLen - nL - nR ) ); 1300 aRes.nChangedPos = (sal_Int16) nL; 1301 aRes.nChangedLength = nLen - nL - nR; 1302 aRes.bIsAltSpelling = sal_True; 1303 aRes.xHyphWord = rHyphWord; 1304 } 1305 return aRes; 1306 } 1307 1308 1309 /////////////////////////////////////////////////////////////////////////// 1310 1311 SvxDicListChgClamp::SvxDicListChgClamp( uno::Reference< XDictionaryList > &rxDicList ) : 1312 xDicList ( rxDicList ) 1313 { 1314 if (xDicList.is()) 1315 { 1316 xDicList->beginCollectEvents(); 1317 } 1318 } 1319 1320 SvxDicListChgClamp::~SvxDicListChgClamp() 1321 { 1322 if (xDicList.is()) 1323 { 1324 xDicList->endCollectEvents(); 1325 } 1326 } 1327 1328 /////////////////////////////////////////////////////////////////////////// 1329 1330 short SvxDicError( Window *pParent, sal_Int16 nError ) 1331 { 1332 short nRes = 0; 1333 if (DIC_ERR_NONE != nError) 1334 { 1335 int nRid; 1336 switch (nError) 1337 { 1338 case DIC_ERR_FULL : nRid = RID_SVXSTR_DIC_ERR_FULL; break; 1339 case DIC_ERR_READONLY : nRid = RID_SVXSTR_DIC_ERR_READONLY; break; 1340 default: 1341 nRid = RID_SVXSTR_DIC_ERR_UNKNOWN; 1342 DBG_ASSERT(0, "unexpected case"); 1343 } 1344 nRes = InfoBox( pParent, EE_RESSTR( nRid ) ).Execute(); 1345 } 1346 return nRes; 1347 } 1348 1349 LanguageType SvxLocaleToLanguage( const Locale& rLocale ) 1350 { 1351 // empty Locale -> LANGUAGE_NONE 1352 if ( rLocale.Language.getLength() == 0 ) 1353 return LANGUAGE_NONE; 1354 1355 return MsLangId::convertLocaleToLanguage( rLocale ); 1356 } 1357 1358 Locale& SvxLanguageToLocale( Locale& rLocale, LanguageType eLang ) 1359 { 1360 if ( eLang != LANGUAGE_NONE /* && eLang != LANGUAGE_SYSTEM */) 1361 MsLangId::convertLanguageToLocale( eLang, rLocale ); 1362 else 1363 rLocale = Locale(); 1364 1365 return rLocale; 1366 } 1367 1368 Locale SvxCreateLocale( LanguageType eLang ) 1369 { 1370 Locale aLocale; 1371 if ( eLang != LANGUAGE_NONE /* && eLang != LANGUAGE_SYSTEM */) 1372 MsLangId::convertLanguageToLocale( eLang, aLocale ); 1373 1374 return aLocale; 1375 } 1376 1377 1378