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