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_cui.hxx" 26 27 // include --------------------------------------------------------------- 28 29 #include <vcl/msgbox.hxx> 30 #include <vcl/field.hxx> 31 #include <vcl/fixed.hxx> 32 #include <tools/shl.hxx> 33 #include <tools/dynary.hxx> 34 #include <i18npool/mslangid.hxx> 35 #include <unotools/lingucfg.hxx> 36 #include <editeng/unolingu.hxx> 37 #include <svx/dlgutil.hxx> 38 #include <linguistic/lngprops.hxx> 39 #include <linguistic/misc.hxx> 40 #include <sfx2/sfxuno.hxx> 41 #include <sfx2/dispatch.hxx> 42 #include <tools/urlobj.hxx> 43 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 44 #include <comphelper/processfactory.hxx> 45 #include <com/sun/star/linguistic2/XSpellChecker.hpp> 46 #include <com/sun/star/linguistic2/XProofreader.hpp> 47 #include <com/sun/star/linguistic2/XHyphenator.hpp> 48 #include <com/sun/star/linguistic2/XThesaurus.hpp> 49 #include <com/sun/star/linguistic2/XAvailableLocales.hpp> 50 #include <com/sun/star/lang/XServiceDisplayName.hpp> 51 #include <com/sun/star/linguistic2/DictionaryListEventFlags.hpp> 52 #include <com/sun/star/linguistic2/DictionaryListEvent.hpp> 53 #include <com/sun/star/linguistic2/XDictionaryListEventListener.hpp> 54 #include <com/sun/star/linguistic2/XDictionaryList.hpp> 55 #include <com/sun/star/frame/XStorable.hpp> 56 #include <com/sun/star/ucb/CommandAbortedException.hpp> 57 #include <com/sun/star/system/XSystemShellExecute.hpp> 58 #include <com/sun/star/system/SystemShellExecuteFlags.hpp> 59 #include <unotools/extendedsecurityoptions.hxx> 60 #include <svtools/svlbox.hxx> 61 #include <svl/eitem.hxx> 62 #include <svl/intitem.hxx> 63 #include <sfx2/viewfrm.hxx> 64 #include <vcl/svapp.hxx> 65 #define _SVX_OPTLINGU_CXX 66 #include "optlingu.hrc" 67 68 #include <svx/svxdlg.hxx> 69 #include <editeng/optitems.hxx> 70 #include "optlingu.hxx" 71 #include <dialmgr.hxx> 72 #include <cuires.hrc> 73 #include "helpid.hrc" 74 75 #include <ucbhelper/content.hxx> 76 77 #include <vector> 78 #include <map> 79 80 81 using namespace ::ucbhelper; 82 using namespace ::rtl; 83 using namespace ::com::sun::star; 84 using namespace ::com::sun::star::lang; 85 using namespace ::com::sun::star::uno; 86 using namespace ::com::sun::star::linguistic2; 87 using namespace ::com::sun::star::beans; 88 namespace css = com::sun::star; 89 90 #define C2U(cChar) OUString::createFromAscii(cChar) 91 #define SVX_MAX_USERDICTS 20 92 #define CBCOL_FIRST 0 93 #define CBCOL_SECOND 1 94 #define CBCOL_BOTH 2 95 96 static const sal_Char cSpell[] = SN_SPELLCHECKER; 97 static const sal_Char cGrammar[] = SN_GRAMMARCHECKER; 98 static const sal_Char cHyph[] = SN_HYPHENATOR; 99 static const sal_Char cThes[] = SN_THESAURUS; 100 101 // static ---------------------------------------------------------------- 102 103 static Sequence< sal_Int16 > lcl_LocaleSeqToLangSeq( const Sequence< Locale > &rSeq ) 104 { 105 sal_Int32 nLen = rSeq.getLength(); 106 Sequence< sal_Int16 > aRes( nLen ); 107 sal_Int16 *pRes = aRes.getArray(); 108 const Locale *pSeq = rSeq.getConstArray(); 109 for (sal_Int32 i = 0; i < nLen; ++i) 110 { 111 pRes[i] = SvxLocaleToLanguage( pSeq[i] ); 112 } 113 return aRes; 114 } 115 116 117 static sal_Bool lcl_SeqHasLang( const Sequence< sal_Int16 > &rSeq, sal_Int16 nLang ) 118 { 119 sal_Int32 nLen = rSeq.getLength(); 120 const sal_Int16 *pLang = rSeq.getConstArray(); 121 sal_Int32 nPos = -1; 122 for (sal_Int32 i = 0; i < nLen && nPos < 0; ++i) 123 { 124 if (nLang == pLang[i]) 125 nPos = i; 126 } 127 return nPos < 0 ? sal_False : sal_True; 128 } 129 130 131 static sal_Int32 lcl_SeqGetEntryPos( 132 const Sequence< OUString > &rSeq, const OUString &rEntry ) 133 { 134 sal_Int32 i; 135 sal_Int32 nLen = rSeq.getLength(); 136 const OUString *pItem = rSeq.getConstArray(); 137 for (i = 0; i < nLen; ++i) 138 { 139 if (rEntry == pItem[i]) 140 break; 141 } 142 return i < nLen ? i : -1; 143 } 144 145 static void lcl_OpenURL( const ::rtl::OUString& rURL ) 146 { 147 if ( rURL.getLength() > 0 ) 148 { 149 try 150 { 151 uno::Reference< lang::XMultiServiceFactory > xSMGR = 152 ::comphelper::getProcessServiceFactory(); 153 uno::Reference< css::system::XSystemShellExecute > xSystemShell( 154 xSMGR->createInstance( ::rtl::OUString( 155 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.system.SystemShellExecute" ) ) ), 156 uno::UNO_QUERY_THROW ); 157 if ( xSystemShell.is() ) 158 xSystemShell->execute( rURL, ::rtl::OUString(), css::system::SystemShellExecuteFlags::DEFAULTS ); 159 } 160 catch( const uno::Exception& e ) 161 { 162 OSL_TRACE( "Caught exception: %s\n thread terminated.\n", 163 rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr()); 164 } 165 } 166 } 167 168 /*-------------------------------------------------- 169 --------------------------------------------------*/ 170 171 static const sal_uInt16 nNameLen = 8; 172 173 static sal_uInt16 pRanges[] = 174 { 175 SID_ATTR_SPELL, 176 SID_ATTR_SPELL, 177 0 178 }; 179 180 sal_Bool KillFile_Impl( const String& rURL ) 181 { 182 sal_Bool bRet = sal_True; 183 try 184 { 185 Content aCnt( rURL, uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () ); 186 aCnt.executeCommand( OUString::createFromAscii( "delete" ), makeAny( sal_Bool( sal_True ) ) ); 187 } 188 catch( ::com::sun::star::ucb::CommandAbortedException& ) 189 { 190 DBG_ERRORFILE( "KillFile: CommandAbortedException" ); 191 bRet = sal_False; 192 } 193 catch( ... ) 194 { 195 DBG_ERRORFILE( "KillFile: Any other exception" ); 196 bRet = sal_False; 197 } 198 199 return bRet; 200 } 201 /* -----------------------------27.11.00 14:07-------------------------------- 202 203 ---------------------------------------------------------------------------*/ 204 // 0x 0p 0t 0c nn 205 // p: 1 -> parent 206 // t: 1 -> spell, 2 -> hyph, 3 -> thes, 4 -> grammar 207 // c: 1 -> checked 0 -> unchecked 208 // n: index 209 210 #define TYPE_SPELL (sal_uInt8)1 211 #define TYPE_GRAMMAR (sal_uInt8)2 212 #define TYPE_HYPH (sal_uInt8)3 213 #define TYPE_THES (sal_uInt8)4 214 215 class ModuleUserData_Impl 216 { 217 sal_Bool bParent; 218 sal_Bool bIsChecked; 219 sal_uInt8 nType; 220 sal_uInt8 nIndex; 221 String sImplName; 222 223 public: 224 ModuleUserData_Impl( String sImpName, sal_Bool bIsParent, sal_Bool bChecked, sal_uInt8 nSetType, sal_uInt8 nSetIndex ) : 225 bParent(bIsParent), 226 bIsChecked(bChecked), 227 nType(nSetType), 228 nIndex(nSetIndex), 229 sImplName(sImpName) 230 { 231 } 232 sal_Bool IsParent() const {return bParent;} 233 sal_uInt8 GetType() const {return nType;} 234 sal_Bool IsChecked() const {return bIsChecked;} 235 sal_uInt8 GetIndex() const {return nIndex;} 236 void SetIndex(sal_uInt8 nSet) {nIndex = nSet;} 237 const String& GetImplName() const {return sImplName;} 238 239 }; 240 241 /*-------------------------------------------------- 242 --------------------------------------------------*/ 243 // 244 // User for user-dictionaries (XDictionary interface) 245 // 246 class DicUserData 247 { 248 sal_uLong nVal; 249 250 public: 251 DicUserData( sal_uLong nUserData ) : nVal( nUserData ) {} 252 DicUserData( sal_uInt16 nEID, 253 sal_Bool bChecked, sal_Bool bEditable, sal_Bool bDeletable ); 254 255 sal_uLong GetUserData() const { return nVal; } 256 sal_uInt16 GetEntryId() const { return (sal_uInt16)(nVal >> 16); } 257 sal_Bool IsChecked() const { return (sal_Bool)(nVal >> 8) & 0x01; } 258 sal_Bool IsEditable() const { return (sal_Bool)(nVal >> 9) & 0x01; } 259 sal_Bool IsDeletable() const { return (sal_Bool)(nVal >> 10) & 0x01; } 260 261 void SetChecked( sal_Bool bVal ); 262 }; 263 264 265 DicUserData::DicUserData( 266 sal_uInt16 nEID, 267 sal_Bool bChecked, sal_Bool bEditable, sal_Bool bDeletable ) 268 { 269 DBG_ASSERT( nEID < 65000, "Entry Id out of range" ); 270 nVal = ((sal_uLong)(0xFFFF & nEID) << 16) | 271 ((sal_uLong)(bChecked ? 1 : 0) << 8) | 272 ((sal_uLong)(bEditable ? 1 : 0) << 9) | 273 ((sal_uLong)(bDeletable ? 1 : 0) << 10); 274 } 275 276 277 void DicUserData::SetChecked( sal_Bool bVal ) 278 { 279 nVal &= ~(1UL << 8); 280 nVal |= (sal_uLong)(bVal ? 1 : 0) << 8; 281 } 282 283 284 // class BrwString_Impl ------------------------------------------------- 285 286 void lcl_SetCheckButton( SvLBoxEntry* pEntry, sal_Bool bCheck ) 287 { 288 SvLBoxButton* pItem = (SvLBoxButton*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXBUTTON)); 289 290 DBG_ASSERT(pItem,"SetCheckButton:Item not found"); 291 if (((SvLBoxItem*)pItem)->IsA() == SV_ITEM_ID_LBOXBUTTON) 292 { 293 if (bCheck) 294 pItem->SetStateChecked(); 295 else 296 pItem->SetStateUnchecked(); 297 //InvalidateEntry( pEntry ); 298 } 299 } 300 301 302 class BrwStringDic_Impl : public SvLBoxString 303 { 304 public: 305 306 BrwStringDic_Impl( SvLBoxEntry* pEntry, sal_uInt16 nFlags, 307 const String& rStr ) : SvLBoxString( pEntry, nFlags, rStr ) {} 308 309 virtual void Paint( const Point& rPos, SvLBox& rDev, sal_uInt16 nFlags, 310 SvLBoxEntry* pEntry); 311 }; 312 313 void BrwStringDic_Impl::Paint( const Point& rPos, SvLBox& rDev, sal_uInt16, 314 SvLBoxEntry* pEntry ) 315 { 316 ModuleUserData_Impl* pData = (ModuleUserData_Impl*)pEntry->GetUserData(); 317 Point aPos(rPos); 318 Font aOldFont( rDev.GetFont()); 319 if(pData->IsParent()) 320 { 321 Font aFont( aOldFont ); 322 aFont.SetWeight( WEIGHT_BOLD ); 323 rDev.SetFont( aFont ); 324 aPos.X() = 0; 325 } 326 else 327 aPos.X() += 5; 328 rDev.DrawText( aPos, GetText() ); 329 rDev.SetFont( aOldFont ); 330 } 331 332 333 /*-------------------------------------------------- 334 --------------------------------------------------*/ 335 336 class OptionsBreakSet : public ModalDialog 337 { 338 OKButton aOKPB; 339 CancelButton aCancelPB; 340 FixedLine aValFL; 341 NumericField aValNF; 342 343 public: 344 OptionsBreakSet(Window* pParent, int nRID) : 345 ModalDialog(pParent, CUI_RES(RID_SVXDLG_LNG_ED_NUM_PREBREAK )), 346 aOKPB (this, CUI_RES(BT_OK_PREBREAK)), 347 aCancelPB (this, CUI_RES(BT_CANCEL_PREBREAK)), 348 aValFL (this, CUI_RES(FL_NUMVAL_PREBREAK)), 349 aValNF (this, CUI_RES(ED_PREBREAK)) 350 { 351 DBG_ASSERT( STR_NUM_PRE_BREAK_DLG == nRID || 352 STR_NUM_POST_BREAK_DLG == nRID || 353 STR_NUM_MIN_WORDLEN_DLG == nRID, "unexpected RID" ); 354 355 if (nRID != -1) 356 aValFL.SetText( String( CUI_RES(nRID) ) ); 357 FreeResource(); 358 } 359 360 NumericField& GetNumericFld() { return aValNF; } 361 }; 362 363 364 /*-------------------------------------------------- 365 Entry IDs for options listbox of dialog 366 --------------------------------------------------*/ 367 368 enum EID_OPTIONS 369 { 370 EID_SPELL_AUTO, 371 EID_GRAMMAR_AUTO, 372 EID_CAPITAL_WORDS, 373 EID_WORDS_WITH_DIGITS, 374 EID_CAPITALIZATION, 375 EID_SPELL_SPECIAL, 376 EID_NUM_MIN_WORDLEN, 377 EID_NUM_PRE_BREAK, 378 EID_NUM_POST_BREAK, 379 EID_HYPH_AUTO, 380 EID_HYPH_SPECIAL 381 }; 382 383 //! this array must have an entry for every value of EID_OPTIONS. 384 // It is used to get the respective property name. 385 static const char * aEidToPropName[] = 386 { 387 UPN_IS_SPELL_AUTO, // EID_SPELL_AUTO 388 UPN_IS_GRAMMAR_AUTO, // EID_GRAMMAR_AUTO 389 UPN_IS_SPELL_UPPER_CASE, // EID_CAPITAL_WORDS 390 UPN_IS_SPELL_WITH_DIGITS, // EID_WORDS_WITH_DIGITS 391 UPN_IS_SPELL_CAPITALIZATION, // EID_CAPITALIZATION 392 UPN_IS_SPELL_SPECIAL, // EID_SPELL_SPECIAL 393 UPN_HYPH_MIN_WORD_LENGTH, // EID_NUM_MIN_WORDLEN, 394 UPN_HYPH_MIN_LEADING, // EID_NUM_PRE_BREAK 395 UPN_HYPH_MIN_TRAILING, // EID_NUM_POST_BREAK 396 UPN_IS_HYPH_AUTO, // EID_HYPH_AUTO 397 UPN_IS_HYPH_SPECIAL // EID_HYPH_SPECIAL 398 }; 399 400 401 static inline String lcl_GetPropertyName( EID_OPTIONS eEntryId ) 402 { 403 DBG_ASSERT( (unsigned int) eEntryId < sizeof(aEidToPropName) / sizeof(aEidToPropName[0]), "index out of range" ); 404 return String::CreateFromAscii( aEidToPropName[ (int) eEntryId ] ); 405 } 406 407 // class OptionsUserData ------------------------------------------------- 408 409 class OptionsUserData 410 { 411 sal_uLong nVal; 412 413 void SetModified(); 414 415 public: 416 OptionsUserData( sal_uLong nUserData ) : nVal( nUserData ) {} 417 OptionsUserData( sal_uInt16 nEID, 418 sal_Bool bHasNV, sal_uInt16 nNumVal, 419 sal_Bool bCheckable, sal_Bool bChecked ); 420 421 sal_uLong GetUserData() const { return nVal; } 422 sal_uInt16 GetEntryId() const { return (sal_uInt16)(nVal >> 16); } 423 sal_Bool HasNumericValue() const { return (sal_Bool)(nVal >> 10) & 0x01; } 424 sal_uInt16 GetNumericValue() const { return (sal_uInt16)(nVal & 0xFF); } 425 sal_Bool IsChecked() const { return (sal_Bool)(nVal >> 8) & 0x01; } 426 sal_Bool IsCheckable() const { return (sal_Bool)(nVal >> 9) & 0x01; } 427 sal_Bool IsModified() const { return (sal_Bool)(nVal >> 11) & 0x01; } 428 429 void SetChecked( sal_Bool bVal ); 430 void SetNumericValue( sal_uInt8 nNumVal ); 431 }; 432 433 OptionsUserData::OptionsUserData( sal_uInt16 nEID, 434 sal_Bool bHasNV, sal_uInt16 nNumVal, 435 sal_Bool bCheckable, sal_Bool bChecked ) 436 { 437 DBG_ASSERT( nEID < 65000, "Entry Id out of range" ); 438 DBG_ASSERT( nNumVal < 256, "value out of range" ); 439 nVal = ((sal_uLong)(0xFFFF & nEID) << 16) | 440 ((sal_uLong)(bHasNV ? 1 : 0) << 10) | 441 ((sal_uLong)(bCheckable ? 1 : 0) << 9) | 442 ((sal_uLong)(bChecked ? 1 : 0) << 8) | 443 ((sal_uLong)(0xFF & nNumVal)); 444 } 445 446 void OptionsUserData::SetChecked( sal_Bool bVal ) 447 { 448 if (IsCheckable() && (IsChecked() != bVal)) 449 { 450 nVal &= ~(1UL << 8); 451 nVal |= (sal_uLong)(bVal ? 1 : 0) << 8; 452 SetModified(); 453 } 454 } 455 456 void OptionsUserData::SetNumericValue( sal_uInt8 nNumVal ) 457 { 458 // DBG_ASSERT( nNumVal < 256, "value out of range" ); 459 if (HasNumericValue() && (GetNumericValue() != nNumVal)) 460 { 461 nVal &= 0xffffff00; 462 nVal |= (nNumVal); 463 SetModified(); 464 } 465 } 466 467 void OptionsUserData::SetModified() 468 { 469 nVal |= (sal_uLong)1 << 11; 470 } 471 472 // class BrwString_Impl ------------------------------------------------- 473 474 class BrwString_Impl : public SvLBoxString 475 { 476 public: 477 478 BrwString_Impl( SvLBoxEntry* pEntry, sal_uInt16 nFlags, 479 const String& rStr ) : SvLBoxString( pEntry, nFlags, rStr ) {} 480 481 virtual void Paint( const Point& rPos, SvLBox& rDev, sal_uInt16 nFlags, 482 SvLBoxEntry* pEntry); 483 }; 484 485 void BrwString_Impl::Paint( const Point& rPos, SvLBox& rDev, sal_uInt16, 486 SvLBoxEntry* pEntry ) 487 { 488 Point aPos(rPos); 489 aPos.X() += 20; 490 rDev.DrawText( aPos, GetText() ); 491 if(pEntry->GetUserData()) 492 { 493 Point aNewPos(aPos); 494 aNewPos.X() += rDev.GetTextWidth(GetText()); 495 Font aOldFont( rDev.GetFont()); 496 Font aFont( aOldFont ); 497 aFont.SetWeight( WEIGHT_BOLD ); 498 499 // sal_Bool bFett = sal_True; 500 // sal_uInt16 nPos = 0; 501 //??? das untere byte aus dem user data in string wandeln 502 OptionsUserData aData( (sal_uLong) pEntry->GetUserData() ); 503 if(aData.HasNumericValue()) 504 { 505 String sTxt( ' ' ); 506 sTxt += String::CreateFromInt32( aData.GetNumericValue() ); 507 rDev.SetFont( aFont ); 508 rDev.DrawText( aNewPos, sTxt ); 509 } 510 511 // if( STRING_NOTFOUND != nPos ) 512 // aNewPos.X() += rDev.GetTextWidth( sTxt ); 513 514 rDev.SetFont( aOldFont ); 515 } 516 } 517 518 // ServiceInfo_Impl ---------------------------------------------------- 519 520 struct ServiceInfo_Impl 521 { 522 OUString sDisplayName; 523 OUString sSpellImplName; 524 OUString sHyphImplName; 525 OUString sThesImplName; 526 OUString sGrammarImplName; 527 uno::Reference< XSpellChecker > xSpell; 528 uno::Reference< XHyphenator > xHyph; 529 uno::Reference< XThesaurus > xThes; 530 uno::Reference< XProofreader > xGrammar; 531 sal_Bool bConfigured; 532 533 ServiceInfo_Impl() : bConfigured(sal_False) {} 534 }; 535 536 typedef std::vector< ServiceInfo_Impl > ServiceInfoArr; 537 typedef std::map< sal_Int16 /*LanguageType*/, Sequence< OUString > > LangImplNameTable; 538 539 540 // SvxLinguData_Impl ---------------------------------------------------- 541 542 class SvxLinguData_Impl 543 { 544 //contains services and implementation names sorted by implementation names 545 ServiceInfoArr aDisplayServiceArr; 546 sal_uLong nDisplayServices; 547 548 Sequence< Locale > aAllServiceLocales; 549 LangImplNameTable aCfgSpellTable; 550 LangImplNameTable aCfgHyphTable; 551 LangImplNameTable aCfgThesTable; 552 LangImplNameTable aCfgGrammarTable; 553 uno::Reference< XMultiServiceFactory > xMSF; 554 uno::Reference< XLinguServiceManager > xLinguSrvcMgr; 555 556 557 sal_Bool AddRemove( Sequence< OUString > &rConfigured, 558 const OUString &rImplName, sal_Bool bAdd ); 559 560 public: 561 SvxLinguData_Impl(); 562 SvxLinguData_Impl( const SvxLinguData_Impl &rData ); 563 ~SvxLinguData_Impl(); 564 565 SvxLinguData_Impl & operator = (const SvxLinguData_Impl &rData); 566 567 uno::Reference<XLinguServiceManager> & GetManager() { return xLinguSrvcMgr; } 568 569 void SetChecked( const Sequence< OUString > &rConfiguredServices ); 570 void Reconfigure( const OUString &rDisplayName, sal_Bool bEnable ); 571 572 const Sequence<Locale> & GetAllSupportedLocales() { return aAllServiceLocales; } 573 574 const LangImplNameTable & GetSpellTable() const { return aCfgSpellTable; } 575 LangImplNameTable & GetSpellTable() { return aCfgSpellTable; } 576 const LangImplNameTable & GetHyphTable() const { return aCfgHyphTable; } 577 LangImplNameTable & GetHyphTable() { return aCfgHyphTable; } 578 const LangImplNameTable & GetThesTable() const { return aCfgThesTable; } 579 LangImplNameTable & GetThesTable() { return aCfgThesTable; } 580 const LangImplNameTable & GetGrammarTable() const { return aCfgGrammarTable; } 581 LangImplNameTable & GetGrammarTable() { return aCfgGrammarTable; } 582 583 const ServiceInfoArr & GetDisplayServiceArray() const { return aDisplayServiceArr; } 584 ServiceInfoArr & GetDisplayServiceArray() { return aDisplayServiceArr; } 585 586 const sal_uLong & GetDisplayServiceCount() const { return nDisplayServices; } 587 void SetDisplayServiceCount( sal_uLong nVal ) { nDisplayServices = nVal; } 588 589 // returns the list of service implementation names for the specified 590 // language and service (TYPE_SPELL, TYPE_HYPH, TYPE_THES) sorted in 591 // the proper order for the SvxEditModulesDlg (the ones from the 592 // configuration (keeping that order!) first and then the other ones. 593 // I.e. the ones available but not configured in arbitrary order). 594 // They available ones may contain names that do not(!) support that 595 // language. 596 Sequence< OUString > GetSortedImplNames( sal_Int16 nLang, sal_uInt8 nType ); 597 598 ServiceInfo_Impl * GetInfoByImplName( const OUString &rSvcImplName ); 599 }; 600 601 602 sal_Int32 lcl_SeqGetIndex( const Sequence< OUString > &rSeq, const OUString &rTxt ) 603 { 604 sal_Int32 nRes = -1; 605 sal_Int32 nLen = rSeq.getLength(); 606 const OUString *pString = rSeq.getConstArray(); 607 for (sal_Int32 i = 0; i < nLen && nRes == -1; ++i) 608 { 609 if (pString[i] == rTxt) 610 nRes = i; 611 } 612 return nRes; 613 } 614 615 616 Sequence< OUString > SvxLinguData_Impl::GetSortedImplNames( sal_Int16 nLang, sal_uInt8 nType ) 617 { 618 LangImplNameTable *pTable = 0; 619 switch (nType) 620 { 621 case TYPE_SPELL : pTable = &aCfgSpellTable; break; 622 case TYPE_HYPH : pTable = &aCfgHyphTable; break; 623 case TYPE_THES : pTable = &aCfgThesTable; break; 624 case TYPE_GRAMMAR : pTable = &aCfgGrammarTable; break; 625 } 626 Sequence< OUString > aRes; 627 if (pTable->count( nLang )) 628 aRes = (*pTable)[ nLang ]; // add configured services 629 sal_Int32 nIdx = aRes.getLength(); 630 DBG_ASSERT( (sal_Int32) nDisplayServices >= nIdx, "size mismatch" ); 631 aRes.realloc( nDisplayServices ); 632 OUString *pRes = aRes.getArray(); 633 634 // add not configured services 635 for (sal_Int32 i = 0; i < (sal_Int32) nDisplayServices; ++i) 636 { 637 const ServiceInfo_Impl &rInfo = aDisplayServiceArr[ i ]; 638 OUString aImplName; 639 switch (nType) 640 { 641 case TYPE_SPELL : aImplName = rInfo.sSpellImplName; break; 642 case TYPE_HYPH : aImplName = rInfo.sHyphImplName; break; 643 case TYPE_THES : aImplName = rInfo.sThesImplName; break; 644 case TYPE_GRAMMAR : aImplName = rInfo.sGrammarImplName; break; 645 } 646 647 if (aImplName.getLength() && (lcl_SeqGetIndex( aRes, aImplName) == -1)) // name not yet added 648 { 649 DBG_ASSERT( nIdx < aRes.getLength(), "index out of range" ); 650 if (nIdx < aRes.getLength()) 651 pRes[ nIdx++ ] = aImplName; 652 } 653 } 654 // don't forget to put aRes back to its actual size just in case you allocated too much 655 // since all of the names may have already been added 656 // otherwise you get duplicate entries in the edit dialog 657 aRes.realloc( nIdx ); 658 return aRes; 659 } 660 661 662 ServiceInfo_Impl * SvxLinguData_Impl::GetInfoByImplName( const OUString &rSvcImplName ) 663 { 664 ServiceInfo_Impl* pInfo = 0; 665 for (sal_uLong i = 0; i < nDisplayServices && !pInfo; ++i) 666 { 667 ServiceInfo_Impl &rTmp = aDisplayServiceArr[ i ]; 668 if (rTmp.sSpellImplName == rSvcImplName || 669 rTmp.sHyphImplName == rSvcImplName || 670 rTmp.sThesImplName == rSvcImplName || 671 rTmp.sGrammarImplName == rSvcImplName) 672 pInfo = &rTmp; 673 } 674 return pInfo; 675 } 676 677 678 //----------------------------------------------------------------------------- 679 680 void lcl_MergeLocales(Sequence< Locale >& aAllLocales, const Sequence< Locale >& rAdd) 681 { 682 const Locale* pAdd = rAdd.getConstArray(); 683 Sequence<Locale> aLocToAdd(rAdd.getLength()); 684 const Locale* pAllLocales = aAllLocales.getConstArray(); 685 Locale* pLocToAdd = aLocToAdd.getArray(); 686 sal_Int32 nFound = 0; 687 sal_Int32 i; 688 for(i = 0; i < rAdd.getLength(); i++) 689 { 690 sal_Bool bFound = sal_False; 691 for(sal_Int32 j = 0; j < aAllLocales.getLength() && !bFound; j++) 692 { 693 bFound = pAdd[i].Language == pAllLocales[j].Language && 694 pAdd[i].Country == pAllLocales[j].Country; 695 } 696 if(!bFound) 697 { 698 pLocToAdd[nFound++] = pAdd[i]; 699 } 700 } 701 sal_Int32 nLength = aAllLocales.getLength(); 702 aAllLocales.realloc( nLength + nFound); 703 Locale* pAllLocales2 = aAllLocales.getArray(); 704 for(i = 0; i < nFound; i++) 705 pAllLocales2[nLength++] = pLocToAdd[i]; 706 } 707 /* -----------------------------27.11.00 16:48-------------------------------- 708 709 ---------------------------------------------------------------------------*/ 710 void lcl_MergeDisplayArray( 711 SvxLinguData_Impl &rData, 712 const ServiceInfo_Impl &rToAdd ) 713 { 714 sal_uLong nCnt = 0; 715 716 ServiceInfoArr &rSvcInfoArr = rData.GetDisplayServiceArray(); 717 sal_uLong nEntries = rData.GetDisplayServiceCount(); 718 719 ServiceInfo_Impl* pEntry; 720 for (sal_uLong i = 0; i < nEntries; ++i) 721 { 722 pEntry = &rSvcInfoArr[i]; 723 if (pEntry && pEntry->sDisplayName == rToAdd.sDisplayName) 724 { 725 if(rToAdd.xSpell.is()) 726 { 727 DBG_ASSERT( !pEntry->xSpell.is() && 728 pEntry->sSpellImplName.getLength() == 0, 729 "merge conflict" ); 730 pEntry->sSpellImplName = rToAdd.sSpellImplName; 731 pEntry->xSpell = rToAdd.xSpell; 732 } 733 if(rToAdd.xGrammar.is()) 734 { 735 DBG_ASSERT( !pEntry->xGrammar.is() && 736 pEntry->sGrammarImplName.getLength() == 0, 737 "merge conflict" ); 738 pEntry->sGrammarImplName = rToAdd.sGrammarImplName; 739 pEntry->xGrammar = rToAdd.xGrammar; 740 } 741 if(rToAdd.xHyph.is()) 742 { 743 DBG_ASSERT( !pEntry->xHyph.is() && 744 pEntry->sHyphImplName.getLength() == 0, 745 "merge conflict" ); 746 pEntry->sHyphImplName = rToAdd.sHyphImplName; 747 pEntry->xHyph = rToAdd.xHyph; 748 } 749 if(rToAdd.xThes.is()) 750 { 751 DBG_ASSERT( !pEntry->xThes.is() && 752 pEntry->sThesImplName.getLength() == 0, 753 "merge conflict" ); 754 pEntry->sThesImplName = rToAdd.sThesImplName; 755 pEntry->xThes = rToAdd.xThes; 756 } 757 return ; 758 } 759 ++nCnt; 760 } 761 rData.GetDisplayServiceArray().push_back( rToAdd ); 762 rData.SetDisplayServiceCount( nCnt + 1 ); 763 } 764 /* -----------------------------26.11.00 18:07-------------------------------- 765 766 ---------------------------------------------------------------------------*/ 767 SvxLinguData_Impl::SvxLinguData_Impl() : 768 nDisplayServices (0) 769 { 770 xMSF = ::comphelper::getProcessServiceFactory(); 771 uno::Reference < XInterface > xI = xMSF->createInstance( 772 C2U( "com.sun.star.linguistic2.LinguServiceManager" ) ); 773 xLinguSrvcMgr = uno::Reference<XLinguServiceManager>(xI, UNO_QUERY); 774 DBG_ASSERT(xLinguSrvcMgr.is(), "No linguistic service available!"); 775 if(xLinguSrvcMgr.is()) 776 { 777 Locale aCurrentLocale; 778 LanguageType eLang = Application::GetSettings().GetLanguage(); 779 SvxLanguageToLocale(aCurrentLocale, eLang); 780 Sequence<Any> aArgs(2);//second arguments has to be empty! 781 aArgs.getArray()[0] <<= SvxGetLinguPropertySet(); 782 783 //read spell checker 784 Sequence< OUString > aSpellNames = xLinguSrvcMgr->getAvailableServices( 785 C2U(cSpell), Locale() ); 786 const OUString* pSpellNames = aSpellNames.getConstArray(); 787 788 sal_Int32 nIdx; 789 for(nIdx = 0; nIdx < aSpellNames.getLength(); nIdx++) 790 { 791 ServiceInfo_Impl aInfo; 792 aInfo.sSpellImplName = pSpellNames[nIdx]; 793 aInfo.xSpell = uno::Reference<XSpellChecker>( 794 xMSF->createInstanceWithArguments(aInfo.sSpellImplName, aArgs), UNO_QUERY); 795 796 uno::Reference<XServiceDisplayName> xDispName(aInfo.xSpell, UNO_QUERY); 797 if(xDispName.is()) 798 aInfo.sDisplayName = xDispName->getServiceDisplayName( aCurrentLocale ); 799 800 const Sequence< Locale > aLocales( aInfo.xSpell->getLocales() ); 801 //! suppress display of entries with no supported languages (see feature 110994) 802 if (aLocales.getLength()) 803 { 804 lcl_MergeLocales( aAllServiceLocales, aLocales ); 805 lcl_MergeDisplayArray( *this, aInfo ); 806 } 807 } 808 809 //read grammar checker 810 Sequence< OUString > aGrammarNames = xLinguSrvcMgr->getAvailableServices( 811 C2U(cGrammar), Locale() ); 812 const OUString* pGrammarNames = aGrammarNames.getConstArray(); 813 for(nIdx = 0; nIdx < aGrammarNames.getLength(); nIdx++) 814 { 815 ServiceInfo_Impl aInfo; 816 aInfo.sGrammarImplName = pGrammarNames[nIdx]; 817 aInfo.xGrammar = uno::Reference<XProofreader>( 818 xMSF->createInstanceWithArguments(aInfo.sGrammarImplName, aArgs), UNO_QUERY); 819 820 uno::Reference<XServiceDisplayName> xDispName(aInfo.xGrammar, UNO_QUERY); 821 if(xDispName.is()) 822 aInfo.sDisplayName = xDispName->getServiceDisplayName( aCurrentLocale ); 823 824 const Sequence< Locale > aLocales( aInfo.xGrammar->getLocales() ); 825 //! suppress display of entries with no supported languages (see feature 110994) 826 if (aLocales.getLength()) 827 { 828 lcl_MergeLocales( aAllServiceLocales, aLocales ); 829 lcl_MergeDisplayArray( *this, aInfo ); 830 } 831 } 832 833 //read hyphenator 834 Sequence< OUString > aHyphNames = xLinguSrvcMgr->getAvailableServices( 835 C2U(cHyph), Locale() ); 836 const OUString* pHyphNames = aHyphNames.getConstArray(); 837 for(nIdx = 0; nIdx < aHyphNames.getLength(); nIdx++) 838 { 839 ServiceInfo_Impl aInfo; 840 aInfo.sHyphImplName = pHyphNames[nIdx]; 841 aInfo.xHyph = uno::Reference<XHyphenator>( 842 xMSF->createInstanceWithArguments(aInfo.sHyphImplName, aArgs), UNO_QUERY); 843 844 uno::Reference<XServiceDisplayName> xDispName(aInfo.xHyph, UNO_QUERY); 845 if(xDispName.is()) 846 aInfo.sDisplayName = xDispName->getServiceDisplayName( aCurrentLocale ); 847 848 const Sequence< Locale > aLocales( aInfo.xHyph->getLocales() ); 849 //! suppress display of entries with no supported languages (see feature 110994) 850 if (aLocales.getLength()) 851 { 852 lcl_MergeLocales( aAllServiceLocales, aLocales ); 853 lcl_MergeDisplayArray( *this, aInfo ); 854 } 855 } 856 857 //read thesauri 858 Sequence< OUString > aThesNames = xLinguSrvcMgr->getAvailableServices( 859 C2U(cThes), Locale() ); 860 const OUString* pThesNames = aThesNames.getConstArray(); 861 for(nIdx = 0; nIdx < aThesNames.getLength(); nIdx++) 862 { 863 ServiceInfo_Impl aInfo; 864 aInfo.sThesImplName = pThesNames[nIdx]; 865 aInfo.xThes = uno::Reference<XThesaurus>( 866 xMSF->createInstanceWithArguments(aInfo.sThesImplName, aArgs), UNO_QUERY); 867 868 uno::Reference<XServiceDisplayName> xDispName(aInfo.xThes, UNO_QUERY); 869 if(xDispName.is()) 870 aInfo.sDisplayName = xDispName->getServiceDisplayName( aCurrentLocale ); 871 872 const Sequence< Locale > aLocales( aInfo.xThes->getLocales() ); 873 //! suppress display of entries with no supported languages (see feature 110994) 874 if (aLocales.getLength()) 875 { 876 lcl_MergeLocales( aAllServiceLocales, aLocales ); 877 lcl_MergeDisplayArray( *this, aInfo ); 878 } 879 } 880 881 Sequence< OUString > aCfgSvcs; 882 const Locale* pAllLocales = aAllServiceLocales.getConstArray(); 883 for(sal_Int32 nLocale = 0; nLocale < aAllServiceLocales.getLength(); nLocale++) 884 { 885 sal_Int16 nLang = SvxLocaleToLanguage( pAllLocales[nLocale] ); 886 887 aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(C2U(cSpell), pAllLocales[nLocale]); 888 SetChecked( aCfgSvcs ); 889 if (aCfgSvcs.getLength()) 890 aCfgSpellTable[ nLang ] = aCfgSvcs; 891 892 aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(C2U(cGrammar), pAllLocales[nLocale]); 893 SetChecked( aCfgSvcs ); 894 if (aCfgSvcs.getLength()) 895 aCfgGrammarTable[ nLang ] = aCfgSvcs; 896 897 aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(C2U(cHyph), pAllLocales[nLocale]); 898 SetChecked( aCfgSvcs ); 899 if (aCfgSvcs.getLength()) 900 aCfgHyphTable[ nLang ] = aCfgSvcs; 901 902 aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(C2U(cThes), pAllLocales[nLocale]); 903 SetChecked( aCfgSvcs ); 904 if (aCfgSvcs.getLength()) 905 aCfgThesTable[ nLang ] = aCfgSvcs; 906 } 907 } 908 } 909 /* -----------------------------22.05.01 10:43-------------------------------- 910 911 ---------------------------------------------------------------------------*/ 912 SvxLinguData_Impl::SvxLinguData_Impl( const SvxLinguData_Impl &rData ) : 913 aDisplayServiceArr (rData.aDisplayServiceArr), 914 nDisplayServices (rData.nDisplayServices), 915 aAllServiceLocales (rData.aAllServiceLocales), 916 aCfgSpellTable (rData.aCfgSpellTable), 917 aCfgHyphTable (rData.aCfgHyphTable), 918 aCfgThesTable (rData.aCfgThesTable), 919 aCfgGrammarTable (rData.aCfgGrammarTable), 920 xMSF (rData.xMSF), 921 xLinguSrvcMgr (rData.xLinguSrvcMgr) 922 { 923 } 924 /* -----------------------------22.05.01 10:43-------------------------------- 925 926 ---------------------------------------------------------------------------*/ 927 SvxLinguData_Impl & SvxLinguData_Impl::operator = (const SvxLinguData_Impl &rData) 928 { 929 xMSF = rData.xMSF; 930 xLinguSrvcMgr = rData.xLinguSrvcMgr; 931 aAllServiceLocales = rData.aAllServiceLocales; 932 aCfgSpellTable = rData.aCfgSpellTable; 933 aCfgHyphTable = rData.aCfgHyphTable; 934 aCfgThesTable = rData.aCfgThesTable; 935 aCfgGrammarTable = rData.aCfgGrammarTable; 936 aDisplayServiceArr = rData.aDisplayServiceArr; 937 nDisplayServices = rData.nDisplayServices; 938 return *this; 939 } 940 /* -----------------------------26.11.00 18:08-------------------------------- 941 942 ---------------------------------------------------------------------------*/ 943 SvxLinguData_Impl::~SvxLinguData_Impl() 944 { 945 } 946 /* -----------------------------26.11.00 19:42-------------------------------- 947 948 ---------------------------------------------------------------------------*/ 949 void SvxLinguData_Impl::SetChecked(const Sequence<OUString>& rConfiguredServices) 950 { 951 const OUString* pConfiguredServices = rConfiguredServices.getConstArray(); 952 for(sal_Int32 n = 0; n < rConfiguredServices.getLength(); n++) 953 { 954 ServiceInfo_Impl* pEntry; 955 for (sal_uLong i = 0; i < nDisplayServices; ++i) 956 { 957 pEntry = &aDisplayServiceArr[i]; 958 if (pEntry && !pEntry->bConfigured) 959 { 960 const OUString &rSrvcImplName = pConfiguredServices[n]; 961 if (rSrvcImplName.getLength() && 962 (pEntry->sSpellImplName == rSrvcImplName || 963 pEntry->sGrammarImplName == rSrvcImplName || 964 pEntry->sHyphImplName == rSrvcImplName || 965 pEntry->sThesImplName == rSrvcImplName)) 966 { 967 pEntry->bConfigured = sal_True; 968 break; 969 } 970 } 971 } 972 } 973 } 974 /* -----------------------------26.11.00 20:43-------------------------------- 975 976 ---------------------------------------------------------------------------*/ 977 978 sal_Bool SvxLinguData_Impl::AddRemove( 979 Sequence< OUString > &rConfigured, 980 const OUString &rImplName, sal_Bool bAdd ) 981 { 982 sal_Bool bRet = sal_False; // modified? 983 984 sal_Int32 nEntries = rConfigured.getLength(); 985 sal_Int32 nPos = lcl_SeqGetEntryPos(rConfigured, rImplName); 986 if (bAdd && nPos < 0) // add new entry 987 { 988 rConfigured.realloc( ++nEntries ); 989 OUString *pConfigured = rConfigured.getArray(); 990 pConfigured = rConfigured.getArray(); 991 pConfigured[nEntries - 1] = rImplName; 992 bRet = sal_True; 993 } 994 else if (!bAdd && nPos >= 0) // remove existing entry 995 { 996 OUString *pConfigured = rConfigured.getArray(); 997 for (sal_Int32 i = nPos; i < nEntries - 1; ++i) 998 pConfigured[i] = pConfigured[i + 1]; 999 rConfigured.realloc(--nEntries); 1000 bRet = sal_True; 1001 } 1002 1003 return bRet; 1004 } 1005 1006 1007 void SvxLinguData_Impl::Reconfigure( const OUString &rDisplayName, sal_Bool bEnable ) 1008 { 1009 DBG_ASSERT( rDisplayName.getLength(), "empty DisplayName" ); 1010 1011 ServiceInfo_Impl *pInfo = 0; 1012 ServiceInfo_Impl *pTmp = 0; 1013 for (sal_uLong i = 0; i < nDisplayServices; ++i) 1014 { 1015 pTmp = &aDisplayServiceArr[i]; 1016 if (pTmp && pTmp->sDisplayName == rDisplayName) 1017 { 1018 pInfo = pTmp; 1019 break; 1020 } 1021 } 1022 DBG_ASSERT( pInfo, "DisplayName entry not found" ); 1023 if (pInfo) 1024 { 1025 pInfo->bConfigured = bEnable; 1026 1027 Sequence< Locale > aLocales; 1028 const Locale *pLocale = 0; 1029 sal_Int32 nLocales = 0; 1030 sal_Int32 i; 1031 1032 // update configured spellchecker entries 1033 if (pInfo->xSpell.is()) 1034 { 1035 aLocales = pInfo->xSpell->getLocales(); 1036 pLocale = aLocales.getConstArray(); 1037 nLocales = aLocales.getLength(); 1038 for (i = 0; i < nLocales; ++i) 1039 { 1040 sal_Int16 nLang = SvxLocaleToLanguage( pLocale[i] ); 1041 if (!aCfgSpellTable.count( nLang ) && bEnable) 1042 aCfgSpellTable[ nLang ] = Sequence< OUString >(); 1043 if (aCfgSpellTable.count( nLang )) 1044 AddRemove( aCfgSpellTable[ nLang ], pInfo->sSpellImplName, bEnable ); 1045 } 1046 } 1047 1048 // update configured grammar checker entries 1049 if (pInfo->xGrammar.is()) 1050 { 1051 aLocales = pInfo->xGrammar->getLocales(); 1052 pLocale = aLocales.getConstArray(); 1053 nLocales = aLocales.getLength(); 1054 for (i = 0; i < nLocales; ++i) 1055 { 1056 sal_Int16 nLang = SvxLocaleToLanguage( pLocale[i] ); 1057 if (!aCfgGrammarTable.count( nLang ) && bEnable) 1058 aCfgGrammarTable[ nLang ] = Sequence< OUString >(); 1059 if (aCfgGrammarTable.count( nLang )) 1060 AddRemove( aCfgGrammarTable[ nLang ], pInfo->sGrammarImplName, bEnable ); 1061 } 1062 } 1063 1064 // update configured hyphenator entries 1065 if (pInfo->xHyph.is()) 1066 { 1067 aLocales = pInfo->xHyph->getLocales(); 1068 pLocale = aLocales.getConstArray(); 1069 nLocales = aLocales.getLength(); 1070 for (i = 0; i < nLocales; ++i) 1071 { 1072 sal_Int16 nLang = SvxLocaleToLanguage( pLocale[i] ); 1073 if (!aCfgHyphTable.count( nLang ) && bEnable) 1074 aCfgHyphTable[ nLang ] = Sequence< OUString >(); 1075 if (aCfgHyphTable.count( nLang )) 1076 AddRemove( aCfgHyphTable[ nLang ], pInfo->sHyphImplName, bEnable ); 1077 } 1078 } 1079 1080 // update configured spellchecker entries 1081 if (pInfo->xThes.is()) 1082 { 1083 aLocales = pInfo->xThes->getLocales(); 1084 pLocale = aLocales.getConstArray(); 1085 nLocales = aLocales.getLength(); 1086 for (i = 0; i < nLocales; ++i) 1087 { 1088 sal_Int16 nLang = SvxLocaleToLanguage( pLocale[i] ); 1089 if (!aCfgThesTable.count( nLang ) && bEnable) 1090 aCfgThesTable[ nLang ] = Sequence< OUString >(); 1091 if (aCfgThesTable.count( nLang )) 1092 AddRemove( aCfgThesTable[ nLang ], pInfo->sThesImplName, bEnable ); 1093 } 1094 } 1095 } 1096 } 1097 1098 1099 // class SvxLinguTabPage ------------------------------------------------- 1100 1101 #define CBCOL_FIRST 0 1102 #define CBCOL_SECOND 1 1103 #define CBCOL_BOTH 2 1104 1105 SvxLinguTabPage::SvxLinguTabPage( Window* pParent, 1106 const SfxItemSet& rSet ): 1107 1108 SfxTabPage( pParent, CUI_RES( RID_SFXPAGE_LINGU ), rSet ), 1109 1110 aLinguisticFL ( this, CUI_RES( FL_LINGUISTIC ) ), 1111 aLinguModulesFT ( this, CUI_RES( FT_LINGU_MODULES ) ), 1112 aLinguModulesCLB ( this, CUI_RES( CLB_LINGU_MODULES ) ), 1113 aLinguModulesEditPB ( this, CUI_RES( PB_LINGU_MODULES_EDIT ) ), 1114 aLinguDicsFT ( this, CUI_RES( FT_LINGU_DICS ) ), 1115 aLinguDicsCLB ( this, CUI_RES( CLB_LINGU_DICS ) ), 1116 aLinguDicsNewPB ( this, CUI_RES( PB_LINGU_DICS_NEW_DIC ) ), 1117 aLinguDicsEditPB ( this, CUI_RES( PB_LINGU_DICS_EDIT_DIC ) ), 1118 aLinguDicsDelPB ( this, CUI_RES( PB_LINGU_DICS_DEL_DIC ) ), 1119 aLinguOptionsFT ( this, CUI_RES( FT_LINGU_OPTIONS ) ), 1120 aLinguOptionsCLB ( this, CUI_RES( CLB_LINGU_OPTIONS ) ), 1121 aLinguOptionsEditPB ( this, CUI_RES( PB_LINGU_OPTIONS_EDIT ) ), 1122 aMoreDictsLink ( this, CUI_RES( FT_LINGU_OPTIONS_MOREDICTS ) ), 1123 sCapitalWords ( CUI_RES( STR_CAPITAL_WORDS ) ), 1124 sWordsWithDigits ( CUI_RES( STR_WORDS_WITH_DIGITS ) ), 1125 sCapitalization ( CUI_RES( STR_CAPITALIZATION ) ), 1126 sSpellSpecial ( CUI_RES( STR_SPELL_SPECIAL ) ), 1127 sSpellAuto ( CUI_RES( STR_SPELL_AUTO ) ), 1128 sGrammarAuto ( CUI_RES( STR_GRAMMAR_AUTO ) ), 1129 sNumMinWordlen ( CUI_RES( STR_NUM_MIN_WORDLEN ) ), 1130 sNumPreBreak ( CUI_RES( STR_NUM_PRE_BREAK ) ), 1131 sNumPostBreak ( CUI_RES( STR_NUM_POST_BREAK ) ), 1132 sHyphAuto ( CUI_RES( STR_HYPH_AUTO ) ), 1133 sHyphSpecial ( CUI_RES( STR_HYPH_SPECIAL ) ), 1134 1135 pLinguData ( NULL ) 1136 { 1137 pCheckButtonData = NULL; 1138 1139 aLinguModulesCLB.SetStyle( aLinguModulesCLB.GetStyle()|WB_CLIPCHILDREN|WB_HSCROLL|WB_FORCE_MAKEVISIBLE ); 1140 aLinguModulesCLB.SetHelpId(HID_CLB_LINGU_MODULES ); 1141 aLinguModulesCLB.SetHighlightRange(); 1142 aLinguModulesCLB.SetSelectHdl( LINK( this, SvxLinguTabPage, SelectHdl_Impl )); 1143 aLinguModulesCLB.SetDoubleClickHdl(LINK(this, SvxLinguTabPage, BoxDoubleClickHdl_Impl)); 1144 aLinguModulesCLB.SetCheckButtonHdl(LINK(this, SvxLinguTabPage, BoxCheckButtonHdl_Impl)); 1145 1146 aLinguModulesEditPB.SetClickHdl( LINK( this, SvxLinguTabPage, ClickHdl_Impl )); 1147 aLinguOptionsEditPB.SetClickHdl( LINK( this, SvxLinguTabPage, ClickHdl_Impl )); 1148 1149 aLinguDicsCLB.SetStyle( aLinguDicsCLB.GetStyle()|WB_CLIPCHILDREN|WB_HSCROLL|WB_FORCE_MAKEVISIBLE ); 1150 aLinguDicsCLB.SetHelpId(HID_CLB_EDIT_MODULES_DICS ); 1151 aLinguDicsCLB.SetHighlightRange(); 1152 aLinguDicsCLB.SetSelectHdl( LINK( this, SvxLinguTabPage, SelectHdl_Impl )); 1153 aLinguDicsCLB.SetCheckButtonHdl(LINK(this, SvxLinguTabPage, BoxCheckButtonHdl_Impl)); 1154 1155 aLinguDicsNewPB.SetClickHdl( LINK( this, SvxLinguTabPage, ClickHdl_Impl )); 1156 aLinguDicsEditPB.SetClickHdl( LINK( this, SvxLinguTabPage, ClickHdl_Impl )); 1157 aLinguDicsDelPB.SetClickHdl( LINK( this, SvxLinguTabPage, ClickHdl_Impl )); 1158 1159 aLinguOptionsCLB.SetStyle( aLinguOptionsCLB.GetStyle()|WB_CLIPCHILDREN|WB_HSCROLL|WB_FORCE_MAKEVISIBLE ); 1160 aLinguOptionsCLB.SetHelpId(HID_CLB_LINGU_OPTIONS ); 1161 aLinguOptionsCLB.SetHighlightRange(); 1162 aLinguOptionsCLB.SetSelectHdl( LINK( this, SvxLinguTabPage, SelectHdl_Impl )); 1163 aLinguOptionsCLB.SetDoubleClickHdl(LINK(this, SvxLinguTabPage, BoxDoubleClickHdl_Impl)); 1164 1165 if ( SvtExtendedSecurityOptions().GetOpenHyperlinkMode() 1166 != SvtExtendedSecurityOptions::OPEN_NEVER ) 1167 { 1168 aMoreDictsLink.SetURL( String( 1169 RTL_CONSTASCII_STRINGPARAM( "http://extensions.services.openoffice.org/dictionary?cid=926386" ) ) ); 1170 aMoreDictsLink.SetClickHdl( LINK( this, SvxLinguTabPage, OpenURLHdl_Impl ) ); 1171 } 1172 else 1173 aMoreDictsLink.Hide(); 1174 1175 String sAccessibleNameModuleEdit( CUI_RES( STR_LINGU_MODULES_EDIT ) ); 1176 String sAccessibleNameDicsEdit ( CUI_RES( STR_LINGU_DICS_EDIT_DIC ) ); 1177 String sAccessibleNameOptionEdit( CUI_RES( STR_LINGU_OPTIONS_EDIT ) ); 1178 1179 aLinguModulesEditPB.SetAccessibleName(sAccessibleNameModuleEdit); 1180 aLinguDicsEditPB.SetAccessibleName(sAccessibleNameDicsEdit); 1181 aLinguOptionsEditPB.SetAccessibleName(sAccessibleNameOptionEdit); 1182 1183 // force recalculation of hash value used for checking the need of updating 1184 // because new dictionaries might be installed / downloaded. 1185 //! Thus it needs to be called now since it may infuence the supported languages 1186 //! to be reported AND the found user-dictionaries(!) as well. 1187 SvxLinguConfigUpdate::UpdateAll( sal_True ); 1188 1189 xProp = uno::Reference< XPropertySet >( SvxGetLinguPropertySet(), UNO_QUERY ); 1190 xDicList = uno::Reference< XDictionaryList >( SvxGetDictionaryList(), UNO_QUERY ); 1191 if (xDicList.is()) 1192 { 1193 // keep references to all **currently** available dictionaries, 1194 // since the diclist may get changed meanwhile (e.g. through the API). 1195 // We want the dialog to operate on the same set of dictionaries it 1196 // was started with. 1197 // Also we have to take care to not loose the last reference when 1198 // someone else removes a dictionary from the list. 1199 // removed dics will be replaced by NULL new entries be added to the end 1200 // Thus we may use indizes as consistent references. 1201 aDics = xDicList->getDictionaries(); 1202 1203 UpdateDicBox_Impl(); 1204 } 1205 else 1206 { 1207 aLinguDicsFT.Disable(); 1208 aLinguDicsCLB.Disable(); 1209 aLinguDicsNewPB.Disable(); 1210 aLinguDicsEditPB.Disable(); 1211 aLinguDicsDelPB.Disable(); 1212 } 1213 1214 const SfxSpellCheckItem* pItem = 0; 1215 SfxItemState eItemState = SFX_ITEM_UNKNOWN; 1216 1217 eItemState = rSet.GetItemState( GetWhich( SID_ATTR_SPELL ), 1218 sal_False, (const SfxPoolItem**)&pItem ); 1219 1220 // handelt es sich um ein Default-Item? 1221 if ( eItemState == SFX_ITEM_DEFAULT ) 1222 pItem = (const SfxSpellCheckItem*)&(rSet.Get( GetWhich( SID_ATTR_SPELL ) ) ); 1223 else if ( eItemState == SFX_ITEM_DONTCARE ) 1224 pItem = NULL; 1225 1226 FreeResource(); 1227 } 1228 1229 // ----------------------------------------------------------------------- 1230 1231 SvxLinguTabPage::~SvxLinguTabPage() 1232 { 1233 if (pLinguData) 1234 delete pLinguData; 1235 } 1236 1237 //------------------------------------------------------------------------ 1238 1239 //nicht �berladen wegschmeissen 1240 sal_uInt16* SvxLinguTabPage::GetRanges() 1241 { 1242 //TL??? 1243 return pRanges; 1244 } 1245 1246 //------------------------------------------------------------------------ 1247 1248 SfxTabPage* SvxLinguTabPage::Create( Window* pParent, 1249 const SfxItemSet& rAttrSet ) 1250 { 1251 return ( new SvxLinguTabPage( pParent, rAttrSet ) ); 1252 } 1253 1254 //------------------------------------------------------------------------ 1255 1256 Any lcl_Bool2Any(sal_Bool bVal) 1257 { 1258 Any aRet(&bVal, ::getBooleanCppuType()); 1259 return aRet; 1260 } 1261 1262 1263 sal_Bool lcl_Bool2Any(Any& rVal) 1264 { 1265 return *(sal_Bool*)rVal.getValue(); 1266 } 1267 1268 1269 sal_Bool SvxLinguTabPage::FillItemSet( SfxItemSet& rCoreSet ) 1270 { 1271 sal_Bool bModified = sal_True; // !!!! 1272 1273 // if not HideGroups was called with GROUP_MODULES... 1274 if (aLinguModulesCLB.IsVisible()) 1275 { 1276 DBG_ASSERT( pLinguData, "pLinguData not yet initialized" ); 1277 if (!pLinguData) 1278 pLinguData = new SvxLinguData_Impl; 1279 1280 LangImplNameTable::const_iterator aIt; 1281 1282 // update spellchecker configuration entries 1283 const LangImplNameTable *pTable = &pLinguData->GetSpellTable(); 1284 for (aIt = pTable->begin(); aIt != pTable->end(); ++aIt) 1285 { 1286 sal_Int16 nLang = aIt->first; 1287 const Sequence< OUString > aImplNames( aIt->second ); 1288 #if OSL_DEBUG_LEVEL > 1 1289 const OUString *pTmpStr; 1290 pTmpStr = aImplNames.getConstArray(); 1291 #endif 1292 uno::Reference< XLinguServiceManager > xMgr( pLinguData->GetManager() ); 1293 Locale aLocale( SvxCreateLocale(nLang) ); 1294 if (xMgr.is()) 1295 xMgr->setConfiguredServices( C2U(cSpell), aLocale, aImplNames ); 1296 } 1297 1298 // update grammar checker configuration entries 1299 pTable = &pLinguData->GetGrammarTable(); 1300 for (aIt = pTable->begin(); aIt != pTable->end(); ++aIt) 1301 { 1302 sal_Int16 nLang = aIt->first; 1303 const Sequence< OUString > aImplNames( aIt->second ); 1304 #if OSL_DEBUG_LEVEL > 1 1305 const OUString *pTmpStr; 1306 pTmpStr = aImplNames.getConstArray(); 1307 #endif 1308 uno::Reference< XLinguServiceManager > xMgr( pLinguData->GetManager() ); 1309 Locale aLocale( SvxCreateLocale(nLang) ); 1310 if (xMgr.is()) 1311 xMgr->setConfiguredServices( C2U(cGrammar), aLocale, aImplNames ); 1312 } 1313 1314 // update hyphenator configuration entries 1315 pTable = &pLinguData->GetHyphTable(); 1316 for (aIt = pTable->begin(); aIt != pTable->end(); ++aIt) 1317 { 1318 sal_Int16 nLang = aIt->first; 1319 const Sequence< OUString > aImplNames( aIt->second ); 1320 #if OSL_DEBUG_LEVEL > 1 1321 const OUString *pTmpStr; 1322 pTmpStr = aImplNames.getConstArray(); 1323 #endif 1324 uno::Reference< XLinguServiceManager > xMgr( pLinguData->GetManager() ); 1325 Locale aLocale( SvxCreateLocale(nLang) ); 1326 if (xMgr.is()) 1327 xMgr->setConfiguredServices( C2U(cHyph), aLocale, aImplNames ); 1328 } 1329 1330 // update thesaurus configuration entries 1331 pTable = &pLinguData->GetThesTable(); 1332 for (aIt = pTable->begin(); aIt != pTable->end(); ++aIt) 1333 { 1334 sal_Int16 nLang = aIt->first; 1335 const Sequence< OUString > aImplNames( aIt->second ); 1336 #if OSL_DEBUG_LEVEL > 1 1337 const OUString *pTmpStr; 1338 pTmpStr = aImplNames.getConstArray(); 1339 #endif 1340 uno::Reference< XLinguServiceManager > xMgr( pLinguData->GetManager() ); 1341 Locale aLocale( SvxCreateLocale(nLang) ); 1342 if (xMgr.is()) 1343 xMgr->setConfiguredServices( C2U(cThes), aLocale, aImplNames ); 1344 } 1345 } 1346 1347 1348 // 1349 // activate dictionaries according to checkbox state 1350 // 1351 Sequence< OUString > aActiveDics; 1352 sal_Int32 nActiveDics = 0; 1353 sal_uLong nEntries = aLinguDicsCLB.GetEntryCount(); 1354 for (sal_uLong i = 0; i < nEntries; ++i) 1355 { 1356 sal_Int32 nDics = aDics.getLength(); 1357 // const uno::Reference< XDictionary > *pDic = aDics.getConstArray(); 1358 1359 aActiveDics.realloc( nDics ); 1360 OUString *pActiveDic = aActiveDics.getArray(); 1361 1362 SvLBoxEntry *pEntry = aLinguDicsCLB.GetEntry( i ); 1363 if (pEntry) 1364 { 1365 DicUserData aData( (sal_uLong)pEntry->GetUserData() ); 1366 if (aData.GetEntryId() < nDics) 1367 { 1368 sal_Bool bChecked = aLinguDicsCLB.IsChecked( (sal_uInt16) i ); 1369 uno::Reference< XDictionary > xDic( aDics.getConstArray()[ i ] ); 1370 if (xDic.is()) 1371 { 1372 if (SvxGetIgnoreAllList() == xDic) 1373 bChecked = sal_True; 1374 xDic->setActive( bChecked ); 1375 1376 if (bChecked) 1377 { 1378 String aDicName( xDic->getName() ); 1379 pActiveDic[ nActiveDics++ ] = aDicName; 1380 } 1381 } 1382 } 1383 } 1384 } 1385 // 1386 aActiveDics.realloc( nActiveDics ); 1387 Any aTmp; 1388 aTmp <<= aActiveDics; 1389 SvtLinguConfig aLngCfg; 1390 aLngCfg.SetProperty( UPH_ACTIVE_DICTIONARIES, aTmp ); 1391 1392 1393 nEntries = aLinguOptionsCLB.GetEntryCount(); 1394 for (sal_uInt16 j = 0; j < nEntries; ++j) 1395 { 1396 SvLBoxEntry *pEntry = aLinguOptionsCLB.GetEntry( j ); 1397 1398 OptionsUserData aData( (sal_uLong)pEntry->GetUserData() ); 1399 String aPropName( lcl_GetPropertyName( (EID_OPTIONS) aData.GetEntryId() ) ); 1400 1401 Any aAny; 1402 if (aData.IsCheckable()) 1403 { 1404 sal_Bool bChecked = aLinguOptionsCLB.IsChecked( j ); 1405 aAny <<= bChecked; 1406 } 1407 else if (aData.HasNumericValue()) 1408 { 1409 sal_Int16 nVal = aData.GetNumericValue(); 1410 aAny <<= nVal; 1411 } 1412 1413 if (xProp.is()) 1414 xProp->setPropertyValue( aPropName, aAny ); 1415 aLngCfg.SetProperty( aPropName, aAny ); 1416 } 1417 1418 SvLBoxEntry *pPreBreakEntry = aLinguOptionsCLB.GetEntry( (sal_uInt16) EID_NUM_PRE_BREAK ); 1419 SvLBoxEntry *pPostBreakEntry = aLinguOptionsCLB.GetEntry( (sal_uInt16) EID_NUM_POST_BREAK ); 1420 DBG_ASSERT( pPreBreakEntry, "NULL Pointer" ); 1421 DBG_ASSERT( pPostBreakEntry, "NULL Pointer" ); 1422 if (pPreBreakEntry && pPostBreakEntry) 1423 { 1424 OptionsUserData aPreBreakData( (sal_uLong)pPreBreakEntry->GetUserData() ); 1425 OptionsUserData aPostBreakData( (sal_uLong)pPostBreakEntry->GetUserData() ); 1426 if ( aPreBreakData.IsModified() || aPostBreakData.IsModified() ) 1427 { 1428 SfxHyphenRegionItem aHyp( GetWhich( SID_ATTR_HYPHENREGION ) ); 1429 aHyp.GetMinLead() = (sal_uInt8) aPreBreakData.GetNumericValue(); 1430 aHyp.GetMinTrail() = (sal_uInt8) aPostBreakData.GetNumericValue(); 1431 rCoreSet.Put( aHyp ); 1432 } 1433 } 1434 1435 1436 // automatic spell checking 1437 sal_Bool bNewAutoCheck = aLinguOptionsCLB.IsChecked( (sal_uInt16) EID_SPELL_AUTO ); 1438 const SfxPoolItem* pOld = GetOldItem( rCoreSet, SID_AUTOSPELL_CHECK ); 1439 if ( !pOld || ( (SfxBoolItem*)pOld )->GetValue() != bNewAutoCheck ) 1440 { 1441 rCoreSet.Put( SfxBoolItem( GetWhich( SID_AUTOSPELL_CHECK ), 1442 bNewAutoCheck ) ); 1443 bModified |= sal_True; 1444 } 1445 1446 return bModified; 1447 } 1448 1449 // ---------------------------------------------------------------------- 1450 1451 sal_uLong SvxLinguTabPage::GetDicUserData( const uno::Reference< XDictionary > &rxDic, sal_uInt16 nIdx ) 1452 { 1453 sal_uLong nRes = 0; 1454 DBG_ASSERT( rxDic.is(), "dictionary not supplied" ); 1455 if (rxDic.is()) 1456 { 1457 uno::Reference< frame::XStorable > xStor( rxDic, UNO_QUERY ); 1458 1459 // sal_uLong nUserData = 0; 1460 sal_Bool bChecked = rxDic->isActive(); 1461 sal_Bool bEditable = !xStor.is() || !xStor->isReadonly(); 1462 sal_Bool bDeletable = bEditable; 1463 // sal_Bool bNegativ = rxDic->getDictionaryType() == DictionaryType_NEGATIVE; 1464 1465 nRes = DicUserData( nIdx, 1466 bChecked, bEditable, bDeletable ).GetUserData(); 1467 } 1468 return nRes; 1469 } 1470 1471 1472 void SvxLinguTabPage::AddDicBoxEntry( 1473 const uno::Reference< XDictionary > &rxDic, 1474 sal_uInt16 nIdx ) 1475 { 1476 aLinguDicsCLB.SetUpdateMode(sal_False); 1477 1478 String aTxt( ::GetDicInfoStr( rxDic->getName(), 1479 SvxLocaleToLanguage( rxDic->getLocale() ), 1480 DictionaryType_NEGATIVE == rxDic->getDictionaryType() ) ); 1481 aLinguDicsCLB.InsertEntry( aTxt, (sal_uInt16)LISTBOX_APPEND ); // append at end 1482 SvLBoxEntry* pEntry = aLinguDicsCLB.GetEntry( aLinguDicsCLB.GetEntryCount() - 1 ); 1483 DBG_ASSERT( pEntry, "failed to add entry" ); 1484 if (pEntry) 1485 { 1486 DicUserData aData( GetDicUserData( rxDic, nIdx ) ); 1487 pEntry->SetUserData( (void *) aData.GetUserData() ); 1488 lcl_SetCheckButton( pEntry, aData.IsChecked() ); 1489 } 1490 1491 aLinguDicsCLB.SetUpdateMode(sal_True); 1492 } 1493 1494 // ---------------------------------------------------------------------- 1495 1496 void SvxLinguTabPage::UpdateDicBox_Impl() 1497 { 1498 aLinguDicsCLB.SetUpdateMode(sal_False); 1499 aLinguDicsCLB.Clear(); 1500 1501 sal_Int32 nDics = aDics.getLength(); 1502 const uno::Reference< XDictionary > *pDic = aDics.getConstArray(); 1503 for (sal_Int32 i = 0; i < nDics; ++i) 1504 { 1505 const uno::Reference< XDictionary > &rDic = pDic[i]; 1506 if (rDic.is()) 1507 AddDicBoxEntry( rDic, (sal_uInt16)i ); 1508 } 1509 1510 aLinguDicsCLB.SetUpdateMode(sal_True); 1511 } 1512 1513 // ---------------------------------------------------------------------- 1514 1515 void SvxLinguTabPage::UpdateModulesBox_Impl() 1516 { 1517 if (pLinguData) 1518 { 1519 const ServiceInfoArr &rAllDispSrvcArr = pLinguData->GetDisplayServiceArray(); 1520 const sal_uLong nDispSrvcCount = pLinguData->GetDisplayServiceCount(); 1521 1522 aLinguModulesCLB.Clear(); 1523 1524 for (sal_uInt16 i = 0; i < nDispSrvcCount; ++i) 1525 { 1526 const ServiceInfo_Impl &rInfo = rAllDispSrvcArr[i]; 1527 aLinguModulesCLB.InsertEntry( rInfo.sDisplayName, (sal_uInt16)LISTBOX_APPEND ); 1528 SvLBoxEntry* pEntry = aLinguModulesCLB.GetEntry(i); 1529 pEntry->SetUserData( (void *) &rInfo ); 1530 aLinguModulesCLB.CheckEntryPos( i, rInfo.bConfigured ); 1531 } 1532 aLinguModulesEditPB.Enable( nDispSrvcCount > 0 ); 1533 } 1534 } 1535 1536 //------------------------------------------------------------------------ 1537 1538 void SvxLinguTabPage::Reset( const SfxItemSet& rSet ) 1539 { 1540 // if not HideGroups was called with GROUP_MODULES... 1541 if (aLinguModulesCLB.IsVisible()) 1542 { 1543 if (!pLinguData) 1544 pLinguData = new SvxLinguData_Impl; 1545 UpdateModulesBox_Impl(); 1546 } 1547 1548 1549 // 1550 // get data from configuration 1551 // 1552 1553 SvtLinguConfig aLngCfg; 1554 1555 aLinguOptionsCLB.SetUpdateMode(sal_False); 1556 aLinguOptionsCLB.Clear(); 1557 1558 SvLBoxTreeList *pModel = aLinguOptionsCLB.GetModel(); 1559 SvLBoxEntry* pEntry = NULL; 1560 1561 sal_Int16 nVal = 0; 1562 sal_Bool bVal = sal_False; 1563 sal_uLong nUserData = 0; 1564 1565 pEntry = CreateEntry( sSpellAuto, CBCOL_FIRST ); 1566 aLngCfg.GetProperty( C2U(UPN_IS_SPELL_AUTO) ) >>= bVal; 1567 const SfxPoolItem* pItem = GetItem( rSet, SID_AUTOSPELL_CHECK ); 1568 if (pItem) 1569 bVal = ((SfxBoolItem *) pItem)->GetValue(); 1570 nUserData = OptionsUserData( EID_SPELL_AUTO, sal_False, 0, sal_True, bVal).GetUserData(); 1571 pEntry->SetUserData( (void *)nUserData ); 1572 pModel->Insert( pEntry ); 1573 lcl_SetCheckButton( pEntry, bVal ); 1574 1575 pEntry = CreateEntry( sGrammarAuto, CBCOL_FIRST ); 1576 aLngCfg.GetProperty( C2U(UPN_IS_GRAMMAR_AUTO) ) >>= bVal; 1577 // const SfxPoolItem* pItem = GetItem( rSet, SID_AUTOSPELL_CHECK ); 1578 // if (pItem) 1579 // bVal = ((SfxBoolItem *) pItem)->GetValue(); 1580 nUserData = OptionsUserData( EID_GRAMMAR_AUTO, sal_False, 0, sal_True, bVal).GetUserData(); 1581 pEntry->SetUserData( (void *)nUserData ); 1582 pModel->Insert( pEntry ); 1583 lcl_SetCheckButton( pEntry, bVal ); 1584 1585 pEntry = CreateEntry( sCapitalWords, CBCOL_FIRST ); 1586 aLngCfg.GetProperty( C2U(UPN_IS_SPELL_UPPER_CASE) ) >>= bVal; 1587 nUserData = OptionsUserData( EID_CAPITAL_WORDS, sal_False, 0, sal_True, bVal).GetUserData(); 1588 pEntry->SetUserData( (void *)nUserData ); 1589 pModel->Insert( pEntry ); 1590 lcl_SetCheckButton( pEntry, bVal ); 1591 1592 pEntry = CreateEntry( sWordsWithDigits, CBCOL_FIRST ); 1593 aLngCfg.GetProperty( C2U(UPN_IS_SPELL_WITH_DIGITS) ) >>= bVal; 1594 nUserData = OptionsUserData( EID_WORDS_WITH_DIGITS, sal_False, 0, sal_True, bVal).GetUserData(); 1595 pEntry->SetUserData( (void *)nUserData ); 1596 pModel->Insert( pEntry ); 1597 lcl_SetCheckButton( pEntry, bVal ); 1598 1599 pEntry = CreateEntry( sCapitalization, CBCOL_FIRST ); 1600 aLngCfg.GetProperty( C2U(UPN_IS_SPELL_CAPITALIZATION) ) >>= bVal; 1601 nUserData = OptionsUserData( EID_CAPITALIZATION, sal_False, 0, sal_True, bVal).GetUserData(); 1602 pEntry->SetUserData( (void *)nUserData ); 1603 pModel->Insert( pEntry ); 1604 lcl_SetCheckButton( pEntry, bVal ); 1605 1606 pEntry = CreateEntry( sSpellSpecial, CBCOL_FIRST ); 1607 aLngCfg.GetProperty( C2U(UPN_IS_SPELL_SPECIAL) ) >>= bVal; 1608 nUserData = OptionsUserData( EID_SPELL_SPECIAL, sal_False, 0, sal_True, bVal).GetUserData(); 1609 pEntry->SetUserData( (void *)nUserData ); 1610 pModel->Insert( pEntry ); 1611 lcl_SetCheckButton( pEntry, bVal ); 1612 1613 pEntry = CreateEntry( sNumMinWordlen, CBCOL_SECOND ); 1614 aLngCfg.GetProperty( C2U(UPN_HYPH_MIN_WORD_LENGTH) ) >>= nVal; 1615 nUserData = OptionsUserData( EID_NUM_MIN_WORDLEN, sal_True, (sal_uInt16)nVal, sal_False, sal_False).GetUserData(); 1616 pEntry->SetUserData( (void *)nUserData ); 1617 pModel->Insert( pEntry ); 1618 1619 const SfxHyphenRegionItem *pHyp = NULL; 1620 sal_uInt16 nWhich = GetWhich( SID_ATTR_HYPHENREGION ); 1621 if ( rSet.GetItemState( nWhich, sal_False ) == SFX_ITEM_SET ) 1622 pHyp = &( (const SfxHyphenRegionItem &) rSet.Get( nWhich ) ); 1623 1624 pEntry = CreateEntry( sNumPreBreak, CBCOL_SECOND ); 1625 aLngCfg.GetProperty( C2U(UPN_HYPH_MIN_LEADING) ) >>= nVal; 1626 if (pHyp) 1627 nVal = (sal_Int16) pHyp->GetMinLead(); 1628 nUserData = OptionsUserData( EID_NUM_PRE_BREAK, sal_True, (sal_uInt16)nVal, sal_False, sal_False).GetUserData(); 1629 pEntry->SetUserData( (void *)nUserData ); 1630 pModel->Insert( pEntry ); 1631 1632 pEntry = CreateEntry( sNumPostBreak, CBCOL_SECOND ); 1633 aLngCfg.GetProperty( C2U(UPN_HYPH_MIN_TRAILING) ) >>= nVal; 1634 if (pHyp) 1635 nVal = (sal_Int16) pHyp->GetMinTrail(); 1636 nUserData = OptionsUserData( EID_NUM_POST_BREAK, sal_True, (sal_uInt16)nVal, sal_False, sal_False).GetUserData(); 1637 pEntry->SetUserData( (void *)nUserData ); 1638 pModel->Insert( pEntry ); 1639 1640 pEntry = CreateEntry( sHyphAuto, CBCOL_FIRST ); 1641 aLngCfg.GetProperty( C2U(UPN_IS_HYPH_AUTO) ) >>= bVal; 1642 nUserData = OptionsUserData( EID_HYPH_AUTO, sal_False, 0, sal_True, bVal).GetUserData(); 1643 pEntry->SetUserData( (void *)nUserData ); 1644 pModel->Insert( pEntry ); 1645 lcl_SetCheckButton( pEntry, bVal ); 1646 1647 pEntry = CreateEntry( sHyphSpecial, CBCOL_FIRST ); 1648 aLngCfg.GetProperty( C2U(UPN_IS_HYPH_SPECIAL) ) >>= bVal; 1649 nUserData = OptionsUserData( EID_HYPH_SPECIAL, sal_False, 0, sal_True, bVal).GetUserData(); 1650 pEntry->SetUserData( (void *)nUserData ); 1651 pModel->Insert( pEntry ); 1652 lcl_SetCheckButton( pEntry, bVal ); 1653 1654 aLinguOptionsCLB.SetUpdateMode(sal_True); 1655 } 1656 1657 // ----------------------------------------------------------------------- 1658 1659 IMPL_LINK( SvxLinguTabPage, BoxDoubleClickHdl_Impl, SvTreeListBox *, pBox ) 1660 { 1661 if (pBox == &aLinguModulesCLB) 1662 { 1663 //! in order to avoid a bug causing a GPF when double clicking 1664 //! on a module entry and exiting the "Edit Modules" dialog 1665 //! after that. 1666 Application::PostUserEvent( LINK( 1667 this, SvxLinguTabPage, PostDblClickHdl_Impl ) ); 1668 } 1669 else if (pBox == &aLinguOptionsCLB) 1670 { 1671 ClickHdl_Impl(&aLinguOptionsEditPB); 1672 } 1673 return 0; 1674 } 1675 1676 // ----------------------------------------------------------------------- 1677 1678 IMPL_LINK( SvxLinguTabPage, PostDblClickHdl_Impl, SvTreeListBox *, EMPTYARG ) 1679 { 1680 ClickHdl_Impl(&aLinguModulesEditPB); 1681 return 0; 1682 } 1683 1684 // ----------------------------------------------------------------------- 1685 1686 IMPL_LINK( SvxLinguTabPage, OpenURLHdl_Impl, svt::FixedHyperlink *, EMPTYARG ) 1687 { 1688 ::rtl::OUString sURL( aMoreDictsLink.GetURL() ); 1689 lcl_OpenURL( sURL ); 1690 return 0; 1691 } 1692 1693 // ----------------------------------------------------------------------- 1694 1695 IMPL_LINK( SvxLinguTabPage, BoxCheckButtonHdl_Impl, SvTreeListBox *, pBox ) 1696 { 1697 if (pBox == &aLinguModulesCLB) 1698 { 1699 DBG_ASSERT( pLinguData, "NULL pointer, LinguData missing" ); 1700 sal_uInt16 nPos = aLinguModulesCLB.GetSelectEntryPos(); 1701 if (nPos != LISTBOX_ENTRY_NOTFOUND && pLinguData) 1702 { 1703 pLinguData->Reconfigure( aLinguModulesCLB.GetText( nPos ), 1704 aLinguModulesCLB.IsChecked( nPos ) ); 1705 } 1706 } 1707 else if (pBox == &aLinguDicsCLB) 1708 { 1709 sal_uInt16 nPos = aLinguDicsCLB.GetSelectEntryPos(); 1710 if (nPos != LISTBOX_ENTRY_NOTFOUND) 1711 { 1712 const uno::Reference< XDictionary > &rDic = aDics.getConstArray()[ nPos ]; 1713 if (SvxGetIgnoreAllList() == rDic) 1714 { 1715 SvLBoxEntry* pEntry = aLinguDicsCLB.GetEntry( nPos ); 1716 if (pEntry) 1717 lcl_SetCheckButton( pEntry, sal_True ); 1718 } 1719 } 1720 } 1721 return 0; 1722 } 1723 1724 // ----------------------------------------------------------------------- 1725 1726 IMPL_LINK( SvxLinguTabPage, ClickHdl_Impl, PushButton *, pBtn ) 1727 { 1728 if (&aLinguModulesEditPB == pBtn) 1729 { 1730 if (!pLinguData) 1731 pLinguData = new SvxLinguData_Impl; 1732 1733 SvxLinguData_Impl aOldLinguData( *pLinguData ); 1734 SvxEditModulesDlg aDlg( this, *pLinguData ); 1735 if (aDlg.Execute() != RET_OK) 1736 *pLinguData = aOldLinguData; 1737 1738 // evaluate new status of 'bConfigured' flag 1739 sal_uLong nLen = pLinguData->GetDisplayServiceCount(); 1740 for (sal_uLong i = 0; i < nLen; ++i) 1741 pLinguData->GetDisplayServiceArray()[i].bConfigured = sal_False; 1742 const Locale* pAllLocales = pLinguData->GetAllSupportedLocales().getConstArray(); 1743 sal_Int32 nLocales = pLinguData->GetAllSupportedLocales().getLength(); 1744 for (sal_Int32 k = 0; k < nLocales; ++k) 1745 { 1746 sal_Int16 nLang = SvxLocaleToLanguage( pAllLocales[k] ); 1747 if (pLinguData->GetSpellTable().count( nLang )) 1748 pLinguData->SetChecked( pLinguData->GetSpellTable()[ nLang ] ); 1749 if (pLinguData->GetGrammarTable().count( nLang )) 1750 pLinguData->SetChecked( pLinguData->GetGrammarTable()[ nLang ] ); 1751 if (pLinguData->GetHyphTable().count( nLang )) 1752 pLinguData->SetChecked( pLinguData->GetHyphTable()[ nLang ] ); 1753 if (pLinguData->GetThesTable().count( nLang )) 1754 pLinguData->SetChecked( pLinguData->GetThesTable()[ nLang ] ); 1755 } 1756 1757 // show new status of modules 1758 UpdateModulesBox_Impl(); 1759 } 1760 else if (&aLinguDicsNewPB == pBtn) 1761 { 1762 uno::Reference< XSpellChecker1 > xSpellChecker1; 1763 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); 1764 if(pFact) 1765 { 1766 AbstractSvxNewDictionaryDialog* aDlg = pFact->CreateSvxNewDictionaryDialog( this, xSpellChecker1, RID_SFXDLG_NEWDICT ); 1767 DBG_ASSERT(aDlg, "Dialogdiet fail!"); 1768 uno::Reference< XDictionary > xNewDic; 1769 if ( aDlg->Execute() == RET_OK ) 1770 xNewDic = uno::Reference< XDictionary >( aDlg->GetNewDictionary(), UNO_QUERY ); 1771 if ( xNewDic.is() ) 1772 { 1773 // add new dics to the end 1774 sal_Int32 nLen = aDics.getLength(); 1775 aDics.realloc( nLen + 1 ); 1776 1777 aDics.getArray()[ nLen ] = xNewDic; 1778 1779 AddDicBoxEntry( xNewDic, (sal_uInt16) nLen ); 1780 } 1781 delete aDlg; //add by CHINA001 1782 } 1783 } 1784 else if (&aLinguDicsEditPB == pBtn) 1785 { 1786 SvLBoxEntry *pEntry = aLinguDicsCLB.GetCurEntry(); 1787 if (pEntry) 1788 { 1789 DicUserData aData( (sal_uLong) pEntry->GetUserData() ); 1790 sal_uInt16 nDicPos = aData.GetEntryId(); 1791 sal_Int32 nDics = aDics.getLength(); 1792 if (nDicPos < nDics) 1793 { 1794 uno::Reference< XDictionary > xDic; 1795 xDic = aDics.getConstArray()[ nDicPos ]; 1796 if (xDic.is()) 1797 { 1798 uno::Reference< XSpellChecker1 > xSpellChecker1; 1799 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); 1800 if(pFact) 1801 { 1802 VclAbstractDialog* aDlg = pFact->CreateSvxEditDictionaryDialog( this, xDic->getName(), xSpellChecker1, RID_SFXDLG_EDITDICT ); 1803 DBG_ASSERT(aDlg, "Dialogdiet fail!"); 1804 aDlg->Execute(); 1805 delete aDlg; 1806 } 1807 } 1808 } 1809 } 1810 } 1811 else if (&aLinguDicsDelPB == pBtn) 1812 { 1813 if ( RET_NO == 1814 QueryBox( this, CUI_RES( RID_SFXQB_DELDICT ) ).Execute() ) 1815 return 0; 1816 1817 SvLBoxEntry *pEntry = aLinguDicsCLB.GetCurEntry(); 1818 if (pEntry) 1819 { 1820 DicUserData aData( (sal_uLong) pEntry->GetUserData() ); 1821 sal_uInt16 nDicPos = aData.GetEntryId(); 1822 sal_Int32 nDics = aDics.getLength(); 1823 if (nDicPos < nDics) 1824 { 1825 uno::Reference< XDictionary > xDic; 1826 xDic = aDics.getConstArray()[ nDicPos ]; 1827 if (xDic.is()) 1828 { 1829 if (SvxGetIgnoreAllList() == xDic) 1830 xDic->clear(); 1831 else 1832 { 1833 if (xDicList.is()) 1834 xDicList->removeDictionary( xDic ); 1835 1836 uno::Reference< frame::XStorable > xStor( xDic, UNO_QUERY ); 1837 if ( xStor->hasLocation() && !xStor->isReadonly() ) 1838 { 1839 String sURL = xStor->getLocation(); 1840 INetURLObject aObj(sURL); 1841 DBG_ASSERT( aObj.GetProtocol() == INET_PROT_FILE, 1842 "non-file URLs cannot be deleted" ); 1843 if ( aObj.GetProtocol() == INET_PROT_FILE ) 1844 { 1845 KillFile_Impl( aObj.GetMainURL( INetURLObject::NO_DECODE ) ); 1846 } 1847 } 1848 1849 aDics.getArray()[ nDicPos ] = 0; 1850 1851 // remove entry from checklistbox 1852 sal_uLong nCnt = aLinguDicsCLB.GetEntryCount(); 1853 for (sal_uLong i = 0; i < nCnt; ++i) 1854 { 1855 SvLBoxEntry *pDicEntry = aLinguDicsCLB.GetEntry( i ); 1856 DBG_ASSERT( pDicEntry, "missing entry" ); 1857 if (pDicEntry) 1858 { 1859 DicUserData aDicData( (sal_uLong) pDicEntry->GetUserData() ); 1860 if (aDicData.GetEntryId() == nDicPos ) 1861 { 1862 aLinguDicsCLB.RemoveEntry( (sal_uInt16) i ); 1863 break; 1864 } 1865 } 1866 } 1867 DBG_ASSERT( nCnt > aLinguDicsCLB.GetEntryCount(), 1868 "remove failed ?"); 1869 } 1870 } 1871 } 1872 } 1873 } 1874 else if (&aLinguOptionsEditPB == pBtn) 1875 { 1876 SvLBoxEntry *pEntry = aLinguOptionsCLB.GetCurEntry(); 1877 DBG_ASSERT( pEntry, "no entry selected" ); 1878 if (pEntry) 1879 { 1880 long nVal = -1; 1881 OptionsUserData aData( (sal_uLong)pEntry->GetUserData() ); 1882 if(aData.HasNumericValue()) 1883 { 1884 int nRID = -1; 1885 switch (aData.GetEntryId()) 1886 { 1887 case EID_NUM_PRE_BREAK : nRID = STR_NUM_PRE_BREAK_DLG; break; 1888 case EID_NUM_POST_BREAK : nRID = STR_NUM_POST_BREAK_DLG; break; 1889 case EID_NUM_MIN_WORDLEN: nRID = STR_NUM_MIN_WORDLEN_DLG; break; 1890 default: 1891 DBG_ERROR( "unexpected case" ); 1892 } 1893 1894 OptionsBreakSet aDlg( this, nRID ); 1895 aDlg.GetNumericFld().SetValue( aData.GetNumericValue() ); 1896 if (RET_OK == aDlg.Execute() ) 1897 { 1898 nVal = static_cast<long>(aDlg.GetNumericFld().GetValue()); 1899 if (-1 != nVal && aData.GetNumericValue() != nVal) 1900 { 1901 aData.SetNumericValue( (sal_uInt8)nVal ); //! sets IsModified ! 1902 pEntry->SetUserData( (void *) aData.GetUserData() ); 1903 aLinguOptionsCLB.Invalidate(); 1904 } 1905 } 1906 } 1907 } 1908 } 1909 else 1910 { 1911 DBG_ERROR( "pBtn unexpected value" ); 1912 } 1913 1914 return 0; 1915 } 1916 1917 // ----------------------------------------------------------------------- 1918 1919 IMPL_LINK( SvxLinguTabPage, SelectHdl_Impl, SvxCheckListBox *, pBox ) 1920 { 1921 if (&aLinguModulesCLB == pBox) 1922 { 1923 } 1924 else if (&aLinguDicsCLB == pBox) 1925 { 1926 SvLBoxEntry *pEntry = pBox->GetCurEntry(); 1927 if (pEntry) 1928 { 1929 DicUserData aData( (sal_uLong) pEntry->GetUserData() ); 1930 1931 // always allow to edit (i.e. at least view the content of the dictionary) 1932 aLinguDicsEditPB.Enable( true/*aData.IsEditable()*/ ); 1933 aLinguDicsDelPB .Enable( aData.IsDeletable() ); 1934 } 1935 } 1936 else if (&aLinguOptionsCLB == pBox) 1937 { 1938 SvLBoxEntry *pEntry = pBox->GetCurEntry(); 1939 if (pEntry) 1940 { 1941 OptionsUserData aData( (sal_uLong) pEntry->GetUserData() ); 1942 aLinguOptionsEditPB.Enable( aData.HasNumericValue() ); 1943 } 1944 } 1945 else 1946 { 1947 DBG_ERROR( "pBox unexpected value" ); 1948 } 1949 1950 return 0; 1951 } 1952 1953 // ----------------------------------------------------------------------- 1954 1955 SvLBoxEntry* SvxLinguTabPage::CreateEntry( String& rTxt, sal_uInt16 nCol ) 1956 { 1957 SvLBoxEntry* pEntry = new SvLBoxEntry; 1958 1959 if( !pCheckButtonData ) 1960 pCheckButtonData = new SvLBoxButtonData( &aLinguOptionsCLB ); 1961 1962 String sEmpty; 1963 if (CBCOL_FIRST == nCol) 1964 pEntry->AddItem( new SvLBoxButton( pEntry, SvLBoxButtonKind_enabledCheckbox, 0, pCheckButtonData ) ); 1965 if (CBCOL_SECOND == nCol) 1966 pEntry->AddItem( new SvLBoxString( pEntry, 0, sEmpty) ); // Leerspalte 1967 pEntry->AddItem( new SvLBoxContextBmp( pEntry, 0, Image(), Image(), 0)); // Sonst Puff! 1968 pEntry->AddItem( new BrwString_Impl( pEntry, 0, rTxt ) ); 1969 1970 return pEntry; 1971 } 1972 1973 // ----------------------------------------------------------------------- 1974 1975 void SvxLinguTabPage::HideGroups( sal_uInt16 nGrp ) 1976 { 1977 if ( 0 != ( GROUP_MODULES & nGrp ) ) 1978 { 1979 aLinguModulesFT.Hide(); 1980 aLinguModulesCLB.Hide(); 1981 aLinguModulesEditPB.Hide(); 1982 1983 // reposition / resize remaining controls 1984 long nDeltaY = aLinguDicsFT.GetPosPixel().Y() - 1985 aLinguModulesFT.GetPosPixel().Y(); 1986 DBG_ASSERT( nDeltaY >= 0, "move/resize value is negative" ); 1987 Point aPos; 1988 // 1989 aPos = aLinguDicsFT.GetPosPixel(); 1990 aPos.Y() -= nDeltaY; 1991 aLinguDicsFT.SetPosPixel( aPos ); 1992 aPos = aLinguDicsCLB.GetPosPixel(); 1993 aPos.Y() -= nDeltaY; 1994 aLinguDicsCLB.SetPosPixel( aPos ); 1995 aPos = aLinguDicsNewPB.GetPosPixel(); 1996 aPos.Y() -= nDeltaY; 1997 aLinguDicsNewPB.SetPosPixel( aPos ); 1998 aPos = aLinguDicsEditPB.GetPosPixel(); 1999 aPos.Y() -= nDeltaY; 2000 aLinguDicsEditPB.SetPosPixel( aPos ); 2001 aPos = aLinguDicsDelPB.GetPosPixel(); 2002 aPos.Y() -= nDeltaY; 2003 aLinguDicsDelPB.SetPosPixel( aPos ); 2004 // 2005 aPos = aLinguOptionsFT.GetPosPixel(); 2006 aPos.Y() -= nDeltaY; 2007 aLinguOptionsFT.SetPosPixel( aPos ); 2008 aPos = aLinguOptionsCLB.GetPosPixel(); 2009 aPos.Y() -= nDeltaY; 2010 aLinguOptionsCLB.SetPosPixel( aPos ); 2011 aPos = aLinguOptionsEditPB.GetPosPixel(); 2012 aPos.Y() -= nDeltaY; 2013 aLinguOptionsEditPB.SetPosPixel( aPos ); 2014 // 2015 Size aSize( aLinguOptionsCLB.GetSizePixel() ); 2016 aSize.Height() += nDeltaY; 2017 aLinguOptionsCLB.SetSizePixel( aSize ); 2018 2019 if ( SvtExtendedSecurityOptions().GetOpenHyperlinkMode() 2020 != SvtExtendedSecurityOptions::OPEN_NEVER ) 2021 { 2022 aSize = GetOutputSizePixel(); 2023 aSize.Height() += ( aMoreDictsLink.GetSizePixel().Height() * 11 / 8 ); 2024 SetSizePixel( aSize ); 2025 aMoreDictsLink.Show(); 2026 } 2027 } 2028 } 2029 /*-------------------------------------------------- 2030 --------------------------------------------------*/ 2031 2032 SvxEditModulesDlg::SvxEditModulesDlg(Window* pParent, SvxLinguData_Impl& rData) : 2033 ModalDialog( pParent, CUI_RES(RID_SVXDLG_EDIT_MODULES ) ), 2034 aModulesFL ( this, CUI_RES( FL_EDIT_MODULES_OPTIONS ) ), 2035 aLanguageFT ( this, CUI_RES( FT_EDIT_MODULES_LANGUAGE ) ), 2036 aLanguageLB ( this, CUI_RES( LB_EDIT_MODULES_LANGUAGE ), sal_False ), 2037 aModulesCLB ( this, CUI_RES( CLB_EDIT_MODULES_MODULES ) ), 2038 aPrioUpPB ( this, CUI_RES( PB_EDIT_MODULES_PRIO_UP ) ), 2039 aPrioDownPB ( this, CUI_RES( PB_EDIT_MODULES_PRIO_DOWN ) ), 2040 aBackPB ( this, CUI_RES( PB_EDIT_MODULES_PRIO_BACK ) ), 2041 aMoreDictsLink ( this, CUI_RES( FT_EDIT_MODULES_NEWDICTSLINK ) ), 2042 aButtonsFL ( this, CUI_RES( FL_EDIT_MODULES_BUTTONS ) ), 2043 aHelpPB ( this, CUI_RES( PB_HELP ) ), 2044 aClosePB ( this, CUI_RES( PB_OK ) ), 2045 sSpell ( CUI_RES( ST_SPELL ) ), 2046 sHyph ( CUI_RES( ST_HYPH ) ), 2047 sThes ( CUI_RES( ST_THES ) ), 2048 sGrammar ( CUI_RES( ST_GRAMMAR ) ), 2049 rLinguData ( rData ) 2050 { 2051 pCheckButtonData = NULL; 2052 FreeResource(); 2053 2054 pDefaultLinguData = new SvxLinguData_Impl( rLinguData ); 2055 2056 aModulesCLB.SetStyle( aModulesCLB.GetStyle()|WB_CLIPCHILDREN|WB_HSCROLL|WB_FORCE_MAKEVISIBLE ); 2057 aModulesCLB.SetHighlightRange(); 2058 aModulesCLB.SetHelpId(HID_CLB_EDIT_MODULES_MODULES ); 2059 aModulesCLB.SetSelectHdl( LINK( this, SvxEditModulesDlg, SelectHdl_Impl )); 2060 aModulesCLB.SetCheckButtonHdl( LINK( this, SvxEditModulesDlg, BoxCheckButtonHdl_Impl) ); 2061 2062 aClosePB .SetClickHdl( LINK( this, SvxEditModulesDlg, ClickHdl_Impl )); 2063 aPrioUpPB .SetClickHdl( LINK( this, SvxEditModulesDlg, UpDownHdl_Impl )); 2064 aPrioDownPB.SetClickHdl( LINK( this, SvxEditModulesDlg, UpDownHdl_Impl )); 2065 aBackPB .SetClickHdl( LINK( this, SvxEditModulesDlg, BackHdl_Impl )); 2066 // in case of not installed language modules 2067 aPrioUpPB .Enable( sal_False ); 2068 aPrioDownPB.Enable( sal_False ); 2069 2070 if ( SvtExtendedSecurityOptions().GetOpenHyperlinkMode() 2071 != SvtExtendedSecurityOptions::OPEN_NEVER ) 2072 { 2073 aMoreDictsLink.SetURL( String( 2074 RTL_CONSTASCII_STRINGPARAM( "http://extensions.services.openoffice.org/dictionary?cid=926386" ) ) ); 2075 aMoreDictsLink.SetClickHdl( LINK( this, SvxEditModulesDlg, OpenURLHdl_Impl ) ); 2076 } 2077 else 2078 { 2079 aMoreDictsLink.Hide(); 2080 long nPos = aMoreDictsLink.GetPosPixel().Y() + aMoreDictsLink.GetSizePixel().Height(); 2081 Size aSize = aModulesCLB.GetSizePixel(); 2082 aSize.Height() += ( nPos - ( aModulesCLB.GetPosPixel().Y() + aSize.Height() ) ); 2083 aModulesCLB.SetSizePixel( aSize ); 2084 } 2085 2086 // 2087 //fill language box 2088 // 2089 Sequence< sal_Int16 > aAvailLang; 2090 uno::Reference< XAvailableLocales > xAvail( rLinguData.GetManager(), UNO_QUERY ); 2091 if (xAvail.is()) 2092 { 2093 aAvailLang = lcl_LocaleSeqToLangSeq( 2094 xAvail->getAvailableLocales( C2U(cSpell) ) ); 2095 } 2096 const Sequence< Locale >& rLoc = rLinguData.GetAllSupportedLocales(); 2097 const Locale* pLocales = rLoc.getConstArray(); 2098 aLanguageLB.Clear(); 2099 for(long i = 0; i < rLoc.getLength(); i++) 2100 { 2101 sal_Int16 nLang = SvxLocaleToLanguage( pLocales[i] ); 2102 aLanguageLB.InsertLanguage( nLang, lcl_SeqHasLang( aAvailLang, nLang ) ); 2103 } 2104 LanguageType eSysLang = MsLangId::getSystemLanguage(); 2105 aLanguageLB.SelectLanguage( eSysLang ); 2106 if(!aLanguageLB.IsLanguageSelected( eSysLang ) ) 2107 aLanguageLB.SelectEntryPos(0); 2108 2109 aLanguageLB.SetSelectHdl( LINK( this, SvxEditModulesDlg, LangSelectHdl_Impl )); 2110 LangSelectHdl_Impl(&aLanguageLB); 2111 } 2112 2113 2114 SvxEditModulesDlg::~SvxEditModulesDlg() 2115 { 2116 delete pDefaultLinguData; 2117 } 2118 2119 2120 SvLBoxEntry* SvxEditModulesDlg::CreateEntry( String& rTxt, sal_uInt16 nCol ) 2121 { 2122 SvLBoxEntry* pEntry = new SvLBoxEntry; 2123 if( !pCheckButtonData ) 2124 { 2125 pCheckButtonData = new SvLBoxButtonData( &aModulesCLB ); 2126 pCheckButtonData->SetLink( aModulesCLB.GetCheckButtonHdl() ); 2127 } 2128 2129 String sEmpty; 2130 if (CBCOL_FIRST == nCol) 2131 pEntry->AddItem( new SvLBoxButton( pEntry, SvLBoxButtonKind_enabledCheckbox, 0, pCheckButtonData ) ); 2132 if (CBCOL_SECOND == nCol) 2133 pEntry->AddItem( new SvLBoxString( pEntry, 0, sEmpty) ); // Leerspalte 2134 pEntry->AddItem( new SvLBoxContextBmp( pEntry, 0, Image(), Image(), 0)); // Sonst Puff! 2135 pEntry->AddItem( new BrwStringDic_Impl( pEntry, 0, rTxt ) ); 2136 2137 return pEntry; 2138 } 2139 2140 /* --------------------------------------------------------------------------- 2141 2142 ---------------------------------------------------------------------------*/ 2143 IMPL_LINK( SvxEditModulesDlg, SelectHdl_Impl, SvxCheckListBox *, pBox ) 2144 { 2145 if (&aModulesCLB == pBox) 2146 { 2147 sal_Bool bDisableUp = sal_True; 2148 sal_Bool bDisableDown = sal_True; 2149 SvLBoxEntry *pEntry = pBox->GetCurEntry(); 2150 if (pEntry) 2151 { 2152 ModuleUserData_Impl* pData = (ModuleUserData_Impl*)pEntry->GetUserData(); 2153 if(!pData->IsParent() && pData->GetType() != TYPE_HYPH) 2154 { 2155 sal_uInt16 nCurPos = pBox->GetSelectEntryPos(); 2156 if(nCurPos < pBox->GetEntryCount() - 1) 2157 { 2158 bDisableDown = ((ModuleUserData_Impl*)pBox-> 2159 GetEntry(nCurPos + 1)->GetUserData())->IsParent(); 2160 } 2161 if(nCurPos > 1) 2162 { 2163 bDisableUp = ((ModuleUserData_Impl*)pBox-> 2164 GetEntry(nCurPos - 1)->GetUserData())->IsParent(); 2165 } 2166 } 2167 aPrioUpPB.Enable(!bDisableUp); 2168 aPrioDownPB.Enable(!bDisableDown); 2169 } 2170 } 2171 else 2172 { 2173 DBG_ERROR( "pBox unexpected value" ); 2174 } 2175 2176 return 0; 2177 } 2178 /* -----------------------------28.05.01 11:00-------------------------------- 2179 2180 ---------------------------------------------------------------------------*/ 2181 IMPL_LINK( SvxEditModulesDlg, BoxCheckButtonHdl_Impl, SvTreeListBox *, pBox ) 2182 { 2183 // if (pBox == (SvTreeListBox *) &aModulesCLB) 2184 // { 2185 pBox = &aModulesCLB; 2186 SvLBoxEntry *pCurEntry = pBox->GetCurEntry(); 2187 if (pCurEntry) 2188 { 2189 ModuleUserData_Impl* pData = (ModuleUserData_Impl *) 2190 pCurEntry->GetUserData(); 2191 if (!pData->IsParent() && pData->GetType() == TYPE_HYPH) 2192 { 2193 // make hyphenator checkboxes function as radio-buttons 2194 // (at most one box may be checked) 2195 SvLBoxEntry *pEntry = pBox->First(); 2196 while (pEntry) 2197 { 2198 pData = (ModuleUserData_Impl *) pEntry->GetUserData(); 2199 if (!pData->IsParent() && 2200 pData->GetType() == TYPE_HYPH && 2201 pEntry != pCurEntry) 2202 { 2203 lcl_SetCheckButton( pEntry, sal_False ); 2204 pBox->InvalidateEntry( pEntry ); 2205 } 2206 pEntry = pBox->Next( pEntry ); 2207 } 2208 } 2209 } 2210 // } 2211 return 0; 2212 } 2213 /* -----------------------------27.11.00 14:00-------------------------------- 2214 2215 ---------------------------------------------------------------------------*/ 2216 OUString lcl_GetServiceName(sal_uInt8 nType) 2217 { 2218 switch(nType) 2219 { 2220 case TYPE_SPELL : return C2U(cSpell); 2221 case TYPE_GRAMMAR : return C2U(cGrammar); 2222 case TYPE_HYPH : return C2U(cHyph); 2223 case TYPE_THES : return C2U(cThes); 2224 } 2225 return OUString(); 2226 } 2227 2228 2229 IMPL_LINK( SvxEditModulesDlg, LangSelectHdl_Impl, ListBox *, pBox ) 2230 { 2231 LanguageType eCurLanguage = aLanguageLB.GetSelectLanguage(); 2232 static Locale aLastLocale; 2233 Locale aCurLocale; 2234 SvxLanguageToLocale(aCurLocale, eCurLanguage); 2235 SvLBoxTreeList *pModel = aModulesCLB.GetModel(); 2236 // uno::Reference<XLinguServiceManager>& xMgr = rLinguData.GetManager(); 2237 2238 if (pBox) 2239 { 2240 // save old probably changed settings 2241 // before switching to new language entries 2242 2243 sal_Int16 nLang = SvxLocaleToLanguage( aLastLocale ); 2244 2245 sal_Int32 nStart = 0, nLocalIndex = 0; 2246 Sequence< OUString > aChange; 2247 sal_Bool bChanged = sal_False; 2248 for(sal_uInt16 i = 0; i < aModulesCLB.GetEntryCount(); i++) 2249 { 2250 SvLBoxEntry *pEntry = aModulesCLB.GetEntry(i); 2251 ModuleUserData_Impl* pData = (ModuleUserData_Impl*)pEntry->GetUserData(); 2252 if(pData->IsParent()) 2253 { 2254 if(bChanged) 2255 { 2256 LangImplNameTable *pTable = 0; 2257 sal_uInt8 nType = pData->GetType(); 2258 switch (nType - 1) 2259 { 2260 case TYPE_SPELL : pTable = &rLinguData.GetSpellTable(); break; 2261 case TYPE_GRAMMAR : pTable = &rLinguData.GetGrammarTable(); break; 2262 case TYPE_HYPH : pTable = &rLinguData.GetHyphTable(); break; 2263 case TYPE_THES : pTable = &rLinguData.GetThesTable(); break; 2264 } 2265 if (pTable) 2266 { 2267 aChange.realloc(nStart); 2268 (*pTable)[ nLang ] = aChange; 2269 } 2270 } 2271 nLocalIndex = nStart = 0; 2272 aChange.realloc(aModulesCLB.GetEntryCount()); 2273 bChanged = sal_False; 2274 } 2275 else 2276 { 2277 OUString* pChange = aChange.getArray(); 2278 pChange[nStart] = pData->GetImplName(); 2279 bChanged |= pData->GetIndex() != nLocalIndex || 2280 pData->IsChecked() != aModulesCLB.IsChecked(i); 2281 if(aModulesCLB.IsChecked(i)) 2282 nStart++; 2283 ++nLocalIndex; 2284 } 2285 } 2286 if(bChanged) 2287 { 2288 aChange.realloc(nStart); 2289 rLinguData.GetThesTable()[ nLang ] = aChange; 2290 } 2291 } 2292 2293 for(sal_uLong i = 0; i < aModulesCLB.GetEntryCount(); i++) 2294 delete (ModuleUserData_Impl*)aModulesCLB.GetEntry(i)->GetUserData(); 2295 2296 // 2297 // display entries for new selected language 2298 // 2299 aModulesCLB.Clear(); 2300 if(LANGUAGE_DONTKNOW != eCurLanguage) 2301 { 2302 // sal_Int32 nEntryPos = 1; 2303 2304 sal_uLong n; 2305 ServiceInfo_Impl* pInfo; 2306 2307 // 2308 // spellchecker entries 2309 // 2310 SvLBoxEntry* pEntry = CreateEntry( sSpell, CBCOL_SECOND ); 2311 ModuleUserData_Impl* pUserData = new ModuleUserData_Impl( 2312 String(), sal_True, sal_False, TYPE_SPELL, 0 ); 2313 pEntry->SetUserData( (void *)pUserData ); 2314 pModel->Insert( pEntry ); 2315 // 2316 Sequence< OUString > aNames( rLinguData.GetSortedImplNames( eCurLanguage, TYPE_SPELL ) ); 2317 const OUString *pName = aNames.getConstArray(); 2318 sal_uLong nNames = (sal_uLong) aNames.getLength(); 2319 sal_Int32 nLocalIndex = 0; // index relative to parent 2320 for (n = 0; n < nNames; ++n) 2321 { 2322 OUString aImplName; 2323 sal_Bool bIsSuppLang = sal_False; 2324 2325 pInfo = rLinguData.GetInfoByImplName( pName[n] ); 2326 if (pInfo) 2327 { 2328 bIsSuppLang = pInfo->xSpell.is() && 2329 pInfo->xSpell->hasLocale( aCurLocale ); 2330 aImplName = pInfo->sSpellImplName; 2331 } 2332 if (aImplName.getLength() && bIsSuppLang) 2333 { 2334 String aTxt( pInfo->sDisplayName ); 2335 SvLBoxEntry* pNewEntry = CreateEntry( aTxt, CBCOL_FIRST ); 2336 2337 LangImplNameTable &rTable = rLinguData.GetSpellTable(); 2338 const bool bHasLang = rTable.count( eCurLanguage ); 2339 if (!bHasLang) 2340 { 2341 DBG_WARNING( "language entry missing" ); // only relevant if all languages found should be supported 2342 } 2343 const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0; 2344 lcl_SetCheckButton( pNewEntry, bCheck ); 2345 pUserData = new ModuleUserData_Impl( aImplName, sal_False, 2346 bCheck, TYPE_SPELL, (sal_uInt8)nLocalIndex++ ); 2347 pNewEntry->SetUserData( (void *)pUserData ); 2348 pModel->Insert( pNewEntry ); 2349 } 2350 } 2351 2352 // 2353 // grammar checker entries 2354 // 2355 pEntry = CreateEntry( sGrammar, CBCOL_SECOND ); 2356 pUserData = new ModuleUserData_Impl( String(), sal_True, sal_False, TYPE_GRAMMAR, 0 ); 2357 pEntry->SetUserData( (void *)pUserData ); 2358 pModel->Insert( pEntry ); 2359 // 2360 aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_GRAMMAR ); 2361 pName = aNames.getConstArray(); 2362 nNames = (sal_uLong) aNames.getLength(); 2363 nLocalIndex = 0; 2364 for (n = 0; n < nNames; ++n) 2365 { 2366 OUString aImplName; 2367 sal_Bool bIsSuppLang = sal_False; 2368 2369 pInfo = rLinguData.GetInfoByImplName( pName[n] ); 2370 if (pInfo) 2371 { 2372 bIsSuppLang = pInfo->xGrammar.is() && 2373 pInfo->xGrammar->hasLocale( aCurLocale ); 2374 aImplName = pInfo->sGrammarImplName; 2375 } 2376 if (aImplName.getLength() && bIsSuppLang) 2377 { 2378 String aTxt( pInfo->sDisplayName ); 2379 SvLBoxEntry* pNewEntry = CreateEntry( aTxt, CBCOL_FIRST ); 2380 2381 LangImplNameTable &rTable = rLinguData.GetGrammarTable(); 2382 const bool bHasLang = rTable.count( eCurLanguage ); 2383 if (!bHasLang) 2384 { 2385 DBG_WARNING( "language entry missing" ); // only relevant if all languages found should be supported 2386 } 2387 const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0; 2388 lcl_SetCheckButton( pNewEntry, bCheck ); 2389 pUserData = new ModuleUserData_Impl( aImplName, sal_False, 2390 bCheck, TYPE_GRAMMAR, (sal_uInt8)nLocalIndex++ ); 2391 pNewEntry->SetUserData( (void *)pUserData ); 2392 pModel->Insert( pNewEntry ); 2393 } 2394 } 2395 2396 // 2397 // hyphenator entries 2398 // 2399 pEntry = CreateEntry( sHyph, CBCOL_SECOND ); 2400 pUserData = new ModuleUserData_Impl( String(), sal_True, sal_False, TYPE_HYPH, 0 ); 2401 pEntry->SetUserData( (void *)pUserData ); 2402 pModel->Insert( pEntry ); 2403 // 2404 aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_HYPH ); 2405 pName = aNames.getConstArray(); 2406 nNames = (sal_uLong) aNames.getLength(); 2407 nLocalIndex = 0; 2408 for (n = 0; n < nNames; ++n) 2409 { 2410 OUString aImplName; 2411 sal_Bool bIsSuppLang = sal_False; 2412 2413 pInfo = rLinguData.GetInfoByImplName( pName[n] ); 2414 if (pInfo) 2415 { 2416 bIsSuppLang = pInfo->xHyph.is() && 2417 pInfo->xHyph->hasLocale( aCurLocale ); 2418 aImplName = pInfo->sHyphImplName; 2419 } 2420 if (aImplName.getLength() && bIsSuppLang) 2421 { 2422 String aTxt( pInfo->sDisplayName ); 2423 SvLBoxEntry* pNewEntry = CreateEntry( aTxt, CBCOL_FIRST ); 2424 2425 LangImplNameTable &rTable = rLinguData.GetHyphTable(); 2426 const bool bHasLang = rTable.count( eCurLanguage ); 2427 if (!bHasLang) 2428 { 2429 DBG_WARNING( "language entry missing" ); // only relevant if all languages found should be supported 2430 } 2431 const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0; 2432 lcl_SetCheckButton( pNewEntry, bCheck ); 2433 pUserData = new ModuleUserData_Impl( aImplName, sal_False, 2434 bCheck, TYPE_HYPH, (sal_uInt8)nLocalIndex++ ); 2435 pNewEntry->SetUserData( (void *)pUserData ); 2436 pModel->Insert( pNewEntry ); 2437 } 2438 } 2439 2440 // 2441 // thesaurus entries 2442 // 2443 pEntry = CreateEntry( sThes, CBCOL_SECOND ); 2444 pUserData = new ModuleUserData_Impl( String(), sal_True, sal_False, TYPE_THES, 0 ); 2445 pEntry->SetUserData( (void *)pUserData ); 2446 pModel->Insert( pEntry ); 2447 // 2448 aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_THES ); 2449 pName = aNames.getConstArray(); 2450 nNames = (sal_uLong) aNames.getLength(); 2451 nLocalIndex = 0; 2452 for (n = 0; n < nNames; ++n) 2453 { 2454 OUString aImplName; 2455 sal_Bool bIsSuppLang = sal_False; 2456 2457 pInfo = rLinguData.GetInfoByImplName( pName[n] ); 2458 if (pInfo) 2459 { 2460 bIsSuppLang = pInfo->xThes.is() && 2461 pInfo->xThes->hasLocale( aCurLocale ); 2462 aImplName = pInfo->sThesImplName; 2463 } 2464 if (aImplName.getLength() && bIsSuppLang) 2465 { 2466 String aTxt( pInfo->sDisplayName ); 2467 SvLBoxEntry* pNewEntry = CreateEntry( aTxt, CBCOL_FIRST ); 2468 2469 LangImplNameTable &rTable = rLinguData.GetThesTable(); 2470 const bool bHasLang = rTable.count( eCurLanguage ); 2471 if (!bHasLang) 2472 { 2473 DBG_WARNING( "language entry missing" ); // only relevant if all languages found should be supported 2474 } 2475 const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0; 2476 lcl_SetCheckButton( pNewEntry, bCheck ); 2477 pUserData = new ModuleUserData_Impl( aImplName, sal_False, 2478 bCheck, TYPE_THES, (sal_uInt8)nLocalIndex++ ); 2479 pNewEntry->SetUserData( (void *)pUserData ); 2480 pModel->Insert( pNewEntry ); 2481 } 2482 } 2483 } 2484 aLastLocale.Language = aCurLocale.Language; 2485 aLastLocale.Country = aCurLocale.Country; 2486 return 0; 2487 } 2488 /* -----------------------------27.11.00 19:50-------------------------------- 2489 2490 ---------------------------------------------------------------------------*/ 2491 IMPL_LINK( SvxEditModulesDlg, UpDownHdl_Impl, PushButton *, pBtn ) 2492 { 2493 sal_Bool bUp = &aPrioUpPB == pBtn; 2494 sal_uInt16 nCurPos = aModulesCLB.GetSelectEntryPos(); 2495 SvLBoxEntry* pEntry; 2496 if (nCurPos != LISTBOX_ENTRY_NOTFOUND && 2497 0 != (pEntry = aModulesCLB.GetEntry(nCurPos))) 2498 { 2499 aModulesCLB.SetUpdateMode(sal_False); 2500 SvLBoxTreeList *pModel = aModulesCLB.GetModel(); 2501 2502 ModuleUserData_Impl* pData = (ModuleUserData_Impl*)pEntry->GetUserData(); 2503 String aStr(aModulesCLB.GetEntryText(pEntry)); 2504 SvLBoxEntry* pToInsert = CreateEntry( aStr, CBCOL_FIRST ); 2505 pToInsert->SetUserData( (void *)pData); 2506 sal_Bool bIsChecked = aModulesCLB.IsChecked(nCurPos); 2507 2508 pModel->Remove(pEntry); 2509 2510 sal_uInt16 nDestPos = bUp ? nCurPos - 1 : nCurPos + 1; 2511 pModel->Insert(pToInsert, nDestPos); 2512 aModulesCLB.CheckEntryPos(nDestPos, bIsChecked ); 2513 aModulesCLB.SelectEntryPos(nDestPos ); 2514 SelectHdl_Impl(&aModulesCLB); 2515 aModulesCLB.SetUpdateMode(sal_True); 2516 } 2517 return 0; 2518 } 2519 /* --------------------------------------------------------------------------- 2520 2521 ---------------------------------------------------------------------------*/ 2522 IMPL_LINK( SvxEditModulesDlg, ClickHdl_Impl, PushButton *, pBtn ) 2523 { 2524 if (&aClosePB == pBtn) 2525 { 2526 // store language config 2527 LangSelectHdl_Impl(&aLanguageLB); 2528 EndDialog( RET_OK ); 2529 } 2530 else 2531 { 2532 DBG_ERROR( "pBtn unexpected value" ); 2533 } 2534 2535 return 0; 2536 } 2537 /* -----------------------------27.11.00 20:31-------------------------------- 2538 2539 ---------------------------------------------------------------------------*/ 2540 IMPL_LINK( SvxEditModulesDlg, BackHdl_Impl, PushButton *, EMPTYARG ) 2541 { 2542 rLinguData = *pDefaultLinguData; 2543 LangSelectHdl_Impl(0); 2544 return 0; 2545 } 2546 2547 // ----------------------------------------------------------------------- 2548 2549 IMPL_LINK( SvxEditModulesDlg, OpenURLHdl_Impl, svt::FixedHyperlink *, EMPTYARG ) 2550 { 2551 ::rtl::OUString sURL( aMoreDictsLink.GetURL() ); 2552 lcl_OpenURL( sURL ); 2553 return 0; 2554 } 2555 2556