diff options
author | Rüdiger Timm <rt@openoffice.org> | 2004-09-17 13:13:10 +0000 |
---|---|---|
committer | Rüdiger Timm <rt@openoffice.org> | 2004-09-17 13:13:10 +0000 |
commit | 07674089fdcd461785adc4649e1f902b3515cacb (patch) | |
tree | a880a4f3073ef5d42f88e952bfb22904a7df39d9 /svx/source/dialog/SpellDialog.cxx | |
parent | d1c6b346f2c119e92225c4fc6356198fdcf908e5 (diff) |
INTEGRATION: CWS os19 (1.1.2); FILE ADDED
2004/09/06 09:35:49 os 1.1.2.18: #i33637# ignore(all) should undo manual modifications
2004/09/06 08:21:09 os 1.1.2.17: #i33646# put inital focus on 'Change' or 'Ignore once'
#i33635##i33647##i33650# PreNotify ony key events fixed
2004/08/11 13:58:47 os 1.1.2.16: #i332235# disable Tab-GetFocus-selection; #i32238# Tab-key doesn't modify anymore; #i323669# re-adjust language attributes on single errors at the start of a sentence
2004/07/27 14:34:35 dr 1.1.2.15: #i32150# don't disable edit field while editing...
2004/07/27 12:20:24 dr 1.1.2.14: #i32139# set initial focus + edit field ignores tab
2004/07/15 13:06:38 os 1.1.2.13: #i18881# re-enabling of controls
2004/07/12 12:21:37 dr 1.1.2.12: #i22092# disable sentence edit field on Invalidate()
2004/06/10 12:54:54 os 1.1.2.11: #i18881# access to empty vector prevented
2004/05/04 08:02:15 os 1.1.2.10: #i18881# SpellDialog moved to cui library
2003/11/21 12:34:58 os 1.1.2.9: #18881# Change after random edit completed
2003/11/18 14:18:03 os 1.1.2.8: #i18881# syntax
2003/11/15 14:25:53 os 1.1.2.7: #18881# Undo implemented
2003/11/05 07:01:24 os 1.1.2.6: #i18881# Field support added
2003/10/31 10:21:24 os 1.1.2.5: #i18881# Get/LoseFocus notification; new Alternatives on language selection added
2003/10/24 05:50:01 os 1.1.2.4: #i18881# modify flag correctly set
2003/10/23 05:37:16 os 1.1.2.3: #i18881# use of MultiLineEdit
2003/10/08 14:47:34 os 1.1.2.2: #i18881# display, change of words and languages work now
2003/09/23 06:49:23 os 1.1.2.1: #i18881# new spelling dialog
Diffstat (limited to 'svx/source/dialog/SpellDialog.cxx')
-rw-r--r-- | svx/source/dialog/SpellDialog.cxx | 1871 |
1 files changed, 1871 insertions, 0 deletions
diff --git a/svx/source/dialog/SpellDialog.cxx b/svx/source/dialog/SpellDialog.cxx new file mode 100644 index 000000000000..46df353c2291 --- /dev/null +++ b/svx/source/dialog/SpellDialog.cxx @@ -0,0 +1,1871 @@ +/************************************************************************* + * + * $RCSfile: SpellDialog.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: rt $ $Date: 2004-09-17 14:13:10 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#pragma hdrstop + +// include --------------------------------------------------------------- +#include <tools/ref.hxx> + +#ifndef _SHL_HXX +#include <tools/shl.hxx> +#endif +#ifndef _SV_WRKWIN_HXX +#include <vcl/wrkwin.hxx> +#endif +#ifndef _SV_MENU_HXX +#include <vcl/menu.hxx> +#endif +#ifndef _SV_MSGBOX_HXX +#include <vcl/msgbox.hxx> +#endif +#ifndef _SCRBAR_HXX //autogen +#include <vcl/scrbar.hxx> +#endif +#ifndef _SVX_SPELL_ATTRIB +#include <SpellAttrib.hxx> +#endif +#ifndef _SFXDISPATCH_HXX +#include <sfx2/dispatch.hxx> +#endif +#ifndef _SFX_BINDINGS_HXX +#include <sfx2/bindings.hxx> +#endif +#ifndef _UNDO_HXX +#include <svtools/undo.hxx> +#endif +#ifndef _TEXTDATA_HXX +#include <svtools/textdata.hxx> +#endif +#ifndef _UNO_LINGU_HXX +#include <unolingu.hxx> +#endif + +#ifndef _SVX_SPLWRAP_HXX +#include "splwrap.hxx" +#endif +#ifndef _LINGUISTIC_LNGPROPS_HHX_ +#include <linguistic/lngprops.hxx> +#endif +#ifndef _COMPHELPER_PROCESSFACTORY_HXX_ +#include <comphelper/processfactory.hxx> +#endif + +#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_ +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#endif +#ifndef _COM_SUN_STAR_LINGUISTIC2_SPELLFAILURE_HPP_ +#include <com/sun/star/linguistic2/SpellFailure.hpp> +#endif +#ifndef _COM_SUN_STAR_FRAME_XSTORABLE_HPP_ +#include <com/sun/star/frame/XStorable.hpp> +#endif + +#ifndef _SFXAPP_HXX //autogen +#include <sfx2/app.hxx> +#endif + + +#include "dialogs.hrc" +#include <helpid.hrc> +#include "SpellDialog.hrc" + +#define ITEMID_SPELLCHECK SID_ATTR_SPELL + +#include "optitems.hxx" +#include "svxenum.hxx" +#include "SpellDialogChildWindow.hxx" +#include "SpellDialog.hxx" +//#include "splwrap.hxx" // Der Wrapper +#include "dlgutil.hxx" // language +#include "optlingu.hxx" +#include "dialmgr.hxx" +#include "svxerr.hxx" + +using namespace ::rtl; +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::linguistic2; + +#define C2U(cChar) OUString::createFromAscii(cChar) +// struct SpellDialog_Impl --------------------------------------------- + +struct SpellDialog_Impl +{ + Sequence< Reference< XDictionary > > aDics; +}; +// ----------------------------------------------------------------------- +#define SPELLUNDO_CHANGE_LANGUAGE (TEXTUNDO_USER + 1) +#define SPELLUNDO_CHANGE_TEXTENGINE (TEXTUNDO_USER + 2) +#define SPELLUNDO_CHANGE_NEXTERROR (TEXTUNDO_USER + 3) +#define SPELLUNDO_CHANGE_ADD_TO_DICTIONARY (TEXTUNDO_USER + 4) +#define SPELLUNDO_CHANGE_GROUP (TEXTUNDO_USER + 5) //undo list +#define SPELLUNDO_MOVE_ERROREND (TEXTUNDO_USER + 6) +#define SPELLUNDO_UNDO_EDIT_MODE (TEXTUNDO_USER + 7) + +namespace svx{ +class SpellUndoAction_Impl : public SfxUndoAction +{ + USHORT m_nId; + const Link& m_rActionLink; + //undo of button enabling + bool m_bEnableChangePB; + bool m_bEnableChangeAllPB; + //undo of MarkNextError - used in change and change all, ignore and ignore all + long m_nNewErrorStart; + long m_nNewErrorEnd; + long m_nOldErrorStart; + long m_nOldErrorEnd; + bool m_bIsErrorLanguageSelected; + //undo of AddToDictionary + Reference<XDictionary> m_xDictionary; + OUString m_sAddedWord; + //move end of error - ::ChangeMarkedWord() + long m_nOffset; + +public: + SpellUndoAction_Impl(USHORT nId, const Link& rActionLink) : + m_nId(nId), + m_rActionLink( rActionLink), + m_bEnableChangePB(false), + m_bEnableChangeAllPB(false), + m_nNewErrorStart(-1), + m_nNewErrorEnd(-1), + m_nOldErrorStart(-1), + m_nOldErrorEnd(-1), + m_bIsErrorLanguageSelected(false), + m_nOffset(0) + {} + + ~SpellUndoAction_Impl(); + + virtual void Undo(); + virtual USHORT GetId() const; + + void SetEnableChangePB(){m_bEnableChangePB = true;} + bool IsEnableChangePB(){return m_bEnableChangePB;} + + void SetEnableChangeAllPB(){m_bEnableChangeAllPB = true;} + bool IsEnableChangeAllPB(){return m_bEnableChangeAllPB;} + + void SetErrorMove(long nNewStart, long nNewEnd, long nOldStart, long nOldEnd) + { + m_nNewErrorStart = nNewStart; + m_nNewErrorEnd = nNewEnd; + m_nOldErrorStart = nOldStart; + m_nOldErrorEnd = nOldEnd; + } + long GetNewErrorStart() { return m_nNewErrorStart;} + long GetNewErrorEnd() { return m_nNewErrorEnd;} + long GetOldErrorStart() { return m_nOldErrorStart;} + long GetOldErrorEnd() { return m_nOldErrorEnd;} + + void SetErrorLanguageSelected(bool bSet){ m_bIsErrorLanguageSelected = bSet;} + bool IsErrorLanguageSelected() const {return m_bIsErrorLanguageSelected;} + + + void SetDictionary(Reference<XDictionary> xDict) { m_xDictionary = xDict; } + Reference<XDictionary> GetDictionary() const {return m_xDictionary;} + void SetAddedWord(const OUString& rWord) {m_sAddedWord = rWord;} + const OUString& GetAddedWord() const { return m_sAddedWord;} + + void SetOffset(long nSet) {m_nOffset = nSet;} + long GetOffset() const {return m_nOffset;} + +}; +}//namespace svx +using namespace ::svx; +/*-- 06.11.2003 12:16:02--------------------------------------------------- + + -----------------------------------------------------------------------*/ +SpellUndoAction_Impl::~SpellUndoAction_Impl() +{ +} +/*-- 06.11.2003 12:16:02--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SpellUndoAction_Impl::Undo() +{ + m_rActionLink.Call(this); +} +/*-- 06.11.2003 12:16:02--------------------------------------------------- + + -----------------------------------------------------------------------*/ +USHORT SpellUndoAction_Impl::GetId()const +{ + return m_nId; +} + +// class SvxSpellCheckDialog --------------------------------------------- + +SpellDialog::SpellDialog( + SpellDialogChildWindow* pChildWindow, + Window * pParent, + SfxBindings* pBindings) + : SfxModelessDialog (pBindings, + pChildWindow, + pParent, + SVX_RES(RID_SVXDLG_SPELLCHECK)), + + aSuggestionFT ( this, ResId( FT_SUGGESTION ) ), + aSuggestionLB ( this, ResId( LB_SUGGESTION ) ), + aNotInDictFT ( this, ResId( FT_NOTINDICT ) ), + aSentenceED ( this, ResId( ED_NEWWORD ) ), + aLanguageFT ( this, ResId( FT_LANGUAGE ) ), + aLanguageLB ( this, ResId( LB_LANGUAGE ) ), + + aIgnorePB ( this, ResId( PB_IGNORE ) ), + aIgnoreAllPB ( this, ResId( PB_IGNOREALL ) ), + aAddToDictMB ( this, ResId( MB_ADDTODICT ) ), + + aChangePB ( this, ResId( PB_CHANGE ) ), + aChangeAllPB ( this, ResId( PB_CHANGEALL ) ), + aAutoCorrPB ( this, ResId( PB_AUTOCORR ) ), + + aBackgroundGB ( this, ResId( GB_BACKGROUND ) ), + aOptionsPB ( this, ResId( PB_OPTIONS ) ), + aHelpPB ( this, ResId( PB_HELP ) ), + aUndoPB ( this, ResId( PB_UNDO ) ), + aClosePB ( this, ResId( PB_CLOSE ) ), + + nOldLang ( LANGUAGE_NONE ), + aResumeST ( ResId(ST_RESUME )), + aNoSuggestionsST( ResId(ST_NOSUGGESTIONS)), + aIgnoreOnceST ( aIgnorePB.GetText()), + rParent ( *pChildWindow ), + aDialogUndoLink( LINK (this, SpellDialog, DialogUndoHdl)), + bModified ( sal_False ) +{ + FreeResource(); + + xSpell = LinguMgr::GetSpellChecker(); + pImpl = new SpellDialog_Impl; + + //HelpIds + aClosePB. SetHelpId(HID_SPLDLG_BUTTON_CLOSE ); + aIgnorePB. SetHelpId(HID_SPLDLG_BUTTON_IGNORE ); + aIgnoreAllPB. SetHelpId(HID_SPLDLG_BUTTON_IGNOREALL); + aChangePB. SetHelpId(HID_SPLDLG_BUTTON_CHANGE ); + aChangeAllPB. SetHelpId(HID_SPLDLG_BUTTON_CHANGEALL); + + Init_Impl(); + + // disable controls if service is missing + if (!xSpell.is()) + Enable( sal_False ); + + Application::PostUserEvent( STATIC_LINK( + this, SpellDialog, InitHdl ) ); +} + +// ----------------------------------------------------------------------- + +SpellDialog::~SpellDialog() +{ + delete aAddToDictMB.GetPopupMenu(); + delete pImpl; +} + +// ----------------------------------------------------------------------- + +void SpellDialog::Init_Impl() +{ + // Handler initialisieren + aClosePB.SetClickHdl(LINK( this, SpellDialog, CancelHdl ) ); + aChangePB.SetClickHdl(LINK( this, SpellDialog, ChangeHdl ) ); + aChangeAllPB.SetClickHdl(LINK( this, SpellDialog, ChangeAllHdl ) ); + aIgnorePB.SetClickHdl(LINK( this, SpellDialog, IgnoreHdl ) ); + aIgnoreAllPB.SetClickHdl(LINK( this, SpellDialog, IgnoreAllHdl ) ); + aUndoPB.SetClickHdl(LINK( this, SpellDialog, UndoHdl ) ); + + aAutoCorrPB.SetClickHdl( LINK( this, SpellDialog, ExtClickHdl ) ); + aOptionsPB .SetClickHdl( LINK( this, SpellDialog, ExtClickHdl ) ); + + aSuggestionLB.SetDoubleClickHdl( LINK( this, SpellDialog, ChangeHdl ) ); + + aSentenceED.SetModifyHdl(LINK ( this, SpellDialog, ModifyHdl) ); + aAddToDictMB.SetSelectHdl(LINK ( this, SpellDialog, AddToDictionaryHdl ) ); + aLanguageLB.SetSelectHdl(LINK( this, SpellDialog, LanguageSelectHdl ) ); + // Save heading + aTitel = GetText(); + + // initialize language ListBox + aLanguageLB.SetLanguageList( LANG_LIST_SPELL_USED, FALSE, FALSE, TRUE ); + + // get current language + UpdateBoxes_Impl(); + + // fill dictionary PopupMenu + InitUserDicts(); + + aSentenceED.ClearModifyFlag(); + SvxGetChangeAllList()->clear(); +} + +// ----------------------------------------------------------------------- + +void SpellDialog::UpdateBoxes_Impl() +{ + sal_Int32 i; + aSuggestionLB.Clear(); + + Reference< XSpellAlternatives > xAlt( aSentenceED.GetAlternatives(), UNO_QUERY ); + + LanguageType nAltLanguage = LANGUAGE_NONE; + String aAltWord; + Sequence< OUString > aNewWords; + if (xAlt.is()) + { + nAltLanguage = SvxLocaleToLanguage( xAlt->getLocale() ); + aAltWord = String( xAlt->getWord() ); + aNewWords = xAlt->getAlternatives(); + } + + + String aStr( aTitel ); + aStr.Append( UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( " (" ) ) ); + if (xAlt.is()) + aStr.Append( ::GetLanguageString( nAltLanguage ) ); + aStr.Append( sal_Unicode( ')' ) ); + SetText( aStr ); + + SetSelectedLang_Impl( nAltLanguage ); + + + // Alternativen eintragen + const OUString *pNewWords = aNewWords.getConstArray(); + const sal_Int32 nSize = aNewWords.getLength(); + for ( i = 0; i < nSize; ++i ) + { + String aTmp( pNewWords[i] ); + if ( LISTBOX_ENTRY_NOTFOUND == aSuggestionLB.GetEntryPos( aTmp ) ) + aSuggestionLB.InsertEntry( aTmp ); + } + if(!nSize) + aSuggestionLB.InsertEntry( aNoSuggestionsST ); + aAutoCorrPB.Enable( nSize > 0 ); + //aSentenceED.GrabFocus(); + + aSuggestionFT.Enable(nSize > 0); + aSuggestionLB.Enable(nSize > 0); + if( nSize ) + { + aSuggestionLB.SelectEntryPos(0); + } + aChangePB.Enable( nSize > 0); + aChangeAllPB.Enable(nSize > 0); +} +// ----------------------------------------------------------------------- + +void SpellDialog::SpellContinue_Impl(bool bUseSavedSentence) +{ + //initially or after the last error of a sentence MarkNextError will fail + //then GetNextSentence() has to be called followed again by MarkNextError() + //MarkNextError is not initally called if the UndoEdit mode is active + if((!aSentenceED.IsUndoEditMode() && aSentenceED.MarkNextError()) || + GetNextSentence_Impl(bUseSavedSentence) && aSentenceED.MarkNextError()) + { + Reference< XSpellAlternatives > xAlt = aSentenceED.GetAlternatives(); + if(xAlt.is()) + { + UpdateBoxes_Impl(); + Control* aControls[] = + { + &aNotInDictFT, + &aSentenceED, + &aLanguageFT, + &aLanguageLB, + 0 + }; + sal_Int32 nIdx = 0; + do + { + aControls[nIdx]->Enable(sal_True); + } + while(aControls[++nIdx]); + + + } + } +} +/* -----------------10.09.2003 14:04----------------- + Initialize, asynchronous to prevent virtial calls + from a constructor + --------------------------------------------------*/ +IMPL_STATIC_LINK( SpellDialog, InitHdl, SpellDialog *, EMPTYARG ) +{ + //show or hide AutoCorrect depending on the modules abilities + pThis->aAutoCorrPB.Show(pThis->rParent.HasAutoCorrection()); + pThis->SpellContinue_Impl(); + pThis->aSentenceED.ResetUndo(); + pThis->aUndoPB.Enable(FALSE); + + if( pThis->aChangePB.IsEnabled() ) + pThis->aChangePB.GrabFocus(); + else if( pThis->aIgnorePB.IsEnabled() ) + pThis->aIgnorePB.GrabFocus(); + else if( pThis->aClosePB.IsEnabled() ) + pThis->aClosePB.GrabFocus(); + + return 0; +}; + +// ----------------------------------------------------------------------- + +IMPL_LINK( SpellDialog, ExtClickHdl, Button *, pBtn ) +{ + if (&aOptionsPB == pBtn) + StartSpellOptDlg_Impl(); + else if(&aAutoCorrPB == pBtn) + { + //get the currently selected wrong word + String sCurrentErrorText = aSentenceED.GetErrorText(); + //get the wrong word from the XSpellAlternative + Reference< XSpellAlternatives > xAlt = aSentenceED.GetAlternatives(); + if(xAlt.is()) + { + String sWrong(xAlt->getWord()); + //if the word has not been edited in the MultiLineEdit then + //the current suggestion should be used + //if it's not the 'no suggestions' entry + if(sWrong == sCurrentErrorText && + aSuggestionLB.IsEnabled() && aSuggestionLB.GetSelectEntryCount() > 0 && + aNoSuggestionsST != aSuggestionLB.GetSelectEntry()) + { + sCurrentErrorText = aSuggestionLB.GetSelectEntry(); + } + if(sWrong != sCurrentErrorText) + { + SvxPrepareAutoCorrect( sWrong, sCurrentErrorText ); + LanguageType eLang = GetSelectedLang_Impl(); + rParent.AddAutoCorrection( sWrong, sCurrentErrorText, eLang ); + } + } + } + return 0; +} +// ----------------------------------------------------------------------- + +void SpellDialog::StartSpellOptDlg_Impl() +{ + sal_uInt16 aSpellInfos[] = + { + SID_ATTR_SPELL,SID_ATTR_SPELL, + 0 + }; + SfxItemSet aSet( SFX_APP()->GetPool(), aSpellInfos); + aSet.Put(SfxSpellCheckItem( xSpell ),SID_ATTR_SPELL ); + SfxSingleTabDialog* pDlg = + new SfxSingleTabDialog( this, aSet, RID_SFXPAGE_LINGU ); + SfxTabPage* pPage = SvxLinguTabPage::Create( pDlg, aSet ); + ( (SvxLinguTabPage*)pPage )->HideGroups( GROUP_MODULES ); + pDlg->SetTabPage( pPage ); + pDlg->Execute(); + delete pDlg; + + // Benutzerb"ucher anzeigen + InitUserDicts(); +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( SpellDialog, ChangeHdl, Button *, EMPTYARG ) +{ + if(aSentenceED.IsUndoEditMode()) + { + SpellContinue_Impl(); + } + else + { + aSentenceED.UndoActionStart( SPELLUNDO_CHANGE_GROUP ); + String aString = aSentenceED.GetErrorText(); + //dots are sometimes part of the spelled word but they are not necessarily part of the replacement + bool bDot = aString.Len() && aString.GetChar(aString.Len() - 1 ) == '.'; + if(aSuggestionLB.IsEnabled() && + aSuggestionLB.GetSelectEntryCount()>0 && + aNoSuggestionsST != aSuggestionLB.GetSelectEntry()) + aString = aSuggestionLB.GetSelectEntry(); + if(bDot && (!aString.Len() || aString.GetChar(aString.Len() - 1 ) != '.')) + aString += '.'; + + aSentenceED.ChangeMarkedWord(aString, GetSelectedLang_Impl()); + SpellContinue_Impl(); + bModified=sal_False; + aSentenceED.UndoActionEnd( SPELLUNDO_CHANGE_GROUP ); + } + if(!aChangePB.IsEnabled()) + aIgnorePB.GrabFocus(); + return 1; +} + + +// ----------------------------------------------------------------------- + +IMPL_LINK( SpellDialog, ChangeAllHdl, Button *, EMPTYARG ) +{ + aSentenceED.UndoActionStart( SPELLUNDO_CHANGE_GROUP ); + // change the current word first + String aString = aSentenceED.GetErrorText(); + if(aSuggestionLB.IsEnabled() && + aSuggestionLB.GetSelectEntryCount()>0 && + aNoSuggestionsST != aSuggestionLB.GetSelectEntry()) + aString = aSuggestionLB.GetSelectEntry(); + + LanguageType eLang = GetSelectedLang_Impl(); + + // add new word to ChangeAll list + String aOldWord( aSentenceED.GetErrorText() ); + SvxPrepareAutoCorrect( aOldWord, aString ); + Reference<XDictionary> aXDictionary( SvxGetChangeAllList(), UNO_QUERY ); + sal_uInt8 nAdded = SvxAddEntryToDic( aXDictionary, + aOldWord , sal_True, + aString, eLang ); + + if(nAdded == DIC_ERR_NONE) + { + SpellUndoAction_Impl* pAction = new SpellUndoAction_Impl( + SPELLUNDO_CHANGE_ADD_TO_DICTIONARY, aDialogUndoLink); + pAction->SetDictionary(aXDictionary); + pAction->SetAddedWord(aOldWord); + aSentenceED.AddUndoAction(pAction); + } + + aSentenceED.ChangeMarkedWord(aString, eLang); + SpellContinue_Impl(); + bModified=sal_False; + aSentenceED.UndoActionEnd( SPELLUNDO_CHANGE_GROUP ); + return 1; +} +// ----------------------------------------------------------------------- + +IMPL_LINK( SpellDialog, IgnoreAllHdl, Button *, EMPTYARG ) +{ + aSentenceED.UndoActionStart( SPELLUNDO_CHANGE_GROUP ); + // add word to IgnoreAll list + Reference< XDictionary > aXDictionary( SvxGetIgnoreAllList(), UNO_QUERY ); + //in case the error has been changed manually it has to be restored + aSentenceED.RestoreCurrentError(); + String sErrorText(aSentenceED.GetErrorText()); + sal_uInt8 nAdded = SvxAddEntryToDic( aXDictionary, + sErrorText, sal_False, + ::rtl::OUString(), LANGUAGE_NONE ); + if(nAdded == DIC_ERR_NONE) + { + SpellUndoAction_Impl* pAction = new SpellUndoAction_Impl( + SPELLUNDO_CHANGE_ADD_TO_DICTIONARY, aDialogUndoLink); + pAction->SetDictionary(aXDictionary); + pAction->SetAddedWord(sErrorText); + aSentenceED.AddUndoAction(pAction); + } + + SpellContinue_Impl(); + bModified=sal_False; + aSentenceED.UndoActionEnd( SPELLUNDO_CHANGE_GROUP ); + return 1; +} +/*-- 06.11.2003 11:24:08--------------------------------------------------- + + -----------------------------------------------------------------------*/ +IMPL_LINK( SpellDialog, UndoHdl, Button*, EMPTYARG ) +{ + aSentenceED.Undo(); + if(!aSentenceED.GetUndoActionCount()) + aUndoPB.Enable(FALSE); + return 0; +} +/*-- 06.11.2003 12:19:15--------------------------------------------------- + + -----------------------------------------------------------------------*/ +IMPL_LINK( SpellDialog, DialogUndoHdl, SpellUndoAction_Impl*, pAction ) +{ + switch(pAction->GetId()) + { + case SPELLUNDO_CHANGE_TEXTENGINE: + { + if(pAction->IsEnableChangePB()) + aChangePB.Enable(FALSE); + if(pAction->IsEnableChangeAllPB()) + aChangeAllPB.Enable(FALSE); + } + break; + case SPELLUNDO_CHANGE_NEXTERROR: + { + aSentenceED.MoveErrorMarkTo((USHORT)pAction->GetOldErrorStart(), (USHORT)pAction->GetOldErrorEnd()); + if(pAction->IsErrorLanguageSelected()) + { + UpdateBoxes_Impl(); + } + } + break; + case SPELLUNDO_CHANGE_ADD_TO_DICTIONARY: + { + if(pAction->GetDictionary().is()) + pAction->GetDictionary()->remove(pAction->GetAddedWord()); + } + break; + case SPELLUNDO_MOVE_ERROREND : + { + if(pAction->GetOffset() != 0) + aSentenceED.MoveErrorEnd(pAction->GetOffset()); + } + break; + case SPELLUNDO_UNDO_EDIT_MODE : + { + //refill the dialog with the currently spelled sentence - throw away all changes + SpellContinue_Impl(true); + } + break; + } + + return 0; +} +// ----------------------------------------------------------------------- + +IMPL_LINK( SpellDialog, IgnoreHdl, Button *, EMPTYARG ) +{ + if(aIgnorePB.GetText() == aResumeST) + { + //clear the "ChangeAllList" + SvxGetChangeAllList()->clear(); + //get a new sentence + aSentenceED.SetText(rtl::OUString()); + aSentenceED.ResetModified(); + SpellContinue_Impl(); + aIgnorePB.SetText(aIgnoreOnceST); + } + else + { + //in case the error has been changed manually it has to be restored + aSentenceED.RestoreCurrentError(); + // the word is being ignored + SpellContinue_Impl(); + bModified=sal_False; + } + return 1; +} + + +// ----------------------------------------------------------------------- + +sal_Bool SpellDialog::Close() +{ + GetBindings().GetDispatcher()-> + Execute(SID_SPELL_DIALOG, + SFX_CALLMODE_ASYNCHRON|SFX_CALLMODE_RECORD); + return sal_True; +} +// ----------------------------------------------------------------------- + +void SpellDialog::SetSelectedLang_Impl( LanguageType nLang ) +{ + aLanguageLB.SelectLanguage( nLang ); +} + +// ----------------------------------------------------------------------- + +LanguageType SpellDialog::GetSelectedLang_Impl() const +{ + INT16 nLang = aLanguageLB.GetSelectLanguage(); + return nLang; +} +/* -----------------28.10.2003 14:27----------------- + + --------------------------------------------------*/ +IMPL_LINK(SpellDialog, LanguageSelectHdl, SvxLanguageBox*, pBox) +{ + //if currently an error is selected then search for alternatives for + //this word and fill the alternatives ListBox accordingly + String sError = aSentenceED.GetErrorText(); + aSuggestionLB.Clear(); + if(sError.Len()) + { + aSentenceED.SetAlternatives(xSpell->spell( sError, pBox->GetSelectLanguage(), + Sequence< PropertyValue >() )); + + aSentenceED.AddUndoAction(new SpellUndoAction_Impl(SPELLUNDO_CHANGE_LANGUAGE, aDialogUndoLink)); + } + SpellDialog::UpdateBoxes_Impl(); + return 0; +} +// ----------------------------------------------------------------------- + +void SpellDialog::SetLanguage( sal_uInt16 nLang ) + +/* [Beschreibung] + + wenn die Sprache im Thesaurus umgestellt wurde, + muss auch hier die Sprache umgestellt werden. +*/ + +{ + String aStr( aTitel ); + aStr.Append( UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( " (" ) ) ); + aStr.Append( ::GetLanguageString( (LanguageType)nLang ) ); + aStr.Append( sal_Unicode( ')' ) );; + SetText( aStr ); + + // den richtigen Eintrag finden, da sortiert + aLanguageLB.SelectLanguage( nLang ); +} +/*------------------------------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SpellDialog::InitUserDicts() +{ + sal_uInt16 nLang = aLanguageLB.GetSelectLanguage(); + + const Reference< XDictionary > *pDic = 0; + + // get list of dictionaries + Reference< XDictionaryList > xDicList( SvxGetDictionaryList() ); + if (xDicList.is()) + { + // add active, positive dictionary to dic-list (if not already done). + // This is to ensure that there is at least on dictionary to which + // words could be added. + Reference< XDictionary1 > xDic( SvxGetOrCreatePosDic( xDicList ) ); + if (xDic.is()) + xDic->setActive( sal_True ); + + pImpl->aDics = xDicList->getDictionaries(); + } + + // Benutzerbuecher anzeigen + const sal_Int32 nSize = pImpl->aDics.getLength(); + pDic = pImpl->aDics.getConstArray(); + sal_Int32 i; + delete aAddToDictMB.GetPopupMenu(); + PopupMenu* pMenu = new PopupMenu; + for (i = 0; i < nSize; ++i ) + { + Reference< XDictionary1 > xDic( pDic[i], UNO_QUERY ); + if (!xDic.is() || SvxGetIgnoreAllList() == xDic) + continue; + + // add only active and not read-only dictionaries to list + // from which to choose from + Reference< frame::XStorable > xStor( xDic, UNO_QUERY ); + if ( xDic->isActive() && (!xStor.is() || !xStor->isReadonly()) ) + { + sal_Bool bNegativ = xDic->getDictionaryType() == DictionaryType_NEGATIVE; + pMenu->InsertItem( (USHORT)i + 1, ::GetDicInfoStr( xDic->getName(), + xDic->getLanguage(), bNegativ ) ); + } + } + aAddToDictMB.SetPopupMenu(pMenu); + + aAddToDictMB.Disable(); + + sal_uInt16 k; + for ( k = 0; k < pMenu->GetItemCount(); ++k ) + { + sal_uInt16 nId = pMenu->GetItemId(k) - 1; + sal_Bool bFound = sal_False; + + const sal_uInt16 nDicLang = SvxLocaleToLanguage( pDic[nId]->getLocale() ); + const sal_Bool bDicNegativ = + pDic[nId]->getDictionaryType() == DictionaryType_NEGATIVE; + // Stimmt die Sprache "uberein, dann enable + if ((nDicLang == nLang || nDicLang == LANGUAGE_NONE) && !bDicNegativ) + bFound = sal_True; + + if (bFound) + { + aAddToDictMB.Enable(); + break; + } + } +} +/*-- 20.10.2003 15:31:06--------------------------------------------------- + + -----------------------------------------------------------------------*/ +IMPL_LINK(SpellDialog, AddToDictionaryHdl, MenuButton*, pButton ) +{ + aSentenceED.UndoActionStart( SPELLUNDO_CHANGE_GROUP ); + USHORT nItem = pButton->GetCurItemId(); + + //GetErrorText() returns the current error even if the text is already + //manually changed + String sNewWord= aSentenceED.GetErrorText(); + + Reference< XDictionary > xDic( pImpl->aDics.getConstArray()[ nItem - 1 ], UNO_QUERY ); + sal_Int16 nAddRes = DIC_ERR_UNKNOWN; + if (xDic.is()) + { + String sTmpTxt( sNewWord ); + sal_Bool bNegEntry = xDic->getDictionaryType() == DictionaryType_NEGATIVE; + nAddRes = SvxAddEntryToDic( xDic, sTmpTxt, bNegEntry, + OUString(), LANGUAGE_NONE ); + + if(nAddRes == DIC_ERR_NONE) + { + SpellUndoAction_Impl* pAction = new SpellUndoAction_Impl( + SPELLUNDO_CHANGE_ADD_TO_DICTIONARY, aDialogUndoLink); + pAction->SetDictionary(xDic); + pAction->SetAddedWord(sTmpTxt); + aSentenceED.AddUndoAction(pAction); + } + // failed because there is already an entry? + if (DIC_ERR_NONE != nAddRes && xDic->getEntry( sTmpTxt ).is()) + nAddRes = DIC_ERR_NONE; + } + if (DIC_ERR_NONE != nAddRes) + { + SvxDicError( this, nAddRes ); + return 0; // Nicht weitermachen + } + // nach dem Aufnehmen ggf. '='-Zeichen entfernen + sNewWord.EraseAllChars( sal_Unicode( '=' ) ); + + // go on + SpellContinue_Impl(); + aSentenceED.UndoActionEnd( SPELLUNDO_CHANGE_GROUP ); + return 0; +} +/*------------------------------------------------------------------------- + + -----------------------------------------------------------------------*/ +IMPL_LINK(SpellDialog, ModifyHdl, SentenceEditWindow_Impl*, pEd) +{ + if (&aSentenceED == pEd) + { + bModified=sal_True; + aSuggestionLB.SetNoSelection(); + aSuggestionLB.Disable(); + String sNewText( aSentenceED.GetText() ); + aAutoCorrPB.Enable( sNewText != aSentenceED.GetText() ); + bool bChange = aChangeAllPB.IsEnabled(); + SpellUndoAction_Impl* pSpellAction = new SpellUndoAction_Impl(SPELLUNDO_CHANGE_TEXTENGINE, aDialogUndoLink); + if(!aChangeAllPB.IsEnabled()) + { + aChangeAllPB.Enable(); + pSpellAction->SetEnableChangeAllPB(); + } + if(!aChangePB.IsEnabled()) + { + aChangePB.Enable(); + pSpellAction->SetEnableChangePB(); + } + aSentenceED.AddUndoAction(pSpellAction); + } + return 0; +}; +/*------------------------------------------------------------------------- + + -----------------------------------------------------------------------*/ +IMPL_LINK(SpellDialog, CancelHdl, Button *, pButton ) +{ + Close(); + return 0; +} +/*------------------------------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SpellDialog::Paint( const Rectangle& rRect ) +{ + ModelessDialog::Paint(rRect ); + Rectangle aRect(aBackgroundGB.GetPosPixel(), aBackgroundGB.GetSizePixel()); + DecorationView aDecoView( this ); + aDecoView.DrawButton( aRect, BUTTON_DRAW_NOFILL); +} +/*-- 28.10.2003 13:26:39--------------------------------------------------- + + -----------------------------------------------------------------------*/ +long SpellDialog::Notify( NotifyEvent& rNEvt ) +{ + if( rNEvt.GetType() == EVENT_GETFOCUS ) + { + //notify the child window of the focus change + rParent.GetFocus(); + } + else if( rNEvt.GetType() == EVENT_LOSEFOCUS ) + { + //notify the child window of the focus change + rParent.LoseFocus(); + } + return SfxModelessDialog::Notify(rNEvt); +} +/* -----------------10.09.2003 08:26----------------- + + --------------------------------------------------*/ +void SpellDialog::Invalidate() +{ + aIgnorePB.SetText(aResumeST); + Window* aDisableArr[] = + { + &aNotInDictFT, + &aSentenceED, + &aSuggestionFT, + &aSuggestionLB, + &aLanguageFT, + &aLanguageLB, + &aIgnoreAllPB, + &aAddToDictMB, + &aChangePB, + &aChangeAllPB, + &aAutoCorrPB, + &aUndoPB, + 0 + }; + sal_Int16 i = 0; + while(aDisableArr[i]) + { + aDisableArr[i]->Enable(FALSE); + i++; + } + SfxModelessDialog::Deactivate(); +} + +/*-- 10.09.2003 08:35:56--------------------------------------------------- + + -----------------------------------------------------------------------*/ +bool SpellDialog::GetNextSentence_Impl(bool bUseSavedSentence) +{ + bool bRet = false; + if(!bUseSavedSentence && aSentenceED.IsModified()) + { + rParent.ApplyChangedSentence(aSentenceED.CreateSpellPortions()); + } + aSentenceED.ResetModified(); + SpellPortions aSentence = bUseSavedSentence ? m_aSavedSentence : rParent.GetNextWrongSentence(); + if(!bUseSavedSentence) + m_aSavedSentence = aSentence; + bool bHasReplaced = false; + while(aSentence.size()) + { + //apply all changes that are already part of the "ChangeAllList" + //returns true if the list still contains errors after the changes have been applied + + if(!ApplyChangeAllList_Impl(aSentence, bHasReplaced)) + { + rParent.ApplyChangedSentence(aSentence); + aSentence = rParent.GetNextWrongSentence(); + } + else + break; + } + + if(aSentence.size()) + { + SpellPortions::iterator aStart = aSentence.begin(); + rtl::OUString sText; + while(aStart != aSentence.end()) + { + sText += aStart->sText; + aStart++; + } + aSentenceED.SetText(sText); + aStart = aSentence.begin(); + sal_Int32 nStartPosition = 0; + sal_Int32 nEndPosition = 0; + + while(aStart != aSentence.end()) + { + nEndPosition += aStart->sText.getLength(); + if(aStart->xAlternatives.is()) + aSentenceED.SetAttrib( SpellErrorAttrib(aStart->xAlternatives), 0, (USHORT) nStartPosition, (USHORT) nEndPosition ); + if(aStart->bIsField) + aSentenceED.SetAttrib( SpellBackgroundAttrib(COL_LIGHTGRAY), 0, (USHORT) nStartPosition, (USHORT) nEndPosition ); + aSentenceED.SetAttrib( SpellLanguageAttrib(aStart->eLanguage), 0, (USHORT) nStartPosition, (USHORT) nEndPosition ); + nStartPosition = nEndPosition; + aStart++; + } + //the edit field needs to be modified to apply the change from the ApplyChangeAllList + if(!bHasReplaced) + aSentenceED.ClearModifyFlag(); + aSentenceED.ResetUndo(); + aUndoPB.Enable(FALSE); + bRet = nStartPosition > 0; + } + return bRet; +} +/*-- 12.11.2003 15:21:25--------------------------------------------------- + replace errrors that have a replacement in the ChangeAllList + returns false if the result doesn't contain errors after the replacement + -----------------------------------------------------------------------*/ +bool SpellDialog::ApplyChangeAllList_Impl(SpellPortions& rSentence, bool &bHasReplaced) +{ + bHasReplaced = false; + bool bRet = true; + SpellPortions::iterator aStart = rSentence.begin(); + Reference<XDictionary> xChangeAll( SvxGetChangeAllList(), UNO_QUERY ); + if(!xChangeAll->getCount()) + return bRet; + bRet = false; + while(aStart != rSentence.end()) + { + if(aStart->xAlternatives.is()) + { + Reference<XDictionaryEntry> xEntry = xChangeAll->getEntry( aStart->sText ); + if(xEntry.is()) + { + aStart->sText = xEntry->getReplacementText(); + bHasReplaced = true; + } + else + bRet = true; + } + aStart++; + } + return bRet; +} +/*-- 10.09.2003 10:40:21--------------------------------------------------- + + -----------------------------------------------------------------------*/ +SentenceEditWindow_Impl::SentenceEditWindow_Impl( SpellDialog* pParent, const ResId& rResId ) : + MultiLineEdit( pParent, rResId ), + m_nErrorStart(0), + m_nErrorEnd(0), + m_bIsUndoEditMode(false) +{ + DisableSelectionOnFocus(); +} +/*-- 10.09.2003 10:40:11--------------------------------------------------- + + -----------------------------------------------------------------------*/ +SentenceEditWindow_Impl::~SentenceEditWindow_Impl() +{ +} +/*-- 20.10.2003 13:42:34--------------------------------------------------- + The selection before inputting a key may have a range or not + and it may be inside or outside of field or error attributes. + A range may include the attribute partially, completely or together + with surrounding text. It may also contain more than one attribute + or no attribute at all. + Depending on this starting conditions some actions are necessary: + Attempts to delete a field are only allowed if the selection is the same + as the field's selection. Otherwise the field has to be selected and the key + input action has to be skipped. + Input of text at the start of the field requires the field attribute to be + corrected - it is not allowed to grow. + + In case of errors the appending of text should grow the error attribute because + that is what the user usually wants to do. + + Backspace at the start of the attribute requires to find out if a field ends + directly in front of the cursor position. In case of a field this attribute has to be + selected otherwise the key input method is allowed. + + All changes outside of the error attributes switch the dialog mode to a "Undo edit" state that + removes all visible attributes and switches off further attribute checks. + Undo in this restarts the dialog with a current sentence newly presented. + All changes to the sentence are undone including the ones before the "Undo edit state" has been reached + + We end up with 9 types of selection + 1 (LEFT_NO) - no range, start of attribute - can also be 3 at the same time + 2 (INSIDE_NO) - no range, inside of attribute + 3 (RIGHT_NO) - no range, end of attribute - can also be 1 at the same time + 4 (FULL) - range, same as attribute + 5 (INSIDE_YES) - range, inside of the attribute + 6 (BRACE)- range, from outside of the attribute to the inside or + including the complete attribute and something outside, + maybe more than one attribute + 7 (OUTSIDE_NO) - no range, not at an attribute + 8 (OUTSIDE_YES) - range, completely outside of all attributes + + What has to be done depending on the attribute type involved + possible actions: UE - Undo edit mode + CO - Continue, no additional action is required + FS - Field has to be completely selected + EX - The attribute has to be expanded to include the added text + + 1 - backspace delete any other + UE on field FS on error CO on field FS on error CO + + 2 - on field FS on error C + 3 - backspace delete any other + on field FS on error CO UE on field UE on error EX + + if 1 and 3 happen to apply both then backspace and other handling is 1 delete is 3 + + 4 - on field UE and on error CO + 5 - on field FS and on error CO + 6 - on field FS and on error UE + 7 - UE + 8 - UE + -----------------------------------------------------------------------*/ +#define INVALID 0 +#define LEFT_NO 1 +#define INSIDE_NO 2 +#define RIGHT_NO 3 +#define FULL 4 +#define INSIDE_YES 5 +#define BRACE 6 +#define OUTSIDE_NO 7 +#define OUTSIDE_YES 8 + +#define ACTION_UNDOEDIT 0 +#define ACTION_CONTINUE 1 +#define ACTION_SELECTFIELD 2 +#define ACTION_EXPAND 3 + +long SentenceEditWindow_Impl::PreNotify( NotifyEvent& rNEvt ) +{ + bool bChange = false; + const TextCharAttrib* pErrorAttrib = 0; + if(rNEvt.GetType() == EVENT_KEYINPUT) + { + const KeyEvent& rKeyEvt = *rNEvt.GetKeyEvent(); + bChange = TextEngine::DoesKeyChangeText( rKeyEvt ); + if(bChange && !IsUndoEditMode() && + rKeyEvt.GetKeyCode().GetCode() != KEY_TAB) + { + TextEngine* pTextEngine = GetTextEngine(); + TextView* pTextView = pTextEngine->GetActiveView(); + const TextSelection& rCurrentSelection = pTextView->GetSelection(); + //determine if the selection contains a field + bool bHasField = false; + bool bHasError = false; + bool bHasFieldLeft = false; + bool bHasErrorLeft = false; +// bool bInsideAttr = false; + + bool bHasRange = rCurrentSelection.HasRange(); + sal_uInt8 nSelectionType = 0; // invalid type! + + TextPaM aCursor(rCurrentSelection.GetStart()); + const TextCharAttrib* pBackAttr = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_BACKGROUND ); + const TextCharAttrib* pErrorAttr = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_ERROR ); + const TextCharAttrib* pBackAttrLeft = 0; + const TextCharAttrib* pErrorAttrLeft = 0; + + bHasField = pBackAttr != 0 && (bHasRange || pBackAttr->GetEnd() > aCursor.GetIndex()); + bHasError = pErrorAttr != 0 && (bHasRange || pErrorAttr->GetEnd() > aCursor.GetIndex()); + if(bHasRange) + { + if(pBackAttr && + pBackAttr->GetStart() == rCurrentSelection.GetStart().GetIndex() && + pBackAttr->GetEnd() == rCurrentSelection.GetEnd().GetIndex()) + { + nSelectionType = FULL; + } + else if(pErrorAttr && + pErrorAttr->GetStart() <= rCurrentSelection.GetStart().GetIndex() && + pErrorAttr->GetEnd() >= rCurrentSelection.GetEnd().GetIndex()) + { + nSelectionType = INSIDE_YES; + } + else + { + nSelectionType = bHasField||bHasError ? BRACE : OUTSIDE_NO; + while(aCursor.GetIndex() < rCurrentSelection.GetEnd().GetIndex()) + { + ++aCursor.GetIndex(); + const TextCharAttrib* pIntBackAttr = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_BACKGROUND ); + const TextCharAttrib* pIntErrorAttr = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_ERROR ); + //if any attr has been found then BRACE + if(pIntBackAttr || pIntErrorAttr) + nSelectionType = BRACE; + //the field has to be selected + if(pIntBackAttr && !pBackAttr) + pBackAttr = pIntBackAttr; + bHasField |= pIntBackAttr != 0; + } + } + } + else + { + //no range selection: then 1 2 3 and 8 are possible + const TextCharAttrib* pCurAttr = pBackAttr ? pBackAttr : pErrorAttr; + if(pCurAttr) + { + nSelectionType = pCurAttr->GetStart() == rCurrentSelection.GetStart().GetIndex() ? + LEFT_NO : pCurAttr->GetEnd() == rCurrentSelection.GetEnd().GetIndex() ? RIGHT_NO : INSIDE_NO; + } + else + nSelectionType = OUTSIDE_NO; + + bHasFieldLeft = pBackAttr && pBackAttr->GetEnd() == aCursor.GetIndex(); + if(bHasFieldLeft) + { + pBackAttrLeft = pBackAttr; + pBackAttr = 0; + } + bHasErrorLeft = pErrorAttr && pErrorAttr->GetEnd() == aCursor.GetIndex(); + if(bHasErrorLeft) + { + pErrorAttrLeft = pErrorAttr; + pErrorAttr = 0; + } + + //check previous position if this exists + //that is a redundant in the case the the attribute found above already is on the left cursor side + //but it's o.k. for two errors/fields side by side + if(aCursor.GetIndex()) + { + --aCursor.GetIndex(); + pBackAttrLeft = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_BACKGROUND ); + pErrorAttrLeft = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_ERROR ); + bHasFieldLeft = pBackAttrLeft !=0; + bHasErrorLeft = pErrorAttrLeft != 0; +// bInsideAttr = (bHasField || bHasError) && (bHasFieldLeft || bHasErrorLeft); + ++aCursor.GetIndex(); + } + } + //Here we have to determine if the error found is the one currently active + bool bIsErrorActive = pErrorAttr && pErrorAttr->GetStart() == m_nErrorStart || + pErrorAttrLeft && pErrorAttrLeft->GetStart() == m_nErrorStart; + + DBG_ASSERT(nSelectionType != INVALID, "selection type not set!") + + const KeyCode& rKeyCode = rKeyEvt.GetKeyCode(); + bool bDelete = rKeyCode.GetCode() == KEY_DELETE; + bool bBackspace = rKeyCode.GetCode() == KEY_BACKSPACE; + + sal_Int8 nAction = ACTION_CONTINUE; +// nAction = ACTION_UNDOEDIT +// nAction = ACTION_SELECTFIELD +// nAction = ACTION_EXPAND + switch(nSelectionType) + { +// 1 - backspace delete any other +// UE on field FS on error CO on field FS on error CO + case LEFT_NO : + if(bBackspace) + { + nAction = bHasFieldLeft ? ACTION_SELECTFIELD : ACTION_UNDOEDIT; + //to force the use of pBackAttrLeft + pBackAttr = 0; + } + else if(bDelete) + nAction = bHasField ? ACTION_SELECTFIELD : ACTION_CONTINUE; + else + nAction = bHasError && !aCursor.GetIndex() ? ACTION_CONTINUE : + bHasError ? ACTION_EXPAND : bHasErrorLeft ? ACTION_CONTINUE : ACTION_UNDOEDIT; + break; +// 2 - on field FS on error C + case INSIDE_NO : + nAction = bHasField ? ACTION_SELECTFIELD : + bIsErrorActive ? ACTION_CONTINUE : ACTION_UNDOEDIT; + break; +// 3 - backspace delete any other +// on field FS on error CO UE on field UE on error EX + case RIGHT_NO : + if(bBackspace) + nAction = bHasFieldLeft ? ACTION_SELECTFIELD : ACTION_CONTINUE; + else if(bDelete) + nAction = bHasFieldLeft && bHasError ? ACTION_CONTINUE : ACTION_UNDOEDIT; + else + nAction = bHasFieldLeft && bHasError ? ACTION_EXPAND : + bHasError ? ACTION_CONTINUE : bHasErrorLeft ? ACTION_EXPAND :ACTION_UNDOEDIT; + break; +// 4 - on field UE and on error CO + case FULL : + nAction = bHasField ? ACTION_UNDOEDIT : ACTION_CONTINUE; + break; +// 5 - on field FS and on error CO + case INSIDE_YES : + nAction = bHasField ? ACTION_SELECTFIELD : ACTION_CONTINUE; + break; +// 6 - on field FS and on error UE + case BRACE : + nAction = bHasField ? ACTION_SELECTFIELD : ACTION_UNDOEDIT;; + break; +// 7 - UE +// 8 - UE + case OUTSIDE_NO : + case OUTSIDE_YES: + nAction = ACTION_UNDOEDIT; + break; + } + //save the current paragraph + USHORT nCurrentLen = GetText().Len(); + if(nAction != ACTION_SELECTFIELD) + pTextView->GetWindow()->KeyInput(rKeyEvt); + else + { + const TextCharAttrib* pCharAttr = pBackAttr ? pBackAttr : pBackAttrLeft; + if(pCharAttr) + { + TextPaM aStart(0, pCharAttr->GetStart()); + TextPaM aEnd(0, pCharAttr->GetEnd()); + TextSelection aNewSel(aStart, aEnd); + pTextView->SetSelection( aNewSel); + } + } + if(nAction == ACTION_EXPAND) + { + DBG_ASSERT(pErrorAttrLeft || pErrorAttr, "where is the error") + //text has been added on the right and only the 'error attribute has to be corrected + if(pErrorAttrLeft) + { + TextAttrib* pNewError = pErrorAttrLeft->GetAttr().Clone(); + USHORT nStart = pErrorAttrLeft->GetStart(); + USHORT nEnd = pErrorAttrLeft->GetEnd(); + pTextEngine->RemoveAttrib( 0, *pErrorAttrLeft ); + SetAttrib( *pNewError, 0, nStart, ++nEnd ); + //only active errors move the mark + if(bIsErrorActive) + MoveErrorMarkTo(nStart, nEnd); + delete pNewError; + } + //text has been added on the left then the error attribute has to be expanded and the + //field attribute on the right - if any - has to be contracted + else if(pErrorAttr) + { + //determine the change + USHORT nAddedChars = GetText().Len() - nCurrentLen; + + TextAttrib* pNewError = pErrorAttr->GetAttr().Clone(); + USHORT nStart = pErrorAttr->GetStart(); + USHORT nEnd = pErrorAttr->GetEnd(); + pTextEngine->RemoveAttrib( 0, *pErrorAttr ); + nStart -= nAddedChars; + SetAttrib( *pNewError, 0, nStart - nAddedChars, nEnd ); + //only if the error is active the mark is moved here + if(bIsErrorActive) + MoveErrorMarkTo(nStart, nEnd); + delete pNewError; + + if(pBackAttrLeft) + { + TextAttrib* pNewBack = pBackAttrLeft->GetAttr().Clone(); + USHORT nStart = pBackAttrLeft->GetStart(); + USHORT nEnd = pBackAttrLeft->GetEnd(); + pTextEngine->RemoveAttrib( 0, *pBackAttrLeft ); + SetAttrib( *pNewBack, 0, nStart, nEnd - nAddedChars); + delete pNewBack; + } + } + } + else if(nAction == ACTION_UNDOEDIT) + { + SetUndoEditMode(true); + } + //make sure the error positions are correct after text changes + //the old attribute may have been deleted + //all changes inside of the current error leave the error attribute at the current + //start position + if(!IsUndoEditMode() && bIsErrorActive) + { + const TextCharAttrib* pFontColor = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_FONTCOLOR ); + pErrorAttrib = pTextEngine->FindCharAttrib( TextPaM(0, m_nErrorStart), TEXTATTR_SPELL_ERROR ); + if(pFontColor && pErrorAttrib ) + { + m_nErrorStart = pFontColor->GetStart(); + m_nErrorEnd = pFontColor->GetEnd(); + if(pErrorAttrib->GetStart() != m_nErrorStart || pErrorAttrib->GetEnd() != m_nErrorEnd) + { + TextAttrib* pNewError = pErrorAttrib->GetAttr().Clone(); + pTextEngine->RemoveAttrib( 0, *pErrorAttr ); + SetAttrib( *pNewError, 0, m_nErrorStart, m_nErrorEnd ); + delete pNewError; + } + } + } + //this is not a modification anymore + if(nAction != ACTION_SELECTFIELD && !m_bIsUndoEditMode) + CallModifyLink(); + } + else + bChange = false; + } + long nRet = bChange ? 1 : MultiLineEdit::PreNotify(rNEvt); + return nRet; +} +/*-- 10.09.2003 13:38:14--------------------------------------------------- + + -----------------------------------------------------------------------*/ +bool SentenceEditWindow_Impl::MarkNextError() +{ + ExtTextEngine* pTextEngine = GetTextEngine(); + USHORT nTextLen = pTextEngine->GetTextLen(0); + if(m_nErrorEnd >= nTextLen - 1) + return false; + //if it's not already modified the modified flag has to be reset at the and of the marking + bool bModified = IsModified(); + bool bRet = false; + const USHORT nOldErrorStart = m_nErrorStart; + const USHORT nOldErrorEnd = m_nErrorEnd; + + //create a cursor behind the end of the last error + //- or at 0 at the start of the sentence + TextPaM aCursor(0, m_nErrorEnd ? m_nErrorEnd + 1 : 0); + //search for SpellErrorAttrib + + const TextCharAttrib* pNextError = 0; + //iterate over the text and search for the next error that maybe has + //to be replace by a ChangeAllList replacement + while(aCursor.GetIndex() < nTextLen) + { + while(aCursor.GetIndex() < nTextLen && + 0 == (pNextError = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_ERROR))) + { + ++aCursor.GetIndex(); + } + // maybe the error found here is already in the ChangeAllList and has to be replaced + + Reference<XDictionary> xChangeAll( SvxGetChangeAllList(), UNO_QUERY ); + Reference<XDictionaryEntry> xEntry; + + Reference <XSpellAlternatives> xAlternatives; + if(pNextError) + xAlternatives = static_cast<const SpellErrorAttrib&>(pNextError->GetAttr()).GetAlternatives(); + if(xChangeAll->getCount() && xAlternatives.is() && + (xEntry = xChangeAll->getEntry( xAlternatives->getWord() )).is()) + { + m_nErrorStart = pNextError->GetStart(); + m_nErrorEnd = pNextError->GetEnd(); + ChangeMarkedWord(xEntry->getReplacementText(), + SvxLocaleToLanguage( xAlternatives->getLocale() )); + aCursor.GetIndex() += (USHORT)xEntry->getReplacementText().getLength(); + } + else + break; + } + + //if an attrib has been found search for the end of the error string + if(aCursor.GetIndex() < nTextLen) + { + m_nErrorStart = aCursor.GetIndex(); + m_nErrorEnd = pNextError->GetEnd(); + MoveErrorMarkTo(m_nErrorStart, m_nErrorEnd); + bRet = true; + //add an undo action + SpellUndoAction_Impl* pAction = new SpellUndoAction_Impl( + SPELLUNDO_CHANGE_NEXTERROR, GetSpellDialog()->aDialogUndoLink); + pAction->SetErrorMove(m_nErrorStart, m_nErrorEnd, nOldErrorStart, nOldErrorEnd); + const SpellErrorAttrib* pOldAttrib = static_cast<const SpellErrorAttrib*>( + pTextEngine->FindAttrib( TextPaM(0, nOldErrorStart), TEXTATTR_SPELL_ERROR )); + //if the window has been modified then an error should have been found + DBG_ASSERT(!bModified || pOldAttrib, "old error could not be found") + pAction->SetErrorLanguageSelected(pOldAttrib && pOldAttrib->GetAlternatives().is() && + SvxLocaleToLanguage( pOldAttrib->GetAlternatives()->getLocale()) == + GetSpellDialog()->aLanguageLB.GetSelectLanguage()); + AddUndoAction(pAction); + } + else + m_nErrorStart = m_nErrorEnd = nTextLen; + if( !bModified ) + ClearModifyFlag(); + SpellDialog* pSpellDialog = GetSpellDialog(); + pSpellDialog->aIgnorePB.Enable(bRet); + pSpellDialog->aIgnoreAllPB.Enable(bRet); + pSpellDialog->aAutoCorrPB.Enable(bRet); + pSpellDialog->aAddToDictMB.Enable(bRet); + return bRet; +} + +/*-- 06.11.2003 13:30:26--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SentenceEditWindow_Impl::MoveErrorMarkTo(USHORT nStart, USHORT nEnd) +{ + TextEngine* pTextEngine = GetTextEngine(); + pTextEngine->RemoveAttribs( 0, (USHORT)TEXTATTR_FONTCOLOR ); + pTextEngine->RemoveAttribs( 0, (USHORT)TEXTATTR_FONTWEIGHT ); + pTextEngine->SetAttrib( TextAttribFontWeight(WEIGHT_BOLD), 0, nStart, nEnd ); + pTextEngine->SetAttrib( TextAttribFontColor(COL_LIGHTRED), 0, nStart, nEnd ); + m_nErrorStart = nStart; + m_nErrorEnd = nEnd; +} + +/*-- 17.09.2003 10:13:08--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SentenceEditWindow_Impl::ChangeMarkedWord(const String& rNewWord, LanguageType eLanguage) +{ + //calculate length changes + long nOldStart = m_nErrorStart; + long nOldEnd = m_nErrorEnd; + long nDiffLen = rNewWord.Len() - m_nErrorEnd + m_nErrorStart; + TextSelection aSel(TextPaM(0, m_nErrorStart), TextPaM(0, m_nErrorEnd)); + //Remove spell errror attribute + ExtTextEngine* pTextEngine = GetTextEngine(); + pTextEngine->UndoActionStart( TEXTUNDO_INSERT ); + const TextCharAttrib* pErrorAttrib = pTextEngine->FindCharAttrib( TextPaM(0, m_nErrorStart), TEXTATTR_SPELL_ERROR ); + DBG_ASSERT(pErrorAttrib, "no error attribute found") + Reference <XSpellAlternatives> xAlternatives; + if(pErrorAttrib) + { + pTextEngine->RemoveAttrib(0, *pErrorAttrib); + xAlternatives = static_cast<const SpellErrorAttrib&>(pErrorAttrib->GetAttr()).GetAlternatives(); + } + const TextCharAttrib* pBackAttrib = pTextEngine->FindCharAttrib( TextPaM(0, m_nErrorStart), TEXTATTR_SPELL_BACKGROUND ); + pTextEngine->ReplaceText( aSel, rNewWord ); + // + if(!m_nErrorStart) + { + //attributes following an error at the start of the text are not moved but expanded from the + //text engine - this is done to keep full-paragraph-attributes + //in the current case that handling is not desired + const TextCharAttrib* pLangAttrib = + pTextEngine->FindCharAttrib( + TextPaM(0, m_nErrorEnd), TEXTATTR_SPELL_LANGUAGE ); + USHORT nTextLen = pTextEngine->GetTextLen( 0 ); + if(pLangAttrib && !pLangAttrib->GetStart() && pLangAttrib->GetEnd() == + nTextLen) + { + SpellLanguageAttrib aNewLangAttrib( static_cast<const SpellLanguageAttrib&>(pLangAttrib->GetAttr()).GetLanguage()); + pTextEngine->RemoveAttrib(0, *pLangAttrib); + pTextEngine->SetAttrib( aNewLangAttrib, 0, m_nErrorEnd + nDiffLen , nTextLen ); + } + } + // undo expanded attributes! + if( pBackAttrib && pBackAttrib->GetStart() < m_nErrorStart && pBackAttrib->GetEnd() == m_nErrorEnd + nDiffLen) + { + TextAttrib* pNewBackground = pBackAttrib->GetAttr().Clone(); + USHORT nStart = pBackAttrib->GetStart(); + pTextEngine->RemoveAttrib(0, *pBackAttrib); + pTextEngine->SetAttrib(*pNewBackground, 0, nStart, m_nErrorStart); + delete pNewBackground; + } + pTextEngine->SetModified(TRUE); + + //adjust end position + long nEndTemp = m_nErrorEnd; + nEndTemp += nDiffLen; + m_nErrorEnd = (USHORT)nEndTemp; + + SpellUndoAction_Impl* pAction = new SpellUndoAction_Impl( + SPELLUNDO_MOVE_ERROREND, GetSpellDialog()->aDialogUndoLink); + pAction->SetOffset(nDiffLen); + AddUndoAction(pAction); + SetAttrib( SpellErrorAttrib(xAlternatives), 0, m_nErrorStart, m_nErrorEnd ); + SetAttrib( SpellLanguageAttrib(eLanguage), 0, m_nErrorStart, m_nErrorEnd ); + pTextEngine->UndoActionEnd( TEXTUNDO_INSERT ); +} +/* -----------------08.10.2003 13:18----------------- + + --------------------------------------------------*/ +String SentenceEditWindow_Impl::GetErrorText() const +{ + return GetTextEngine()->GetText(TextSelection(TextPaM(0, m_nErrorStart), TextPaM(0, m_nErrorEnd) )); +} +/*-- 10.09.2003 13:38:14--------------------------------------------------- + + -----------------------------------------------------------------------*/ +Reference<XSpellAlternatives> SentenceEditWindow_Impl::GetAlternatives() +{ + TextPaM aCursor(0, m_nErrorStart); + const SpellErrorAttrib* pAttrib = static_cast<const SpellErrorAttrib*>( + GetTextEngine()->FindAttrib( aCursor, TEXTATTR_SPELL_ERROR)); + Reference <XSpellAlternatives> xRet; + if(pAttrib) + xRet = pAttrib->GetAlternatives(); + return xRet; +} +/*-- 06.09.2004 10:50:32--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SentenceEditWindow_Impl::RestoreCurrentError() +{ + TextPaM aCursor(0, m_nErrorStart); + const SpellErrorAttrib* pAttrib = static_cast<const SpellErrorAttrib*>( + GetTextEngine()->FindAttrib( aCursor, TEXTATTR_SPELL_ERROR)); + Reference <XSpellAlternatives> xRet; + Reference<XSpellAlternatives> xAlt = pAttrib ? pAttrib->GetAlternatives() : 0; + if(xAlt.is()) + { + String sError = xAlt->getWord(); + if( GetErrorText() != sError ) + ChangeMarkedWord(sError, SvxLocaleToLanguage( xAlt->getLocale() )); + } +} +/*-- 28.10.2003 14:44:10--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SentenceEditWindow_Impl::SetAlternatives( Reference< XSpellAlternatives> xAlt ) +{ + TextPaM aCursor(0, m_nErrorStart); + DBG_ASSERT(static_cast<const SpellErrorAttrib*>( + GetTextEngine()->FindAttrib( aCursor, TEXTATTR_SPELL_ERROR)), "no error set?") + GetTextEngine()->SetAttrib( SpellErrorAttrib(xAlt), 0, m_nErrorStart, m_nErrorEnd ); +} + +/*-- 10.09.2003 14:43:02--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SentenceEditWindow_Impl::SetAttrib( const TextAttrib& rAttr, ULONG nPara, USHORT nStart, USHORT nEnd ) +{ + GetTextEngine()->SetAttrib(rAttr, nPara, nStart, nEnd); +} +/*-- 10.09.2003 14:43:02--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SentenceEditWindow_Impl::SetText( const String& rStr ) +{ + m_nErrorStart = m_nErrorEnd = 0; + GetTextEngine()->SetText(rStr); +// InitScrollBars(); +} +/*-- 08.10.2003 14:35:52--------------------------------------------------- + + -----------------------------------------------------------------------*/ +struct LanguagePosition_Impl +{ + USHORT nPosition; + LanguageType eLanguage; + + LanguagePosition_Impl(USHORT nPos, LanguageType eLang) : + nPosition(nPos), + eLanguage(eLang) + {} +}; +typedef std::vector<LanguagePosition_Impl> LanguagePositions_Impl; + +void lcl_InsertBreakPosition_Impl( + LanguagePositions_Impl& rBreakPositions, USHORT nInsert, LanguageType eLanguage) +{ + LanguagePositions_Impl::iterator aStart = rBreakPositions.begin(); + while(aStart != rBreakPositions.end()) + { + if(aStart->nPosition == nInsert) + { + //the language of following starts has to overwrite + //the one of previous ends + aStart->eLanguage = eLanguage; + return; + } + else if(aStart->nPosition > nInsert) + { + + rBreakPositions.insert(aStart, LanguagePosition_Impl(nInsert, eLanguage)); + return; + } + else + ++aStart; + } + rBreakPositions.push_back(LanguagePosition_Impl(nInsert, eLanguage)); +} +/*-- 17.09.2003 14:26:59--------------------------------------------------- + Returns the text in spell portions. Each portion contains text with an + equal language and attribute. The spell alternatives are empty. + -----------------------------------------------------------------------*/ +svx::SpellPortions SentenceEditWindow_Impl::CreateSpellPortions() const +{ + svx::SpellPortions aRet; + ExtTextEngine* pTextEngine = GetTextEngine(); + const USHORT nTextLen = pTextEngine->GetTextLen(0); + if(nTextLen) + { + TextPaM aCursor(0, 0); + LanguagePositions_Impl aBreakPositions; + const TextCharAttrib* pLastLang = 0; + const TextCharAttrib* pLastError = 0; + LanguageType eLang = LANGUAGE_DONTKNOW; + while(aCursor.GetIndex() < nTextLen) + { + const TextCharAttrib* pLang = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_LANGUAGE); + if(pLang && pLang != pLastLang) + { + eLang = static_cast<const SpellLanguageAttrib&>(pLang->GetAttr()).GetLanguage(); + lcl_InsertBreakPosition_Impl(aBreakPositions, pLang->GetStart(), eLang); + lcl_InsertBreakPosition_Impl(aBreakPositions, pLang->GetEnd(), eLang); + pLastLang = pLang; + } + const TextCharAttrib* pError = pTextEngine->FindCharAttrib( aCursor, TEXTATTR_SPELL_ERROR); + if(pError && pLastError != pError) + { + lcl_InsertBreakPosition_Impl(aBreakPositions, pError->GetStart(), eLang); + lcl_InsertBreakPosition_Impl(aBreakPositions, pError->GetEnd(), eLang); + pLastError = pError; + } + aCursor.GetIndex()++; + } + // + if(nTextLen && aBreakPositions.empty()) + { + //if all content has been overwritten the attributes may have been removed, too + svx::SpellPortion aPortion1; + aPortion1.eLanguage = GetSpellDialog()->GetSelectedLang_Impl(); + aPortion1.sText = pTextEngine->GetText( + TextSelection(TextPaM(0, 0), TextPaM(0, nTextLen))); + + aRet.push_back(aPortion1); + + } + else if(!aBreakPositions.empty()) + { + LanguagePositions_Impl::iterator aStart = aBreakPositions.begin(); + //start should always be Null + eLang = aStart->eLanguage; + USHORT nStart = aStart->nPosition; + DBG_ASSERT(!nStart, "invalid start position - language attribute missing?") + ++aStart; + + while(aStart != aBreakPositions.end()) + { + svx::SpellPortion aPortion1; + aPortion1.eLanguage = eLang; + aPortion1.sText = pTextEngine->GetText( + TextSelection(TextPaM(0, nStart), TextPaM(0, aStart->nPosition))); + + aRet.push_back(aPortion1); + nStart = aStart->nPosition; + eLang = aStart->eLanguage; + ++aStart; + } + } + } + return aRet; +} + +/*-- 06.11.2003 11:30:10--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SentenceEditWindow_Impl::Undo() +{ + SfxUndoManager& rUndoMgr = GetTextEngine()->GetUndoManager(); + DBG_ASSERT(GetUndoActionCount(), "no undo actions available" ) + if(!GetUndoActionCount()) + return; + bool bSaveUndoEdit = IsUndoEditMode(); + USHORT nId; + //if the undo edit mode is active then undo all changes until the UNDO_EDIT_MODE action has been found + do + { + nId = rUndoMgr.GetUndoActionId(); + rUndoMgr.Undo(); + }while(bSaveUndoEdit && SPELLUNDO_UNDO_EDIT_MODE != nId && GetUndoActionCount()); + + if(bSaveUndoEdit || SPELLUNDO_CHANGE_GROUP == nId) + GetSpellDialog()->UpdateBoxes_Impl(); +} +/*-- 06.11.2003 11:30:10--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SentenceEditWindow_Impl::ResetUndo() +{ + GetTextEngine()->ResetUndo(); +} +/*-- 06.11.2003 12:30:41--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SentenceEditWindow_Impl::AddUndoAction( SfxUndoAction *pAction, BOOL bTryMerg ) +{ + SfxUndoManager& rUndoMgr = GetTextEngine()->GetUndoManager(); + rUndoMgr.AddUndoAction(pAction, bTryMerg); + GetSpellDialog()->aUndoPB.Enable(); +} +/*-- 06.11.2003 12:38:44--------------------------------------------------- + + -----------------------------------------------------------------------*/ +USHORT SentenceEditWindow_Impl::GetUndoActionCount() +{ + return GetTextEngine()->GetUndoManager().GetUndoActionCount(); +} + +/*-- 12.11.2003 12:12:38--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SentenceEditWindow_Impl::UndoActionStart( USHORT nId ) +{ + GetTextEngine()->UndoActionStart(nId); +} +/*-- 12.11.2003 12:12:38--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SentenceEditWindow_Impl::UndoActionEnd( USHORT nId ) +{ + GetTextEngine()->UndoActionEnd(nId); +} +/*-- 12.11.2003 12:12:38--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SentenceEditWindow_Impl::MoveErrorEnd(long nOffset) +{ + if(nOffset > 0) + m_nErrorEnd -= (USHORT)nOffset; + else + m_nErrorEnd += (USHORT)- nOffset; +} +/*-- 13.11.2003 15:15:19--------------------------------------------------- + + -----------------------------------------------------------------------*/ +void SentenceEditWindow_Impl::SetUndoEditMode(bool bSet) +{ + DBG_ASSERT(!bSet || m_bIsUndoEditMode != bSet, "SetUndoEditMode with equal values?") + m_bIsUndoEditMode = bSet; + //disable all buttons except the Change + SpellDialog* pSpellDialog = GetSpellDialog(); + Control* aControls[] = + { + &pSpellDialog->aChangeAllPB, + &pSpellDialog->aIgnoreAllPB, + &pSpellDialog->aIgnorePB, + &pSpellDialog->aSuggestionLB, + &pSpellDialog->aSuggestionFT, + &pSpellDialog->aLanguageFT, + &pSpellDialog->aLanguageLB, + &pSpellDialog->aAddToDictMB, + &pSpellDialog->aAutoCorrPB, + 0 + }; + sal_Int32 nIdx = 0; + do + { + aControls[nIdx]->Enable(sal_False); + } + while(aControls[++nIdx]); + + //remove error marks + TextEngine* pTextEngine = GetTextEngine(); + pTextEngine->RemoveAttribs( 0, (USHORT)TEXTATTR_FONTCOLOR ); + pTextEngine->RemoveAttribs( 0, (USHORT)TEXTATTR_FONTWEIGHT ); + + //put the appropriate action on the Undo-stack + SpellUndoAction_Impl* pAction = new SpellUndoAction_Impl( + SPELLUNDO_UNDO_EDIT_MODE, GetSpellDialog()->aDialogUndoLink); + AddUndoAction(pAction); + pSpellDialog->aChangePB.Enable(); +} + + |