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 #include <tools/shl.hxx> 33 #include <editeng/unolingu.hxx> 34 #include <svx/dlgutil.hxx> 35 #include <sfx2/sfxuno.hxx> 36 #include <svl/eitem.hxx> 37 #include <com/sun/star/frame/XStorable.hpp> 38 #include <comphelper/processfactory.hxx> 39 #include <unotools/intlwrapper.hxx> 40 #include <vcl/svapp.hxx> 41 #include <vcl/msgbox.hxx> 42 #include <svx/dialogs.hrc> 43 44 #define _SVX_OPTDICT_CXX 45 46 #include <linguistic/misc.hxx> 47 #include <cuires.hrc> 48 #include "optdict.hrc" 49 #include "optdict.hxx" 50 #include <dialmgr.hxx> 51 #include <svx/svxerr.hxx> 52 53 using namespace ::com::sun::star; 54 using namespace ::com::sun::star::uno; 55 using namespace ::com::sun::star::linguistic2; 56 57 // static ---------------------------------------------------------------- 58 59 static const sal_uInt16 nNameLen = 8; 60 static const short NOACTDICT = -1; 61 62 static long nStaticTabs[]= 63 { 64 2,10,71,120 65 }; 66 67 // static function ------------------------------------------------------- 68 69 static String getNormDicEntry_Impl( const String &rText ) 70 { 71 String aTmp( rText ); 72 aTmp.EraseTrailingChars( '.' ); 73 aTmp.EraseAllChars( '=' ); 74 return aTmp; 75 } 76 77 78 // Compare Dictionary Entry result 79 enum CDE_RESULT { CDE_EQUAL, CDE_SIMILAR, CDE_DIFFERENT }; 80 81 static CDE_RESULT cmpDicEntry_Impl( const String &rText1, const String &rText2 ) 82 { 83 CDE_RESULT eRes = CDE_DIFFERENT; 84 85 if (rText1 == rText2) 86 eRes = CDE_EQUAL; 87 else 88 { // similar = equal up to trailing '.' and hyphenation positions 89 // marked with '=' 90 if (getNormDicEntry_Impl( rText1 ) == getNormDicEntry_Impl( rText2 )) 91 eRes = CDE_SIMILAR; 92 } 93 94 return eRes; 95 } 96 97 // class SvxNewDictionaryDialog ------------------------------------------- 98 99 SvxNewDictionaryDialog::SvxNewDictionaryDialog( Window* pParent, 100 Reference< XSpellChecker1 > &xSpl ) : 101 102 ModalDialog( pParent, CUI_RES( RID_SFXDLG_NEWDICT ) ), 103 104 aNewDictBox ( this, CUI_RES( GB_NEWDICT ) ), 105 aNameText ( this, CUI_RES( FT_DICTNAME ) ), 106 aNameEdit ( this, CUI_RES( ED_DICTNAME ) ), 107 aLanguageText ( this, CUI_RES( FT_DICTLANG ) ), 108 aLanguageLB ( this, CUI_RES( LB_DICTLANG ) ), 109 aExceptBtn ( this, CUI_RES( BTN_EXCEPT ) ), 110 aOKBtn ( this, CUI_RES( BTN_NEWDICT_OK ) ), 111 aCancelBtn ( this, CUI_RES( BTN_NEWDICT_ESC ) ), 112 aHelpBtn ( this, CUI_RES( BTN_NEWDICT_HLP ) ), 113 xSpell( xSpl ) 114 { 115 // Handler installieren 116 aNameEdit.SetModifyHdl( 117 LINK( this, SvxNewDictionaryDialog, ModifyHdl_Impl ) ); 118 aOKBtn.SetClickHdl( LINK( this, SvxNewDictionaryDialog, OKHdl_Impl ) ); 119 120 // Sprachen anzeigen 121 aLanguageLB.SetLanguageList( LANG_LIST_ALL, sal_True, sal_True ); 122 aLanguageLB.SelectEntryPos(0); 123 124 aNameText.SetAccessibleRelationMemberOf( &aNewDictBox ); 125 aNameEdit.SetAccessibleRelationMemberOf( &aNewDictBox ); 126 aLanguageText.SetAccessibleRelationMemberOf( &aNewDictBox ); 127 aLanguageLB.SetAccessibleRelationMemberOf( &aNewDictBox ); 128 129 FreeResource(); 130 } 131 132 // ----------------------------------------------------------------------- 133 134 IMPL_LINK( SvxNewDictionaryDialog, OKHdl_Impl, Button *, EMPTYARG ) 135 { 136 String sDict = aNameEdit.GetText(); 137 sDict.EraseTrailingChars(); 138 // add extension for personal dictionaries 139 sDict.AppendAscii(".dic"); 140 141 Reference< XDictionaryList > xDicList( SvxGetDictionaryList() ); 142 143 Sequence< Reference< XDictionary > > aDics; 144 if (xDicList.is()) 145 aDics = xDicList->getDictionaries(); 146 const Reference< XDictionary > *pDic = aDics.getConstArray(); 147 sal_Int32 nCount = (sal_uInt16) aDics.getLength(); 148 149 sal_Bool bFound = sal_False; 150 sal_uInt16 i; 151 for (i = 0; !bFound && i < nCount; ++i ) 152 if ( sDict.EqualsIgnoreCaseAscii( String(pDic[i]->getName()) )) 153 bFound = sal_True; 154 155 if ( bFound ) 156 { 157 // Doppelte Namen? 158 InfoBox( this, CUI_RESSTR( RID_SVXSTR_OPT_DOUBLE_DICTS ) ).Execute(); 159 aNameEdit.GrabFocus(); 160 return 0; 161 } 162 163 // Erzeugen und hinzufuegen 164 sal_uInt16 nLang = aLanguageLB.GetSelectLanguage(); 165 try 166 { 167 // create new dictionary 168 DictionaryType eType = aExceptBtn.IsChecked() ? 169 DictionaryType_NEGATIVE : DictionaryType_POSITIVE; 170 if (xDicList.is()) 171 { 172 lang::Locale aLocale( SvxCreateLocale(nLang) ); 173 String aURL( linguistic::GetWritableDictionaryURL( sDict ) ); 174 xNewDic = Reference< XDictionary > ( 175 xDicList->createDictionary( sDict, aLocale, eType, aURL ) , UNO_QUERY ); 176 xNewDic->setActive( sal_True ); 177 } 178 DBG_ASSERT(xNewDic.is(), "NULL pointer"); 179 } 180 catch(...) 181 { 182 xNewDic = NULL; 183 184 // Fehler: konnte neues W"orterbuch nicht anlegen 185 SfxErrorContext aContext( ERRCTX_SVX_LINGU_DICTIONARY, String(), 186 this, RID_SVXERRCTX, &CUI_MGR() ); 187 ErrorHandler::HandleError( *new StringErrorInfo( 188 ERRCODE_SVX_LINGU_DICT_NOTWRITEABLE, sDict ) ); 189 190 EndDialog( RET_CANCEL ); 191 } 192 193 if (xDicList.is() && xNewDic.is()) 194 { 195 xDicList->addDictionary( Reference< XDictionary > ( xNewDic, UNO_QUERY ) ); 196 197 // refresh list of dictionaries 198 //! dictionaries may have been added/removed elsewhere too. 199 aDics = xDicList->getDictionaries(); 200 } 201 pDic = aDics.getConstArray(); 202 nCount = (sal_uInt16) aDics.getLength(); 203 204 205 EndDialog( RET_OK ); 206 return 0; 207 } 208 209 // ----------------------------------------------------------------------- 210 211 IMPL_LINK_INLINE_START( SvxNewDictionaryDialog, ModifyHdl_Impl, Edit *, EMPTYARG ) 212 { 213 if ( aNameEdit.GetText().Len() ) 214 aOKBtn.Enable(); 215 else 216 aOKBtn.Disable(); 217 return 0; 218 } 219 IMPL_LINK_INLINE_END( SvxNewDictionaryDialog, ModifyHdl_Impl, Edit *, EMPTYARG ) 220 221 //========================================================================== 222 // 223 // class SvxEditDictionaryDialog ------------------------------------------- 224 // 225 //========================================================================== 226 227 SvxEditDictionaryDialog::SvxEditDictionaryDialog( 228 Window* pParent, 229 const String& rName, 230 Reference< XSpellChecker1 > &xSpl ) : 231 232 ModalDialog( pParent, CUI_RES( RID_SFXDLG_EDITDICT ) ), 233 234 aBookFT ( this, CUI_RES( FT_BOOK ) ), 235 aAllDictsLB ( this, CUI_RES( LB_ALLDICTS ) ), 236 aLangFT ( this, CUI_RES( FT_DICTLANG ) ), 237 aLangLB ( this, CUI_RES( LB_DICTLANG ) ), 238 239 aWordFT ( this, CUI_RES( FT_WORD ) ), 240 aWordED ( this, CUI_RES( ED_WORD ) ), 241 aReplaceFT ( this, CUI_RES( FT_REPLACE ) ), 242 aReplaceED ( this, CUI_RES( ED_REPLACE ) ), 243 aWordsLB ( this, CUI_RES( TLB_REPLACE ) ), 244 aNewReplacePB ( this, CUI_RES( PB_NEW_REPLACE ) ), 245 aDeletePB ( this, CUI_RES( PB_DELETE_REPLACE ) ), 246 aEditDictsBox ( this, CUI_RES( GB_EDITDICTS ) ), 247 aHelpBtn ( this, CUI_RES( BTN_EDITHELP ) ), 248 aCloseBtn ( this, CUI_RES( BTN_EDITCLOSE ) ), 249 sModify (CUI_RES(STR_MODIFY)), 250 sNew (aNewReplacePB.GetText()), 251 aDecoView ( this), 252 xSpell ( xSpl ), 253 nOld ( NOACTDICT ), 254 bFirstSelect (sal_True), 255 bDoNothing (sal_False) 256 257 { 258 if (SvxGetDictionaryList().is()) 259 aDics = SvxGetDictionaryList()->getDictionaries(); 260 261 aWordsLB.SetSelectHdl(LINK(this, SvxEditDictionaryDialog, SelectHdl)); 262 aWordsLB.SetTabs(nStaticTabs); 263 264 //! we use an algorithm of our own to insert elements sorted 265 aWordsLB.SetStyle(aWordsLB.GetStyle()|/*WB_SORT|*/WB_HSCROLL|WB_CLIPCHILDREN); 266 267 268 nWidth=aWordED.GetSizePixel().Width(); 269 // Handler installieren 270 aNewReplacePB.SetClickHdl( 271 LINK( this, SvxEditDictionaryDialog, NewDelHdl)); 272 aDeletePB.SetClickHdl( 273 LINK( this, SvxEditDictionaryDialog, NewDelHdl)); 274 275 aLangLB.SetSelectHdl( 276 LINK( this, SvxEditDictionaryDialog, SelectLangHdl_Impl ) ); 277 aAllDictsLB.SetSelectHdl( 278 LINK( this, SvxEditDictionaryDialog, SelectBookHdl_Impl ) ); 279 280 aWordED.SetModifyHdl(LINK(this, SvxEditDictionaryDialog, ModifyHdl)); 281 aReplaceED.SetModifyHdl(LINK(this, SvxEditDictionaryDialog, ModifyHdl)); 282 aWordED.SetActionHdl(LINK(this, SvxEditDictionaryDialog, NewDelHdl)); 283 aReplaceED.SetActionHdl(LINK(this, SvxEditDictionaryDialog, NewDelHdl)); 284 285 // Listbox mit allen verfuegbaren WB's fuellen 286 const Reference< XDictionary > *pDic = aDics.getConstArray(); 287 sal_Int32 nCount = aDics.getLength(); 288 289 String aLookUpEntry; 290 for ( sal_Int32 i = 0; i < nCount; ++i ) 291 { 292 Reference< XDictionary > xDic( pDic[i], UNO_QUERY ); 293 if (xDic.is()) 294 { 295 sal_Bool bNegative = xDic->getDictionaryType() == DictionaryType_NEGATIVE ? 296 sal_True : sal_False; 297 String aDicName( xDic->getName() ); 298 const String aTxt( ::GetDicInfoStr( aDicName, SvxLocaleToLanguage( xDic->getLocale() ), 299 bNegative ) ); 300 aAllDictsLB.InsertEntry( aTxt ); 301 302 if (rName == aDicName) 303 aLookUpEntry = aTxt; 304 } 305 } 306 307 aLangLB.SetLanguageList( LANG_LIST_ALL, sal_True, sal_True ); 308 309 aReplaceED.SetSpaces(sal_True); 310 aWordED.SetSpaces(sal_True); 311 312 if ( nCount > 0 ) 313 { 314 aAllDictsLB.SelectEntry( aLookUpEntry ); 315 sal_uInt16 nPos = aAllDictsLB.GetSelectEntryPos(); 316 317 if ( nPos == LISTBOX_ENTRY_NOTFOUND ) 318 { 319 nPos = 0; 320 aAllDictsLB.SelectEntryPos( nPos ); 321 } 322 Reference< XDictionary > xDic; 323 if (nPos != LISTBOX_ENTRY_NOTFOUND) 324 xDic = Reference< XDictionary > ( aDics.getConstArray()[ nPos ], UNO_QUERY ); 325 if (xDic.is()) 326 SetLanguage_Impl( SvxLocaleToLanguage( xDic->getLocale() ) ); 327 328 // check if dictionary is read-only 329 SetDicReadonly_Impl(xDic); 330 sal_Bool bEnable = !IsDicReadonly_Impl(); 331 aNewReplacePB .Enable( sal_False ); 332 aDeletePB .Enable( sal_False ); 333 aLangFT.Enable( bEnable ); 334 aLangLB.Enable( bEnable ); 335 ShowWords_Impl( nPos ); 336 337 } 338 else 339 { 340 aNewReplacePB.Disable(); 341 aDeletePB .Disable(); 342 } 343 FreeResource(); 344 } 345 346 // ----------------------------------------------------------------------- 347 348 SvxEditDictionaryDialog::~SvxEditDictionaryDialog() 349 { 350 } 351 352 // ----------------------------------------------------------------------- 353 354 void SvxEditDictionaryDialog::Paint( const Rectangle& rRect ) 355 { 356 ModalDialog::Paint(rRect ); 357 358 Rectangle aRect(aEditDictsBox.GetPosPixel(),aEditDictsBox.GetSizePixel()); 359 360 sal_uInt16 nStyle=BUTTON_DRAW_NOFILL; 361 aDecoView.DrawButton( aRect, nStyle); 362 } 363 364 // ----------------------------------------------------------------------- 365 366 void SvxEditDictionaryDialog::SetDicReadonly_Impl( 367 Reference< XDictionary > &xDic ) 368 { 369 // enable or disable new and delete button according to file attributes 370 bDicIsReadonly = sal_True; 371 if (xDic.is()) 372 { 373 Reference< frame::XStorable > xStor( xDic, UNO_QUERY ); 374 if ( !xStor.is() // non persistent dictionary 375 || !xStor->hasLocation() // not yet persistent 376 || !xStor->isReadonly() ) 377 { 378 bDicIsReadonly = sal_False; 379 } 380 } 381 } 382 383 // ----------------------------------------------------------------------- 384 385 void SvxEditDictionaryDialog::SetLanguage_Impl( util::Language nLanguage ) 386 { 387 // select language 388 aLangLB.SelectLanguage( nLanguage ); 389 } 390 391 sal_uInt16 SvxEditDictionaryDialog::GetLBInsertPos(const String &rDicWord) 392 { 393 sal_uInt16 nPos = USHRT_MAX; 394 395 IntlWrapper aIntlWrapper( ::comphelper::getProcessServiceFactory(), Application::GetSettings().GetLocale() ); 396 const CollatorWrapper* pCollator = aIntlWrapper.getCollator(); 397 sal_uInt16 j; 398 for( j = 0; j < aWordsLB.GetEntryCount(); j++ ) 399 { 400 SvLBoxEntry* pEntry = aWordsLB.GetEntry(j); 401 DBG_ASSERT( pEntry, "NULL pointer"); 402 String aNormEntry( getNormDicEntry_Impl( rDicWord ) ); 403 StringCompare eCmpRes = (StringCompare)pCollator-> 404 compareString( aNormEntry, getNormDicEntry_Impl( aWordsLB.GetEntryText(pEntry, 0) ) ); 405 if( COMPARE_LESS == eCmpRes ) 406 break; 407 } 408 if (j < aWordsLB.GetEntryCount()) // entry found? 409 nPos = j; 410 411 return nPos; 412 } 413 414 void SvxEditDictionaryDialog::RemoveDictEntry(SvLBoxEntry* pEntry) 415 { 416 sal_uInt16 nLBPos = aAllDictsLB.GetSelectEntryPos(); 417 418 if ( pEntry != NULL && nLBPos != LISTBOX_ENTRY_NOTFOUND ) 419 { 420 String sTmpShort(aWordsLB.GetEntryText(pEntry, 0)); 421 422 Reference< XDictionary > xDic = aDics.getConstArray()[ nLBPos ]; 423 if (xDic->remove( sTmpShort )) // sal_True on success 424 { 425 aWordsLB.GetModel()->Remove(pEntry); 426 } 427 } 428 } 429 430 // ----------------------------------------------------------------------- 431 432 IMPL_LINK( SvxEditDictionaryDialog, SelectBookHdl_Impl, ListBox *, EMPTYARG ) 433 { 434 sal_uInt16 nPos = aAllDictsLB.GetSelectEntryPos(); 435 436 if ( nPos != LISTBOX_ENTRY_NOTFOUND ) 437 { 438 aNewReplacePB.Enable( sal_False ); 439 aDeletePB .Enable( sal_False ); 440 // Dictionary anzeigen 441 ShowWords_Impl( nPos ); 442 // enable or disable new and delete button according to file attributes 443 Reference< XDictionary > xDic( aDics.getConstArray()[ nPos ], UNO_QUERY ); 444 if (xDic.is()) 445 SetLanguage_Impl( SvxLocaleToLanguage( xDic->getLocale() ) ); 446 447 SetDicReadonly_Impl(xDic); 448 sal_Bool bEnable = !IsDicReadonly_Impl(); 449 aLangFT.Enable( bEnable ); 450 aLangLB.Enable( bEnable ); 451 } 452 return 0; 453 } 454 455 // ----------------------------------------------------------------------- 456 457 IMPL_LINK( SvxEditDictionaryDialog, SelectLangHdl_Impl, ListBox *, EMPTYARG ) 458 { 459 sal_uInt16 nDicPos = aAllDictsLB.GetSelectEntryPos(); 460 sal_uInt16 nLang = aLangLB.GetSelectLanguage(); 461 Reference< XDictionary > xDic( aDics.getConstArray()[ nDicPos ], UNO_QUERY ); 462 sal_Int16 nOldLang = SvxLocaleToLanguage( xDic->getLocale() ); 463 464 if ( nLang != nOldLang ) 465 { 466 QueryBox aBox( this, CUI_RES( RID_SFXQB_SET_LANGUAGE ) ); 467 String sTxt( aBox.GetMessText() ); 468 sTxt.SearchAndReplaceAscii( "%1", aAllDictsLB.GetSelectEntry() ); 469 aBox.SetMessText( sTxt ); 470 471 if ( aBox.Execute() == RET_YES ) 472 { 473 xDic->setLocale( SvxCreateLocale( nLang ) ); 474 sal_Bool bNegativ = xDic->getDictionaryType() == DictionaryType_NEGATIVE; 475 476 const String sName( 477 ::GetDicInfoStr( xDic->getName(), 478 SvxLocaleToLanguage( xDic->getLocale() ), 479 bNegativ ) ); 480 aAllDictsLB.RemoveEntry( nDicPos ); 481 aAllDictsLB.InsertEntry( sName, nDicPos ); 482 aAllDictsLB.SelectEntryPos( nDicPos ); 483 } 484 else 485 SetLanguage_Impl( nOldLang ); 486 } 487 return 1; 488 } 489 490 // ----------------------------------------------------------------------- 491 492 void SvxEditDictionaryDialog::ShowWords_Impl( sal_uInt16 nId ) 493 { 494 Reference< XDictionary > xDic = aDics.getConstArray()[ nId ]; 495 496 nOld = nId; 497 EnterWait(); 498 499 String aStr; 500 501 aWordED.SetText(aStr); 502 aReplaceED.SetText(aStr); 503 504 if(xDic->getDictionaryType() != DictionaryType_POSITIVE) 505 { 506 nStaticTabs[0]=2; 507 508 // make controls for replacement text active 509 if(!aReplaceFT.IsVisible()) 510 { 511 Size aSize=aWordED.GetSizePixel(); 512 aSize.Width()=nWidth; 513 aWordED.SetSizePixel(aSize); 514 aReplaceFT.Show(); 515 aReplaceED.Show(); 516 } 517 } 518 else 519 { 520 nStaticTabs[0]=1; 521 522 // deactivate controls for replacement text 523 if(aReplaceFT.IsVisible()) 524 { 525 Size aSize=aWordED.GetSizePixel(); 526 aSize.Width()=aWordsLB.GetSizePixel().Width(); 527 aWordED.SetSizePixel(aSize); 528 aReplaceFT.Hide(); 529 aReplaceED.Hide(); 530 } 531 532 } 533 534 aWordsLB.SetTabs(nStaticTabs); 535 aWordsLB.Clear(); 536 537 Sequence< Reference< XDictionaryEntry > > aEntries( xDic->getEntries() ); 538 const Reference< XDictionaryEntry > *pEntry = aEntries.getConstArray(); 539 sal_Int32 nCount = aEntries.getLength(); 540 541 for (sal_Int32 i = 0; i < nCount; i++) 542 { 543 aStr = String(pEntry[i]->getDictionaryWord()); 544 sal_uInt16 nPos = GetLBInsertPos( aStr ); 545 if(pEntry[i]->isNegative()) 546 { 547 aStr += '\t'; 548 aStr += String(pEntry[i]->getReplacementText()); 549 } 550 aWordsLB.InsertEntry(aStr, 0, sal_False, nPos == USHRT_MAX ? LIST_APPEND : nPos); 551 } 552 553 if (aWordsLB.GetEntryCount()) 554 { 555 aWordED .SetText( aWordsLB.GetEntryText(0LU, 0) ); 556 aReplaceED.SetText( aWordsLB.GetEntryText(0LU, 1) ); 557 } 558 559 LeaveWait(); 560 } 561 562 // ----------------------------------------------------------------------- 563 564 IMPL_LINK(SvxEditDictionaryDialog, SelectHdl, SvTabListBox*, pBox) 565 { 566 if(!bDoNothing) 567 { 568 if(!bFirstSelect) 569 { 570 SvLBoxEntry* pEntry = pBox->FirstSelected(); 571 String sTmpShort(pBox->GetEntryText(pEntry, 0)); 572 // wird der Text ueber den ModifyHdl gesetzt, dann steht der Cursor 573 //sonst immer am Wortanfang, obwohl man gerade hier editiert 574 if(aWordED.GetText() != sTmpShort) 575 aWordED.SetText(sTmpShort); 576 aReplaceED.SetText(pBox->GetEntryText(pEntry, 1)); 577 } 578 else 579 bFirstSelect = sal_False; 580 581 // entries in the list box should exactly correspond to those from the 582 // dictionary. Thus: 583 aNewReplacePB.Enable(sal_False); 584 aDeletePB .Enable( sal_True && !IsDicReadonly_Impl() ); 585 } 586 return 0; 587 }; 588 589 // ----------------------------------------------------------------------- 590 591 IMPL_LINK(SvxEditDictionaryDialog, NewDelHdl, PushButton*, pBtn) 592 { 593 SvLBoxEntry* pEntry = aWordsLB.FirstSelected(); 594 595 if(pBtn == &aDeletePB) 596 { 597 DBG_ASSERT(pEntry, "keine Eintrag selektiert"); 598 String aStr; 599 600 aWordED.SetText(aStr); 601 aReplaceED.SetText(aStr); 602 aDeletePB.Disable(); 603 604 RemoveDictEntry(pEntry); // remove entry from dic and list-box 605 } 606 if(pBtn == &aNewReplacePB || aNewReplacePB.IsEnabled()) 607 { 608 SvLBoxEntry* _pEntry = aWordsLB.FirstSelected(); 609 XubString aNewWord(aWordED.GetText()); 610 String sEntry(aNewWord); 611 XubString aReplaceStr(aReplaceED.GetText()); 612 613 sal_Int16 nAddRes = DIC_ERR_UNKNOWN; 614 sal_uInt16 nPos = aAllDictsLB.GetSelectEntryPos(); 615 if ( nPos != LISTBOX_ENTRY_NOTFOUND && aNewWord.Len() > 0) 616 { 617 DBG_ASSERT(nPos < aDics.getLength(), "invalid dictionary index"); 618 Reference< XDictionary > xDic( aDics.getConstArray()[ nPos ], UNO_QUERY ); 619 if (xDic.is()) 620 { 621 // make changes in dic 622 623 //! ...IsVisible should reflect wether the dictionary is a negativ 624 //! or not (hopefully...) 625 sal_Bool bIsNegEntry = aReplaceFT.IsVisible(); 626 ::rtl::OUString aRplcText; 627 if(bIsNegEntry) 628 aRplcText = aReplaceStr; 629 630 if (_pEntry) // entry selected in aWordsLB ie action = modify entry 631 xDic->remove( aWordsLB.GetEntryText( _pEntry, 0 ) ); 632 // if remove has failed the following add should fail too 633 // and thus a warning message should be triggered... 634 635 Reference<XDictionary> aXDictionary(xDic, UNO_QUERY); 636 nAddRes = linguistic::AddEntryToDic( aXDictionary, 637 aNewWord, bIsNegEntry, 638 aRplcText, SvxLocaleToLanguage( xDic->getLocale() ), sal_False ); 639 } 640 } 641 if (DIC_ERR_NONE != nAddRes) 642 SvxDicError( this, nAddRes ); 643 644 if(DIC_ERR_NONE == nAddRes && sEntry.Len()) 645 { 646 // insert new entry in list-box etc... 647 648 aWordsLB.SetUpdateMode(sal_False); 649 sal_uInt16 _nPos = USHRT_MAX; 650 651 if(aReplaceFT.IsVisible()) 652 { 653 sEntry += '\t'; 654 sEntry += aReplaceStr; 655 } 656 657 SvLBoxEntry* pNewEntry = NULL; 658 if(_pEntry) // entry selected in aWordsLB ie action = modify entry 659 { 660 aWordsLB.SetEntryText( sEntry, _pEntry ); 661 pNewEntry = _pEntry; 662 } 663 else 664 { 665 _nPos = GetLBInsertPos( aNewWord ); 666 SvLBoxEntry* pInsEntry = aWordsLB.InsertEntry(sEntry, 0, sal_False, 667 _nPos == USHRT_MAX ? LIST_APPEND : (sal_uInt32)_nPos); 668 pNewEntry = pInsEntry; 669 } 670 671 aWordsLB.MakeVisible( pNewEntry ); 672 aWordsLB.SetUpdateMode(sal_True); 673 // falls der Request aus dem ReplaceEdit kam, dann Focus in das ShortEdit setzen 674 if(aReplaceED.HasFocus()) 675 aWordED.GrabFocus(); 676 } 677 } 678 else 679 { 680 // das kann nur ein Enter in einem der beiden Edit-Felder sein und das 681 // bedeutet EndDialog() - muss im KeyInput ausgewertet werden 682 return 0; 683 } 684 ModifyHdl(&aWordED); 685 return 1; 686 } 687 688 // ----------------------------------------------------------------------- 689 690 IMPL_LINK(SvxEditDictionaryDialog, ModifyHdl, Edit*, pEdt) 691 { 692 SvLBoxEntry* pFirstSel = aWordsLB.FirstSelected(); 693 String rEntry = pEdt->GetText(); 694 695 xub_StrLen nWordLen=rEntry.Len(); 696 const String& rRepString = aReplaceED.GetText(); 697 698 sal_Bool bEnableNewReplace = sal_False; 699 sal_Bool bEnableDelete = sal_False; 700 String aNewReplaceText = sNew; 701 702 if(pEdt == &aWordED) 703 { 704 if(nWordLen>0) 705 { 706 sal_Bool bFound = sal_False; 707 sal_Bool bTmpSelEntry=sal_False; 708 CDE_RESULT eCmpRes = CDE_DIFFERENT; 709 710 for(sal_uInt16 i = 0; i < aWordsLB.GetEntryCount(); i++) 711 { 712 SvLBoxEntry* pEntry = aWordsLB.GetEntry( i ); 713 String aTestStr( aWordsLB.GetEntryText(pEntry, 0) ); 714 eCmpRes = cmpDicEntry_Impl( rEntry, aTestStr ); 715 if(CDE_DIFFERENT != eCmpRes) 716 { 717 if(rRepString.Len()) 718 bFirstSelect = sal_True; 719 bDoNothing=sal_True; 720 aWordsLB.SetCurEntry(pEntry); 721 bDoNothing=sal_False; 722 pFirstSel = pEntry; 723 aReplaceED.SetText(aWordsLB.GetEntryText(pEntry, 1)); 724 725 if (CDE_SIMILAR == eCmpRes) 726 { 727 aNewReplaceText = sModify; 728 bEnableNewReplace = sal_True; 729 } 730 bFound= sal_True; 731 break; 732 } 733 else if(getNormDicEntry_Impl(aTestStr).Search( 734 getNormDicEntry_Impl( rEntry ) ) == 0 735 && !bTmpSelEntry) 736 { 737 bDoNothing=sal_True; 738 aWordsLB.MakeVisible(pEntry); 739 bDoNothing=sal_False; 740 bTmpSelEntry=sal_True; 741 742 aNewReplaceText = sNew; 743 bEnableNewReplace = sal_True; 744 } 745 } 746 747 if(!bFound) 748 { 749 aWordsLB.SelectAll(sal_False); 750 pFirstSel = 0; 751 752 aNewReplaceText = sNew; 753 bEnableNewReplace = sal_True; 754 } 755 bEnableDelete = CDE_DIFFERENT != eCmpRes; 756 } 757 else if(aWordsLB.GetEntryCount()>0) 758 { 759 SvLBoxEntry* pEntry = aWordsLB.GetEntry( 0 ); 760 bDoNothing=sal_True; 761 aWordsLB.MakeVisible(pEntry); 762 bDoNothing=sal_False; 763 } 764 } 765 else if(pEdt == &aReplaceED) 766 { 767 String aReplaceText; 768 String aWordText; 769 if (pFirstSel) // a aWordsLB entry is selected 770 { 771 aWordText = aWordsLB.GetEntryText( pFirstSel, 0 ); 772 aReplaceText = aWordsLB.GetEntryText( pFirstSel, 1 ); 773 774 aNewReplaceText = sModify; 775 bEnableDelete = sal_True; 776 } 777 sal_Bool bIsChange = 778 CDE_EQUAL != cmpDicEntry_Impl(aWordED.GetText(), aWordText) 779 || CDE_EQUAL != cmpDicEntry_Impl(aReplaceED.GetText(), aReplaceText); 780 if (aWordED.GetText().Len() && bIsChange) 781 bEnableNewReplace = sal_True; 782 } 783 784 aNewReplacePB.SetText( aNewReplaceText ); 785 aNewReplacePB.Enable( bEnableNewReplace && !IsDicReadonly_Impl() ); 786 aDeletePB .Enable( bEnableDelete && !IsDicReadonly_Impl() ); 787 788 return 0; 789 } 790 791 //========================================================= 792 //SvxDictEdit 793 //========================================================= 794 void SvxDictEdit::KeyInput( const KeyEvent& rKEvt ) 795 { 796 const KeyCode aKeyCode = rKEvt.GetKeyCode(); 797 const sal_uInt16 nModifier = aKeyCode.GetModifier(); 798 if( aKeyCode.GetCode() == KEY_RETURN ) 799 { 800 //wird bei Enter nichts getan, dann doch die Basisklasse rufen 801 // um den Dialog zu schliessen 802 if(!nModifier && !aActionLink.Call(this)) 803 Edit::KeyInput(rKEvt); 804 } 805 else if(bSpaces || aKeyCode.GetCode() != KEY_SPACE) 806 Edit::KeyInput(rKEvt); 807 } 808 809 810