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