1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_cui.hxx" 26 27 // include --------------------------------------------------------------- 28 29 #include <tools/ref.hxx> 30 #include <tools/shl.hxx> 31 #include <vcl/wrkwin.hxx> 32 #include <vcl/menu.hxx> 33 #include <vcl/msgbox.hxx> 34 #include <vcl/scrbar.hxx> 35 #include <SpellAttrib.hxx> 36 #include <sfx2/dispatch.hxx> 37 #include <sfx2/bindings.hxx> 38 #include <svl/undo.hxx> 39 #include <unotools/lingucfg.hxx> 40 #include <svtools/textdata.hxx> 41 #include <svtools/filter.hxx> 42 #include <editeng/unolingu.hxx> 43 #include <editeng/splwrap.hxx> 44 #include <linguistic/lngprops.hxx> 45 #include <linguistic/misc.hxx> 46 #include <comphelper/processfactory.hxx> 47 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 48 #include <com/sun/star/lang/XServiceInfo.hpp> 49 #include <com/sun/star/lang/XServiceDisplayName.hpp> 50 #include <com/sun/star/linguistic2/SpellFailure.hpp> 51 #include <com/sun/star/frame/XStorable.hpp> 52 #include <sfx2/app.hxx> 53 #include <vcl/help.hxx> 54 #include <vcl/graph.hxx> 55 #include <osl/file.hxx> 56 #include <cuires.hrc> 57 #include <helpid.hrc> 58 #include "SpellDialog.hrc" 59 #include <editeng/optitems.hxx> 60 #include <editeng/svxenum.hxx> 61 #include <svx/SpellDialogChildWindow.hxx> 62 #include "SpellDialog.hxx" 63 #include <svx/dlgutil.hxx> 64 #include "optlingu.hxx" 65 #include <dialmgr.hxx> 66 #include <svx/svxerr.hxx> 67 #include "treeopt.hxx" 68 #include <svtools/langtab.hxx> 69 70 using namespace ::com::sun::star; 71 using namespace ::com::sun::star::uno; 72 using namespace ::com::sun::star::beans; 73 using namespace ::com::sun::star::linguistic2; 74 75 using ::rtl::OUString; 76 77 #define C2U(cChar) ::rtl::OUString::createFromAscii(cChar) 78 // struct SpellDialog_Impl --------------------------------------------- 79 80 struct SpellDialog_Impl 81 { 82 Sequence< Reference< XDictionary > > aDics; 83 }; 84 // ----------------------------------------------------------------------- 85 //#define VENDOR_IMAGE_HEIGHT 44 //as specified 86 87 #define SPELLUNDO_START 200 88 89 #define SPELLUNDO_CHANGE_LANGUAGE (SPELLUNDO_START + 1) 90 #define SPELLUNDO_CHANGE_TEXTENGINE (SPELLUNDO_START + 2) 91 #define SPELLUNDO_CHANGE_NEXTERROR (SPELLUNDO_START + 3) 92 #define SPELLUNDO_CHANGE_ADD_TO_DICTIONARY (SPELLUNDO_START + 4) 93 #define SPELLUNDO_CHANGE_GROUP (SPELLUNDO_START + 5) //undo list 94 #define SPELLUNDO_MOVE_ERROREND (SPELLUNDO_START + 6) 95 #define SPELLUNDO_UNDO_EDIT_MODE (SPELLUNDO_START + 7) 96 #define SPELLUNDO_ADD_IGNORE_RULE (SPELLUNDO_START + 8) 97 98 namespace svx{ 99 class SpellUndoAction_Impl : public SfxUndoAction 100 { 101 sal_uInt16 m_nId; 102 const Link& m_rActionLink; 103 //undo of button enabling 104 bool m_bEnableChangePB; 105 bool m_bEnableChangeAllPB; 106 //undo of MarkNextError - used in change and change all, ignore and ignore all 107 long m_nNewErrorStart; 108 long m_nNewErrorEnd; 109 long m_nOldErrorStart; 110 long m_nOldErrorEnd; 111 bool m_bIsErrorLanguageSelected; 112 ::rtl::OUString m_sRuleId; 113 //undo of AddToDictionary 114 Reference<XDictionary> m_xDictionary; 115 ::rtl::OUString m_sAddedWord; 116 //move end of error - ::ChangeMarkedWord() 117 long m_nOffset; 118 119 public: 120 SpellUndoAction_Impl(sal_uInt16 nId, const Link& rActionLink) : 121 m_nId(nId), 122 m_rActionLink( rActionLink), 123 m_bEnableChangePB(false), 124 m_bEnableChangeAllPB(false), 125 m_nNewErrorStart(-1), 126 m_nNewErrorEnd(-1), 127 m_nOldErrorStart(-1), 128 m_nOldErrorEnd(-1), 129 m_bIsErrorLanguageSelected(false), 130 m_nOffset(0) 131 {} 132 133 ~SpellUndoAction_Impl(); 134 135 virtual void Undo(); 136 virtual sal_uInt16 GetId() const; 137 138 void SetEnableChangePB(){m_bEnableChangePB = true;} 139 bool IsEnableChangePB(){return m_bEnableChangePB;} 140 141 void SetEnableChangeAllPB(){m_bEnableChangeAllPB = true;} 142 bool IsEnableChangeAllPB(){return m_bEnableChangeAllPB;} 143 144 void SetErrorMove(long nNewStart, long nNewEnd, long nOldStart, long nOldEnd) 145 { 146 m_nNewErrorStart = nNewStart; 147 m_nNewErrorEnd = nNewEnd; 148 m_nOldErrorStart = nOldStart; 149 m_nOldErrorEnd = nOldEnd; 150 } 151 long GetNewErrorStart() { return m_nNewErrorStart;} 152 long GetNewErrorEnd() { return m_nNewErrorEnd;} 153 long GetOldErrorStart() { return m_nOldErrorStart;} 154 long GetOldErrorEnd() { return m_nOldErrorEnd;} 155 156 void SetErrorLanguageSelected(bool bSet){ m_bIsErrorLanguageSelected = bSet;} 157 bool IsErrorLanguageSelected() const {return m_bIsErrorLanguageSelected;} 158 159 160 void SetDictionary(Reference<XDictionary> xDict) { m_xDictionary = xDict; } 161 Reference<XDictionary> GetDictionary() const {return m_xDictionary;} 162 void SetAddedWord(const ::rtl::OUString& rWord) {m_sAddedWord = rWord;} 163 const ::rtl::OUString& GetAddedWord() const { return m_sAddedWord;} 164 165 void SetOffset(long nSet) {m_nOffset = nSet;} 166 long GetOffset() const {return m_nOffset;} 167 168 void SetErrorType( const ::rtl::OUString& rId ) { m_sRuleId = rId; } 169 const ::rtl::OUString& GetErrorType() const { return m_sRuleId; } 170 171 }; 172 }//namespace svx 173 using namespace ::svx; 174 /*-- 06.11.2003 12:16:02--------------------------------------------------- 175 176 -----------------------------------------------------------------------*/ 177 SpellUndoAction_Impl::~SpellUndoAction_Impl() 178 { 179 } 180 /*-- 06.11.2003 12:16:02--------------------------------------------------- 181 182 -----------------------------------------------------------------------*/ 183 void SpellUndoAction_Impl::Undo() 184 { 185 m_rActionLink.Call(this); 186 } 187 /*-- 06.11.2003 12:16:02--------------------------------------------------- 188 189 -----------------------------------------------------------------------*/ 190 sal_uInt16 SpellUndoAction_Impl::GetId()const 191 { 192 return m_nId; 193 } 194 195 // class SvxSpellCheckDialog --------------------------------------------- 196 197 SpellDialog::SpellDialog( 198 SpellDialogChildWindow* pChildWindow, 199 Window * pParent, 200 SfxBindings* _pBindings) 201 : SfxModelessDialog (_pBindings, 202 pChildWindow, 203 pParent, 204 CUI_RES(RID_SVXDLG_SPELLCHECK)), 205 206 aVendorImageFI ( this , CUI_RES( IMG_VENDOR ) ), 207 aLanguageFT ( this, CUI_RES( FT_LANGUAGE ) ), 208 aLanguageLB ( this, CUI_RES( LB_LANGUAGE ) ), 209 aNotInDictFT ( this, CUI_RES( FT_NOTINDICT ) ), 210 aSentenceED ( this, CUI_RES( ED_NEWWORD ) ), 211 aSuggestionFT ( this, CUI_RES( FT_SUGGESTION ) ), 212 aSuggestionLB ( this, CUI_RES( LB_SUGGESTION ) ), 213 214 aIgnorePB ( this, CUI_RES( PB_IGNORE ) ), 215 aIgnoreAllPB ( this, CUI_RES( PB_IGNOREALL ) ), 216 aIgnoreRulePB ( this, CUI_RES( PB_IGNORERULE ) ), 217 aAddToDictMB ( this, CUI_RES( MB_ADDTODICT ) ), 218 219 aChangePB ( this, CUI_RES( PB_CHANGE ) ), 220 aChangeAllPB ( this, CUI_RES( PB_CHANGEALL ) ), 221 aExplainPB ( this, CUI_RES( PB_EXPLAIN) ), 222 aAutoCorrPB ( this, CUI_RES( PB_AUTOCORR ) ), 223 224 aCheckGrammarCB ( this, CUI_RES( CB_CHECK_GRAMMAR ) ), 225 226 aHelpPB ( this, CUI_RES( PB_HELP ) ), 227 aOptionsPB ( this, CUI_RES( PB_OPTIONS ) ), 228 aUndoPB ( this, CUI_RES( PB_UNDO ) ), 229 aClosePB ( this, CUI_RES( PB_CLOSE ) ), 230 aBackgroundGB ( this, CUI_RES( GB_BACKGROUND ) ), 231 232 aVendorImage ( CUI_RES( IMG_DEFAULT_VENDOR ) ), 233 aVendorImageHC ( CUI_RES( IMG_DEFAULT_VENDOR_HC ) ), 234 235 aResumeST ( CUI_RES(ST_RESUME )), 236 aIgnoreOnceST ( aIgnorePB.GetText()), 237 aNoSuggestionsST( CUI_RES(ST_NOSUGGESTIONS)), 238 m_sTitleSpelling ( CUI_RES( ST_SPELLING ) ), 239 m_sTitleSpellingGrammar ( CUI_RES( ST_SPELLING_AND_GRAMMAR ) ), 240 m_sTitleSpellingGrammarVendor ( CUI_RES( ST_SPELLING_AND_GRAMMAR_VENDORNAME ) ), 241 aDialogUndoLink( LINK (this, SpellDialog, DialogUndoHdl)), 242 bModified( false ), 243 bFocusLocked( true ), 244 rParent ( *pChildWindow ), 245 nOldLang ( LANGUAGE_NONE ) 246 { 247 FreeResource(); 248 xSpell = LinguMgr::GetSpellChecker(); 249 pImpl = new SpellDialog_Impl; 250 251 //HelpIds 252 aClosePB. SetHelpId(HID_SPLDLG_BUTTON_CLOSE ); 253 aIgnorePB. SetHelpId(HID_SPLDLG_BUTTON_IGNORE ); 254 aIgnoreAllPB. SetHelpId(HID_SPLDLG_BUTTON_IGNOREALL); 255 aIgnoreRulePB. SetHelpId(HID_SPLDLG_BUTTON_IGNORERULE); 256 aChangePB. SetHelpId(HID_SPLDLG_BUTTON_CHANGE ); 257 aChangeAllPB. SetHelpId(HID_SPLDLG_BUTTON_CHANGEALL); 258 aExplainPB. SetHelpId(HID_SPLDLG_BUTTON_EXPLAIN ); 259 Init_Impl(); 260 261 // disable controls if service is missing 262 if (!xSpell.is()) 263 Enable( sal_False ); 264 265 Application::PostUserEvent( STATIC_LINK( 266 this, SpellDialog, InitHdl ) ); 267 } 268 269 // ----------------------------------------------------------------------- 270 271 SpellDialog::~SpellDialog() 272 { 273 // save possibly modified user-dictionaries 274 Reference< XDictionaryList > xDicList( SvxGetDictionaryList() ); 275 if (xDicList.is()) 276 { 277 linguistic::SaveDictionaries( xDicList ); 278 } 279 280 delete aAddToDictMB.GetPopupMenu(); 281 delete pImpl; 282 } 283 284 // ----------------------------------------------------------------------- 285 286 void SpellDialog::Init_Impl() 287 { 288 // Handler initialisieren 289 aClosePB.SetClickHdl(LINK( this, SpellDialog, CancelHdl ) ); 290 aChangePB.SetClickHdl(LINK( this, SpellDialog, ChangeHdl ) ); 291 aChangeAllPB.SetClickHdl(LINK( this, SpellDialog, ChangeAllHdl ) ); 292 aIgnorePB.SetClickHdl(LINK( this, SpellDialog, IgnoreHdl ) ); 293 aIgnoreAllPB.SetClickHdl(LINK( this, SpellDialog, IgnoreAllHdl ) ); 294 aIgnoreRulePB.SetClickHdl(LINK( this, SpellDialog, IgnoreAllHdl ) ); 295 aUndoPB.SetClickHdl(LINK( this, SpellDialog, UndoHdl ) ); 296 297 aAutoCorrPB.SetClickHdl( LINK( this, SpellDialog, ExtClickHdl ) ); 298 aCheckGrammarCB.SetClickHdl( LINK( this, SpellDialog, CheckGrammarHdl )); 299 aOptionsPB .SetClickHdl( LINK( this, SpellDialog, ExtClickHdl ) ); 300 301 aSuggestionLB.SetDoubleClickHdl( LINK( this, SpellDialog, ChangeHdl ) ); 302 303 aSentenceED.SetModifyHdl(LINK ( this, SpellDialog, ModifyHdl) ); 304 aAddToDictMB.SetSelectHdl(LINK ( this, SpellDialog, AddToDictionaryHdl ) ); 305 aLanguageLB.SetSelectHdl(LINK( this, SpellDialog, LanguageSelectHdl ) ); 306 307 // initialize language ListBox 308 aLanguageLB.SetLanguageList( LANG_LIST_SPELL_USED, sal_False, sal_False, sal_True ); 309 310 // get current language 311 UpdateBoxes_Impl(); 312 313 // fill dictionary PopupMenu 314 InitUserDicts(); 315 316 aSentenceED.ClearModifyFlag(); 317 SvxGetChangeAllList()->clear(); 318 } 319 320 // ----------------------------------------------------------------------- 321 322 void SpellDialog::UpdateBoxes_Impl() 323 { 324 sal_Int32 i; 325 aSuggestionLB.Clear(); 326 327 const SpellErrorDescription* pSpellErrorDescription = aSentenceED.GetAlternatives(); 328 329 LanguageType nAltLanguage = LANGUAGE_NONE; 330 //String aAltWord; 331 Sequence< ::rtl::OUString > aNewWords; 332 bool bIsGrammarError = false; 333 if( pSpellErrorDescription ) 334 { 335 nAltLanguage = SvxLocaleToLanguage( pSpellErrorDescription->aLocale ); 336 //aAltWord = String( xAlt->getWord() ); 337 aNewWords = pSpellErrorDescription->aSuggestions; 338 bIsGrammarError = pSpellErrorDescription->bIsGrammarError; 339 aExplainPB.SetExplanation(pSpellErrorDescription->sExplanation ); 340 } 341 if( pSpellErrorDescription && pSpellErrorDescription->sDialogTitle.getLength() ) 342 { 343 // use this function to apply the correct image to be used... 344 SetTitle_Impl( nAltLanguage ); 345 // then change the title to the one to be actually used 346 SetText( pSpellErrorDescription->sDialogTitle ); 347 } 348 else 349 SetTitle_Impl( nAltLanguage ); 350 SetSelectedLang_Impl( nAltLanguage ); 351 352 353 // Alternativen eintragen 354 const ::rtl::OUString *pNewWords = aNewWords.getConstArray(); 355 const sal_Int32 nSize = aNewWords.getLength(); 356 for ( i = 0; i < nSize; ++i ) 357 { 358 String aTmp( pNewWords[i] ); 359 if ( LISTBOX_ENTRY_NOTFOUND == aSuggestionLB.GetEntryPos( aTmp ) ) 360 { 361 aSuggestionLB.InsertEntry( aTmp ); 362 aSuggestionLB.SetEntryFlags(aSuggestionLB.GetEntryCount() - 1, LISTBOX_ENTRY_FLAG_MULTILINE); 363 } 364 } 365 if(!nSize) 366 aSuggestionLB.InsertEntry( aNoSuggestionsST ); 367 aAutoCorrPB.Enable( nSize > 0 ); 368 //aSentenceED.GrabFocus(); 369 370 aSuggestionFT.Enable(nSize > 0); 371 aSuggestionLB.Enable(nSize > 0); 372 if( nSize ) 373 { 374 aSuggestionLB.SelectEntryPos(0); 375 } 376 aChangePB.Enable( nSize > 0); 377 aChangeAllPB.Enable(nSize > 0); 378 bool bShowChangeAll = !bIsGrammarError; 379 aChangeAllPB.Show( bShowChangeAll ); 380 aExplainPB.Show( !bShowChangeAll ); 381 aLanguageLB.Enable( bShowChangeAll ); 382 aIgnoreAllPB.Show( bShowChangeAll ); 383 aAddToDictMB.Show( bShowChangeAll ); 384 aIgnoreRulePB.Show( !bShowChangeAll ); 385 aIgnoreRulePB.Enable(pSpellErrorDescription && pSpellErrorDescription->sRuleId.getLength()); 386 aExplainPB.Enable( aExplainPB.HasExplanation() ); 387 aAutoCorrPB.Show( bShowChangeAll && rParent.HasAutoCorrection() ); 388 389 } 390 // ----------------------------------------------------------------------- 391 392 void SpellDialog::SpellContinue_Impl(bool bUseSavedSentence, bool bIgnoreCurrentError ) 393 { 394 //initially or after the last error of a sentence MarkNextError will fail 395 //then GetNextSentence() has to be called followed again by MarkNextError() 396 //MarkNextError is not initally called if the UndoEdit mode is active 397 bool bNextSentence = false; 398 if((!aSentenceED.IsUndoEditMode() && aSentenceED.MarkNextError( bIgnoreCurrentError )) || 399 true == ( bNextSentence = GetNextSentence_Impl(bUseSavedSentence, aSentenceED.IsUndoEditMode()) && aSentenceED.MarkNextError( false ))) 400 { 401 const SpellErrorDescription* pSpellErrorDescription = aSentenceED.GetAlternatives(); 402 if( pSpellErrorDescription ) 403 { 404 UpdateBoxes_Impl(); 405 Control* aControls[] = 406 { 407 &aNotInDictFT, 408 &aSentenceED, 409 &aLanguageFT, 410 0 411 }; 412 sal_Int32 nIdx = 0; 413 do 414 { 415 aControls[nIdx]->Enable(sal_True); 416 } 417 while(aControls[++nIdx]); 418 419 420 } 421 if( bNextSentence ) 422 { 423 //remove undo if a new sentence is active 424 aSentenceED.ResetUndo(); 425 aUndoPB.Enable(sal_False); 426 } 427 } 428 } 429 /* -----------------10.09.2003 14:04----------------- 430 Initialize, asynchronous to prevent virtial calls 431 from a constructor 432 --------------------------------------------------*/ 433 IMPL_STATIC_LINK( SpellDialog, InitHdl, SpellDialog *, EMPTYARG ) 434 { 435 pThis->SetUpdateMode( sal_False ); 436 //show or hide AutoCorrect depending on the modules abilities 437 pThis->aAutoCorrPB.Show(pThis->rParent.HasAutoCorrection()); 438 pThis->SpellContinue_Impl(); 439 pThis->aSentenceED.ResetUndo(); 440 pThis->aUndoPB.Enable(sal_False); 441 442 pThis->LockFocusChanges(true); 443 if( pThis->aChangePB.IsEnabled() ) 444 pThis->aChangePB.GrabFocus(); 445 else if( pThis->aIgnorePB.IsEnabled() ) 446 pThis->aIgnorePB.GrabFocus(); 447 else if( pThis->aClosePB.IsEnabled() ) 448 pThis->aClosePB.GrabFocus(); 449 pThis->LockFocusChanges(false); 450 //show grammar CheckBox depending on the modules abilities 451 bool bHasGrammarChecking = pThis->rParent.HasGrammarChecking(); 452 pThis->aCheckGrammarCB.Show( bHasGrammarChecking ); 453 if( !bHasGrammarChecking ) 454 { 455 //resize the dialog to hide the hidden area of the CheckBox 456 Size aBackSize = pThis->aBackgroundGB.GetSizePixel(); 457 sal_Int32 nDiff = pThis->aBackgroundGB.GetPosPixel().Y() + aBackSize.Height() 458 - pThis->aCheckGrammarCB.GetPosPixel().Y(); 459 aBackSize.Height() -= nDiff; 460 pThis->aBackgroundGB.SetSizePixel(aBackSize); 461 Button* aButtons[] = { &pThis->aHelpPB, &pThis->aOptionsPB, &pThis->aUndoPB, &pThis->aClosePB, 0 }; 462 sal_Int32 nButton = 0; 463 while( aButtons[nButton]) 464 { 465 Point aPos = aButtons[nButton]->GetPosPixel(); 466 aPos.Y() -= nDiff; 467 aButtons[nButton]->SetPosPixel(aPos); 468 ++nButton; 469 } 470 Size aDlgSize = pThis->GetSizePixel(); 471 aDlgSize.Height() -= nDiff; 472 pThis->SetSizePixel( aDlgSize ); 473 } 474 else 475 { 476 if( SvtLinguConfig().HasVendorImages( "SpellAndGrammarDialogImage" ) ) 477 { 478 pThis->aVendorImageFI.Show(); 479 Size aVendorSize = pThis->aVendorImageFI.GetSizePixel(); 480 Size aImageSize = pThis->aVendorImageFI.GetImage().GetSizePixel(); 481 if( aImageSize.Height() ) 482 { 483 aVendorSize.Height() = aImageSize.Height(); 484 if(aVendorSize.Width() < aImageSize.Width()) 485 aVendorSize.Width() = aImageSize.Width(); 486 pThis->aVendorImageFI.SetSizePixel( aVendorSize ); 487 } 488 //aVendorSize.Height() = nDiff; 489 sal_Int32 nDiff = aVendorSize.Height(); 490 pThis->aVendorImageFI.SetSizePixel(aVendorSize); 491 Control* aControls[] = { 492 &pThis->aLanguageFT, 493 &pThis->aLanguageLB, 494 &pThis->aNotInDictFT, 495 &pThis->aSentenceED, 496 &pThis->aSuggestionFT, 497 &pThis->aSuggestionLB, 498 &pThis->aIgnorePB, 499 &pThis->aIgnoreAllPB, 500 &pThis->aIgnoreRulePB, 501 &pThis->aAddToDictMB, 502 &pThis->aChangePB, 503 &pThis->aChangeAllPB, 504 &pThis->aExplainPB, 505 &pThis->aAutoCorrPB, 506 &pThis->aCheckGrammarCB, 507 &pThis->aHelpPB, 508 &pThis->aOptionsPB, 509 &pThis->aUndoPB, 510 &pThis->aClosePB, 511 &pThis->aBackgroundGB, 512 0 513 }; 514 sal_Int32 nControl = 0; 515 while( aControls[nControl]) 516 { 517 Point aPos = aControls[nControl]->GetPosPixel(); 518 aPos.Y() += nDiff; 519 aControls[nControl]->SetPosPixel(aPos); 520 ++nControl; 521 } 522 Size aDlgSize = pThis->GetSizePixel(); 523 aDlgSize.Height() += nDiff; 524 pThis->SetSizePixel( aDlgSize ); 525 pThis->Invalidate(); 526 } 527 } 528 pThis->aCheckGrammarCB.Check( pThis->rParent.IsGrammarChecking() ); 529 pThis->SetUpdateMode( sal_True ); 530 pThis->Show(); 531 return 0; 532 }; 533 534 // ----------------------------------------------------------------------- 535 536 IMPL_LINK( SpellDialog, ExtClickHdl, Button *, pBtn ) 537 { 538 if (&aOptionsPB == pBtn) 539 StartSpellOptDlg_Impl(); 540 else if(&aAutoCorrPB == pBtn) 541 { 542 //get the currently selected wrong word 543 String sCurrentErrorText = aSentenceED.GetErrorText(); 544 //get the wrong word from the XSpellAlternative 545 const SpellErrorDescription* pSpellErrorDescription = aSentenceED.GetAlternatives(); 546 if( pSpellErrorDescription ) 547 { 548 String sWrong(pSpellErrorDescription->sErrorText); 549 //if the word has not been edited in the MultiLineEdit then 550 //the current suggestion should be used 551 //if it's not the 'no suggestions' entry 552 if(sWrong == sCurrentErrorText && 553 aSuggestionLB.IsEnabled() && aSuggestionLB.GetSelectEntryCount() > 0 && 554 aNoSuggestionsST != aSuggestionLB.GetSelectEntry()) 555 { 556 sCurrentErrorText = aSuggestionLB.GetSelectEntry(); 557 } 558 if(sWrong != sCurrentErrorText) 559 { 560 SvxPrepareAutoCorrect( sWrong, sCurrentErrorText ); 561 LanguageType eLang = GetSelectedLang_Impl(); 562 rParent.AddAutoCorrection( sWrong, sCurrentErrorText, eLang ); 563 } 564 } 565 } 566 return 0; 567 } 568 // ----------------------------------------------------------------------- 569 IMPL_LINK( SpellDialog, CheckGrammarHdl, CheckBox*, pBox ) 570 { 571 rParent.SetGrammarChecking( pBox->IsChecked() ); 572 Impl_Restore(); 573 return 0; 574 } 575 576 void SpellDialog::StartSpellOptDlg_Impl() 577 { 578 sal_uInt16 aSpellInfos[] = 579 { 580 SID_ATTR_SPELL,SID_ATTR_SPELL, 581 SID_SPELL_MODIFIED, SID_SPELL_MODIFIED, 582 SID_AUTOSPELL_CHECK, SID_AUTOSPELL_CHECK, 583 0 584 }; 585 SfxItemSet aSet( SFX_APP()->GetPool(), aSpellInfos); 586 aSet.Put(SfxSpellCheckItem( xSpell, SID_ATTR_SPELL )); 587 SfxSingleTabDialog* pDlg = 588 new SfxSingleTabDialog( this, aSet, RID_SFXPAGE_LINGU ); 589 SfxTabPage* pPage = SvxLinguTabPage::Create( pDlg, aSet ); 590 ( (SvxLinguTabPage*)pPage )->HideGroups( GROUP_MODULES ); 591 pDlg->SetTabPage( pPage ); 592 if(RET_OK == pDlg->Execute()) 593 { 594 595 // Benutzerb"ucher anzeigen 596 InitUserDicts(); 597 const SfxItemSet* pOutSet = pDlg->GetOutputItemSet(); 598 if(pOutSet) 599 OfaTreeOptionsDialog::ApplyLanguageOptions(*pOutSet); 600 } 601 delete pDlg; 602 603 } 604 605 // ----------------------------------------------------------------------- 606 607 IMPL_LINK( SpellDialog, ChangeHdl, Button *, EMPTYARG ) 608 { 609 if(aSentenceED.IsUndoEditMode()) 610 { 611 SpellContinue_Impl(); 612 } 613 else 614 { 615 aSentenceED.UndoActionStart( SPELLUNDO_CHANGE_GROUP ); 616 String aString = aSentenceED.GetErrorText(); 617 //dots are sometimes part of the spelled word but they are not necessarily part of the replacement 618 bool bDot = aString.Len() && aString.GetChar(aString.Len() - 1 ) == '.'; 619 if(aSuggestionLB.IsEnabled() && 620 aSuggestionLB.GetSelectEntryCount()>0 && 621 aNoSuggestionsST != aSuggestionLB.GetSelectEntry()) 622 aString = aSuggestionLB.GetSelectEntry(); 623 if(bDot && (!aString.Len() || aString.GetChar(aString.Len() - 1 ) != '.')) 624 aString += '.'; 625 626 aSentenceED.ChangeMarkedWord(aString, GetSelectedLang_Impl()); 627 SpellContinue_Impl(); 628 bModified = false; 629 aSentenceED.UndoActionEnd(); 630 } 631 if(!aChangePB.IsEnabled()) 632 aIgnorePB.GrabFocus(); 633 return 1; 634 } 635 636 637 // ----------------------------------------------------------------------- 638 639 IMPL_LINK( SpellDialog, ChangeAllHdl, Button *, EMPTYARG ) 640 { 641 aSentenceED.UndoActionStart( SPELLUNDO_CHANGE_GROUP ); 642 // change the current word first 643 String aString = aSentenceED.GetErrorText(); 644 if(aSuggestionLB.IsEnabled() && 645 aSuggestionLB.GetSelectEntryCount()>0 && 646 aNoSuggestionsST != aSuggestionLB.GetSelectEntry()) 647 aString = aSuggestionLB.GetSelectEntry(); 648 649 LanguageType eLang = GetSelectedLang_Impl(); 650 651 // add new word to ChangeAll list 652 String aOldWord( aSentenceED.GetErrorText() ); 653 SvxPrepareAutoCorrect( aOldWord, aString ); 654 Reference<XDictionary> aXDictionary( SvxGetChangeAllList(), UNO_QUERY ); 655 sal_uInt8 nAdded = linguistic::AddEntryToDic( aXDictionary, 656 aOldWord , sal_True, 657 aString, eLang ); 658 659 if(nAdded == DIC_ERR_NONE) 660 { 661 SpellUndoAction_Impl* pAction = new SpellUndoAction_Impl( 662 SPELLUNDO_CHANGE_ADD_TO_DICTIONARY, aDialogUndoLink); 663 pAction->SetDictionary(aXDictionary); 664 pAction->SetAddedWord(aOldWord); 665 aSentenceED.AddUndoAction(pAction); 666 } 667 668 aSentenceED.ChangeMarkedWord(aString, eLang); 669 SpellContinue_Impl(); 670 bModified = false; 671 aSentenceED.UndoActionEnd(); 672 return 1; 673 } 674 // ----------------------------------------------------------------------- 675 676 IMPL_LINK( SpellDialog, IgnoreAllHdl, Button *, pButton ) 677 { 678 aSentenceED.UndoActionStart( SPELLUNDO_CHANGE_GROUP ); 679 // add word to IgnoreAll list 680 Reference< XDictionary > aXDictionary( SvxGetIgnoreAllList(), UNO_QUERY ); 681 //in case the error has been changed manually it has to be restored 682 aSentenceED.RestoreCurrentError(); 683 if( pButton == &aIgnoreRulePB ) 684 { 685 const SpellErrorDescription* pSpellErrorDescription = aSentenceED.GetAlternatives(); 686 try 687 { 688 if( pSpellErrorDescription && pSpellErrorDescription->xGrammarChecker.is() ) 689 { 690 pSpellErrorDescription->xGrammarChecker->ignoreRule( pSpellErrorDescription->sRuleId, 691 pSpellErrorDescription->aLocale ); 692 } 693 } 694 catch( const uno::Exception& ) 695 { 696 } 697 } 698 else 699 { 700 String sErrorText(aSentenceED.GetErrorText()); 701 sal_uInt8 nAdded = linguistic::AddEntryToDic( aXDictionary, 702 sErrorText, sal_False, 703 ::rtl::OUString(), LANGUAGE_NONE ); 704 if(nAdded == DIC_ERR_NONE) 705 { 706 SpellUndoAction_Impl* pAction = new SpellUndoAction_Impl( 707 SPELLUNDO_CHANGE_ADD_TO_DICTIONARY, aDialogUndoLink); 708 pAction->SetDictionary(aXDictionary); 709 pAction->SetAddedWord(sErrorText); 710 aSentenceED.AddUndoAction(pAction); 711 } 712 } 713 714 SpellContinue_Impl(); 715 bModified = false; 716 aSentenceED.UndoActionEnd(); 717 return 1; 718 } 719 /*-- 06.11.2003 11:24:08--------------------------------------------------- 720 721 -----------------------------------------------------------------------*/ 722 IMPL_LINK( SpellDialog, UndoHdl, Button*, EMPTYARG ) 723 { 724 aSentenceED.Undo(); 725 if(!aSentenceED.GetUndoActionCount()) 726 aUndoPB.Enable(sal_False); 727 return 0; 728 } 729 /*-- 06.11.2003 12:19:15--------------------------------------------------- 730 731 -----------------------------------------------------------------------*/ 732 IMPL_LINK( SpellDialog, DialogUndoHdl, SpellUndoAction_Impl*, pAction ) 733 { 734 switch(pAction->GetId()) 735 { 736 case SPELLUNDO_CHANGE_TEXTENGINE: 737 { 738 if(pAction->IsEnableChangePB()) 739 aChangePB.Enable(sal_False); 740 if(pAction->IsEnableChangeAllPB()) 741 aChangeAllPB.Enable(sal_False); 742 } 743 break; 744 case SPELLUNDO_CHANGE_NEXTERROR: 745 { 746 aSentenceED.MoveErrorMarkTo((sal_uInt16)pAction->GetOldErrorStart(), (sal_uInt16)pAction->GetOldErrorEnd(), false); 747 if(pAction->IsErrorLanguageSelected()) 748 { 749 UpdateBoxes_Impl(); 750 } 751 } 752 break; 753 case SPELLUNDO_CHANGE_ADD_TO_DICTIONARY: 754 { 755 if(pAction->GetDictionary().is()) 756 pAction->GetDictionary()->remove(pAction->GetAddedWord()); 757 } 758 break; 759 case SPELLUNDO_MOVE_ERROREND : 760 { 761 if(pAction->GetOffset() != 0) 762 aSentenceED.MoveErrorEnd(pAction->GetOffset()); 763 } 764 break; 765 case SPELLUNDO_UNDO_EDIT_MODE : 766 { 767 //refill the dialog with the currently spelled sentence - throw away all changes 768 SpellContinue_Impl(true); 769 } 770 break; 771 case SPELLUNDO_ADD_IGNORE_RULE: 772 //undo of ignored rules is not supported 773 break; 774 } 775 776 return 0; 777 } 778 // ----------------------------------------------------------------------- 779 void SpellDialog::Impl_Restore() 780 { 781 //clear the "ChangeAllList" 782 SvxGetChangeAllList()->clear(); 783 //get a new sentence 784 aSentenceED.SetText(rtl::OUString()); 785 aSentenceED.ResetModified(); 786 SpellContinue_Impl(); 787 aIgnorePB.SetText(aIgnoreOnceST); 788 } 789 790 IMPL_LINK( SpellDialog, IgnoreHdl, Button *, EMPTYARG ) 791 { 792 if(aIgnorePB.GetText() == aResumeST) 793 { 794 Impl_Restore(); 795 } 796 else 797 { 798 //in case the error has been changed manually it has to be restored, 799 // since the users choice now was to ignore the error 800 aSentenceED.RestoreCurrentError(); 801 802 // the word is being ignored 803 SpellContinue_Impl( false, true ); 804 } 805 return 1; 806 } 807 808 809 // ----------------------------------------------------------------------- 810 811 sal_Bool SpellDialog::Close() 812 { 813 GetBindings().GetDispatcher()-> 814 Execute(rParent.GetType(), 815 SFX_CALLMODE_ASYNCHRON|SFX_CALLMODE_RECORD); 816 return sal_True; 817 } 818 // ----------------------------------------------------------------------- 819 820 void SpellDialog::SetSelectedLang_Impl( LanguageType nLang ) 821 { 822 aLanguageLB.SelectLanguage( nLang ); 823 } 824 825 // ----------------------------------------------------------------------- 826 827 LanguageType SpellDialog::GetSelectedLang_Impl() const 828 { 829 sal_Int16 nLang = aLanguageLB.GetSelectLanguage(); 830 return nLang; 831 } 832 /* -----------------28.10.2003 14:27----------------- 833 834 --------------------------------------------------*/ 835 IMPL_LINK(SpellDialog, LanguageSelectHdl, SvxLanguageBox*, pBox) 836 { 837 //if currently an error is selected then search for alternatives for 838 //this word and fill the alternatives ListBox accordingly 839 String sError = aSentenceED.GetErrorText(); 840 aSuggestionLB.Clear(); 841 if(sError.Len()) 842 { 843 LanguageType eLanguage = pBox->GetSelectLanguage(); 844 Reference <XSpellAlternatives> xAlt = xSpell->spell( sError, eLanguage, 845 Sequence< PropertyValue >() ); 846 if( xAlt.is() ) 847 aSentenceED.SetAlternatives( xAlt ); 848 else 849 { 850 aSentenceED.ChangeMarkedWord( sError, eLanguage ); 851 SpellContinue_Impl(); 852 } 853 854 aSentenceED.AddUndoAction(new SpellUndoAction_Impl(SPELLUNDO_CHANGE_LANGUAGE, aDialogUndoLink)); 855 } 856 SpellDialog::UpdateBoxes_Impl(); 857 return 0; 858 } 859 // ----------------------------------------------------------------------- 860 861 void SpellDialog::SetLanguage( sal_uInt16 nLang ) 862 863 /* [Beschreibung] 864 865 wenn die Sprache im Thesaurus umgestellt wurde, 866 muss auch hier die Sprache umgestellt werden. 867 */ 868 869 { 870 SetTitle_Impl( nLang ); 871 872 // den richtigen Eintrag finden, da sortiert 873 aLanguageLB.SelectLanguage( nLang ); 874 } 875 /*-- 16.06.2008 11:27:02--------------------------------------------------- 876 877 -----------------------------------------------------------------------*/ 878 static Image lcl_GetImageFromPngUrl( const ::rtl::OUString &rFileUrl ) 879 { 880 Image aRes; 881 ::rtl::OUString aTmp; 882 osl::FileBase::getSystemPathFromFileURL( rFileUrl, aTmp ); 883 Graphic aGraphic; 884 const String aFilterName( RTL_CONSTASCII_USTRINGPARAM( IMP_PNG ) ); 885 if( GRFILTER_OK == GraphicFilter::LoadGraphic( aTmp, aFilterName, aGraphic ) ) 886 { 887 aRes = Image( aGraphic.GetBitmapEx() ); 888 } 889 return aRes; 890 } 891 void SpellDialog::SetTitle_Impl(LanguageType nLang) 892 { 893 String sTitle( m_sTitleSpelling ); 894 if( rParent.HasGrammarChecking() ) 895 { 896 String sVendor; 897 const SpellErrorDescription* pSpellErrorDescription = aSentenceED.GetAlternatives(); 898 if( pSpellErrorDescription && pSpellErrorDescription->sServiceName.getLength() ) 899 { 900 bool bHighContrast = GetSettings().GetStyleSettings().GetHighContrastMode(); 901 ::rtl::OUString sSuggestionImageUrl = 902 SvtLinguConfig().GetSpellAndGrammarDialogImage( pSpellErrorDescription->sServiceName, bHighContrast ); 903 aVendorImageFI.SetImage( lcl_GetImageFromPngUrl( sSuggestionImageUrl ) ); 904 uno::Reference< lang::XServiceDisplayName > xDisplayName( pSpellErrorDescription->xGrammarChecker, uno::UNO_QUERY ); 905 if( xDisplayName.is() ) 906 sVendor = xDisplayName->getServiceDisplayName( pSpellErrorDescription->aLocale ); 907 } 908 else 909 { 910 bool bHighContrast = GetSettings().GetStyleSettings().GetHighContrastMode(); 911 aVendorImageFI.SetImage( bHighContrast ? aVendorImageHC : aVendorImage ); 912 } 913 914 if( sVendor.Len() ) 915 { 916 sTitle = m_sTitleSpellingGrammarVendor; 917 sTitle.SearchAndReplaceAscii( "$VendorName", sVendor ); 918 } 919 else 920 { 921 //bool bHighContrast = GetSettings().GetStyleSettings().GetHighContrastMode(); 922 sTitle = m_sTitleSpellingGrammar; 923 } 924 } 925 sTitle.SearchAndReplaceAscii( "$LANGUAGE ($LOCATION)", SvtLanguageTable::GetLanguageString(nLang) ); 926 SetText( sTitle ); 927 } 928 /*------------------------------------------------------------------------- 929 930 -----------------------------------------------------------------------*/ 931 void SpellDialog::InitUserDicts() 932 { 933 const LanguageType nLang = aLanguageLB.GetSelectLanguage(); 934 935 const Reference< XDictionary > *pDic = 0; 936 937 // get list of dictionaries 938 Reference< XDictionaryList > xDicList( SvxGetDictionaryList() ); 939 if (xDicList.is()) 940 { 941 // add active, positive dictionary to dic-list (if not already done). 942 // This is to ensure that there is at least on dictionary to which 943 // words could be added. 944 Reference< XDictionary > xDic( SvxGetOrCreatePosDic( xDicList ) ); 945 if (xDic.is()) 946 xDic->setActive( sal_True ); 947 948 pImpl->aDics = xDicList->getDictionaries(); 949 } 950 951 SvtLinguConfig aCfg; 952 const bool bHC = Application::GetSettings().GetStyleSettings().GetHighContrastMode(); 953 954 // list suitable dictionaries 955 bool bEnable = false; 956 const sal_Int32 nSize = pImpl->aDics.getLength(); 957 pDic = pImpl->aDics.getConstArray(); 958 delete aAddToDictMB.GetPopupMenu(); 959 PopupMenu* pMenu = new PopupMenu; 960 pMenu->SetMenuFlags(MENU_FLAG_NOAUTOMNEMONICS); 961 sal_uInt16 nItemId = 1; // menu items should be enumerated from 1 and not 0 962 for (sal_Int32 i = 0; i < nSize; ++i) 963 { 964 uno::Reference< linguistic2::XDictionary > xDicTmp( pDic[i], uno::UNO_QUERY ); 965 if (!xDicTmp.is() || SvxGetIgnoreAllList() == xDicTmp) 966 continue; 967 968 uno::Reference< frame::XStorable > xStor( xDicTmp, uno::UNO_QUERY ); 969 LanguageType nActLanguage = SvxLocaleToLanguage( xDicTmp->getLocale() ); 970 if( xDicTmp->isActive() 971 && xDicTmp->getDictionaryType() != linguistic2::DictionaryType_NEGATIVE 972 && (nLang == nActLanguage || LANGUAGE_NONE == nActLanguage ) 973 && (!xStor.is() || !xStor->isReadonly()) ) 974 { 975 pMenu->InsertItem( nItemId, xDicTmp->getName() ); 976 bEnable = sal_True; 977 978 uno::Reference< lang::XServiceInfo > xSvcInfo( xDicTmp, uno::UNO_QUERY ); 979 if (xSvcInfo.is()) 980 { 981 OUString aDictionaryImageUrl( aCfg.GetSpellAndGrammarContextDictionaryImage( 982 xSvcInfo->getImplementationName(), bHC) ); 983 if (aDictionaryImageUrl.getLength() > 0) 984 { 985 Image aImage( lcl_GetImageFromPngUrl( aDictionaryImageUrl ) ); 986 pMenu->SetItemImage( nItemId, aImage ); 987 } 988 } 989 990 ++nItemId; 991 } 992 } 993 aAddToDictMB.SetPopupMenu(pMenu); 994 aAddToDictMB.Enable( bEnable ); 995 } 996 /*-- 20.10.2003 15:31:06--------------------------------------------------- 997 998 -----------------------------------------------------------------------*/ 999 IMPL_LINK(SpellDialog, AddToDictionaryHdl, MenuButton*, pButton ) 1000 { 1001 aSentenceED.UndoActionStart( SPELLUNDO_CHANGE_GROUP ); 1002 1003 //GetErrorText() returns the current error even if the text is already 1004 //manually changed 1005 const String aNewWord= aSentenceED.GetErrorText(); 1006 1007 sal_uInt16 nItemId = pButton->GetCurItemId(); 1008 PopupMenu *pMenu = pButton->GetPopupMenu(); 1009 String aDicName ( pMenu->GetItemText( nItemId ) ); 1010 1011 uno::Reference< linguistic2::XDictionary > xDic; 1012 uno::Reference< linguistic2::XDictionaryList > xDicList( SvxGetDictionaryList() ); 1013 if (xDicList.is()) 1014 xDic = xDicList->getDictionaryByName( aDicName ); 1015 1016 sal_Int16 nAddRes = DIC_ERR_UNKNOWN; 1017 if (xDic.is()) 1018 { 1019 nAddRes = linguistic::AddEntryToDic( xDic, aNewWord, sal_False, OUString(), LANGUAGE_NONE ); 1020 // save modified user-dictionary if it is persistent 1021 uno::Reference< frame::XStorable > xSavDic( xDic, uno::UNO_QUERY ); 1022 if (xSavDic.is()) 1023 xSavDic->store(); 1024 1025 if (nAddRes == DIC_ERR_NONE) 1026 { 1027 SpellUndoAction_Impl* pAction = new SpellUndoAction_Impl( 1028 SPELLUNDO_CHANGE_ADD_TO_DICTIONARY, aDialogUndoLink); 1029 pAction->SetDictionary( xDic ); 1030 pAction->SetAddedWord( aNewWord ); 1031 aSentenceED.AddUndoAction( pAction ); 1032 } 1033 // failed because there is already an entry? 1034 if (DIC_ERR_NONE != nAddRes && xDic->getEntry( aNewWord ).is()) 1035 nAddRes = DIC_ERR_NONE; 1036 } 1037 if (DIC_ERR_NONE != nAddRes) 1038 { 1039 SvxDicError( this, nAddRes ); 1040 return 0; // Nicht weitermachen 1041 } 1042 1043 // go on 1044 SpellContinue_Impl(); 1045 aSentenceED.UndoActionEnd(); 1046 return 0; 1047 } 1048 /*------------------------------------------------------------------------- 1049 1050 -----------------------------------------------------------------------*/ 1051 IMPL_LINK(SpellDialog, ModifyHdl, SentenceEditWindow_Impl*, pEd) 1052 { 1053 if (&aSentenceED == pEd) 1054 { 1055 bModified = true; 1056 aSuggestionLB.SetNoSelection(); 1057 aSuggestionLB.Disable(); 1058 String sNewText( aSentenceED.GetText() ); 1059 aAutoCorrPB.Enable( sNewText != aSentenceED.GetText() ); 1060 SpellUndoAction_Impl* pSpellAction = new SpellUndoAction_Impl(SPELLUNDO_CHANGE_TEXTENGINE, aDialogUndoLink); 1061 if(!aChangeAllPB.IsEnabled()) 1062 { 1063 aChangeAllPB.Enable(); 1064 pSpellAction->SetEnableChangeAllPB(); 1065 } 1066 if(!aChangePB.IsEnabled()) 1067 { 1068 aChangePB.Enable(); 1069 pSpellAction->SetEnableChangePB(); 1070 } 1071 aSentenceED.AddUndoAction(pSpellAction); 1072 } 1073 return 0; 1074 }; 1075 /*------------------------------------------------------------------------- 1076 1077 -----------------------------------------------------------------------*/ 1078 IMPL_LINK(SpellDialog, CancelHdl, Button *, EMPTYARG ) 1079 { 1080 //apply changes and ignored text parts first - if there are any 1081 rParent.ApplyChangedSentence(aSentenceED.CreateSpellPortions(true), false); 1082 Close(); 1083 return 0; 1084 } 1085 /*------------------------------------------------------------------------- 1086 1087 -----------------------------------------------------------------------*/ 1088 void SpellDialog::Paint( const Rectangle& rRect ) 1089 { 1090 ModelessDialog::Paint(rRect ); 1091 Rectangle aRect(aBackgroundGB.GetPosPixel(), aBackgroundGB.GetSizePixel()); 1092 DecorationView aDecoView( this ); 1093 aDecoView.DrawButton( aRect, BUTTON_DRAW_NOFILL); 1094 } 1095 /*-- 28.10.2003 13:26:39--------------------------------------------------- 1096 1097 -----------------------------------------------------------------------*/ 1098 long SpellDialog::Notify( NotifyEvent& rNEvt ) 1099 { 1100 /* #i38338# 1101 * FIXME: LoseFocus and GetFocus are signals from vcl that 1102 * a window actually got/lost the focus, it never should be 1103 * forwarded from another window, that is simply wrong. 1104 * FIXME: overloading the virtual methods GetFocus and LoseFocus 1105 * in SpellDialogChildWindow by making them pure is at least questionable. 1106 * The only sensible thing would be to call the new Method differently, 1107 * e.g. DialogGot/LostFocus or so. 1108 */ 1109 if( IsVisible() && !bFocusLocked ) 1110 { 1111 if( rNEvt.GetType() == EVENT_GETFOCUS ) 1112 { 1113 //notify the child window of the focus change 1114 rParent.GetFocus(); 1115 } 1116 else if( rNEvt.GetType() == EVENT_LOSEFOCUS ) 1117 { 1118 //notify the child window of the focus change 1119 rParent.LoseFocus(); 1120 } 1121 } 1122 return SfxModelessDialog::Notify(rNEvt); 1123 } 1124 /* -----------------10.09.2003 08:26----------------- 1125 1126 --------------------------------------------------*/ 1127 void SpellDialog::InvalidateDialog() 1128 { 1129 if( bFocusLocked ) 1130 return; 1131 aIgnorePB.SetText(aResumeST); 1132 Window* aDisableArr[] = 1133 { 1134 &aNotInDictFT, 1135 &aSentenceED, 1136 &aSuggestionFT, 1137 &aSuggestionLB, 1138 &aLanguageFT, 1139 &aLanguageLB, 1140 &aIgnoreAllPB, 1141 &aIgnoreRulePB, 1142 &aAddToDictMB, 1143 &aChangePB, 1144 &aChangeAllPB, 1145 &aAutoCorrPB, 1146 &aUndoPB, 1147 0 1148 }; 1149 sal_Int16 i = 0; 1150 while(aDisableArr[i]) 1151 { 1152 aDisableArr[i]->Enable(sal_False); 1153 i++; 1154 } 1155 SfxModelessDialog::Deactivate(); 1156 } 1157 1158 /*-- 10.09.2003 08:35:56--------------------------------------------------- 1159 1160 -----------------------------------------------------------------------*/ 1161 bool SpellDialog::GetNextSentence_Impl(bool bUseSavedSentence, bool bRecheck) 1162 { 1163 bool bRet = false; 1164 if(!bUseSavedSentence /*&& aSentenceED.IsModified()*/) 1165 { 1166 //apply changes and ignored text parts 1167 rParent.ApplyChangedSentence(aSentenceED.CreateSpellPortions(true), bRecheck); 1168 } 1169 aSentenceED.ResetIgnoreErrorsAt(); 1170 aSentenceED.ResetModified(); 1171 SpellPortions aSentence = bUseSavedSentence ? m_aSavedSentence : rParent.GetNextWrongSentence( bRecheck ); 1172 if(!bUseSavedSentence) 1173 m_aSavedSentence = aSentence; 1174 bool bHasReplaced = false; 1175 while(aSentence.size()) 1176 { 1177 //apply all changes that are already part of the "ChangeAllList" 1178 //returns true if the list still contains errors after the changes have been applied 1179 1180 if(!ApplyChangeAllList_Impl(aSentence, bHasReplaced)) 1181 { 1182 rParent.ApplyChangedSentence(aSentence, bRecheck); 1183 aSentence = rParent.GetNextWrongSentence( bRecheck ); 1184 } 1185 else 1186 break; 1187 } 1188 1189 if(aSentence.size()) 1190 { 1191 SpellPortions::iterator aStart = aSentence.begin(); 1192 rtl::OUString sText; 1193 while(aStart != aSentence.end()) 1194 { 1195 // hidden text has to be ignored 1196 if(!aStart->bIsHidden) 1197 sText += aStart->sText; 1198 aStart++; 1199 } 1200 aSentenceED.SetText(sText); 1201 aStart = aSentence.begin(); 1202 sal_Int32 nStartPosition = 0; 1203 sal_Int32 nEndPosition = 0; 1204 1205 while(aStart != aSentence.end()) 1206 { 1207 // hidden text has to be ignored 1208 if(!aStart->bIsHidden) 1209 { 1210 nEndPosition += aStart->sText.getLength(); 1211 if(aStart->xAlternatives.is()) 1212 { 1213 uno::Reference< container::XNamed > xNamed( aStart->xAlternatives, uno::UNO_QUERY ); 1214 ::rtl::OUString sServiceName; 1215 if( xNamed.is() ) 1216 sServiceName = xNamed->getName(); 1217 SpellErrorDescription aDesc( false, aStart->xAlternatives->getWord(), 1218 aStart->xAlternatives->getLocale(), aStart->xAlternatives->getAlternatives(), 0, sServiceName); 1219 aSentenceED.SetAttrib( SpellErrorAttrib(aDesc), 0, (sal_uInt16) nStartPosition, (sal_uInt16) nEndPosition ); 1220 } 1221 else if(aStart->bIsGrammarError ) 1222 { 1223 uno::Reference< lang::XServiceInfo > xInfo( aStart->xGrammarChecker, uno::UNO_QUERY ); 1224 SpellErrorDescription aDesc( true, 1225 aStart->sText, 1226 SvxCreateLocale( aStart->eLanguage ), 1227 aStart->aGrammarError.aSuggestions, 1228 aStart->xGrammarChecker, 1229 xInfo->getImplementationName(), 1230 &aStart->sDialogTitle, 1231 &aStart->aGrammarError.aFullComment, 1232 &aStart->aGrammarError.aRuleIdentifier ); 1233 aSentenceED.SetAttrib( SpellErrorAttrib(aDesc), 0, (sal_uInt16) nStartPosition, (sal_uInt16) nEndPosition ); 1234 } 1235 if(aStart->bIsField) 1236 aSentenceED.SetAttrib( SpellBackgroundAttrib(COL_LIGHTGRAY), 0, (sal_uInt16) nStartPosition, (sal_uInt16) nEndPosition ); 1237 aSentenceED.SetAttrib( SpellLanguageAttrib(aStart->eLanguage), 0, (sal_uInt16) nStartPosition, (sal_uInt16) nEndPosition ); 1238 nStartPosition = nEndPosition; 1239 } 1240 aStart++; 1241 } 1242 //the edit field needs to be modified to apply the change from the ApplyChangeAllList 1243 if(!bHasReplaced) 1244 aSentenceED.ClearModifyFlag(); 1245 aSentenceED.ResetUndo(); 1246 aUndoPB.Enable(sal_False); 1247 bRet = nStartPosition > 0; 1248 } 1249 return bRet; 1250 } 1251 /*-- 12.11.2003 15:21:25--------------------------------------------------- 1252 replace errrors that have a replacement in the ChangeAllList 1253 returns false if the result doesn't contain errors after the replacement 1254 -----------------------------------------------------------------------*/ 1255 bool SpellDialog::ApplyChangeAllList_Impl(SpellPortions& rSentence, bool &bHasReplaced) 1256 { 1257 bHasReplaced = false; 1258 bool bRet = true; 1259 SpellPortions::iterator aStart = rSentence.begin(); 1260 Reference<XDictionary> xChangeAll( SvxGetChangeAllList(), UNO_QUERY ); 1261 if(!xChangeAll->getCount()) 1262 return bRet; 1263 bRet = false; 1264 while(aStart != rSentence.end()) 1265 { 1266 if(aStart->xAlternatives.is()) 1267 { 1268 Reference<XDictionaryEntry> xEntry = xChangeAll->getEntry( aStart->sText ); 1269 if(xEntry.is()) 1270 { 1271 aStart->sText = xEntry->getReplacementText(); 1272 aStart->xAlternatives = 0; 1273 bHasReplaced = true; 1274 } 1275 else 1276 bRet = true; 1277 } 1278 else if( aStart->bIsGrammarError ) 1279 bRet = true; 1280 aStart++; 1281 } 1282 return bRet; 1283 } 1284 /*-- 10.09.2003 10:40:21--------------------------------------------------- 1285 1286 -----------------------------------------------------------------------*/ 1287 SentenceEditWindow_Impl::SentenceEditWindow_Impl( SpellDialog* pParent, const ResId& rResId ) : 1288 MultiLineEdit( pParent, rResId ), 1289 m_nErrorStart(0), 1290 m_nErrorEnd(0), 1291 m_bIsUndoEditMode(false) 1292 { 1293 DisableSelectionOnFocus(); 1294 } 1295 /*-- 10.09.2003 10:40:11--------------------------------------------------- 1296 1297 -----------------------------------------------------------------------*/ 1298 SentenceEditWindow_Impl::~SentenceEditWindow_Impl() 1299 { 1300 } 1301 /*-- 20.10.2003 13:42:34--------------------------------------------------- 1302 The selection before inputting a key may have a range or not 1303 and it may be inside or outside of field or error attributes. 1304 A range may include the attribute partially, completely or together 1305 with surrounding text. It may also contain more than one attribute 1306 or no attribute at all. 1307 Depending on this starting conditions some actions are necessary: 1308 Attempts to delete a field are only allowed if the selection is the same 1309 as the field's selection. Otherwise the field has to be selected and the key 1310 input action has to be skipped. 1311 Input of text at the start of the field requires the field attribute to be 1312 corrected - it is not allowed to grow. 1313 1314 In case of errors the appending of text should grow the error attribute because 1315 that is what the user usually wants to do. 1316 1317 Backspace at the start of the attribute requires to find out if a field ends 1318 directly in front of the cursor position. In case of a field this attribute has to be 1319 selected otherwise the key input method is allowed. 1320 1321 All changes outside of the error attributes switch the dialog mode to a "Undo edit" state that 1322 removes all visible attributes and switches off further attribute checks. 1323 Undo in this restarts the dialog with a current sentence newly presented. 1324 All changes to the sentence are undone including the ones before the "Undo edit state" has been reached 1325 1326 We end up with 9 types of selection 1327 1 (LEFT_NO) - no range, start of attribute - can also be 3 at the same time 1328 2 (INSIDE_NO) - no range, inside of attribute 1329 3 (RIGHT_NO) - no range, end of attribute - can also be 1 at the same time 1330 4 (FULL) - range, same as attribute 1331 5 (INSIDE_YES) - range, inside of the attribute 1332 6 (BRACE)- range, from outside of the attribute to the inside or 1333 including the complete attribute and something outside, 1334 maybe more than one attribute 1335 7 (OUTSIDE_NO) - no range, not at an attribute 1336 8 (OUTSIDE_YES) - range, completely outside of all attributes 1337 1338 What has to be done depending on the attribute type involved 1339 possible actions: UE - Undo edit mode 1340 CO - Continue, no additional action is required 1341 FS - Field has to be completely selected 1342 EX - The attribute has to be expanded to include the added text 1343 1344 1 - backspace delete any other 1345 UE on field FS on error CO on field FS on error CO 1346 1347 2 - on field FS on error C 1348 3 - backspace delete any other 1349 on field FS on error CO UE on field UE on error EX 1350 1351 if 1 and 3 happen to apply both then backspace and other handling is 1 delete is 3 1352 1353 4 - on field UE and on error CO 1354 5 - on field FS and on error CO 1355 6 - on field FS and on error UE 1356 7 - UE 1357 8 - UE 1358 -----------------------------------------------------------------------*/ 1359 #define INVALID 0 1360 #define LEFT_NO 1 1361 #define INSIDE_NO 2 1362 #define RIGHT_NO 3 1363 #define FULL 4 1364 #define INSIDE_YES 5 1365 #define BRACE 6 1366 #define OUTSIDE_NO 7 1367 #define OUTSIDE_YES 8 1368 1369 #define ACTION_UNDOEDIT 0 1370 #define ACTION_CONTINUE 1 1371 #define ACTION_SELECTFIELD 2 1372 #define ACTION_EXPAND 3 1373 1374 long SentenceEditWindow_Impl::PreNotify( NotifyEvent& rNEvt ) 1375 { 1376 bool bChange = false; 1377 const TextCharAttrib* pErrorAttrib = 0; 1378 if(rNEvt.GetType() == EVENT_KEYINPUT) 1379 { 1380 const KeyEvent& rKeyEvt = *rNEvt.GetKeyEvent(); 1381 bChange = TextEngine::DoesKeyChangeText( rKeyEvt ); 1382 if(bChange && !IsUndoEditMode() && 1383 rKeyEvt.GetKeyCode().GetCode() != KEY_TAB) 1384 { 1385 TextEngine* pTextEngine = GetTextEngine(); 1386 TextView* pTextView = pTextEngine->GetActiveView(); 1387 const TextSelection& rCurrentSelection = pTextView->GetSelection(); 1388 //determine if the selection contains a field 1389 bool bHasField = false; 1390 bool bHasError = false; 1391 bool bHasFieldLeft = false; 1392 bool bHasErrorLeft = false; 1393 // bool bInsideAttr = false; 1394 1395 bool bHasRange = rCurrentSelection.HasRange(); 1396 sal_uInt8 nSelectionType = 0; // invalid type! 1397 1398 TextPaM aCursor(rCurrentSelection.GetStart()); 1399 const TextCharAttrib* pBackAttr = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_BACKGROUND ); 1400 const TextCharAttrib* pErrorAttr = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_ERROR ); 1401 const TextCharAttrib* pBackAttrLeft = 0; 1402 const TextCharAttrib* pErrorAttrLeft = 0; 1403 1404 bHasField = pBackAttr != 0 && (bHasRange || pBackAttr->GetEnd() > aCursor.GetIndex()); 1405 bHasError = pErrorAttr != 0 && (bHasRange || pErrorAttr->GetEnd() > aCursor.GetIndex()); 1406 if(bHasRange) 1407 { 1408 if(pBackAttr && 1409 pBackAttr->GetStart() == rCurrentSelection.GetStart().GetIndex() && 1410 pBackAttr->GetEnd() == rCurrentSelection.GetEnd().GetIndex()) 1411 { 1412 nSelectionType = FULL; 1413 } 1414 else if(pErrorAttr && 1415 pErrorAttr->GetStart() <= rCurrentSelection.GetStart().GetIndex() && 1416 pErrorAttr->GetEnd() >= rCurrentSelection.GetEnd().GetIndex()) 1417 { 1418 nSelectionType = INSIDE_YES; 1419 } 1420 else 1421 { 1422 nSelectionType = bHasField||bHasError ? BRACE : OUTSIDE_NO; 1423 while(aCursor.GetIndex() < rCurrentSelection.GetEnd().GetIndex()) 1424 { 1425 ++aCursor.GetIndex(); 1426 const TextCharAttrib* pIntBackAttr = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_BACKGROUND ); 1427 const TextCharAttrib* pIntErrorAttr = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_ERROR ); 1428 //if any attr has been found then BRACE 1429 if(pIntBackAttr || pIntErrorAttr) 1430 nSelectionType = BRACE; 1431 //the field has to be selected 1432 if(pIntBackAttr && !pBackAttr) 1433 pBackAttr = pIntBackAttr; 1434 bHasField |= pIntBackAttr != 0; 1435 } 1436 } 1437 } 1438 else 1439 { 1440 //no range selection: then 1 2 3 and 8 are possible 1441 const TextCharAttrib* pCurAttr = pBackAttr ? pBackAttr : pErrorAttr; 1442 if(pCurAttr) 1443 { 1444 nSelectionType = pCurAttr->GetStart() == rCurrentSelection.GetStart().GetIndex() ? 1445 LEFT_NO : pCurAttr->GetEnd() == rCurrentSelection.GetEnd().GetIndex() ? RIGHT_NO : INSIDE_NO; 1446 } 1447 else 1448 nSelectionType = OUTSIDE_NO; 1449 1450 bHasFieldLeft = pBackAttr && pBackAttr->GetEnd() == aCursor.GetIndex(); 1451 if(bHasFieldLeft) 1452 { 1453 pBackAttrLeft = pBackAttr; 1454 pBackAttr = 0; 1455 } 1456 bHasErrorLeft = pErrorAttr && pErrorAttr->GetEnd() == aCursor.GetIndex(); 1457 if(bHasErrorLeft) 1458 { 1459 pErrorAttrLeft = pErrorAttr; 1460 pErrorAttr = 0; 1461 } 1462 1463 //check previous position if this exists 1464 //that is a redundant in the case the the attribute found above already is on the left cursor side 1465 //but it's o.k. for two errors/fields side by side 1466 if(aCursor.GetIndex()) 1467 { 1468 --aCursor.GetIndex(); 1469 pBackAttrLeft = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_BACKGROUND ); 1470 pErrorAttrLeft = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_ERROR ); 1471 bHasFieldLeft = pBackAttrLeft !=0; 1472 bHasErrorLeft = pErrorAttrLeft != 0; 1473 // bInsideAttr = (bHasField || bHasError) && (bHasFieldLeft || bHasErrorLeft); 1474 ++aCursor.GetIndex(); 1475 } 1476 } 1477 //Here we have to determine if the error found is the one currently active 1478 bool bIsErrorActive = (pErrorAttr && pErrorAttr->GetStart() == m_nErrorStart) || 1479 (pErrorAttrLeft && pErrorAttrLeft->GetStart() == m_nErrorStart); 1480 1481 DBG_ASSERT(nSelectionType != INVALID, "selection type not set!"); 1482 1483 const KeyCode& rKeyCode = rKeyEvt.GetKeyCode(); 1484 bool bDelete = rKeyCode.GetCode() == KEY_DELETE; 1485 bool bBackspace = rKeyCode.GetCode() == KEY_BACKSPACE; 1486 1487 sal_Int8 nAction = ACTION_CONTINUE; 1488 // nAction = ACTION_UNDOEDIT 1489 // nAction = ACTION_SELECTFIELD 1490 // nAction = ACTION_EXPAND 1491 switch(nSelectionType) 1492 { 1493 // 1 - backspace delete any other 1494 // UE on field FS on error CO on field FS on error CO 1495 case LEFT_NO : 1496 if(bBackspace) 1497 { 1498 nAction = bHasFieldLeft ? ACTION_SELECTFIELD : ACTION_UNDOEDIT; 1499 //to force the use of pBackAttrLeft 1500 pBackAttr = 0; 1501 } 1502 else if(bDelete) 1503 nAction = bHasField ? ACTION_SELECTFIELD : ACTION_CONTINUE; 1504 else 1505 nAction = bHasError && !aCursor.GetIndex() ? ACTION_CONTINUE : 1506 bHasError ? ACTION_EXPAND : bHasErrorLeft ? ACTION_CONTINUE : ACTION_UNDOEDIT; 1507 break; 1508 // 2 - on field FS on error C 1509 case INSIDE_NO : 1510 nAction = bHasField ? ACTION_SELECTFIELD : 1511 bIsErrorActive ? ACTION_CONTINUE : ACTION_UNDOEDIT; 1512 break; 1513 // 3 - backspace delete any other 1514 // on field FS on error CO UE on field UE on error EX 1515 case RIGHT_NO : 1516 if(bBackspace) 1517 nAction = bHasFieldLeft ? ACTION_SELECTFIELD : ACTION_CONTINUE; 1518 else if(bDelete) 1519 nAction = bHasFieldLeft && bHasError ? ACTION_CONTINUE : ACTION_UNDOEDIT; 1520 else 1521 nAction = bHasFieldLeft && bHasError ? ACTION_EXPAND : 1522 bHasError ? ACTION_CONTINUE : bHasErrorLeft ? ACTION_EXPAND :ACTION_UNDOEDIT; 1523 break; 1524 // 4 - on field UE and on error CO 1525 case FULL : 1526 nAction = bHasField ? ACTION_UNDOEDIT : ACTION_CONTINUE; 1527 break; 1528 // 5 - on field FS and on error CO 1529 case INSIDE_YES : 1530 nAction = bHasField ? ACTION_SELECTFIELD : ACTION_CONTINUE; 1531 break; 1532 // 6 - on field FS and on error UE 1533 case BRACE : 1534 nAction = bHasField ? ACTION_SELECTFIELD : ACTION_UNDOEDIT;; 1535 break; 1536 // 7 - UE 1537 // 8 - UE 1538 case OUTSIDE_NO : 1539 case OUTSIDE_YES: 1540 nAction = ACTION_UNDOEDIT; 1541 break; 1542 } 1543 //save the current paragraph 1544 sal_uInt16 nCurrentLen = GetText().Len(); 1545 if(nAction != ACTION_SELECTFIELD) 1546 pTextView->GetWindow()->KeyInput(rKeyEvt); 1547 else 1548 { 1549 const TextCharAttrib* pCharAttr = pBackAttr ? pBackAttr : pBackAttrLeft; 1550 if(pCharAttr) 1551 { 1552 TextPaM aStart(0, pCharAttr->GetStart()); 1553 TextPaM aEnd(0, pCharAttr->GetEnd()); 1554 TextSelection aNewSel(aStart, aEnd); 1555 pTextView->SetSelection( aNewSel); 1556 } 1557 } 1558 if(nAction == ACTION_EXPAND) 1559 { 1560 DBG_ASSERT(pErrorAttrLeft || pErrorAttr, "where is the error"); 1561 //text has been added on the right and only the 'error attribute has to be corrected 1562 if(pErrorAttrLeft) 1563 { 1564 TextAttrib* pNewError = pErrorAttrLeft->GetAttr().Clone(); 1565 sal_uInt16 nStart = pErrorAttrLeft->GetStart(); 1566 sal_uInt16 nEnd = pErrorAttrLeft->GetEnd(); 1567 pTextEngine->RemoveAttrib( 0, *pErrorAttrLeft ); 1568 SetAttrib( *pNewError, 0, nStart, ++nEnd ); 1569 //only active errors move the mark 1570 if(bIsErrorActive) 1571 { 1572 bool bGrammar = static_cast<const SpellErrorAttrib&>(*pNewError).GetErrorDescription().bIsGrammarError; 1573 MoveErrorMarkTo(nStart, nEnd, bGrammar); 1574 } 1575 delete pNewError; 1576 } 1577 //text has been added on the left then the error attribute has to be expanded and the 1578 //field attribute on the right - if any - has to be contracted 1579 else if(pErrorAttr) 1580 { 1581 //determine the change 1582 sal_uInt16 nAddedChars = GetText().Len() - nCurrentLen; 1583 1584 TextAttrib* pNewError = pErrorAttr->GetAttr().Clone(); 1585 sal_uInt16 nStart = pErrorAttr->GetStart(); 1586 sal_uInt16 nEnd = pErrorAttr->GetEnd(); 1587 pTextEngine->RemoveAttrib( 0, *pErrorAttr ); 1588 nStart = nStart - (sal_uInt16)nAddedChars; 1589 SetAttrib( *pNewError, 0, nStart - nAddedChars, nEnd ); 1590 //only if the error is active the mark is moved here 1591 if(bIsErrorActive) 1592 { 1593 bool bGrammar = static_cast<const SpellErrorAttrib&>(*pNewError).GetErrorDescription().bIsGrammarError; 1594 MoveErrorMarkTo(nStart, nEnd, bGrammar); 1595 } 1596 delete pNewError; 1597 1598 if(pBackAttrLeft) 1599 { 1600 TextAttrib* pNewBack = pBackAttrLeft->GetAttr().Clone(); 1601 sal_uInt16 _nStart = pBackAttrLeft->GetStart(); 1602 sal_uInt16 _nEnd = pBackAttrLeft->GetEnd(); 1603 pTextEngine->RemoveAttrib( 0, *pBackAttrLeft ); 1604 SetAttrib( *pNewBack, 0, _nStart, _nEnd - nAddedChars); 1605 delete pNewBack; 1606 } 1607 } 1608 } 1609 else if(nAction == ACTION_UNDOEDIT) 1610 { 1611 SetUndoEditMode(true); 1612 } 1613 //make sure the error positions are correct after text changes 1614 //the old attribute may have been deleted 1615 //all changes inside of the current error leave the error attribute at the current 1616 //start position 1617 if(!IsUndoEditMode() && bIsErrorActive) 1618 { 1619 const TextCharAttrib* pFontColor = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_FONTCOLOR ); 1620 pErrorAttrib = pTextEngine->FindCharAttrib( TextPaM(0, m_nErrorStart), TEXTATTR_SPELL_ERROR ); 1621 if(pFontColor && pErrorAttrib ) 1622 { 1623 m_nErrorStart = pFontColor->GetStart(); 1624 m_nErrorEnd = pFontColor->GetEnd(); 1625 if(pErrorAttrib->GetStart() != m_nErrorStart || pErrorAttrib->GetEnd() != m_nErrorEnd) 1626 { 1627 TextAttrib* pNewError = pErrorAttrib->GetAttr().Clone(); 1628 pTextEngine->RemoveAttrib( 0, *pErrorAttr ); 1629 SetAttrib( *pNewError, 0, m_nErrorStart, m_nErrorEnd ); 1630 delete pNewError; 1631 } 1632 } 1633 } 1634 //this is not a modification anymore 1635 if(nAction != ACTION_SELECTFIELD && !m_bIsUndoEditMode) 1636 CallModifyLink(); 1637 } 1638 else 1639 bChange = false; 1640 } 1641 long nRet = bChange ? 1 : MultiLineEdit::PreNotify(rNEvt); 1642 return nRet; 1643 } 1644 /*-- 10.09.2003 13:38:14--------------------------------------------------- 1645 1646 -----------------------------------------------------------------------*/ 1647 bool SentenceEditWindow_Impl::MarkNextError( bool bIgnoreCurrentError ) 1648 { 1649 if (bIgnoreCurrentError) 1650 m_aIgnoreErrorsAt.insert( m_nErrorStart ); 1651 ExtTextEngine* pTextEngine = GetTextEngine(); 1652 sal_uInt16 nTextLen = pTextEngine->GetTextLen(0); 1653 if(m_nErrorEnd >= nTextLen - 1) 1654 return false; 1655 //if it's not already modified the modified flag has to be reset at the and of the marking 1656 bool bModified = IsModified(); 1657 bool bRet = false; 1658 const sal_uInt16 nOldErrorStart = m_nErrorStart; 1659 const sal_uInt16 nOldErrorEnd = m_nErrorEnd; 1660 1661 //create a cursor behind the end of the last error 1662 //- or at 0 at the start of the sentence 1663 TextPaM aCursor(0, m_nErrorEnd ? m_nErrorEnd + 1 : 0); 1664 //search for SpellErrorAttrib 1665 1666 const TextCharAttrib* pNextError = 0; 1667 //iterate over the text and search for the next error that maybe has 1668 //to be replace by a ChangeAllList replacement 1669 bool bGrammarError = false; 1670 while(aCursor.GetIndex() < nTextLen) 1671 { 1672 while(aCursor.GetIndex() < nTextLen && 1673 0 == (pNextError = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_ERROR))) 1674 { 1675 ++aCursor.GetIndex(); 1676 } 1677 // maybe the error found here is already in the ChangeAllList and has to be replaced 1678 1679 Reference<XDictionary> xChangeAll( SvxGetChangeAllList(), UNO_QUERY ); 1680 Reference<XDictionaryEntry> xEntry; 1681 1682 // Reference <XSpellAlternatives> xAlternatives; 1683 const SpellErrorDescription* pSpellErrorDescription = 0; 1684 if(pNextError) 1685 { 1686 pSpellErrorDescription = &static_cast<const SpellErrorAttrib&>(pNextError->GetAttr()).GetErrorDescription(); 1687 bGrammarError = pSpellErrorDescription->bIsGrammarError; 1688 } 1689 if(xChangeAll->getCount() && pSpellErrorDescription && 1690 (xEntry = xChangeAll->getEntry( pSpellErrorDescription->sErrorText )).is()) 1691 { 1692 m_nErrorStart = pNextError->GetStart(); 1693 m_nErrorEnd = pNextError->GetEnd(); 1694 ChangeMarkedWord(xEntry->getReplacementText(), 1695 SvxLocaleToLanguage( pSpellErrorDescription->aLocale )); 1696 aCursor.GetIndex() = aCursor.GetIndex() + (sal_uInt16)(xEntry->getReplacementText().getLength()); 1697 } 1698 else 1699 break; 1700 } 1701 1702 //if an attrib has been found search for the end of the error string 1703 if(aCursor.GetIndex() < nTextLen) 1704 { 1705 m_nErrorStart = aCursor.GetIndex(); 1706 m_nErrorEnd = pNextError->GetEnd(); 1707 MoveErrorMarkTo(m_nErrorStart, m_nErrorEnd, bGrammarError); 1708 bRet = true; 1709 //add an undo action 1710 SpellUndoAction_Impl* pAction = new SpellUndoAction_Impl( 1711 SPELLUNDO_CHANGE_NEXTERROR, GetSpellDialog()->aDialogUndoLink); 1712 pAction->SetErrorMove(m_nErrorStart, m_nErrorEnd, nOldErrorStart, nOldErrorEnd); 1713 const SpellErrorAttrib* pOldAttrib = static_cast<const SpellErrorAttrib*>( 1714 pTextEngine->FindAttrib( TextPaM(0, nOldErrorStart), TEXTATTR_SPELL_ERROR )); 1715 pAction->SetErrorLanguageSelected(pOldAttrib && pOldAttrib->GetErrorDescription().aSuggestions.getLength() && 1716 SvxLocaleToLanguage( pOldAttrib->GetErrorDescription().aLocale) == 1717 GetSpellDialog()->aLanguageLB.GetSelectLanguage()); 1718 AddUndoAction(pAction); 1719 } 1720 else 1721 m_nErrorStart = m_nErrorEnd = nTextLen; 1722 if( !bModified ) 1723 ClearModifyFlag(); 1724 SpellDialog* pSpellDialog = GetSpellDialog(); 1725 pSpellDialog->aIgnorePB.Enable(bRet); 1726 pSpellDialog->aIgnoreAllPB.Enable(bRet); 1727 pSpellDialog->aAutoCorrPB.Enable(bRet); 1728 pSpellDialog->aAddToDictMB.Enable(bRet); 1729 return bRet; 1730 } 1731 1732 /*-- 06.11.2003 13:30:26--------------------------------------------------- 1733 1734 -----------------------------------------------------------------------*/ 1735 void SentenceEditWindow_Impl::MoveErrorMarkTo(sal_uInt16 nStart, sal_uInt16 nEnd, bool bGrammarError) 1736 { 1737 TextEngine* pTextEngine = GetTextEngine(); 1738 pTextEngine->RemoveAttribs( 0, (sal_uInt16)TEXTATTR_FONTCOLOR, sal_True ); 1739 pTextEngine->RemoveAttribs( 0, (sal_uInt16)TEXTATTR_FONTWEIGHT, sal_True ); 1740 pTextEngine->SetAttrib( TextAttribFontWeight(WEIGHT_BOLD), 0, nStart, nEnd ); 1741 pTextEngine->SetAttrib( TextAttribFontColor(bGrammarError ? COL_LIGHTBLUE : COL_LIGHTRED), 0, nStart, nEnd ); 1742 m_nErrorStart = nStart; 1743 m_nErrorEnd = nEnd; 1744 } 1745 1746 /*-- 17.09.2003 10:13:08--------------------------------------------------- 1747 1748 -----------------------------------------------------------------------*/ 1749 void SentenceEditWindow_Impl::ChangeMarkedWord(const String& rNewWord, LanguageType eLanguage) 1750 { 1751 //calculate length changes 1752 long nDiffLen = rNewWord.Len() - m_nErrorEnd + m_nErrorStart; 1753 TextSelection aSel(TextPaM(0, m_nErrorStart), TextPaM(0, m_nErrorEnd)); 1754 //Remove spell errror attribute 1755 ExtTextEngine* pTextEngine = GetTextEngine(); 1756 pTextEngine->UndoActionStart(); 1757 const TextCharAttrib* pErrorAttrib = pTextEngine->FindCharAttrib( TextPaM(0, m_nErrorStart), TEXTATTR_SPELL_ERROR ); 1758 DBG_ASSERT(pErrorAttrib, "no error attribute found"); 1759 // Reference <XSpellAlternatives> xAlternatives; 1760 const SpellErrorDescription* pSpellErrorDescription = 0; 1761 if(pErrorAttrib) 1762 { 1763 pTextEngine->RemoveAttrib(0, *pErrorAttrib); 1764 pSpellErrorDescription = &static_cast<const SpellErrorAttrib&>(pErrorAttrib->GetAttr()).GetErrorDescription(); 1765 } 1766 const TextCharAttrib* pBackAttrib = pTextEngine->FindCharAttrib( TextPaM(0, m_nErrorStart), TEXTATTR_SPELL_BACKGROUND ); 1767 pTextEngine->ReplaceText( aSel, rNewWord ); 1768 // 1769 if(!m_nErrorStart) 1770 { 1771 //attributes following an error at the start of the text are not moved but expanded from the 1772 //text engine - this is done to keep full-paragraph-attributes 1773 //in the current case that handling is not desired 1774 const TextCharAttrib* pLangAttrib = 1775 pTextEngine->FindCharAttrib( 1776 TextPaM(0, m_nErrorEnd), TEXTATTR_SPELL_LANGUAGE ); 1777 sal_uInt16 nTextLen = pTextEngine->GetTextLen( 0 ); 1778 if(pLangAttrib && !pLangAttrib->GetStart() && pLangAttrib->GetEnd() == 1779 nTextLen) 1780 { 1781 SpellLanguageAttrib aNewLangAttrib( static_cast<const SpellLanguageAttrib&>(pLangAttrib->GetAttr()).GetLanguage()); 1782 pTextEngine->RemoveAttrib(0, *pLangAttrib); 1783 pTextEngine->SetAttrib( aNewLangAttrib, 0, (sal_uInt16)(m_nErrorEnd + nDiffLen) , nTextLen ); 1784 } 1785 } 1786 // undo expanded attributes! 1787 if( pBackAttrib && pBackAttrib->GetStart() < m_nErrorStart && pBackAttrib->GetEnd() == m_nErrorEnd + nDiffLen) 1788 { 1789 TextAttrib* pNewBackground = pBackAttrib->GetAttr().Clone(); 1790 sal_uInt16 nStart = pBackAttrib->GetStart(); 1791 pTextEngine->RemoveAttrib(0, *pBackAttrib); 1792 pTextEngine->SetAttrib(*pNewBackground, 0, nStart, m_nErrorStart); 1793 delete pNewBackground; 1794 } 1795 pTextEngine->SetModified(sal_True); 1796 1797 //adjust end position 1798 long nEndTemp = m_nErrorEnd; 1799 nEndTemp += nDiffLen; 1800 m_nErrorEnd = (sal_uInt16)nEndTemp; 1801 1802 SpellUndoAction_Impl* pAction = new SpellUndoAction_Impl( 1803 SPELLUNDO_MOVE_ERROREND, GetSpellDialog()->aDialogUndoLink); 1804 pAction->SetOffset(nDiffLen); 1805 AddUndoAction(pAction); 1806 if(pSpellErrorDescription) 1807 SetAttrib( SpellErrorAttrib(*pSpellErrorDescription), 0, m_nErrorStart, m_nErrorEnd ); 1808 SetAttrib( SpellLanguageAttrib(eLanguage), 0, m_nErrorStart, m_nErrorEnd ); 1809 pTextEngine->UndoActionEnd(); 1810 } 1811 /* -----------------08.10.2003 13:18----------------- 1812 1813 --------------------------------------------------*/ 1814 String SentenceEditWindow_Impl::GetErrorText() const 1815 { 1816 return GetTextEngine()->GetText(TextSelection(TextPaM(0, m_nErrorStart), TextPaM(0, m_nErrorEnd) )); 1817 } 1818 /*-- 26.06.2008 10:54:13--------------------------------------------------- 1819 1820 -----------------------------------------------------------------------*/ 1821 const SpellErrorDescription* SentenceEditWindow_Impl::GetAlternatives() 1822 { 1823 TextPaM aCursor(0, m_nErrorStart); 1824 const SpellErrorAttrib* pAttrib = static_cast<const SpellErrorAttrib*>( 1825 GetTextEngine()->FindAttrib( aCursor, TEXTATTR_SPELL_ERROR)); 1826 return pAttrib ? &pAttrib->GetErrorDescription() : 0; 1827 } 1828 /*-- 06.09.2004 10:50:32--------------------------------------------------- 1829 1830 -----------------------------------------------------------------------*/ 1831 void SentenceEditWindow_Impl::RestoreCurrentError() 1832 { 1833 TextPaM aCursor(0, m_nErrorStart); 1834 const SpellErrorAttrib* pAttrib = static_cast<const SpellErrorAttrib*>( 1835 GetTextEngine()->FindAttrib( aCursor, TEXTATTR_SPELL_ERROR)); 1836 if( pAttrib ) 1837 { 1838 const SpellErrorDescription& rDesc = pAttrib->GetErrorDescription(); 1839 if( !rDesc.sErrorText.equals( GetErrorText() ) ) 1840 ChangeMarkedWord(rDesc.sErrorText, SvxLocaleToLanguage( rDesc.aLocale )); 1841 } 1842 } 1843 /*-- 28.10.2003 14:44:10--------------------------------------------------- 1844 1845 -----------------------------------------------------------------------*/ 1846 void SentenceEditWindow_Impl::SetAlternatives( Reference< XSpellAlternatives> xAlt ) 1847 { 1848 TextPaM aCursor(0, m_nErrorStart); 1849 DBG_ASSERT(static_cast<const SpellErrorAttrib*>( 1850 GetTextEngine()->FindAttrib( aCursor, TEXTATTR_SPELL_ERROR)), "no error set?"); 1851 1852 ::rtl::OUString aWord; 1853 lang::Locale aLocale; 1854 uno::Sequence< ::rtl::OUString > aAlts; 1855 ::rtl::OUString sServiceName; 1856 if (xAlt.is()) 1857 { 1858 aWord = xAlt->getWord(); 1859 aLocale = xAlt->getLocale(); 1860 aAlts = xAlt->getAlternatives(); 1861 uno::Reference< container::XNamed > xNamed( xAlt, uno::UNO_QUERY ); 1862 if (xNamed.is()) 1863 sServiceName = xNamed->getName(); 1864 } 1865 SpellErrorDescription aDesc( false, aWord, aLocale, aAlts, 0, sServiceName); 1866 GetTextEngine()->SetAttrib( SpellErrorAttrib(aDesc), 0, m_nErrorStart, m_nErrorEnd ); 1867 } 1868 1869 /*-- 10.09.2003 14:43:02--------------------------------------------------- 1870 1871 -----------------------------------------------------------------------*/ 1872 void SentenceEditWindow_Impl::SetAttrib( const TextAttrib& rAttr, sal_uLong nPara, sal_uInt16 nStart, sal_uInt16 nEnd ) 1873 { 1874 GetTextEngine()->SetAttrib(rAttr, nPara, nStart, nEnd); 1875 } 1876 /*-- 10.09.2003 14:43:02--------------------------------------------------- 1877 1878 -----------------------------------------------------------------------*/ 1879 void SentenceEditWindow_Impl::SetText( const String& rStr ) 1880 { 1881 m_nErrorStart = m_nErrorEnd = 0; 1882 GetTextEngine()->SetText(rStr); 1883 // InitScrollBars(); 1884 } 1885 /*-- 08.10.2003 14:35:52--------------------------------------------------- 1886 1887 -----------------------------------------------------------------------*/ 1888 struct LanguagePosition_Impl 1889 { 1890 sal_uInt16 nPosition; 1891 LanguageType eLanguage; 1892 1893 LanguagePosition_Impl(sal_uInt16 nPos, LanguageType eLang) : 1894 nPosition(nPos), 1895 eLanguage(eLang) 1896 {} 1897 }; 1898 typedef std::vector<LanguagePosition_Impl> LanguagePositions_Impl; 1899 1900 void lcl_InsertBreakPosition_Impl( 1901 LanguagePositions_Impl& rBreakPositions, sal_uInt16 nInsert, LanguageType eLanguage) 1902 { 1903 LanguagePositions_Impl::iterator aStart = rBreakPositions.begin(); 1904 while(aStart != rBreakPositions.end()) 1905 { 1906 if(aStart->nPosition == nInsert) 1907 { 1908 //the language of following starts has to overwrite 1909 //the one of previous ends 1910 aStart->eLanguage = eLanguage; 1911 return; 1912 } 1913 else if(aStart->nPosition > nInsert) 1914 { 1915 1916 rBreakPositions.insert(aStart, LanguagePosition_Impl(nInsert, eLanguage)); 1917 return; 1918 } 1919 else 1920 ++aStart; 1921 } 1922 rBreakPositions.push_back(LanguagePosition_Impl(nInsert, eLanguage)); 1923 } 1924 /*-- 17.09.2003 14:26:59--------------------------------------------------- 1925 Returns the text in spell portions. Each portion contains text with an 1926 equal language and attribute. The spell alternatives are empty. 1927 -----------------------------------------------------------------------*/ 1928 svx::SpellPortions SentenceEditWindow_Impl::CreateSpellPortions( bool bSetIgnoreFlag ) const 1929 { 1930 svx::SpellPortions aRet; 1931 ExtTextEngine* pTextEngine = GetTextEngine(); 1932 const sal_uInt16 nTextLen = pTextEngine->GetTextLen(0); 1933 if(nTextLen) 1934 { 1935 TextPaM aCursor(0, 0); 1936 LanguagePositions_Impl aBreakPositions; 1937 const TextCharAttrib* pLastLang = 0; 1938 const TextCharAttrib* pLastError = 0; 1939 LanguageType eLang = LANGUAGE_DONTKNOW; 1940 const TextCharAttrib* pError = 0; 1941 while(aCursor.GetIndex() < nTextLen) 1942 { 1943 const TextCharAttrib* pLang = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_LANGUAGE); 1944 if(pLang && pLang != pLastLang) 1945 { 1946 eLang = static_cast<const SpellLanguageAttrib&>(pLang->GetAttr()).GetLanguage(); 1947 lcl_InsertBreakPosition_Impl(aBreakPositions, pLang->GetStart(), eLang); 1948 lcl_InsertBreakPosition_Impl(aBreakPositions, pLang->GetEnd(), eLang); 1949 pLastLang = pLang; 1950 } 1951 pError = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_ERROR); 1952 if(pError && pLastError != pError) 1953 { 1954 lcl_InsertBreakPosition_Impl(aBreakPositions, pError->GetStart(), eLang); 1955 lcl_InsertBreakPosition_Impl(aBreakPositions, pError->GetEnd(), eLang); 1956 pLastError = pError; 1957 1958 } 1959 aCursor.GetIndex()++; 1960 } 1961 // 1962 if(nTextLen && aBreakPositions.empty()) 1963 { 1964 //if all content has been overwritten the attributes may have been removed, too 1965 svx::SpellPortion aPortion1; 1966 aPortion1.eLanguage = GetSpellDialog()->GetSelectedLang_Impl(); 1967 aPortion1.sText = pTextEngine->GetText( 1968 TextSelection(TextPaM(0, 0), TextPaM(0, nTextLen))); 1969 1970 aRet.push_back(aPortion1); 1971 1972 } 1973 else if(!aBreakPositions.empty()) 1974 { 1975 LanguagePositions_Impl::iterator aStart = aBreakPositions.begin(); 1976 //start should always be Null 1977 eLang = aStart->eLanguage; 1978 sal_uInt16 nStart = aStart->nPosition; 1979 DBG_ASSERT(!nStart, "invalid start position - language attribute missing?"); 1980 ++aStart; 1981 1982 while(aStart != aBreakPositions.end()) 1983 { 1984 svx::SpellPortion aPortion1; 1985 aPortion1.eLanguage = eLang; 1986 aPortion1.sText = pTextEngine->GetText( 1987 TextSelection(TextPaM(0, nStart), TextPaM(0, aStart->nPosition))); 1988 bool bIsIgnoreError = m_aIgnoreErrorsAt.find( nStart ) != m_aIgnoreErrorsAt.end(); 1989 if( bSetIgnoreFlag && bIsIgnoreError /*m_nErrorStart == nStart*/ ) 1990 { 1991 aPortion1.bIgnoreThisError = true; 1992 } 1993 aRet.push_back(aPortion1); 1994 nStart = aStart->nPosition; 1995 eLang = aStart->eLanguage; 1996 ++aStart; 1997 } 1998 } 1999 2000 // quick partly fix of #i71318. Correct fix needs to patch the TextEngine itself... 2001 // this one will only prevent text from disappearing. It may to not have the 2002 // correct language and will probably not spell checked... 2003 sal_uLong nPara = pTextEngine->GetParagraphCount(); 2004 if (nPara > 1) 2005 { 2006 String aLeftOverText; 2007 for (sal_uLong i = 1; i < nPara; ++i) 2008 { 2009 aLeftOverText.AppendAscii( "\x0a" ); // the manual line break... 2010 aLeftOverText += pTextEngine->GetText(i); 2011 } 2012 if (pError) 2013 { // we need to add a new portion containing the left-over text 2014 svx::SpellPortion aPortion2; 2015 aPortion2.eLanguage = eLang; 2016 aPortion2.sText = aLeftOverText; 2017 aRet.push_back( aPortion2 ); 2018 } 2019 else 2020 { // we just need to append the left-over text to the last portion (which had no errors) 2021 aRet[ aRet.size() - 1 ].sText += aLeftOverText; 2022 } 2023 } 2024 } 2025 return aRet; 2026 } 2027 2028 /*-- 06.11.2003 11:30:10--------------------------------------------------- 2029 2030 -----------------------------------------------------------------------*/ 2031 void SentenceEditWindow_Impl::Undo() 2032 { 2033 ::svl::IUndoManager& rUndoMgr = GetTextEngine()->GetUndoManager(); 2034 DBG_ASSERT(GetUndoActionCount(), "no undo actions available" ); 2035 if(!GetUndoActionCount()) 2036 return; 2037 bool bSaveUndoEdit = IsUndoEditMode(); 2038 sal_uInt16 nId; 2039 //if the undo edit mode is active then undo all changes until the UNDO_EDIT_MODE action has been found 2040 do 2041 { 2042 nId = rUndoMgr.GetUndoActionId(); 2043 rUndoMgr.Undo(); 2044 }while(bSaveUndoEdit && SPELLUNDO_UNDO_EDIT_MODE != nId && GetUndoActionCount()); 2045 2046 if(bSaveUndoEdit || SPELLUNDO_CHANGE_GROUP == nId) 2047 GetSpellDialog()->UpdateBoxes_Impl(); 2048 } 2049 /*-- 06.11.2003 11:30:10--------------------------------------------------- 2050 2051 -----------------------------------------------------------------------*/ 2052 void SentenceEditWindow_Impl::ResetUndo() 2053 { 2054 GetTextEngine()->ResetUndo(); 2055 } 2056 /*-- 06.11.2003 12:30:41--------------------------------------------------- 2057 2058 -----------------------------------------------------------------------*/ 2059 void SentenceEditWindow_Impl::AddUndoAction( SfxUndoAction *pAction, sal_Bool bTryMerg ) 2060 { 2061 ::svl::IUndoManager& rUndoMgr = GetTextEngine()->GetUndoManager(); 2062 rUndoMgr.AddUndoAction(pAction, bTryMerg); 2063 GetSpellDialog()->aUndoPB.Enable(); 2064 } 2065 /*-- 06.11.2003 12:38:44--------------------------------------------------- 2066 2067 -----------------------------------------------------------------------*/ 2068 sal_uInt16 SentenceEditWindow_Impl::GetUndoActionCount() 2069 { 2070 return GetTextEngine()->GetUndoManager().GetUndoActionCount(); 2071 } 2072 2073 /*-- 12.11.2003 12:12:38--------------------------------------------------- 2074 2075 -----------------------------------------------------------------------*/ 2076 void SentenceEditWindow_Impl::UndoActionStart( sal_uInt16 nId ) 2077 { 2078 GetTextEngine()->UndoActionStart(nId); 2079 } 2080 /*-- 12.11.2003 12:12:38--------------------------------------------------- 2081 2082 -----------------------------------------------------------------------*/ 2083 void SentenceEditWindow_Impl::UndoActionEnd() 2084 { 2085 GetTextEngine()->UndoActionEnd(); 2086 } 2087 /*-- 12.11.2003 12:12:38--------------------------------------------------- 2088 2089 -----------------------------------------------------------------------*/ 2090 void SentenceEditWindow_Impl::MoveErrorEnd(long nOffset) 2091 { 2092 if(nOffset > 0) 2093 m_nErrorEnd = m_nErrorEnd - (sal_uInt16)nOffset; 2094 else 2095 m_nErrorEnd = m_nErrorEnd -(sal_uInt16)- nOffset; 2096 } 2097 /*-- 13.11.2003 15:15:19--------------------------------------------------- 2098 2099 -----------------------------------------------------------------------*/ 2100 void SentenceEditWindow_Impl::SetUndoEditMode(bool bSet) 2101 { 2102 DBG_ASSERT(!bSet || m_bIsUndoEditMode != bSet, "SetUndoEditMode with equal values?"); 2103 m_bIsUndoEditMode = bSet; 2104 //disable all buttons except the Change 2105 SpellDialog* pSpellDialog = GetSpellDialog(); 2106 Control* aControls[] = 2107 { 2108 &pSpellDialog->aChangeAllPB, 2109 &pSpellDialog->aExplainPB, 2110 &pSpellDialog->aIgnoreAllPB, 2111 &pSpellDialog->aIgnoreRulePB, 2112 &pSpellDialog->aIgnorePB, 2113 &pSpellDialog->aSuggestionLB, 2114 &pSpellDialog->aSuggestionFT, 2115 &pSpellDialog->aLanguageFT, 2116 &pSpellDialog->aLanguageLB, 2117 &pSpellDialog->aAddToDictMB, 2118 &pSpellDialog->aAutoCorrPB, 2119 0 2120 }; 2121 sal_Int32 nIdx = 0; 2122 do 2123 { 2124 aControls[nIdx]->Enable(sal_False); 2125 } 2126 while(aControls[++nIdx]); 2127 2128 //remove error marks 2129 TextEngine* pTextEngine = GetTextEngine(); 2130 pTextEngine->RemoveAttribs( 0, (sal_uInt16)TEXTATTR_FONTCOLOR, sal_True ); 2131 pTextEngine->RemoveAttribs( 0, (sal_uInt16)TEXTATTR_FONTWEIGHT, sal_True ); 2132 2133 //put the appropriate action on the Undo-stack 2134 SpellUndoAction_Impl* pAction = new SpellUndoAction_Impl( 2135 SPELLUNDO_UNDO_EDIT_MODE, GetSpellDialog()->aDialogUndoLink); 2136 AddUndoAction(pAction); 2137 pSpellDialog->aChangePB.Enable(); 2138 } 2139 2140 /*-- 30.06.2008 14:15:19--------------------------------------------------- 2141 2142 -----------------------------------------------------------------------*/ 2143 ExplainButton::~ExplainButton() 2144 { 2145 } 2146 /*-- 30.06.2008 14:15:19--------------------------------------------------- 2147 2148 -----------------------------------------------------------------------*/ 2149 void ExplainButton::RequestHelp( const HelpEvent& ) 2150 { 2151 Help::ShowBalloon( this, GetPosPixel(), m_sExplanation ); 2152 } 2153 2154 void ExplainButton::Click() 2155 { 2156 RequestHelp( HelpEvent() ); 2157 } 2158