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