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