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