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