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