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:
SpellUndoAction_Impl(sal_uInt16 nId,const Link & rActionLink)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
SetEnableChangePB()138 void SetEnableChangePB(){m_bEnableChangePB = true;}
IsEnableChangePB()139 bool IsEnableChangePB(){return m_bEnableChangePB;}
140
SetEnableChangeAllPB()141 void SetEnableChangeAllPB(){m_bEnableChangeAllPB = true;}
IsEnableChangeAllPB()142 bool IsEnableChangeAllPB(){return m_bEnableChangeAllPB;}
143
SetErrorMove(long nNewStart,long nNewEnd,long nOldStart,long nOldEnd)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 }
GetNewErrorStart()151 long GetNewErrorStart() { return m_nNewErrorStart;}
GetNewErrorEnd()152 long GetNewErrorEnd() { return m_nNewErrorEnd;}
GetOldErrorStart()153 long GetOldErrorStart() { return m_nOldErrorStart;}
GetOldErrorEnd()154 long GetOldErrorEnd() { return m_nOldErrorEnd;}
155
SetErrorLanguageSelected(bool bSet)156 void SetErrorLanguageSelected(bool bSet){ m_bIsErrorLanguageSelected = bSet;}
IsErrorLanguageSelected() const157 bool IsErrorLanguageSelected() const {return m_bIsErrorLanguageSelected;}
158
159
SetDictionary(Reference<XDictionary> xDict)160 void SetDictionary(Reference<XDictionary> xDict) { m_xDictionary = xDict; }
GetDictionary() const161 Reference<XDictionary> GetDictionary() const {return m_xDictionary;}
SetAddedWord(const::rtl::OUString & rWord)162 void SetAddedWord(const ::rtl::OUString& rWord) {m_sAddedWord = rWord;}
GetAddedWord() const163 const ::rtl::OUString& GetAddedWord() const { return m_sAddedWord;}
164
SetOffset(long nSet)165 void SetOffset(long nSet) {m_nOffset = nSet;}
GetOffset() const166 long GetOffset() const {return m_nOffset;}
167
SetErrorType(const::rtl::OUString & rId)168 void SetErrorType( const ::rtl::OUString& rId ) { m_sRuleId = rId; }
GetErrorType() const169 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 -----------------------------------------------------------------------*/
~SpellUndoAction_Impl()177 SpellUndoAction_Impl::~SpellUndoAction_Impl()
178 {
179 }
180 /*-- 06.11.2003 12:16:02---------------------------------------------------
181
182 -----------------------------------------------------------------------*/
Undo()183 void SpellUndoAction_Impl::Undo()
184 {
185 m_rActionLink.Call(this);
186 }
187 /*-- 06.11.2003 12:16:02---------------------------------------------------
188
189 -----------------------------------------------------------------------*/
GetId() const190 sal_uInt16 SpellUndoAction_Impl::GetId()const
191 {
192 return m_nId;
193 }
194
195 // class SvxSpellCheckDialog ---------------------------------------------
196
SpellDialog(SpellDialogChildWindow * pChildWindow,Window * pParent,SfxBindings * _pBindings)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
260 aAddToDictMB.SetPopupMenu( new PopupMenu );
261
262 Init_Impl();
263
264 // disable controls if service is missing
265 if (!xSpell.is())
266 Enable( sal_False );
267
268 Application::PostUserEvent( STATIC_LINK(
269 this, SpellDialog, InitHdl ) );
270 }
271
272 // -----------------------------------------------------------------------
273
~SpellDialog()274 SpellDialog::~SpellDialog()
275 {
276 // save possibly modified user-dictionaries
277 Reference< XDictionaryList > xDicList( SvxGetDictionaryList() );
278 if (xDicList.is())
279 {
280 linguistic::SaveDictionaries( xDicList );
281 }
282
283 delete aAddToDictMB.GetPopupMenu();
284 delete pImpl;
285 }
286
287 // -----------------------------------------------------------------------
288
Init_Impl()289 void SpellDialog::Init_Impl()
290 {
291 // Handler initialisieren
292 aClosePB.SetClickHdl(LINK( this, SpellDialog, CancelHdl ) );
293 aChangePB.SetClickHdl(LINK( this, SpellDialog, ChangeHdl ) );
294 aChangeAllPB.SetClickHdl(LINK( this, SpellDialog, ChangeAllHdl ) );
295 aIgnorePB.SetClickHdl(LINK( this, SpellDialog, IgnoreHdl ) );
296 aIgnoreAllPB.SetClickHdl(LINK( this, SpellDialog, IgnoreAllHdl ) );
297 aIgnoreRulePB.SetClickHdl(LINK( this, SpellDialog, IgnoreAllHdl ) );
298 aUndoPB.SetClickHdl(LINK( this, SpellDialog, UndoHdl ) );
299
300 aAutoCorrPB.SetClickHdl( LINK( this, SpellDialog, ExtClickHdl ) );
301 aCheckGrammarCB.SetClickHdl( LINK( this, SpellDialog, CheckGrammarHdl ));
302 aOptionsPB .SetClickHdl( LINK( this, SpellDialog, ExtClickHdl ) );
303
304 aSuggestionLB.SetDoubleClickHdl( LINK( this, SpellDialog, ChangeHdl ) );
305
306 aSentenceED.SetModifyHdl(LINK ( this, SpellDialog, ModifyHdl) );
307 aAddToDictMB.SetActivateHdl(LINK ( this, SpellDialog, MenuButtonActivateHdl ) );
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 aSentenceED.ClearModifyFlag();
318 SvxGetChangeAllList()->clear();
319 }
320
321 // -----------------------------------------------------------------------
322
UpdateBoxes_Impl()323 void SpellDialog::UpdateBoxes_Impl()
324 {
325 sal_Int32 i;
326 aSuggestionLB.Clear();
327
328 const SpellErrorDescription* pSpellErrorDescription = aSentenceED.GetAlternatives();
329
330 LanguageType nAltLanguage = LANGUAGE_NONE;
331 //String aAltWord;
332 Sequence< ::rtl::OUString > aNewWords;
333 bool bIsGrammarError = false;
334 if( pSpellErrorDescription )
335 {
336 nAltLanguage = SvxLocaleToLanguage( pSpellErrorDescription->aLocale );
337 //aAltWord = String( xAlt->getWord() );
338 aNewWords = pSpellErrorDescription->aSuggestions;
339 bIsGrammarError = pSpellErrorDescription->bIsGrammarError;
340 aExplainPB.SetExplanation(pSpellErrorDescription->sExplanation );
341 }
342 if( pSpellErrorDescription && pSpellErrorDescription->sDialogTitle.getLength() )
343 {
344 // use this function to apply the correct image to be used...
345 SetTitle_Impl( nAltLanguage );
346 // then change the title to the one to be actually used
347 SetText( pSpellErrorDescription->sDialogTitle );
348 }
349 else
350 SetTitle_Impl( nAltLanguage );
351
352 SetSelectedLang_Impl( nAltLanguage );
353
354 // Initialize/update user dictionaries after setting the language in the listbox
355 InitUserDicts();
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
SpellContinue_Impl(bool bUseSavedSentence,bool bIgnoreCurrentError)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 initially 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 virtual calls
435 from a constructor
436 --------------------------------------------------*/
IMPL_STATIC_LINK(SpellDialog,InitHdl,SpellDialog *,EMPTYARG)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
IMPL_LINK(SpellDialog,ExtClickHdl,Button *,pBtn)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 // -----------------------------------------------------------------------
IMPL_LINK(SpellDialog,CheckGrammarHdl,CheckBox *,pBox)573 IMPL_LINK( SpellDialog, CheckGrammarHdl, CheckBox*, pBox )
574 {
575 rParent.SetGrammarChecking( pBox->IsChecked() );
576 Impl_Restore();
577 return 0;
578 }
579
StartSpellOptDlg_Impl()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
IMPL_LINK(SpellDialog,ChangeHdl,Button *,EMPTYARG)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
IMPL_LINK(SpellDialog,ChangeAllHdl,Button *,EMPTYARG)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
IMPL_LINK(SpellDialog,IgnoreAllHdl,Button *,pButton)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 -----------------------------------------------------------------------*/
IMPL_LINK(SpellDialog,UndoHdl,Button *,EMPTYARG)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 -----------------------------------------------------------------------*/
IMPL_LINK(SpellDialog,DialogUndoHdl,SpellUndoAction_Impl *,pAction)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 // -----------------------------------------------------------------------
Impl_Restore()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(true);
791 aIgnorePB.SetText(aIgnoreOnceST);
792 }
793
IMPL_LINK(SpellDialog,IgnoreHdl,Button *,EMPTYARG)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
Close()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
SetSelectedLang_Impl(LanguageType nLang)824 void SpellDialog::SetSelectedLang_Impl( LanguageType nLang )
825 {
826 aLanguageLB.SelectLanguage( nLang );
827 }
828
829 // -----------------------------------------------------------------------
830
GetSelectedLang_Impl() const831 LanguageType SpellDialog::GetSelectedLang_Impl() const
832 {
833 sal_Int16 nLang = aLanguageLB.GetSelectLanguage();
834 return nLang;
835 }
836 /* -----------------28.10.2003 14:27-----------------
837
838 --------------------------------------------------*/
IMPL_LINK(SpellDialog,LanguageSelectHdl,SvxLanguageBox *,pBox)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
861 // Update listboxes and user dictionaries when selected language changes
862 SpellDialog::UpdateBoxes_Impl();
863 return 0;
864 }
865 // -----------------------------------------------------------------------
866
SetLanguage(sal_uInt16 nLang)867 void SpellDialog::SetLanguage( sal_uInt16 nLang )
868
869 /* [Beschreibung]
870
871 wenn die Sprache im Thesaurus umgestellt wurde,
872 muss auch hier die Sprache umgestellt werden.
873 */
874
875 {
876 SetTitle_Impl( nLang );
877
878 // den richtigen Eintrag finden, da sortiert
879 aLanguageLB.SelectLanguage( nLang );
880 }
881 /*-- 16.06.2008 11:27:02---------------------------------------------------
882
883 -----------------------------------------------------------------------*/
lcl_GetImageFromPngUrl(const::rtl::OUString & rFileUrl)884 static Image lcl_GetImageFromPngUrl( const ::rtl::OUString &rFileUrl )
885 {
886 Image aRes;
887 ::rtl::OUString aTmp;
888 osl::FileBase::getSystemPathFromFileURL( rFileUrl, aTmp );
889 Graphic aGraphic;
890 const String aFilterName( RTL_CONSTASCII_USTRINGPARAM( IMP_PNG ) );
891 if( GRFILTER_OK == GraphicFilter::LoadGraphic( aTmp, aFilterName, aGraphic ) )
892 {
893 aRes = Image( aGraphic.GetBitmapEx() );
894 }
895 return aRes;
896 }
SetTitle_Impl(LanguageType nLang)897 void SpellDialog::SetTitle_Impl(LanguageType nLang)
898 {
899 String sTitle( m_sTitleSpelling );
900 if( rParent.HasGrammarChecking() )
901 {
902 String sVendor;
903 const SpellErrorDescription* pSpellErrorDescription = aSentenceED.GetAlternatives();
904 if( pSpellErrorDescription && pSpellErrorDescription->sServiceName.getLength() )
905 {
906 bool bHighContrast = GetSettings().GetStyleSettings().GetHighContrastMode();
907 ::rtl::OUString sSuggestionImageUrl =
908 SvtLinguConfig().GetSpellAndGrammarDialogImage( pSpellErrorDescription->sServiceName, bHighContrast );
909 aVendorImageFI.SetImage( lcl_GetImageFromPngUrl( sSuggestionImageUrl ) );
910 uno::Reference< lang::XServiceDisplayName > xDisplayName( pSpellErrorDescription->xGrammarChecker, uno::UNO_QUERY );
911 if( xDisplayName.is() )
912 sVendor = xDisplayName->getServiceDisplayName( pSpellErrorDescription->aLocale );
913 }
914 else
915 {
916 bool bHighContrast = GetSettings().GetStyleSettings().GetHighContrastMode();
917 aVendorImageFI.SetImage( bHighContrast ? aVendorImageHC : aVendorImage );
918 }
919
920 if( sVendor.Len() )
921 {
922 sTitle = m_sTitleSpellingGrammarVendor;
923 sTitle.SearchAndReplaceAscii( "$VendorName", sVendor );
924 }
925 else
926 {
927 //bool bHighContrast = GetSettings().GetStyleSettings().GetHighContrastMode();
928 sTitle = m_sTitleSpellingGrammar;
929 }
930 }
931 sTitle.SearchAndReplaceAscii( "$LANGUAGE ($LOCATION)", SvtLanguageTable::GetLanguageString(nLang) );
932 SetText( sTitle );
933 }
934 /*-------------------------------------------------------------------------
935
936 -----------------------------------------------------------------------*/
InitUserDicts()937 void SpellDialog::InitUserDicts()
938 {
939 bool bEnable = false;
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 one 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 // this is redundant, there will always be *at least* one dictionary
955 bEnable = pImpl->aDics.getLength();
956 }
957
958 aAddToDictMB.Enable( bEnable );
959 }
960
961 IMPL_LINK(SpellDialog, MenuButtonActivateHdl, MenuButton*, )
962 {
963 bool bEnable = false;
964 const LanguageType nLang = aLanguageLB.GetSelectLanguage();
965 const Reference< XDictionary > *pDic = 0;
966
967 SvtLinguConfig aCfg;
968 const bool bHC = Application::GetSettings().GetStyleSettings().GetHighContrastMode();
969
970 // list suitable dictionaries
971 const sal_Int32 nSize = pImpl->aDics.getLength();
972 pDic = pImpl->aDics.getConstArray();
973
974 PopupMenu* pMenu = aAddToDictMB.GetPopupMenu();
975 OSL_ENSURE( pMenu, "svx::SpellDialog::MenuButtonActivateHdl - no PopupMenu!" );
976 pMenu->Clear();
977 pMenu->SetMenuFlags(MENU_FLAG_NOAUTOMNEMONICS);
978
979 sal_uInt16 nItemId = 1; // menu items should be enumerated from 1 and not 0
980 for (sal_Int32 i = 0; i < nSize; ++i)
981 {
982 uno::Reference< linguistic2::XDictionary > xDicTmp( pDic[i], uno::UNO_QUERY );
983 if (!xDicTmp.is() || SvxGetIgnoreAllList() == xDicTmp)
984 continue;
985
986 uno::Reference< frame::XStorable > xStor( xDicTmp, uno::UNO_QUERY );
987 LanguageType nActLanguage = SvxLocaleToLanguage( xDicTmp->getLocale() );
988 if( xDicTmp->isActive()
989 && xDicTmp->getDictionaryType() != linguistic2::DictionaryType_NEGATIVE
990 && (nLang == nActLanguage || LANGUAGE_NONE == nActLanguage )
991 && (!xStor.is() || !xStor->isReadonly()) )
992 {
993 pMenu->InsertItem( nItemId, xDicTmp->getName() );
994 bEnable = sal_True;
995
996 uno::Reference< lang::XServiceInfo > xSvcInfo( xDicTmp, uno::UNO_QUERY );
997 if (xSvcInfo.is())
998 {
999 OUString aDictionaryImageUrl( aCfg.GetSpellAndGrammarContextDictionaryImage(
1000 xSvcInfo->getImplementationName(), bHC) );
1001 if (aDictionaryImageUrl.getLength() > 0)
1002 {
1003 Image aImage( lcl_GetImageFromPngUrl( aDictionaryImageUrl ) );
1004 pMenu->SetItemImage( nItemId, aImage );
1005 }
1006 }
1007
1008 ++nItemId;
1009 }
1010 }
1011
1012 aAddToDictMB.Enable( bEnable );
1013
1014 return 0;
1015 }
1016
1017 /*-- 20.10.2003 15:31:06---------------------------------------------------
1018
1019 -----------------------------------------------------------------------*/
IMPL_LINK(SpellDialog,AddToDictionaryHdl,MenuButton *,pButton)1020 IMPL_LINK(SpellDialog, AddToDictionaryHdl, MenuButton*, pButton )
1021 {
1022 aSentenceED.UndoActionStart( SPELLUNDO_CHANGE_GROUP );
1023
1024 //GetErrorText() returns the current error even if the text is already
1025 //manually changed
1026 const String aNewWord= aSentenceED.GetErrorText();
1027
1028 sal_uInt16 nItemId = pButton->GetCurItemId();
1029 PopupMenu *pMenu = pButton->GetPopupMenu();
1030 String aDicName ( pMenu->GetItemText( nItemId ) );
1031
1032 uno::Reference< linguistic2::XDictionary > xDic;
1033 uno::Reference< linguistic2::XDictionaryList > xDicList( SvxGetDictionaryList() );
1034 if (xDicList.is())
1035 xDic = xDicList->getDictionaryByName( aDicName );
1036
1037 sal_Int16 nAddRes = DIC_ERR_UNKNOWN;
1038 if (xDic.is())
1039 {
1040 nAddRes = linguistic::AddEntryToDic( xDic, aNewWord, sal_False, OUString(), LANGUAGE_NONE );
1041 // save modified user-dictionary if it is persistent
1042 uno::Reference< frame::XStorable > xSavDic( xDic, uno::UNO_QUERY );
1043 if (xSavDic.is())
1044 xSavDic->store();
1045
1046 if (nAddRes == DIC_ERR_NONE)
1047 {
1048 SpellUndoAction_Impl* pAction = new SpellUndoAction_Impl(
1049 SPELLUNDO_CHANGE_ADD_TO_DICTIONARY, aDialogUndoLink);
1050 pAction->SetDictionary( xDic );
1051 pAction->SetAddedWord( aNewWord );
1052 aSentenceED.AddUndoAction( pAction );
1053 }
1054 // failed because there is already an entry?
1055 if (DIC_ERR_NONE != nAddRes && xDic->getEntry( aNewWord ).is())
1056 nAddRes = DIC_ERR_NONE;
1057 }
1058 if (DIC_ERR_NONE != nAddRes)
1059 {
1060 SvxDicError( this, nAddRes );
1061 return 0; // Nicht weitermachen
1062 }
1063
1064 // go on
1065 SpellContinue_Impl();
1066 aSentenceED.UndoActionEnd();
1067 return 0;
1068 }
1069 /*-------------------------------------------------------------------------
1070
1071 -----------------------------------------------------------------------*/
IMPL_LINK(SpellDialog,ModifyHdl,SentenceEditWindow_Impl *,pEd)1072 IMPL_LINK(SpellDialog, ModifyHdl, SentenceEditWindow_Impl*, pEd)
1073 {
1074 if (&aSentenceED == pEd)
1075 {
1076 bModified = true;
1077 aSuggestionLB.SetNoSelection();
1078 aSuggestionLB.Disable();
1079 String sNewText( aSentenceED.GetText() );
1080 aAutoCorrPB.Enable( sNewText != aSentenceED.GetText() );
1081 SpellUndoAction_Impl* pSpellAction = new SpellUndoAction_Impl(SPELLUNDO_CHANGE_TEXTENGINE, aDialogUndoLink);
1082 if(!aChangeAllPB.IsEnabled())
1083 {
1084 aChangeAllPB.Enable();
1085 pSpellAction->SetEnableChangeAllPB();
1086 }
1087 if(!aChangePB.IsEnabled())
1088 {
1089 aChangePB.Enable();
1090 pSpellAction->SetEnableChangePB();
1091 }
1092 aSentenceED.AddUndoAction(pSpellAction);
1093 }
1094 return 0;
1095 };
1096 /*-------------------------------------------------------------------------
1097
1098 -----------------------------------------------------------------------*/
IMPL_LINK(SpellDialog,CancelHdl,Button *,EMPTYARG)1099 IMPL_LINK(SpellDialog, CancelHdl, Button *, EMPTYARG )
1100 {
1101 //apply changes and ignored text parts first - if there are any
1102 rParent.ApplyChangedSentence(aSentenceED.CreateSpellPortions(true), false);
1103 Close();
1104 return 0;
1105 }
1106 /*-------------------------------------------------------------------------
1107
1108 -----------------------------------------------------------------------*/
Paint(const Rectangle & rRect)1109 void SpellDialog::Paint( const Rectangle& rRect )
1110 {
1111 ModelessDialog::Paint(rRect );
1112 Rectangle aRect(aBackgroundGB.GetPosPixel(), aBackgroundGB.GetSizePixel());
1113 DecorationView aDecoView( this );
1114 aDecoView.DrawButton( aRect, BUTTON_DRAW_NOFILL);
1115 }
1116 /*-- 28.10.2003 13:26:39---------------------------------------------------
1117
1118 -----------------------------------------------------------------------*/
Notify(NotifyEvent & rNEvt)1119 long SpellDialog::Notify( NotifyEvent& rNEvt )
1120 {
1121 /* #i38338#
1122 * FIXME: LoseFocus and GetFocus are signals from vcl that
1123 * a window actually got/lost the focus, it never should be
1124 * forwarded from another window, that is simply wrong.
1125 * FIXME: overloading the virtual methods GetFocus and LoseFocus
1126 * in SpellDialogChildWindow by making them pure is at least questionable.
1127 * The only sensible thing would be to call the new Method differently,
1128 * e.g. DialogGot/LostFocus or so.
1129 */
1130 if( IsVisible() && !bFocusLocked )
1131 {
1132 if( rNEvt.GetType() == EVENT_GETFOCUS )
1133 {
1134 //notify the child window of the focus change
1135 rParent.GetFocus();
1136 }
1137 else if( rNEvt.GetType() == EVENT_LOSEFOCUS )
1138 {
1139 //notify the child window of the focus change
1140 rParent.LoseFocus();
1141 }
1142 }
1143 return SfxModelessDialog::Notify(rNEvt);
1144 }
1145 /* -----------------10.09.2003 08:26-----------------
1146
1147 --------------------------------------------------*/
InvalidateDialog()1148 void SpellDialog::InvalidateDialog()
1149 {
1150 if( bFocusLocked )
1151 return;
1152 aIgnorePB.SetText(aResumeST);
1153 Window* aDisableArr[] =
1154 {
1155 &aNotInDictFT,
1156 &aSentenceED,
1157 &aSuggestionFT,
1158 &aSuggestionLB,
1159 &aLanguageFT,
1160 &aLanguageLB,
1161 &aIgnoreAllPB,
1162 &aIgnoreRulePB,
1163 &aAddToDictMB,
1164 &aChangePB,
1165 &aChangeAllPB,
1166 &aAutoCorrPB,
1167 &aUndoPB,
1168 0
1169 };
1170 sal_Int16 i = 0;
1171 while(aDisableArr[i])
1172 {
1173 aDisableArr[i]->Enable(sal_False);
1174 i++;
1175 }
1176 SfxModelessDialog::Deactivate();
1177 }
1178
1179 /*-- 10.09.2003 08:35:56---------------------------------------------------
1180
1181 -----------------------------------------------------------------------*/
GetNextSentence_Impl(bool bUseSavedSentence,bool bRecheck)1182 bool SpellDialog::GetNextSentence_Impl(bool bUseSavedSentence, bool bRecheck)
1183 {
1184 bool bRet = false;
1185 if(!bUseSavedSentence /*&& aSentenceED.IsModified()*/)
1186 {
1187 //apply changes and ignored text parts
1188 rParent.ApplyChangedSentence(aSentenceED.CreateSpellPortions(true), bRecheck);
1189 }
1190 aSentenceED.ResetIgnoreErrorsAt();
1191 aSentenceED.ResetModified();
1192 SpellPortions aSentence = bUseSavedSentence ? m_aSavedSentence : rParent.GetNextWrongSentence( bRecheck );
1193 if(!bUseSavedSentence)
1194 m_aSavedSentence = aSentence;
1195 bool bHasReplaced = false;
1196 while(aSentence.size())
1197 {
1198 //apply all changes that are already part of the "ChangeAllList"
1199 //returns true if the list still contains errors after the changes have been applied
1200
1201 if(!ApplyChangeAllList_Impl(aSentence, bHasReplaced))
1202 {
1203 rParent.ApplyChangedSentence(aSentence, bRecheck);
1204 aSentence = rParent.GetNextWrongSentence( bRecheck );
1205 }
1206 else
1207 break;
1208 }
1209
1210 if(aSentence.size())
1211 {
1212 SpellPortions::iterator aStart = aSentence.begin();
1213 rtl::OUString sText;
1214 while(aStart != aSentence.end())
1215 {
1216 // hidden text has to be ignored
1217 if(!aStart->bIsHidden)
1218 sText += aStart->sText;
1219 aStart++;
1220 }
1221 aSentenceED.SetText(sText);
1222 aStart = aSentence.begin();
1223 sal_Int32 nStartPosition = 0;
1224 sal_Int32 nEndPosition = 0;
1225
1226 while(aStart != aSentence.end())
1227 {
1228 // hidden text has to be ignored
1229 if(!aStart->bIsHidden)
1230 {
1231 nEndPosition += aStart->sText.getLength();
1232 if(aStart->xAlternatives.is())
1233 {
1234 uno::Reference< container::XNamed > xNamed( aStart->xAlternatives, uno::UNO_QUERY );
1235 ::rtl::OUString sServiceName;
1236 if( xNamed.is() )
1237 sServiceName = xNamed->getName();
1238 SpellErrorDescription aDesc( false, aStart->xAlternatives->getWord(),
1239 aStart->xAlternatives->getLocale(), aStart->xAlternatives->getAlternatives(), 0, sServiceName);
1240 aSentenceED.SetAttrib( SpellErrorAttrib(aDesc), 0, (sal_uInt16) nStartPosition, (sal_uInt16) nEndPosition );
1241 }
1242 else if(aStart->bIsGrammarError )
1243 {
1244 uno::Reference< lang::XServiceInfo > xInfo( aStart->xGrammarChecker, uno::UNO_QUERY );
1245 SpellErrorDescription aDesc( true,
1246 aStart->sText,
1247 SvxCreateLocale( aStart->eLanguage ),
1248 aStart->aGrammarError.aSuggestions,
1249 aStart->xGrammarChecker,
1250 xInfo->getImplementationName(),
1251 &aStart->sDialogTitle,
1252 &aStart->aGrammarError.aFullComment,
1253 &aStart->aGrammarError.aRuleIdentifier );
1254 aSentenceED.SetAttrib( SpellErrorAttrib(aDesc), 0, (sal_uInt16) nStartPosition, (sal_uInt16) nEndPosition );
1255 }
1256 if(aStart->bIsField)
1257 aSentenceED.SetAttrib( SpellBackgroundAttrib(COL_LIGHTGRAY), 0, (sal_uInt16) nStartPosition, (sal_uInt16) nEndPosition );
1258 aSentenceED.SetAttrib( SpellLanguageAttrib(aStart->eLanguage), 0, (sal_uInt16) nStartPosition, (sal_uInt16) nEndPosition );
1259 nStartPosition = nEndPosition;
1260 }
1261 aStart++;
1262 }
1263 //the edit field needs to be modified to apply the change from the ApplyChangeAllList
1264 if(!bHasReplaced)
1265 aSentenceED.ClearModifyFlag();
1266 aSentenceED.ResetUndo();
1267 aUndoPB.Enable(sal_False);
1268 bRet = nStartPosition > 0;
1269 }
1270 return bRet;
1271 }
1272 /*-- 12.11.2003 15:21:25---------------------------------------------------
1273 replace errors that have a replacement in the ChangeAllList
1274 returns false if the result doesn't contain errors after the replacement
1275 -----------------------------------------------------------------------*/
ApplyChangeAllList_Impl(SpellPortions & rSentence,bool & bHasReplaced)1276 bool SpellDialog::ApplyChangeAllList_Impl(SpellPortions& rSentence, bool &bHasReplaced)
1277 {
1278 bHasReplaced = false;
1279 bool bRet = true;
1280 SpellPortions::iterator aStart = rSentence.begin();
1281 Reference<XDictionary> xChangeAll( SvxGetChangeAllList(), UNO_QUERY );
1282 if(!xChangeAll->getCount())
1283 return bRet;
1284 bRet = false;
1285 while(aStart != rSentence.end())
1286 {
1287 if(aStart->xAlternatives.is())
1288 {
1289 Reference<XDictionaryEntry> xEntry = xChangeAll->getEntry( aStart->sText );
1290 if(xEntry.is())
1291 {
1292 aStart->sText = xEntry->getReplacementText();
1293 aStart->xAlternatives = 0;
1294 bHasReplaced = true;
1295 }
1296 else
1297 bRet = true;
1298 }
1299 else if( aStart->bIsGrammarError )
1300 bRet = true;
1301 aStart++;
1302 }
1303 return bRet;
1304 }
1305 /*-- 10.09.2003 10:40:21---------------------------------------------------
1306
1307 -----------------------------------------------------------------------*/
SentenceEditWindow_Impl(SpellDialog * pParent,const ResId & rResId)1308 SentenceEditWindow_Impl::SentenceEditWindow_Impl( SpellDialog* pParent, const ResId& rResId ) :
1309 MultiLineEdit( pParent, rResId ),
1310 m_nErrorStart(0),
1311 m_nErrorEnd(0),
1312 m_bIsUndoEditMode(false)
1313 {
1314 DisableSelectionOnFocus();
1315 }
1316 /*-- 10.09.2003 10:40:11---------------------------------------------------
1317
1318 -----------------------------------------------------------------------*/
~SentenceEditWindow_Impl()1319 SentenceEditWindow_Impl::~SentenceEditWindow_Impl()
1320 {
1321 }
1322 /*-- 20.10.2003 13:42:34---------------------------------------------------
1323 The selection before inputting a key may have a range or not
1324 and it may be inside or outside of field or error attributes.
1325 A range may include the attribute partially, completely or together
1326 with surrounding text. It may also contain more than one attribute
1327 or no attribute at all.
1328 Depending on this starting conditions some actions are necessary:
1329 Attempts to delete a field are only allowed if the selection is the same
1330 as the field's selection. Otherwise the field has to be selected and the key
1331 input action has to be skipped.
1332 Input of text at the start of the field requires the field attribute to be
1333 corrected - it is not allowed to grow.
1334
1335 In case of errors the appending of text should grow the error attribute because
1336 that is what the user usually wants to do.
1337
1338 Backspace at the start of the attribute requires to find out if a field ends
1339 directly in front of the cursor position. In case of a field this attribute has to be
1340 selected otherwise the key input method is allowed.
1341
1342 All changes outside of the error attributes switch the dialog mode to a "Undo edit" state that
1343 removes all visible attributes and switches off further attribute checks.
1344 Undo in this restarts the dialog with a current sentence newly presented.
1345 All changes to the sentence are undone including the ones before the "Undo edit state" has been reached
1346
1347 We end up with 9 types of selection
1348 1 (LEFT_NO) - no range, start of attribute - can also be 3 at the same time
1349 2 (INSIDE_NO) - no range, inside of attribute
1350 3 (RIGHT_NO) - no range, end of attribute - can also be 1 at the same time
1351 4 (FULL) - range, same as attribute
1352 5 (INSIDE_YES) - range, inside of the attribute
1353 6 (BRACE)- range, from outside of the attribute to the inside or
1354 including the complete attribute and something outside,
1355 maybe more than one attribute
1356 7 (OUTSIDE_NO) - no range, not at an attribute
1357 8 (OUTSIDE_YES) - range, completely outside of all attributes
1358
1359 What has to be done depending on the attribute type involved
1360 possible actions: UE - Undo edit mode
1361 CO - Continue, no additional action is required
1362 FS - Field has to be completely selected
1363 EX - The attribute has to be expanded to include the added text
1364
1365 1 - backspace delete any other
1366 UE on field FS on error CO on field FS on error CO
1367
1368 2 - on field FS on error C
1369 3 - backspace delete any other
1370 on field FS on error CO UE on field UE on error EX
1371
1372 if 1 and 3 happen to apply both then backspace and other handling is 1 delete is 3
1373
1374 4 - on field UE and on error CO
1375 5 - on field FS and on error CO
1376 6 - on field FS and on error UE
1377 7 - UE
1378 8 - UE
1379 -----------------------------------------------------------------------*/
1380 #define INVALID 0
1381 #define LEFT_NO 1
1382 #define INSIDE_NO 2
1383 #define RIGHT_NO 3
1384 #define FULL 4
1385 #define INSIDE_YES 5
1386 #define BRACE 6
1387 #define OUTSIDE_NO 7
1388 #define OUTSIDE_YES 8
1389
1390 #define ACTION_UNDOEDIT 0
1391 #define ACTION_CONTINUE 1
1392 #define ACTION_SELECTFIELD 2
1393 #define ACTION_EXPAND 3
1394
PreNotify(NotifyEvent & rNEvt)1395 long SentenceEditWindow_Impl::PreNotify( NotifyEvent& rNEvt )
1396 {
1397 bool bChange = false;
1398 const TextCharAttrib* pErrorAttrib = 0;
1399 if(rNEvt.GetType() == EVENT_KEYINPUT)
1400 {
1401 const KeyEvent& rKeyEvt = *rNEvt.GetKeyEvent();
1402 bChange = TextEngine::DoesKeyChangeText( rKeyEvt );
1403 if(bChange && !IsUndoEditMode() &&
1404 rKeyEvt.GetKeyCode().GetCode() != KEY_TAB)
1405 {
1406 TextEngine* pTextEngine = GetTextEngine();
1407 TextView* pTextView = pTextEngine->GetActiveView();
1408 const TextSelection& rCurrentSelection = pTextView->GetSelection();
1409 //determine if the selection contains a field
1410 bool bHasField = false;
1411 bool bHasError = false;
1412 bool bHasFieldLeft = false;
1413 bool bHasErrorLeft = false;
1414 // bool bInsideAttr = false;
1415
1416 bool bHasRange = rCurrentSelection.HasRange();
1417 sal_uInt8 nSelectionType = 0; // invalid type!
1418
1419 TextPaM aCursor(rCurrentSelection.GetStart());
1420 const TextCharAttrib* pBackAttr = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_BACKGROUND );
1421 const TextCharAttrib* pErrorAttr = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_ERROR );
1422 const TextCharAttrib* pBackAttrLeft = 0;
1423 const TextCharAttrib* pErrorAttrLeft = 0;
1424
1425 bHasField = pBackAttr != 0 && (bHasRange || pBackAttr->GetEnd() > aCursor.GetIndex());
1426 bHasError = pErrorAttr != 0 && (bHasRange || pErrorAttr->GetEnd() > aCursor.GetIndex());
1427 if(bHasRange)
1428 {
1429 if(pBackAttr &&
1430 pBackAttr->GetStart() == rCurrentSelection.GetStart().GetIndex() &&
1431 pBackAttr->GetEnd() == rCurrentSelection.GetEnd().GetIndex())
1432 {
1433 nSelectionType = FULL;
1434 }
1435 else if(pErrorAttr &&
1436 pErrorAttr->GetStart() <= rCurrentSelection.GetStart().GetIndex() &&
1437 pErrorAttr->GetEnd() >= rCurrentSelection.GetEnd().GetIndex())
1438 {
1439 nSelectionType = INSIDE_YES;
1440 }
1441 else
1442 {
1443 nSelectionType = bHasField||bHasError ? BRACE : OUTSIDE_NO;
1444 while(aCursor.GetIndex() < rCurrentSelection.GetEnd().GetIndex())
1445 {
1446 ++aCursor.GetIndex();
1447 const TextCharAttrib* pIntBackAttr = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_BACKGROUND );
1448 const TextCharAttrib* pIntErrorAttr = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_ERROR );
1449 //if any attr has been found then BRACE
1450 if(pIntBackAttr || pIntErrorAttr)
1451 nSelectionType = BRACE;
1452 //the field has to be selected
1453 if(pIntBackAttr && !pBackAttr)
1454 pBackAttr = pIntBackAttr;
1455 bHasField |= pIntBackAttr != 0;
1456 }
1457 }
1458 }
1459 else
1460 {
1461 //no range selection: then 1 2 3 and 8 are possible
1462 const TextCharAttrib* pCurAttr = pBackAttr ? pBackAttr : pErrorAttr;
1463 if(pCurAttr)
1464 {
1465 nSelectionType = pCurAttr->GetStart() == rCurrentSelection.GetStart().GetIndex() ?
1466 LEFT_NO : pCurAttr->GetEnd() == rCurrentSelection.GetEnd().GetIndex() ? RIGHT_NO : INSIDE_NO;
1467 }
1468 else
1469 nSelectionType = OUTSIDE_NO;
1470
1471 bHasFieldLeft = pBackAttr && pBackAttr->GetEnd() == aCursor.GetIndex();
1472 if(bHasFieldLeft)
1473 {
1474 pBackAttrLeft = pBackAttr;
1475 pBackAttr = 0;
1476 }
1477 bHasErrorLeft = pErrorAttr && pErrorAttr->GetEnd() == aCursor.GetIndex();
1478 if(bHasErrorLeft)
1479 {
1480 pErrorAttrLeft = pErrorAttr;
1481 pErrorAttr = 0;
1482 }
1483
1484 //check previous position if this exists
1485 //that is a redundant in the case the attribute found above already is on the left cursor side
1486 //but it's o.k. for two errors/fields side by side
1487 if(aCursor.GetIndex())
1488 {
1489 --aCursor.GetIndex();
1490 pBackAttrLeft = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_BACKGROUND );
1491 pErrorAttrLeft = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_ERROR );
1492 bHasFieldLeft = pBackAttrLeft !=0;
1493 bHasErrorLeft = pErrorAttrLeft != 0;
1494 // bInsideAttr = (bHasField || bHasError) && (bHasFieldLeft || bHasErrorLeft);
1495 ++aCursor.GetIndex();
1496 }
1497 }
1498 //Here we have to determine if the error found is the one currently active
1499 bool bIsErrorActive = (pErrorAttr && pErrorAttr->GetStart() == m_nErrorStart) ||
1500 (pErrorAttrLeft && pErrorAttrLeft->GetStart() == m_nErrorStart);
1501
1502 DBG_ASSERT(nSelectionType != INVALID, "selection type not set!");
1503
1504 const KeyCode& rKeyCode = rKeyEvt.GetKeyCode();
1505 bool bDelete = rKeyCode.GetCode() == KEY_DELETE;
1506 bool bBackspace = rKeyCode.GetCode() == KEY_BACKSPACE;
1507
1508 sal_Int8 nAction = ACTION_CONTINUE;
1509 // nAction = ACTION_UNDOEDIT
1510 // nAction = ACTION_SELECTFIELD
1511 // nAction = ACTION_EXPAND
1512 switch(nSelectionType)
1513 {
1514 // 1 - backspace delete any other
1515 // UE on field FS on error CO on field FS on error CO
1516 case LEFT_NO :
1517 if(bBackspace)
1518 {
1519 nAction = bHasFieldLeft ? ACTION_SELECTFIELD : ACTION_UNDOEDIT;
1520 //to force the use of pBackAttrLeft
1521 pBackAttr = 0;
1522 }
1523 else if(bDelete)
1524 nAction = bHasField ? ACTION_SELECTFIELD : ACTION_CONTINUE;
1525 else
1526 nAction = bHasError && !aCursor.GetIndex() ? ACTION_CONTINUE :
1527 bHasError ? ACTION_EXPAND : bHasErrorLeft ? ACTION_CONTINUE : ACTION_UNDOEDIT;
1528 break;
1529 // 2 - on field FS on error C
1530 case INSIDE_NO :
1531 nAction = bHasField ? ACTION_SELECTFIELD :
1532 bIsErrorActive ? ACTION_CONTINUE : ACTION_UNDOEDIT;
1533 break;
1534 // 3 - backspace delete any other
1535 // on field FS on error CO UE on field UE on error EX
1536 case RIGHT_NO :
1537 if(bBackspace)
1538 nAction = bHasFieldLeft ? ACTION_SELECTFIELD : ACTION_CONTINUE;
1539 else if(bDelete)
1540 nAction = bHasFieldLeft && bHasError ? ACTION_CONTINUE : ACTION_UNDOEDIT;
1541 else
1542 nAction = bHasFieldLeft && bHasError ? ACTION_EXPAND :
1543 bHasError ? ACTION_CONTINUE : bHasErrorLeft ? ACTION_EXPAND :ACTION_UNDOEDIT;
1544 break;
1545 // 4 - on field UE and on error CO
1546 case FULL :
1547 nAction = bHasField ? ACTION_UNDOEDIT : ACTION_CONTINUE;
1548 break;
1549 // 5 - on field FS and on error CO
1550 case INSIDE_YES :
1551 nAction = bHasField ? ACTION_SELECTFIELD : ACTION_CONTINUE;
1552 break;
1553 // 6 - on field FS and on error UE
1554 case BRACE :
1555 nAction = bHasField ? ACTION_SELECTFIELD : ACTION_UNDOEDIT;;
1556 break;
1557 // 7 - UE
1558 // 8 - UE
1559 case OUTSIDE_NO :
1560 case OUTSIDE_YES:
1561 nAction = ACTION_UNDOEDIT;
1562 break;
1563 }
1564 //save the current paragraph
1565 sal_uInt16 nCurrentLen = GetText().Len();
1566 if(nAction != ACTION_SELECTFIELD)
1567 pTextView->GetWindow()->KeyInput(rKeyEvt);
1568 else
1569 {
1570 const TextCharAttrib* pCharAttr = pBackAttr ? pBackAttr : pBackAttrLeft;
1571 if(pCharAttr)
1572 {
1573 TextPaM aStart(0, pCharAttr->GetStart());
1574 TextPaM aEnd(0, pCharAttr->GetEnd());
1575 TextSelection aNewSel(aStart, aEnd);
1576 pTextView->SetSelection( aNewSel);
1577 }
1578 }
1579 if(nAction == ACTION_EXPAND)
1580 {
1581 DBG_ASSERT(pErrorAttrLeft || pErrorAttr, "where is the error");
1582 //text has been added on the right and only the 'error attribute has to be corrected
1583 if(pErrorAttrLeft)
1584 {
1585 TextAttrib* pNewError = pErrorAttrLeft->GetAttr().Clone();
1586 sal_uInt16 nStart = pErrorAttrLeft->GetStart();
1587 sal_uInt16 nEnd = pErrorAttrLeft->GetEnd();
1588 pTextEngine->RemoveAttrib( 0, *pErrorAttrLeft );
1589 SetAttrib( *pNewError, 0, nStart, ++nEnd );
1590 //only active errors move the mark
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 //text has been added on the left then the error attribute has to be expanded and the
1599 //field attribute on the right - if any - has to be contracted
1600 else if(pErrorAttr)
1601 {
1602 //determine the change
1603 sal_uInt16 nAddedChars = GetText().Len() - nCurrentLen;
1604
1605 TextAttrib* pNewError = pErrorAttr->GetAttr().Clone();
1606 sal_uInt16 nStart = pErrorAttr->GetStart();
1607 sal_uInt16 nEnd = pErrorAttr->GetEnd();
1608 pTextEngine->RemoveAttrib( 0, *pErrorAttr );
1609 nStart = nStart - (sal_uInt16)nAddedChars;
1610 SetAttrib( *pNewError, 0, nStart - nAddedChars, nEnd );
1611 //only if the error is active the mark is moved here
1612 if(bIsErrorActive)
1613 {
1614 bool bGrammar = static_cast<const SpellErrorAttrib&>(*pNewError).GetErrorDescription().bIsGrammarError;
1615 MoveErrorMarkTo(nStart, nEnd, bGrammar);
1616 }
1617 delete pNewError;
1618
1619 if(pBackAttrLeft)
1620 {
1621 TextAttrib* pNewBack = pBackAttrLeft->GetAttr().Clone();
1622 sal_uInt16 _nStart = pBackAttrLeft->GetStart();
1623 sal_uInt16 _nEnd = pBackAttrLeft->GetEnd();
1624 pTextEngine->RemoveAttrib( 0, *pBackAttrLeft );
1625 SetAttrib( *pNewBack, 0, _nStart, _nEnd - nAddedChars);
1626 delete pNewBack;
1627 }
1628 }
1629 }
1630 else if(nAction == ACTION_UNDOEDIT)
1631 {
1632 SetUndoEditMode(true);
1633 }
1634 //make sure the error positions are correct after text changes
1635 //the old attribute may have been deleted
1636 //all changes inside of the current error leave the error attribute at the current
1637 //start position
1638 if(!IsUndoEditMode() && bIsErrorActive)
1639 {
1640 const TextCharAttrib* pFontColor = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_FONTCOLOR );
1641 pErrorAttrib = pTextEngine->FindCharAttrib( TextPaM(0, m_nErrorStart), TEXTATTR_SPELL_ERROR );
1642 if(pFontColor && pErrorAttrib )
1643 {
1644 m_nErrorStart = pFontColor->GetStart();
1645 m_nErrorEnd = pFontColor->GetEnd();
1646 if(pErrorAttrib->GetStart() != m_nErrorStart || pErrorAttrib->GetEnd() != m_nErrorEnd)
1647 {
1648 TextAttrib* pNewError = pErrorAttrib->GetAttr().Clone();
1649 pTextEngine->RemoveAttrib( 0, *pErrorAttr );
1650 SetAttrib( *pNewError, 0, m_nErrorStart, m_nErrorEnd );
1651 delete pNewError;
1652 }
1653 }
1654 }
1655 //this is not a modification anymore
1656 if(nAction != ACTION_SELECTFIELD && !m_bIsUndoEditMode)
1657 CallModifyLink();
1658 }
1659 else
1660 bChange = false;
1661 }
1662 long nRet = bChange ? 1 : MultiLineEdit::PreNotify(rNEvt);
1663 return nRet;
1664 }
1665 /*-- 10.09.2003 13:38:14---------------------------------------------------
1666
1667 -----------------------------------------------------------------------*/
MarkNextError(bool bIgnoreCurrentError)1668 bool SentenceEditWindow_Impl::MarkNextError( bool bIgnoreCurrentError )
1669 {
1670 if (bIgnoreCurrentError)
1671 m_aIgnoreErrorsAt.insert( m_nErrorStart );
1672 ExtTextEngine* pTextEngine = GetTextEngine();
1673 sal_uInt16 nTextLen = pTextEngine->GetTextLen(0);
1674 if(m_nErrorEnd >= nTextLen - 1)
1675 return false;
1676 //if it's not already modified the modified flag has to be reset at the and of the marking
1677 bool bModified = IsModified();
1678 bool bRet = false;
1679 const sal_uInt16 nOldErrorStart = m_nErrorStart;
1680 const sal_uInt16 nOldErrorEnd = m_nErrorEnd;
1681
1682 //create a cursor behind the end of the last error
1683 //- or at 0 at the start of the sentence
1684 TextPaM aCursor(0, m_nErrorEnd ? m_nErrorEnd + 1 : 0);
1685 //search for SpellErrorAttrib
1686
1687 const TextCharAttrib* pNextError = 0;
1688 //iterate over the text and search for the next error that maybe has
1689 //to be replace by a ChangeAllList replacement
1690 bool bGrammarError = false;
1691 while(aCursor.GetIndex() < nTextLen)
1692 {
1693 while(aCursor.GetIndex() < nTextLen &&
1694 0 == (pNextError = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_ERROR)))
1695 {
1696 ++aCursor.GetIndex();
1697 }
1698 // maybe the error found here is already in the ChangeAllList and has to be replaced
1699
1700 Reference<XDictionary> xChangeAll( SvxGetChangeAllList(), UNO_QUERY );
1701 Reference<XDictionaryEntry> xEntry;
1702
1703 // Reference <XSpellAlternatives> xAlternatives;
1704 const SpellErrorDescription* pSpellErrorDescription = 0;
1705 if(pNextError)
1706 {
1707 pSpellErrorDescription = &static_cast<const SpellErrorAttrib&>(pNextError->GetAttr()).GetErrorDescription();
1708 bGrammarError = pSpellErrorDescription->bIsGrammarError;
1709 }
1710 if(xChangeAll->getCount() && pSpellErrorDescription &&
1711 (xEntry = xChangeAll->getEntry( pSpellErrorDescription->sErrorText )).is())
1712 {
1713 m_nErrorStart = pNextError->GetStart();
1714 m_nErrorEnd = pNextError->GetEnd();
1715 ChangeMarkedWord(xEntry->getReplacementText(),
1716 SvxLocaleToLanguage( pSpellErrorDescription->aLocale ));
1717 aCursor.GetIndex() = aCursor.GetIndex() + (sal_uInt16)(xEntry->getReplacementText().getLength());
1718 }
1719 else
1720 break;
1721 }
1722
1723 //if an attrib has been found search for the end of the error string
1724 if(aCursor.GetIndex() < nTextLen)
1725 {
1726 m_nErrorStart = aCursor.GetIndex();
1727 m_nErrorEnd = pNextError->GetEnd();
1728 MoveErrorMarkTo(m_nErrorStart, m_nErrorEnd, bGrammarError);
1729 bRet = true;
1730 //add an undo action
1731 SpellUndoAction_Impl* pAction = new SpellUndoAction_Impl(
1732 SPELLUNDO_CHANGE_NEXTERROR, GetSpellDialog()->aDialogUndoLink);
1733 pAction->SetErrorMove(m_nErrorStart, m_nErrorEnd, nOldErrorStart, nOldErrorEnd);
1734 const SpellErrorAttrib* pOldAttrib = static_cast<const SpellErrorAttrib*>(
1735 pTextEngine->FindAttrib( TextPaM(0, nOldErrorStart), TEXTATTR_SPELL_ERROR ));
1736 pAction->SetErrorLanguageSelected(pOldAttrib && pOldAttrib->GetErrorDescription().aSuggestions.getLength() &&
1737 SvxLocaleToLanguage( pOldAttrib->GetErrorDescription().aLocale) ==
1738 GetSpellDialog()->aLanguageLB.GetSelectLanguage());
1739 AddUndoAction(pAction);
1740 }
1741 else
1742 m_nErrorStart = m_nErrorEnd = nTextLen;
1743 if( !bModified )
1744 ClearModifyFlag();
1745 SpellDialog* pSpellDialog = GetSpellDialog();
1746 pSpellDialog->aIgnorePB.Enable(bRet);
1747 pSpellDialog->aIgnoreAllPB.Enable(bRet);
1748 pSpellDialog->aAutoCorrPB.Enable(bRet);
1749 pSpellDialog->aAddToDictMB.Enable(bRet);
1750 return bRet;
1751 }
1752
1753 /*-- 06.11.2003 13:30:26---------------------------------------------------
1754
1755 -----------------------------------------------------------------------*/
MoveErrorMarkTo(sal_uInt16 nStart,sal_uInt16 nEnd,bool bGrammarError)1756 void SentenceEditWindow_Impl::MoveErrorMarkTo(sal_uInt16 nStart, sal_uInt16 nEnd, bool bGrammarError)
1757 {
1758 TextEngine* pTextEngine = GetTextEngine();
1759 pTextEngine->RemoveAttribs( 0, (sal_uInt16)TEXTATTR_FONTCOLOR, sal_True );
1760 pTextEngine->RemoveAttribs( 0, (sal_uInt16)TEXTATTR_FONTWEIGHT, sal_True );
1761 pTextEngine->SetAttrib( TextAttribFontWeight(WEIGHT_BOLD), 0, nStart, nEnd );
1762 pTextEngine->SetAttrib( TextAttribFontColor(bGrammarError ? COL_LIGHTBLUE : COL_LIGHTRED), 0, nStart, nEnd );
1763 m_nErrorStart = nStart;
1764 m_nErrorEnd = nEnd;
1765 }
1766
1767 /*-- 17.09.2003 10:13:08---------------------------------------------------
1768
1769 -----------------------------------------------------------------------*/
ChangeMarkedWord(const String & rNewWord,LanguageType eLanguage)1770 void SentenceEditWindow_Impl::ChangeMarkedWord(const String& rNewWord, LanguageType eLanguage)
1771 {
1772 //calculate length changes
1773 long nDiffLen = rNewWord.Len() - m_nErrorEnd + m_nErrorStart;
1774 TextSelection aSel(TextPaM(0, m_nErrorStart), TextPaM(0, m_nErrorEnd));
1775 //Remove spell error attribute
1776 ExtTextEngine* pTextEngine = GetTextEngine();
1777 pTextEngine->UndoActionStart();
1778 const TextCharAttrib* pErrorAttrib = pTextEngine->FindCharAttrib( TextPaM(0, m_nErrorStart), TEXTATTR_SPELL_ERROR );
1779 DBG_ASSERT(pErrorAttrib, "no error attribute found");
1780 // Reference <XSpellAlternatives> xAlternatives;
1781 const SpellErrorDescription* pSpellErrorDescription = 0;
1782 if(pErrorAttrib)
1783 {
1784 pTextEngine->RemoveAttrib(0, *pErrorAttrib);
1785 pSpellErrorDescription = &static_cast<const SpellErrorAttrib&>(pErrorAttrib->GetAttr()).GetErrorDescription();
1786 }
1787 const TextCharAttrib* pBackAttrib = pTextEngine->FindCharAttrib( TextPaM(0, m_nErrorStart), TEXTATTR_SPELL_BACKGROUND );
1788 pTextEngine->ReplaceText( aSel, rNewWord );
1789 //
1790 if(!m_nErrorStart)
1791 {
1792 //attributes following an error at the start of the text are not moved but expanded from the
1793 //text engine - this is done to keep full-paragraph-attributes
1794 //in the current case that handling is not desired
1795 const TextCharAttrib* pLangAttrib =
1796 pTextEngine->FindCharAttrib(
1797 TextPaM(0, m_nErrorEnd), TEXTATTR_SPELL_LANGUAGE );
1798 sal_uInt16 nTextLen = pTextEngine->GetTextLen( 0 );
1799 if(pLangAttrib && !pLangAttrib->GetStart() && pLangAttrib->GetEnd() ==
1800 nTextLen)
1801 {
1802 SpellLanguageAttrib aNewLangAttrib( static_cast<const SpellLanguageAttrib&>(pLangAttrib->GetAttr()).GetLanguage());
1803 pTextEngine->RemoveAttrib(0, *pLangAttrib);
1804 pTextEngine->SetAttrib( aNewLangAttrib, 0, (sal_uInt16)(m_nErrorEnd + nDiffLen) , nTextLen );
1805 }
1806 }
1807 // undo expanded attributes!
1808 if( pBackAttrib && pBackAttrib->GetStart() < m_nErrorStart && pBackAttrib->GetEnd() == m_nErrorEnd + nDiffLen)
1809 {
1810 TextAttrib* pNewBackground = pBackAttrib->GetAttr().Clone();
1811 sal_uInt16 nStart = pBackAttrib->GetStart();
1812 pTextEngine->RemoveAttrib(0, *pBackAttrib);
1813 pTextEngine->SetAttrib(*pNewBackground, 0, nStart, m_nErrorStart);
1814 delete pNewBackground;
1815 }
1816 pTextEngine->SetModified(sal_True);
1817
1818 //adjust end position
1819 long nEndTemp = m_nErrorEnd;
1820 nEndTemp += nDiffLen;
1821 m_nErrorEnd = (sal_uInt16)nEndTemp;
1822
1823 SpellUndoAction_Impl* pAction = new SpellUndoAction_Impl(
1824 SPELLUNDO_MOVE_ERROREND, GetSpellDialog()->aDialogUndoLink);
1825 pAction->SetOffset(nDiffLen);
1826 AddUndoAction(pAction);
1827 if(pSpellErrorDescription)
1828 SetAttrib( SpellErrorAttrib(*pSpellErrorDescription), 0, m_nErrorStart, m_nErrorEnd );
1829 SetAttrib( SpellLanguageAttrib(eLanguage), 0, m_nErrorStart, m_nErrorEnd );
1830 pTextEngine->UndoActionEnd();
1831 }
1832 /* -----------------08.10.2003 13:18-----------------
1833
1834 --------------------------------------------------*/
GetErrorText() const1835 String SentenceEditWindow_Impl::GetErrorText() const
1836 {
1837 return GetTextEngine()->GetText(TextSelection(TextPaM(0, m_nErrorStart), TextPaM(0, m_nErrorEnd) ));
1838 }
1839 /*-- 26.06.2008 10:54:13---------------------------------------------------
1840
1841 -----------------------------------------------------------------------*/
GetAlternatives()1842 const SpellErrorDescription* SentenceEditWindow_Impl::GetAlternatives()
1843 {
1844 TextPaM aCursor(0, m_nErrorStart);
1845 const SpellErrorAttrib* pAttrib = static_cast<const SpellErrorAttrib*>(
1846 GetTextEngine()->FindAttrib( aCursor, TEXTATTR_SPELL_ERROR));
1847 return pAttrib ? &pAttrib->GetErrorDescription() : 0;
1848 }
1849 /*-- 06.09.2004 10:50:32---------------------------------------------------
1850
1851 -----------------------------------------------------------------------*/
RestoreCurrentError()1852 void SentenceEditWindow_Impl::RestoreCurrentError()
1853 {
1854 TextPaM aCursor(0, m_nErrorStart);
1855 const SpellErrorAttrib* pAttrib = static_cast<const SpellErrorAttrib*>(
1856 GetTextEngine()->FindAttrib( aCursor, TEXTATTR_SPELL_ERROR));
1857 if( pAttrib )
1858 {
1859 const SpellErrorDescription& rDesc = pAttrib->GetErrorDescription();
1860 if( !rDesc.sErrorText.equals( GetErrorText() ) )
1861 ChangeMarkedWord(rDesc.sErrorText, SvxLocaleToLanguage( rDesc.aLocale ));
1862 }
1863 }
1864 /*-- 28.10.2003 14:44:10---------------------------------------------------
1865
1866 -----------------------------------------------------------------------*/
SetAlternatives(Reference<XSpellAlternatives> xAlt)1867 void SentenceEditWindow_Impl::SetAlternatives( Reference< XSpellAlternatives> xAlt )
1868 {
1869 TextPaM aCursor(0, m_nErrorStart);
1870 DBG_ASSERT(static_cast<const SpellErrorAttrib*>(
1871 GetTextEngine()->FindAttrib( aCursor, TEXTATTR_SPELL_ERROR)), "no error set?");
1872
1873 ::rtl::OUString aWord;
1874 lang::Locale aLocale;
1875 uno::Sequence< ::rtl::OUString > aAlts;
1876 ::rtl::OUString sServiceName;
1877 if (xAlt.is())
1878 {
1879 aWord = xAlt->getWord();
1880 aLocale = xAlt->getLocale();
1881 aAlts = xAlt->getAlternatives();
1882 uno::Reference< container::XNamed > xNamed( xAlt, uno::UNO_QUERY );
1883 if (xNamed.is())
1884 sServiceName = xNamed->getName();
1885 }
1886 SpellErrorDescription aDesc( false, aWord, aLocale, aAlts, 0, sServiceName);
1887 GetTextEngine()->SetAttrib( SpellErrorAttrib(aDesc), 0, m_nErrorStart, m_nErrorEnd );
1888 }
1889
1890 /*-- 10.09.2003 14:43:02---------------------------------------------------
1891
1892 -----------------------------------------------------------------------*/
SetAttrib(const TextAttrib & rAttr,sal_uLong nPara,sal_uInt16 nStart,sal_uInt16 nEnd)1893 void SentenceEditWindow_Impl::SetAttrib( const TextAttrib& rAttr, sal_uLong nPara, sal_uInt16 nStart, sal_uInt16 nEnd )
1894 {
1895 GetTextEngine()->SetAttrib(rAttr, nPara, nStart, nEnd);
1896 }
1897 /*-- 10.09.2003 14:43:02---------------------------------------------------
1898
1899 -----------------------------------------------------------------------*/
SetText(const String & rStr)1900 void SentenceEditWindow_Impl::SetText( const String& rStr )
1901 {
1902 m_nErrorStart = m_nErrorEnd = 0;
1903 GetTextEngine()->SetText(rStr);
1904 // InitScrollBars();
1905 }
1906 /*-- 08.10.2003 14:35:52---------------------------------------------------
1907
1908 -----------------------------------------------------------------------*/
1909 struct LanguagePosition_Impl
1910 {
1911 sal_uInt16 nPosition;
1912 LanguageType eLanguage;
1913
LanguagePosition_ImplLanguagePosition_Impl1914 LanguagePosition_Impl(sal_uInt16 nPos, LanguageType eLang) :
1915 nPosition(nPos),
1916 eLanguage(eLang)
1917 {}
1918 };
1919 typedef std::vector<LanguagePosition_Impl> LanguagePositions_Impl;
1920
lcl_InsertBreakPosition_Impl(LanguagePositions_Impl & rBreakPositions,sal_uInt16 nInsert,LanguageType eLanguage)1921 void lcl_InsertBreakPosition_Impl(
1922 LanguagePositions_Impl& rBreakPositions, sal_uInt16 nInsert, LanguageType eLanguage)
1923 {
1924 LanguagePositions_Impl::iterator aStart = rBreakPositions.begin();
1925 while(aStart != rBreakPositions.end())
1926 {
1927 if(aStart->nPosition == nInsert)
1928 {
1929 //the language of following starts has to overwrite
1930 //the one of previous ends
1931 aStart->eLanguage = eLanguage;
1932 return;
1933 }
1934 else if(aStart->nPosition > nInsert)
1935 {
1936
1937 rBreakPositions.insert(aStart, LanguagePosition_Impl(nInsert, eLanguage));
1938 return;
1939 }
1940 else
1941 ++aStart;
1942 }
1943 rBreakPositions.push_back(LanguagePosition_Impl(nInsert, eLanguage));
1944 }
1945 /*-- 17.09.2003 14:26:59---------------------------------------------------
1946 Returns the text in spell portions. Each portion contains text with an
1947 equal language and attribute. The spell alternatives are empty.
1948 -----------------------------------------------------------------------*/
CreateSpellPortions(bool bSetIgnoreFlag) const1949 svx::SpellPortions SentenceEditWindow_Impl::CreateSpellPortions( bool bSetIgnoreFlag ) const
1950 {
1951 svx::SpellPortions aRet;
1952 ExtTextEngine* pTextEngine = GetTextEngine();
1953 const sal_uInt16 nTextLen = pTextEngine->GetTextLen(0);
1954 if(nTextLen)
1955 {
1956 TextPaM aCursor(0, 0);
1957 LanguagePositions_Impl aBreakPositions;
1958 const TextCharAttrib* pLastLang = 0;
1959 const TextCharAttrib* pLastError = 0;
1960 LanguageType eLang = LANGUAGE_DONTKNOW;
1961 const TextCharAttrib* pError = 0;
1962 while(aCursor.GetIndex() < nTextLen)
1963 {
1964 const TextCharAttrib* pLang = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_LANGUAGE);
1965 if(pLang && pLang != pLastLang)
1966 {
1967 eLang = static_cast<const SpellLanguageAttrib&>(pLang->GetAttr()).GetLanguage();
1968 lcl_InsertBreakPosition_Impl(aBreakPositions, pLang->GetStart(), eLang);
1969 lcl_InsertBreakPosition_Impl(aBreakPositions, pLang->GetEnd(), eLang);
1970 pLastLang = pLang;
1971 }
1972 pError = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_ERROR);
1973 if(pError && pLastError != pError)
1974 {
1975 lcl_InsertBreakPosition_Impl(aBreakPositions, pError->GetStart(), eLang);
1976 lcl_InsertBreakPosition_Impl(aBreakPositions, pError->GetEnd(), eLang);
1977 pLastError = pError;
1978
1979 }
1980 aCursor.GetIndex()++;
1981 }
1982 //
1983 if(nTextLen && aBreakPositions.empty())
1984 {
1985 //if all content has been overwritten the attributes may have been removed, too
1986 svx::SpellPortion aPortion1;
1987 aPortion1.eLanguage = GetSpellDialog()->GetSelectedLang_Impl();
1988 aPortion1.sText = pTextEngine->GetText(
1989 TextSelection(TextPaM(0, 0), TextPaM(0, nTextLen)));
1990
1991 aRet.push_back(aPortion1);
1992
1993 }
1994 else if(!aBreakPositions.empty())
1995 {
1996 LanguagePositions_Impl::iterator aStart = aBreakPositions.begin();
1997 //start should always be Null
1998 eLang = aStart->eLanguage;
1999 sal_uInt16 nStart = aStart->nPosition;
2000 DBG_ASSERT(!nStart, "invalid start position - language attribute missing?");
2001 ++aStart;
2002
2003 while(aStart != aBreakPositions.end())
2004 {
2005 svx::SpellPortion aPortion1;
2006 aPortion1.eLanguage = eLang;
2007 aPortion1.sText = pTextEngine->GetText(
2008 TextSelection(TextPaM(0, nStart), TextPaM(0, aStart->nPosition)));
2009 bool bIsIgnoreError = m_aIgnoreErrorsAt.find( nStart ) != m_aIgnoreErrorsAt.end();
2010 if( bSetIgnoreFlag && bIsIgnoreError /*m_nErrorStart == nStart*/ )
2011 {
2012 aPortion1.bIgnoreThisError = true;
2013 }
2014 aRet.push_back(aPortion1);
2015 nStart = aStart->nPosition;
2016 eLang = aStart->eLanguage;
2017 ++aStart;
2018 }
2019 }
2020
2021 // quick partly fix of #i71318. Correct fix needs to patch the TextEngine itself...
2022 // this one will only prevent text from disappearing. It may to not have the
2023 // correct language and will probably not spell checked...
2024 sal_uLong nPara = pTextEngine->GetParagraphCount();
2025 if (nPara > 1)
2026 {
2027 String aLeftOverText;
2028 for (sal_uLong i = 1; i < nPara; ++i)
2029 {
2030 aLeftOverText.AppendAscii( "\x0a" ); // the manual line break...
2031 aLeftOverText += pTextEngine->GetText(i);
2032 }
2033 if (pError)
2034 { // we need to add a new portion containing the left-over text
2035 svx::SpellPortion aPortion2;
2036 aPortion2.eLanguage = eLang;
2037 aPortion2.sText = aLeftOverText;
2038 aRet.push_back( aPortion2 );
2039 }
2040 else
2041 { // we just need to append the left-over text to the last portion (which had no errors)
2042 aRet[ aRet.size() - 1 ].sText += aLeftOverText;
2043 }
2044 }
2045 }
2046 return aRet;
2047 }
2048
2049 /*-- 06.11.2003 11:30:10---------------------------------------------------
2050
2051 -----------------------------------------------------------------------*/
Undo()2052 void SentenceEditWindow_Impl::Undo()
2053 {
2054 ::svl::IUndoManager& rUndoMgr = GetTextEngine()->GetUndoManager();
2055 DBG_ASSERT(GetUndoActionCount(), "no undo actions available" );
2056 if(!GetUndoActionCount())
2057 return;
2058 bool bSaveUndoEdit = IsUndoEditMode();
2059 sal_uInt16 nId;
2060 //if the undo edit mode is active then undo all changes until the UNDO_EDIT_MODE action has been found
2061 do
2062 {
2063 nId = rUndoMgr.GetUndoActionId();
2064 rUndoMgr.Undo();
2065 }while(bSaveUndoEdit && SPELLUNDO_UNDO_EDIT_MODE != nId && GetUndoActionCount());
2066
2067 if(bSaveUndoEdit || SPELLUNDO_CHANGE_GROUP == nId)
2068 GetSpellDialog()->UpdateBoxes_Impl();
2069 }
2070 /*-- 06.11.2003 11:30:10---------------------------------------------------
2071
2072 -----------------------------------------------------------------------*/
ResetUndo()2073 void SentenceEditWindow_Impl::ResetUndo()
2074 {
2075 GetTextEngine()->ResetUndo();
2076 }
2077 /*-- 06.11.2003 12:30:41---------------------------------------------------
2078
2079 -----------------------------------------------------------------------*/
AddUndoAction(SfxUndoAction * pAction,sal_Bool bTryMerg)2080 void SentenceEditWindow_Impl::AddUndoAction( SfxUndoAction *pAction, sal_Bool bTryMerg )
2081 {
2082 ::svl::IUndoManager& rUndoMgr = GetTextEngine()->GetUndoManager();
2083 rUndoMgr.AddUndoAction(pAction, bTryMerg);
2084 GetSpellDialog()->aUndoPB.Enable();
2085 }
2086 /*-- 06.11.2003 12:38:44---------------------------------------------------
2087
2088 -----------------------------------------------------------------------*/
GetUndoActionCount()2089 sal_uInt16 SentenceEditWindow_Impl::GetUndoActionCount()
2090 {
2091 return GetTextEngine()->GetUndoManager().GetUndoActionCount();
2092 }
2093
2094 /*-- 12.11.2003 12:12:38---------------------------------------------------
2095
2096 -----------------------------------------------------------------------*/
UndoActionStart(sal_uInt16 nId)2097 void SentenceEditWindow_Impl::UndoActionStart( sal_uInt16 nId )
2098 {
2099 GetTextEngine()->UndoActionStart(nId);
2100 }
2101 /*-- 12.11.2003 12:12:38---------------------------------------------------
2102
2103 -----------------------------------------------------------------------*/
UndoActionEnd()2104 void SentenceEditWindow_Impl::UndoActionEnd()
2105 {
2106 GetTextEngine()->UndoActionEnd();
2107 }
2108 /*-- 12.11.2003 12:12:38---------------------------------------------------
2109
2110 -----------------------------------------------------------------------*/
MoveErrorEnd(long nOffset)2111 void SentenceEditWindow_Impl::MoveErrorEnd(long nOffset)
2112 {
2113 if(nOffset > 0)
2114 m_nErrorEnd = m_nErrorEnd - (sal_uInt16)nOffset;
2115 else
2116 m_nErrorEnd = m_nErrorEnd -(sal_uInt16)- nOffset;
2117 }
2118 /*-- 13.11.2003 15:15:19---------------------------------------------------
2119
2120 -----------------------------------------------------------------------*/
SetUndoEditMode(bool bSet)2121 void SentenceEditWindow_Impl::SetUndoEditMode(bool bSet)
2122 {
2123 DBG_ASSERT(!bSet || m_bIsUndoEditMode != bSet, "SetUndoEditMode with equal values?");
2124 m_bIsUndoEditMode = bSet;
2125 //disable all buttons except the Change
2126 SpellDialog* pSpellDialog = GetSpellDialog();
2127 Control* aControls[] =
2128 {
2129 &pSpellDialog->aChangeAllPB,
2130 &pSpellDialog->aExplainPB,
2131 &pSpellDialog->aIgnoreAllPB,
2132 &pSpellDialog->aIgnoreRulePB,
2133 &pSpellDialog->aIgnorePB,
2134 &pSpellDialog->aSuggestionLB,
2135 &pSpellDialog->aSuggestionFT,
2136 &pSpellDialog->aLanguageFT,
2137 &pSpellDialog->aLanguageLB,
2138 &pSpellDialog->aAddToDictMB,
2139 &pSpellDialog->aAutoCorrPB,
2140 0
2141 };
2142 sal_Int32 nIdx = 0;
2143 do
2144 {
2145 aControls[nIdx]->Enable(sal_False);
2146 }
2147 while(aControls[++nIdx]);
2148
2149 //remove error marks
2150 TextEngine* pTextEngine = GetTextEngine();
2151 pTextEngine->RemoveAttribs( 0, (sal_uInt16)TEXTATTR_FONTCOLOR, sal_True );
2152 pTextEngine->RemoveAttribs( 0, (sal_uInt16)TEXTATTR_FONTWEIGHT, sal_True );
2153
2154 //put the appropriate action on the Undo-stack
2155 SpellUndoAction_Impl* pAction = new SpellUndoAction_Impl(
2156 SPELLUNDO_UNDO_EDIT_MODE, GetSpellDialog()->aDialogUndoLink);
2157 AddUndoAction(pAction);
2158 pSpellDialog->aChangePB.Enable();
2159 }
2160
2161 /*-- 30.06.2008 14:15:19---------------------------------------------------
2162
2163 -----------------------------------------------------------------------*/
~ExplainButton()2164 ExplainButton::~ExplainButton()
2165 {
2166 }
2167 /*-- 30.06.2008 14:15:19---------------------------------------------------
2168
2169 -----------------------------------------------------------------------*/
RequestHelp(const HelpEvent &)2170 void ExplainButton::RequestHelp( const HelpEvent& )
2171 {
2172 Help::ShowBalloon( this, GetPosPixel(), m_sExplanation );
2173 }
2174
Click()2175 void ExplainButton::Click()
2176 {
2177 RequestHelp( HelpEvent() );
2178 }
2179