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