/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_cui.hxx"

// include ---------------------------------------------------------------

#include <tools/ref.hxx>
#include <tools/shl.hxx>
#include <vcl/wrkwin.hxx>
#include <vcl/menu.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/scrbar.hxx>
#include <SpellAttrib.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/bindings.hxx>
#include <svl/undo.hxx>
#include <unotools/lingucfg.hxx>
#include <svtools/textdata.hxx>
#include <svtools/filter.hxx>
#include <editeng/unolingu.hxx>
#include <editeng/splwrap.hxx>
#include <linguistic/lngprops.hxx>
#include <linguistic/misc.hxx>
#include <comphelper/processfactory.hxx>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/XServiceDisplayName.hpp>
#include <com/sun/star/linguistic2/SpellFailure.hpp>
#include <com/sun/star/frame/XStorable.hpp>
#include <sfx2/app.hxx>
#include <vcl/help.hxx>
#include <vcl/graph.hxx>
#include <osl/file.hxx>
#include <cuires.hrc>
#include <helpid.hrc>
#include "SpellDialog.hrc"
#include <editeng/optitems.hxx>
#include <editeng/svxenum.hxx>
#include <svx/SpellDialogChildWindow.hxx>
#include "SpellDialog.hxx"
#include <svx/dlgutil.hxx>
#include "optlingu.hxx"
#include <dialmgr.hxx>
#include <svx/svxerr.hxx>
#include "treeopt.hxx"
#include <svtools/langtab.hxx>

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::linguistic2;

using ::rtl::OUString;

#define C2U(cChar) 					::rtl::OUString::createFromAscii(cChar)
// struct SpellDialog_Impl ---------------------------------------------

struct SpellDialog_Impl
{
	Sequence< Reference< XDictionary >  >	aDics;
};
// -----------------------------------------------------------------------
//#define VENDOR_IMAGE_HEIGHT 44 //as specified

#define SPELLUNDO_START                     200

#define SPELLUNDO_CHANGE_LANGUAGE           (SPELLUNDO_START + 1)
#define SPELLUNDO_CHANGE_TEXTENGINE         (SPELLUNDO_START + 2)
#define SPELLUNDO_CHANGE_NEXTERROR          (SPELLUNDO_START + 3)
#define SPELLUNDO_CHANGE_ADD_TO_DICTIONARY  (SPELLUNDO_START + 4)
#define SPELLUNDO_CHANGE_GROUP              (SPELLUNDO_START + 5) //undo list
#define SPELLUNDO_MOVE_ERROREND             (SPELLUNDO_START + 6)
#define SPELLUNDO_UNDO_EDIT_MODE            (SPELLUNDO_START + 7)
#define SPELLUNDO_ADD_IGNORE_RULE           (SPELLUNDO_START + 8)

namespace svx{
class SpellUndoAction_Impl : public SfxUndoAction
{
    sal_uInt16          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;
    ::rtl::OUString m_sRuleId;
    //undo of AddToDictionary
    Reference<XDictionary>  m_xDictionary;
    ::rtl::OUString                m_sAddedWord;
    //move end of error - ::ChangeMarkedWord()
    long            m_nOffset;

public:
    SpellUndoAction_Impl(sal_uInt16 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 sal_uInt16          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 ::rtl::OUString& rWord) {m_sAddedWord = rWord;}
    const ::rtl::OUString&         GetAddedWord() const { return m_sAddedWord;}

    void                    SetOffset(long nSet) {m_nOffset = nSet;}
    long                    GetOffset() const {return m_nOffset;}

    void                    SetErrorType( const ::rtl::OUString& rId ) { m_sRuleId = rId; }
    const ::rtl::OUString&  GetErrorType() const { return m_sRuleId; }

};
}//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---------------------------------------------------

  -----------------------------------------------------------------------*/
sal_uInt16 SpellUndoAction_Impl::GetId()const
{
    return m_nId;
}

// class SvxSpellCheckDialog ---------------------------------------------

SpellDialog::SpellDialog(
        SpellDialogChildWindow* pChildWindow,
        Window * pParent,
        SfxBindings* _pBindings)
            : SfxModelessDialog (_pBindings,
                                    pChildWindow,
                                    pParent,
                                    CUI_RES(RID_SVXDLG_SPELLCHECK)),

    aVendorImageFI  ( this , CUI_RES( IMG_VENDOR ) ),
    aLanguageFT     ( this, CUI_RES( FT_LANGUAGE ) ),
    aLanguageLB     ( this, CUI_RES( LB_LANGUAGE ) ),
    aNotInDictFT    ( this, CUI_RES( FT_NOTINDICT ) ),
    aSentenceED      ( this, CUI_RES( ED_NEWWORD ) ),
    aSuggestionFT   ( this, CUI_RES( FT_SUGGESTION ) ),
    aSuggestionLB   ( this, CUI_RES( LB_SUGGESTION ) ),

    aIgnorePB       ( this, CUI_RES( PB_IGNORE ) ),
    aIgnoreAllPB    ( this, CUI_RES( PB_IGNOREALL ) ),
    aIgnoreRulePB   ( this, CUI_RES( PB_IGNORERULE ) ),
    aAddToDictMB    ( this, CUI_RES( MB_ADDTODICT ) ),

    aChangePB       ( this, CUI_RES( PB_CHANGE ) ),
    aChangeAllPB    ( this, CUI_RES( PB_CHANGEALL ) ),
    aExplainPB      ( this, CUI_RES( PB_EXPLAIN) ),
    aAutoCorrPB     ( this, CUI_RES( PB_AUTOCORR ) ),

    aCheckGrammarCB ( this, CUI_RES( CB_CHECK_GRAMMAR ) ),

    aHelpPB         ( this, CUI_RES( PB_HELP ) ),
    aOptionsPB      ( this, CUI_RES( PB_OPTIONS ) ),
    aUndoPB         ( this, CUI_RES( PB_UNDO ) ),
    aClosePB        ( this, CUI_RES( PB_CLOSE ) ),
    aBackgroundGB   ( this, CUI_RES( GB_BACKGROUND ) ),

    aVendorImage    ( CUI_RES( IMG_DEFAULT_VENDOR ) ),
    aVendorImageHC  ( CUI_RES( IMG_DEFAULT_VENDOR_HC ) ),

    aResumeST       ( CUI_RES(ST_RESUME )),
    aIgnoreOnceST   ( aIgnorePB.GetText()),
    aNoSuggestionsST( CUI_RES(ST_NOSUGGESTIONS)),
    m_sTitleSpelling              ( CUI_RES( ST_SPELLING                        ) ),
    m_sTitleSpellingGrammar       ( CUI_RES( ST_SPELLING_AND_GRAMMAR            ) ),
    m_sTitleSpellingGrammarVendor ( CUI_RES( ST_SPELLING_AND_GRAMMAR_VENDORNAME ) ),
    aDialogUndoLink( LINK (this, SpellDialog, DialogUndoHdl)),
    bModified( false ),
    bFocusLocked( true ),
    rParent         ( *pChildWindow ),
    nOldLang        ( LANGUAGE_NONE )
{
    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);
    aIgnoreRulePB.  SetHelpId(HID_SPLDLG_BUTTON_IGNORERULE);
    aChangePB.      SetHelpId(HID_SPLDLG_BUTTON_CHANGE   );
    aChangeAllPB.   SetHelpId(HID_SPLDLG_BUTTON_CHANGEALL);
    aExplainPB.     SetHelpId(HID_SPLDLG_BUTTON_EXPLAIN );

    aAddToDictMB.SetPopupMenu( new PopupMenu );

	Init_Impl();

	// disable controls if service is missing
	if (!xSpell.is())
		Enable( sal_False );

    Application::PostUserEvent( STATIC_LINK(
                        this, SpellDialog, InitHdl ) );
}

// -----------------------------------------------------------------------

SpellDialog::~SpellDialog()
{
    // save possibly modified user-dictionaries
    Reference< XDictionaryList >  xDicList( SvxGetDictionaryList() );
    if (xDicList.is())
    {
        linguistic::SaveDictionaries( xDicList );
    }

    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 ) );
    aIgnoreRulePB.SetClickHdl(LINK( this, SpellDialog, IgnoreAllHdl ) );
    aUndoPB.SetClickHdl(LINK( this, SpellDialog, UndoHdl ) );

    aAutoCorrPB.SetClickHdl( LINK( this, SpellDialog, ExtClickHdl ) );
    aCheckGrammarCB.SetClickHdl( LINK( this, SpellDialog, CheckGrammarHdl ));
    aOptionsPB .SetClickHdl( LINK( this, SpellDialog, ExtClickHdl ) );

    aSuggestionLB.SetDoubleClickHdl( LINK( this, SpellDialog, ChangeHdl ) );

    aSentenceED.SetModifyHdl(LINK ( this, SpellDialog, ModifyHdl) );
    aAddToDictMB.SetActivateHdl(LINK ( this, SpellDialog, MenuButtonActivateHdl ) );
    aAddToDictMB.SetSelectHdl(LINK ( this, SpellDialog, AddToDictionaryHdl ) );
    aLanguageLB.SetSelectHdl(LINK( this, SpellDialog, LanguageSelectHdl ) );

    // initialize language ListBox
    aLanguageLB.SetLanguageList( LANG_LIST_SPELL_USED, sal_False, sal_False, sal_True );

    // get current language
	UpdateBoxes_Impl();

    aSentenceED.ClearModifyFlag();
	SvxGetChangeAllList()->clear();
}

// -----------------------------------------------------------------------

void SpellDialog::UpdateBoxes_Impl()
{
    sal_Int32 i;
    aSuggestionLB.Clear();

    const SpellErrorDescription* pSpellErrorDescription = aSentenceED.GetAlternatives();

	LanguageType nAltLanguage = LANGUAGE_NONE;
    //String      aAltWord;
	Sequence< ::rtl::OUString >	aNewWords;
    bool bIsGrammarError = false;
    if( pSpellErrorDescription )
	{
        nAltLanguage    = SvxLocaleToLanguage( pSpellErrorDescription->aLocale );
        //aAltWord       = String( xAlt->getWord() );
        aNewWords       = pSpellErrorDescription->aSuggestions;
        bIsGrammarError = pSpellErrorDescription->bIsGrammarError;
        aExplainPB.SetExplanation(pSpellErrorDescription->sExplanation );
	}
    if( pSpellErrorDescription && pSpellErrorDescription->sDialogTitle.getLength() )
    {
        // use this function to apply the correct image to be used...
        SetTitle_Impl( nAltLanguage );
        // then change the title to the one to be actually used
        SetText( pSpellErrorDescription->sDialogTitle );
    }
    else
        SetTitle_Impl( nAltLanguage );

    SetSelectedLang_Impl( nAltLanguage );

    // Initialize/update user dictionaries after setting the language in the listbox
    InitUserDicts();

	// Alternativen eintragen
	const ::rtl::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 );
            aSuggestionLB.SetEntryFlags(aSuggestionLB.GetEntryCount() - 1, LISTBOX_ENTRY_FLAG_MULTILINE);
        }
	}
    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);
    bool bShowChangeAll = !bIsGrammarError;
    aChangeAllPB.Show( bShowChangeAll );
    aExplainPB.Show( !bShowChangeAll );
    aLanguageLB.Enable( bShowChangeAll );
    aIgnoreAllPB.Show( bShowChangeAll );
    aAddToDictMB.Show( bShowChangeAll );
    aIgnoreRulePB.Show( !bShowChangeAll );
    aIgnoreRulePB.Enable(pSpellErrorDescription && pSpellErrorDescription->sRuleId.getLength());
    aExplainPB.Enable( aExplainPB.HasExplanation() );
    aAutoCorrPB.Show( bShowChangeAll && rParent.HasAutoCorrection() );

}
// -----------------------------------------------------------------------

void SpellDialog::SpellContinue_Impl(bool bUseSavedSentence, bool bIgnoreCurrentError )
{
    //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
    bool bNextSentence = false;
    if((!aSentenceED.IsUndoEditMode() && aSentenceED.MarkNextError( bIgnoreCurrentError )) ||
            true == ( bNextSentence = GetNextSentence_Impl(bUseSavedSentence, aSentenceED.IsUndoEditMode()) && aSentenceED.MarkNextError( false )))
    {
        const SpellErrorDescription* pSpellErrorDescription = aSentenceED.GetAlternatives();
        if( pSpellErrorDescription )
        {
			UpdateBoxes_Impl();
            Control* aControls[] =
            {
                &aNotInDictFT,
                &aSentenceED,
                &aLanguageFT,
                0
            };
            sal_Int32 nIdx = 0;
            do
            {
                aControls[nIdx]->Enable(sal_True);
            }
            while(aControls[++nIdx]);


        }
        if( bNextSentence )
        {
            //remove undo if a new sentence is active
            aSentenceED.ResetUndo();
            aUndoPB.Enable(sal_False);
        }
    }
}
/* -----------------10.09.2003 14:04-----------------
    Initialize, asynchronous to prevent virtial calls
    from a constructor
 --------------------------------------------------*/
IMPL_STATIC_LINK( SpellDialog, InitHdl, SpellDialog *, EMPTYARG )
{
    pThis->SetUpdateMode( sal_False );
    //show or hide AutoCorrect depending on the modules abilities
    pThis->aAutoCorrPB.Show(pThis->rParent.HasAutoCorrection());
    pThis->SpellContinue_Impl();
    pThis->aSentenceED.ResetUndo();
    pThis->aUndoPB.Enable(sal_False);

    pThis->LockFocusChanges(true);
    if( pThis->aChangePB.IsEnabled() )
        pThis->aChangePB.GrabFocus();
    else if( pThis->aIgnorePB.IsEnabled() )
        pThis->aIgnorePB.GrabFocus();
    else if( pThis->aClosePB.IsEnabled() )
        pThis->aClosePB.GrabFocus();
    pThis->LockFocusChanges(false);
    //show grammar CheckBox depending on the modules abilities
    bool bHasGrammarChecking = pThis->rParent.HasGrammarChecking();
    pThis->aCheckGrammarCB.Show( bHasGrammarChecking );
    if( !bHasGrammarChecking )
    {
        //resize the dialog to hide the hidden area of the CheckBox
        Size aBackSize = pThis->aBackgroundGB.GetSizePixel();
        sal_Int32 nDiff = pThis->aBackgroundGB.GetPosPixel().Y() + aBackSize.Height()
                            - pThis->aCheckGrammarCB.GetPosPixel().Y();
        aBackSize.Height() -= nDiff;
        pThis->aBackgroundGB.SetSizePixel(aBackSize);
        Button* aButtons[] = { &pThis->aHelpPB, &pThis->aOptionsPB, &pThis->aUndoPB, &pThis->aClosePB, 0 };
        sal_Int32 nButton = 0;
        while( aButtons[nButton])
        {
            Point aPos = aButtons[nButton]->GetPosPixel();
            aPos.Y() -= nDiff;
            aButtons[nButton]->SetPosPixel(aPos);
            ++nButton;
        }
        Size aDlgSize = pThis->GetSizePixel();
        aDlgSize.Height() -= nDiff;
        pThis->SetSizePixel( aDlgSize );
    }
    else
    {
        if( SvtLinguConfig().HasVendorImages( "SpellAndGrammarDialogImage" ) )
        {
            pThis->aVendorImageFI.Show();
            Size aVendorSize = pThis->aVendorImageFI.GetSizePixel();
            Size aImageSize = pThis->aVendorImageFI.GetImage().GetSizePixel();
            if( aImageSize.Height() )
            {
                aVendorSize.Height() = aImageSize.Height();
                if(aVendorSize.Width() < aImageSize.Width())
                    aVendorSize.Width() = aImageSize.Width();
                pThis->aVendorImageFI.SetSizePixel( aVendorSize );
            }
            //aVendorSize.Height() = nDiff;
            sal_Int32 nDiff = aVendorSize.Height();
            pThis->aVendorImageFI.SetSizePixel(aVendorSize);
            Control* aControls[] = {
                &pThis->aLanguageFT,
                &pThis->aLanguageLB,
                &pThis->aNotInDictFT,
                &pThis->aSentenceED,
                &pThis->aSuggestionFT,
                &pThis->aSuggestionLB,
                &pThis->aIgnorePB,
                &pThis->aIgnoreAllPB,
                &pThis->aIgnoreRulePB,
                &pThis->aAddToDictMB,
                &pThis->aChangePB,
                &pThis->aChangeAllPB,
                &pThis->aExplainPB,
                &pThis->aAutoCorrPB,
                &pThis->aCheckGrammarCB,
                &pThis->aHelpPB,
                &pThis->aOptionsPB,
                &pThis->aUndoPB,
                &pThis->aClosePB,
                &pThis->aBackgroundGB,
                0
            };
            sal_Int32 nControl = 0;
            while( aControls[nControl])
            {
                Point aPos = aControls[nControl]->GetPosPixel();
                aPos.Y() += nDiff;
                aControls[nControl]->SetPosPixel(aPos);
                ++nControl;
            }
            Size aDlgSize = pThis->GetSizePixel();
            aDlgSize.Height() += nDiff;
            pThis->SetSizePixel( aDlgSize );
            pThis->Invalidate();
        }
    }
    pThis->aCheckGrammarCB.Check( pThis->rParent.IsGrammarChecking() );
    pThis->SetUpdateMode( sal_True );
    pThis->Show();
    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
        const SpellErrorDescription* pSpellErrorDescription = aSentenceED.GetAlternatives();
        if( pSpellErrorDescription )
        {
            String sWrong(pSpellErrorDescription->sErrorText);
            //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;
}
// -----------------------------------------------------------------------
IMPL_LINK( SpellDialog, CheckGrammarHdl, CheckBox*, pBox )
{
    rParent.SetGrammarChecking( pBox->IsChecked() );
    Impl_Restore();
    return 0;
}

void SpellDialog::StartSpellOptDlg_Impl()
{
    sal_uInt16 aSpellInfos[] =
    {
        SID_ATTR_SPELL,SID_ATTR_SPELL,
        SID_SPELL_MODIFIED, SID_SPELL_MODIFIED,
        SID_AUTOSPELL_CHECK, SID_AUTOSPELL_CHECK,
        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 );
	if(RET_OK == pDlg->Execute())
	{

    	// Benutzerb"ucher anzeigen
	    InitUserDicts();
        const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
        if(pOutSet)
            OfaTreeOptionsDialog::ApplyLanguageOptions(*pOutSet);
    }
	delete pDlg;

}

// -----------------------------------------------------------------------

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 = false;
        aSentenceED.UndoActionEnd();
    }
    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 = linguistic::AddEntryToDic( 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 = false;
    aSentenceED.UndoActionEnd();
    return 1;
}
// -----------------------------------------------------------------------

IMPL_LINK( SpellDialog, IgnoreAllHdl, Button *, pButton )
{
    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();
    if( pButton == &aIgnoreRulePB )
    {
        const SpellErrorDescription* pSpellErrorDescription = aSentenceED.GetAlternatives();
        try
        {
            if( pSpellErrorDescription && pSpellErrorDescription->xGrammarChecker.is() )
            {
                pSpellErrorDescription->xGrammarChecker->ignoreRule( pSpellErrorDescription->sRuleId,
                    pSpellErrorDescription->aLocale );
            }
        }
        catch( const uno::Exception& )
        {
        }
    }
    else
    {
        String sErrorText(aSentenceED.GetErrorText());
        sal_uInt8 nAdded = linguistic::AddEntryToDic( 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 = false;
    aSentenceED.UndoActionEnd();
    return 1;
}
/*-- 06.11.2003 11:24:08---------------------------------------------------

  -----------------------------------------------------------------------*/
IMPL_LINK( SpellDialog, UndoHdl, Button*, EMPTYARG )
{
    aSentenceED.Undo();
    if(!aSentenceED.GetUndoActionCount())
        aUndoPB.Enable(sal_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(sal_False);
            if(pAction->IsEnableChangeAllPB())
                aChangeAllPB.Enable(sal_False);
        }
        break;
        case SPELLUNDO_CHANGE_NEXTERROR:
        {
            aSentenceED.MoveErrorMarkTo((sal_uInt16)pAction->GetOldErrorStart(), (sal_uInt16)pAction->GetOldErrorEnd(), false);
            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;
        case SPELLUNDO_ADD_IGNORE_RULE:
            //undo of ignored rules is not supported
        break;
    }

    return 0;
}
// -----------------------------------------------------------------------
void SpellDialog::Impl_Restore()
{
    //clear the "ChangeAllList"
    SvxGetChangeAllList()->clear();
    //get a new sentence
    aSentenceED.SetText(rtl::OUString());
    aSentenceED.ResetModified();
    SpellContinue_Impl();
    aIgnorePB.SetText(aIgnoreOnceST);
}

IMPL_LINK( SpellDialog, IgnoreHdl, Button *, EMPTYARG )
{
    if(aIgnorePB.GetText() == aResumeST)
    {
        Impl_Restore();
    }
    else
    {
        //in case the error has been changed manually it has to be restored,
        // since the users choice now was to ignore the error
        aSentenceED.RestoreCurrentError();

        // the word is being ignored
        SpellContinue_Impl( false, true );
    }
	return 1;
}


// -----------------------------------------------------------------------

sal_Bool SpellDialog::Close()
{
    GetBindings().GetDispatcher()->
        Execute(rParent.GetType(),
        SFX_CALLMODE_ASYNCHRON|SFX_CALLMODE_RECORD);
    return sal_True;
}
// -----------------------------------------------------------------------

void SpellDialog::SetSelectedLang_Impl( LanguageType nLang )
{
    aLanguageLB.SelectLanguage( nLang );
}

// -----------------------------------------------------------------------

LanguageType SpellDialog::GetSelectedLang_Impl() const
{
    sal_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())
    {
        LanguageType eLanguage = pBox->GetSelectLanguage();
        Reference <XSpellAlternatives> xAlt = xSpell->spell( sError, eLanguage,
                                            Sequence< PropertyValue >() );
        if( xAlt.is() )
            aSentenceED.SetAlternatives( xAlt );
        else
        {
            aSentenceED.ChangeMarkedWord( sError, eLanguage );
            SpellContinue_Impl();
        }

         aSentenceED.AddUndoAction(new SpellUndoAction_Impl(SPELLUNDO_CHANGE_LANGUAGE, aDialogUndoLink));
    }

    // Update listboxes and user dictionaries when selected language changes
    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.
*/

{
    SetTitle_Impl( nLang );

	// den richtigen Eintrag finden, da sortiert
    aLanguageLB.SelectLanguage( nLang );
}
/*-- 16.06.2008 11:27:02---------------------------------------------------

  -----------------------------------------------------------------------*/
static Image lcl_GetImageFromPngUrl( const ::rtl::OUString &rFileUrl )
{
    Image aRes;
    ::rtl::OUString aTmp;
    osl::FileBase::getSystemPathFromFileURL( rFileUrl, aTmp );
    Graphic aGraphic;
    const String aFilterName( RTL_CONSTASCII_USTRINGPARAM( IMP_PNG ) );
    if( GRFILTER_OK == GraphicFilter::LoadGraphic( aTmp, aFilterName, aGraphic ) )
    {
        aRes = Image( aGraphic.GetBitmapEx() );
    }
    return aRes;
}
void SpellDialog::SetTitle_Impl(LanguageType nLang)
{
    String sTitle( m_sTitleSpelling );
    if( rParent.HasGrammarChecking() )
    {
        String sVendor;
        const SpellErrorDescription* pSpellErrorDescription = aSentenceED.GetAlternatives();
        if( pSpellErrorDescription && pSpellErrorDescription->sServiceName.getLength() )
        {
            bool bHighContrast = GetSettings().GetStyleSettings().GetHighContrastMode();
            ::rtl::OUString sSuggestionImageUrl = 
                SvtLinguConfig().GetSpellAndGrammarDialogImage( pSpellErrorDescription->sServiceName, bHighContrast );
            aVendorImageFI.SetImage( lcl_GetImageFromPngUrl( sSuggestionImageUrl ) );
            uno::Reference< lang::XServiceDisplayName > xDisplayName( pSpellErrorDescription->xGrammarChecker, uno::UNO_QUERY );
            if( xDisplayName.is() )
                sVendor = xDisplayName->getServiceDisplayName( pSpellErrorDescription->aLocale );
        }
        else
        {
            bool bHighContrast = GetSettings().GetStyleSettings().GetHighContrastMode();            
            aVendorImageFI.SetImage( bHighContrast ? aVendorImageHC : aVendorImage );
        }

        if( sVendor.Len() )
        {
            sTitle = m_sTitleSpellingGrammarVendor;
            sTitle.SearchAndReplaceAscii( "$VendorName", sVendor );
        }
        else
        {
            //bool bHighContrast = GetSettings().GetStyleSettings().GetHighContrastMode();
            sTitle = m_sTitleSpellingGrammar;
        }
    }
    sTitle.SearchAndReplaceAscii( "$LANGUAGE ($LOCATION)", SvtLanguageTable::GetLanguageString(nLang) );
    SetText( sTitle );
}
/*-------------------------------------------------------------------------

  -----------------------------------------------------------------------*/
void SpellDialog::InitUserDicts()
{
    bool bEnable = false;

    // 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 one dictionary to which
        // words could be added.
        Reference< XDictionary >  xDic( SvxGetOrCreatePosDic( xDicList ) );
        if (xDic.is())
            xDic->setActive( sal_True );

        pImpl->aDics = xDicList->getDictionaries();

        // this is redundant, there will always be *at least* one dictionary
        bEnable = pImpl->aDics.getLength();
    }

    aAddToDictMB.Enable( bEnable );
}

IMPL_LINK(SpellDialog, MenuButtonActivateHdl, MenuButton*, )
{
    bool bEnable = false;
    const LanguageType nLang = aLanguageLB.GetSelectLanguage();
    const Reference< XDictionary >  *pDic = 0;

    SvtLinguConfig aCfg;
    const bool bHC = Application::GetSettings().GetStyleSettings().GetHighContrastMode();

    // list suitable dictionaries
    const sal_Int32 nSize = pImpl->aDics.getLength();
    pDic = pImpl->aDics.getConstArray();

    PopupMenu* pMenu = aAddToDictMB.GetPopupMenu();
    OSL_ENSURE( pMenu, "svx::SpellDialog::MenuButtonActivateHdl - no PopupMenu!" );
    pMenu->Clear();
    pMenu->SetMenuFlags(MENU_FLAG_NOAUTOMNEMONICS);

    sal_uInt16 nItemId = 1;     // menu items should be enumerated from 1 and not 0
    for (sal_Int32 i = 0; i < nSize; ++i)
    {
        uno::Reference< linguistic2::XDictionary >  xDicTmp( pDic[i], uno::UNO_QUERY );
        if (!xDicTmp.is() || SvxGetIgnoreAllList() == xDicTmp)
            continue;

        uno::Reference< frame::XStorable > xStor( xDicTmp, uno::UNO_QUERY );
        LanguageType nActLanguage = SvxLocaleToLanguage( xDicTmp->getLocale() );
        if( xDicTmp->isActive()
            &&  xDicTmp->getDictionaryType() != linguistic2::DictionaryType_NEGATIVE
            && (nLang == nActLanguage || LANGUAGE_NONE == nActLanguage )
            && (!xStor.is() || !xStor->isReadonly()) )
        {
            pMenu->InsertItem( nItemId, xDicTmp->getName() );
            bEnable = sal_True;

            uno::Reference< lang::XServiceInfo > xSvcInfo( xDicTmp, uno::UNO_QUERY );
            if (xSvcInfo.is())
            {
                OUString aDictionaryImageUrl( aCfg.GetSpellAndGrammarContextDictionaryImage(
                        xSvcInfo->getImplementationName(), bHC) );
                if (aDictionaryImageUrl.getLength() > 0)
                {
                    Image aImage( lcl_GetImageFromPngUrl( aDictionaryImageUrl ) );
                    pMenu->SetItemImage( nItemId, aImage );
                }
            }

            ++nItemId;
        }
    }

    aAddToDictMB.Enable( bEnable );

    return 0;
}

/*-- 20.10.2003 15:31:06---------------------------------------------------

  -----------------------------------------------------------------------*/
IMPL_LINK(SpellDialog, AddToDictionaryHdl, MenuButton*, pButton )
{
    aSentenceED.UndoActionStart( SPELLUNDO_CHANGE_GROUP );

    //GetErrorText() returns the current error even if the text is already
    //manually changed
    const String aNewWord= aSentenceED.GetErrorText();

    sal_uInt16 nItemId = pButton->GetCurItemId();
    PopupMenu *pMenu = pButton->GetPopupMenu();
    String aDicName ( pMenu->GetItemText( nItemId ) );

    uno::Reference< linguistic2::XDictionary >      xDic;
    uno::Reference< linguistic2::XDictionaryList >  xDicList( SvxGetDictionaryList() );
    if (xDicList.is())
        xDic = xDicList->getDictionaryByName( aDicName );

    sal_Int16 nAddRes = DIC_ERR_UNKNOWN;
    if (xDic.is())
    {
        nAddRes = linguistic::AddEntryToDic( xDic, aNewWord, sal_False, OUString(), LANGUAGE_NONE );
        // save modified user-dictionary if it is persistent
        uno::Reference< frame::XStorable >  xSavDic( xDic, uno::UNO_QUERY );
        if (xSavDic.is())
            xSavDic->store();

        if (nAddRes == DIC_ERR_NONE)
        {
            SpellUndoAction_Impl* pAction = new SpellUndoAction_Impl(
                            SPELLUNDO_CHANGE_ADD_TO_DICTIONARY, aDialogUndoLink);
            pAction->SetDictionary( xDic );
            pAction->SetAddedWord( aNewWord );
            aSentenceED.AddUndoAction( pAction );
        }
        // failed because there is already an entry?
        if (DIC_ERR_NONE != nAddRes && xDic->getEntry( aNewWord ).is())
            nAddRes = DIC_ERR_NONE;
    }
    if (DIC_ERR_NONE != nAddRes)
    {
        SvxDicError( this, nAddRes );
        return 0;   // Nicht weitermachen
    }

    // go on
    SpellContinue_Impl();
    aSentenceED.UndoActionEnd();
    return 0;
}
/*-------------------------------------------------------------------------

  -----------------------------------------------------------------------*/
IMPL_LINK(SpellDialog, ModifyHdl, SentenceEditWindow_Impl*, pEd)
{
    if (&aSentenceED == pEd)
	{
        bModified = true;
        aSuggestionLB.SetNoSelection();
        aSuggestionLB.Disable();
        String sNewText( aSentenceED.GetText() );
        aAutoCorrPB.Enable( sNewText != aSentenceED.GetText() );
        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 *, EMPTYARG )
{
    //apply changes and ignored text parts first - if there are any
    rParent.ApplyChangedSentence(aSentenceED.CreateSpellPortions(true), false);
    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 )
{
    /* #i38338#
    *   FIXME: LoseFocus and GetFocus are signals from vcl that
    *   a window actually got/lost the focus, it never should be
    *   forwarded from another window, that is simply wrong.
    *   FIXME: overloading the virtual methods GetFocus and LoseFocus
    *   in SpellDialogChildWindow by making them pure is at least questionable.
    *   The only sensible thing would be to call the new Method differently,
    *   e.g. DialogGot/LostFocus or so.
    */
    if( IsVisible() && !bFocusLocked )
    {
        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::InvalidateDialog()
{
    if( bFocusLocked )
        return;
    aIgnorePB.SetText(aResumeST);
    Window* aDisableArr[] =
            {
                &aNotInDictFT,
                &aSentenceED,
                &aSuggestionFT,
                &aSuggestionLB,
                &aLanguageFT,
                &aLanguageLB,
                &aIgnoreAllPB,
                &aIgnoreRulePB,
                &aAddToDictMB,
                &aChangePB,
                &aChangeAllPB,
                &aAutoCorrPB,
                &aUndoPB,
                0
            };
    sal_Int16 i = 0;
	while(aDisableArr[i])
    {
        aDisableArr[i]->Enable(sal_False);
        i++;
    }
    SfxModelessDialog::Deactivate();
}

/*-- 10.09.2003 08:35:56---------------------------------------------------

  -----------------------------------------------------------------------*/
bool SpellDialog::GetNextSentence_Impl(bool bUseSavedSentence, bool bRecheck)
{
    bool bRet = false;
    if(!bUseSavedSentence /*&& aSentenceED.IsModified()*/)
    {
        //apply changes and ignored text parts 
        rParent.ApplyChangedSentence(aSentenceED.CreateSpellPortions(true), bRecheck);
    }
    aSentenceED.ResetIgnoreErrorsAt();
    aSentenceED.ResetModified();
    SpellPortions aSentence = bUseSavedSentence ? m_aSavedSentence : rParent.GetNextWrongSentence( bRecheck );
    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, bRecheck);
			aSentence = rParent.GetNextWrongSentence( bRecheck );
        }
		else
            break;
    }

    if(aSentence.size())
    {
        SpellPortions::iterator aStart = aSentence.begin();
        rtl::OUString sText;
        while(aStart != aSentence.end())
        {
            // hidden text has to be ignored
            if(!aStart->bIsHidden)
                sText += aStart->sText;
            aStart++;
        }
        aSentenceED.SetText(sText);
        aStart = aSentence.begin();
        sal_Int32 nStartPosition = 0;
        sal_Int32 nEndPosition = 0;

        while(aStart != aSentence.end())
        {
            // hidden text has to be ignored
            if(!aStart->bIsHidden)
            {
                nEndPosition += aStart->sText.getLength();
                if(aStart->xAlternatives.is())
                {
                    uno::Reference< container::XNamed > xNamed( aStart->xAlternatives, uno::UNO_QUERY );
                    ::rtl::OUString sServiceName;
                    if( xNamed.is() )
                        sServiceName = xNamed->getName();
                    SpellErrorDescription aDesc( false, aStart->xAlternatives->getWord(),
                                    aStart->xAlternatives->getLocale(), aStart->xAlternatives->getAlternatives(), 0, sServiceName);
                    aSentenceED.SetAttrib( SpellErrorAttrib(aDesc), 0, (sal_uInt16) nStartPosition, (sal_uInt16) nEndPosition );
                }
                else if(aStart->bIsGrammarError )
                {
                    uno::Reference< lang::XServiceInfo > xInfo( aStart->xGrammarChecker, uno::UNO_QUERY );
                    SpellErrorDescription aDesc( true,
                        aStart->sText,
						SvxCreateLocale( aStart->eLanguage ),
                        aStart->aGrammarError.aSuggestions,
                        aStart->xGrammarChecker,
                        xInfo->getImplementationName(),
                        &aStart->sDialogTitle,
                        &aStart->aGrammarError.aFullComment,
                        &aStart->aGrammarError.aRuleIdentifier );
                    aSentenceED.SetAttrib( SpellErrorAttrib(aDesc), 0, (sal_uInt16) nStartPosition, (sal_uInt16) nEndPosition );
                }
                if(aStart->bIsField)
                    aSentenceED.SetAttrib( SpellBackgroundAttrib(COL_LIGHTGRAY), 0, (sal_uInt16) nStartPosition, (sal_uInt16) nEndPosition );
                aSentenceED.SetAttrib( SpellLanguageAttrib(aStart->eLanguage), 0, (sal_uInt16) nStartPosition, (sal_uInt16) 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(sal_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();
                aStart->xAlternatives = 0;
                bHasReplaced = true;
            }
            else
                bRet = true;
        }
        else if( aStart->bIsGrammarError )
            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
			sal_uInt16 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();
                    sal_uInt16 nStart = pErrorAttrLeft->GetStart();
                    sal_uInt16 nEnd = pErrorAttrLeft->GetEnd();
                    pTextEngine->RemoveAttrib( 0, *pErrorAttrLeft );
                    SetAttrib( *pNewError, 0, nStart, ++nEnd );
                    //only active errors move the mark
					if(bIsErrorActive)
                    {
                        bool bGrammar = static_cast<const SpellErrorAttrib&>(*pNewError).GetErrorDescription().bIsGrammarError;
                        MoveErrorMarkTo(nStart, nEnd, bGrammar);
                    }
                    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
					sal_uInt16 nAddedChars = GetText().Len() - nCurrentLen;

                    TextAttrib* pNewError =  pErrorAttr->GetAttr().Clone();
                    sal_uInt16 nStart = pErrorAttr->GetStart();
                    sal_uInt16 nEnd = pErrorAttr->GetEnd();
                    pTextEngine->RemoveAttrib( 0, *pErrorAttr );
                    nStart = nStart - (sal_uInt16)nAddedChars;
					SetAttrib( *pNewError, 0, nStart - nAddedChars, nEnd );
                    //only if the error is active the mark is moved here
					if(bIsErrorActive)
                    {
                        bool bGrammar = static_cast<const SpellErrorAttrib&>(*pNewError).GetErrorDescription().bIsGrammarError;
                        MoveErrorMarkTo(nStart, nEnd, bGrammar);
                    }
                    delete pNewError;

					if(pBackAttrLeft)
					{
						TextAttrib* pNewBack =  pBackAttrLeft->GetAttr().Clone();
                        sal_uInt16 _nStart = pBackAttrLeft->GetStart();
                        sal_uInt16 _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( bool bIgnoreCurrentError )
{
    if (bIgnoreCurrentError)
        m_aIgnoreErrorsAt.insert( m_nErrorStart );
    ExtTextEngine* pTextEngine = GetTextEngine();
    sal_uInt16 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 sal_uInt16 nOldErrorStart = m_nErrorStart;
    const sal_uInt16 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
    bool bGrammarError = false;
    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;
        const SpellErrorDescription* pSpellErrorDescription = 0;
        if(pNextError)
        {
            pSpellErrorDescription = &static_cast<const SpellErrorAttrib&>(pNextError->GetAttr()).GetErrorDescription();
            bGrammarError = pSpellErrorDescription->bIsGrammarError;
        }
        if(xChangeAll->getCount() && pSpellErrorDescription &&
                (xEntry = xChangeAll->getEntry( pSpellErrorDescription->sErrorText )).is())
        {
            m_nErrorStart = pNextError->GetStart();
            m_nErrorEnd = pNextError->GetEnd();
            ChangeMarkedWord(xEntry->getReplacementText(),
                    SvxLocaleToLanguage( pSpellErrorDescription->aLocale ));
            aCursor.GetIndex() = aCursor.GetIndex() + (sal_uInt16)(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, bGrammarError);
        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 ));
        pAction->SetErrorLanguageSelected(pOldAttrib && pOldAttrib->GetErrorDescription().aSuggestions.getLength() &&
                SvxLocaleToLanguage( pOldAttrib->GetErrorDescription().aLocale) ==
                                        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(sal_uInt16 nStart, sal_uInt16 nEnd, bool bGrammarError)
{
    TextEngine* pTextEngine = GetTextEngine();
    pTextEngine->RemoveAttribs( 0, (sal_uInt16)TEXTATTR_FONTCOLOR, sal_True );
    pTextEngine->RemoveAttribs( 0, (sal_uInt16)TEXTATTR_FONTWEIGHT, sal_True );
    pTextEngine->SetAttrib( TextAttribFontWeight(WEIGHT_BOLD), 0, nStart, nEnd );
    pTextEngine->SetAttrib( TextAttribFontColor(bGrammarError ? COL_LIGHTBLUE : 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 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();
    const TextCharAttrib*  pErrorAttrib = pTextEngine->FindCharAttrib( TextPaM(0, m_nErrorStart), TEXTATTR_SPELL_ERROR );
    DBG_ASSERT(pErrorAttrib, "no error attribute found");
//  Reference <XSpellAlternatives> xAlternatives;
    const SpellErrorDescription* pSpellErrorDescription = 0;
    if(pErrorAttrib)
	{
        pTextEngine->RemoveAttrib(0, *pErrorAttrib);
        pSpellErrorDescription = &static_cast<const SpellErrorAttrib&>(pErrorAttrib->GetAttr()).GetErrorDescription();
	}
    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 );
        sal_uInt16 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, (sal_uInt16)(m_nErrorEnd + nDiffLen) , nTextLen );
        }
    }
	// undo expanded attributes!
	if( pBackAttrib && pBackAttrib->GetStart() < m_nErrorStart && pBackAttrib->GetEnd() == m_nErrorEnd + nDiffLen)
	{
		TextAttrib* pNewBackground = pBackAttrib->GetAttr().Clone();
        sal_uInt16 nStart = pBackAttrib->GetStart();
		pTextEngine->RemoveAttrib(0, *pBackAttrib);
		pTextEngine->SetAttrib(*pNewBackground, 0, nStart, m_nErrorStart);
		delete pNewBackground;
	}
    pTextEngine->SetModified(sal_True);

    //adjust end position
    long nEndTemp = m_nErrorEnd;
    nEndTemp += nDiffLen;
    m_nErrorEnd = (sal_uInt16)nEndTemp;

    SpellUndoAction_Impl* pAction = new SpellUndoAction_Impl(
                    SPELLUNDO_MOVE_ERROREND, GetSpellDialog()->aDialogUndoLink);
    pAction->SetOffset(nDiffLen);
    AddUndoAction(pAction);
    if(pSpellErrorDescription)
        SetAttrib( SpellErrorAttrib(*pSpellErrorDescription), 0, m_nErrorStart, m_nErrorEnd );
    SetAttrib( SpellLanguageAttrib(eLanguage), 0, m_nErrorStart, m_nErrorEnd );
    pTextEngine->UndoActionEnd();
}
/* -----------------08.10.2003 13:18-----------------

 --------------------------------------------------*/
String SentenceEditWindow_Impl::GetErrorText() const
{
    return GetTextEngine()->GetText(TextSelection(TextPaM(0, m_nErrorStart), TextPaM(0, m_nErrorEnd) ));
}
/*-- 26.06.2008 10:54:13---------------------------------------------------

  -----------------------------------------------------------------------*/
const SpellErrorDescription* SentenceEditWindow_Impl::GetAlternatives()
{
    TextPaM aCursor(0, m_nErrorStart);
    const SpellErrorAttrib* pAttrib = static_cast<const SpellErrorAttrib*>(
            GetTextEngine()->FindAttrib( aCursor, TEXTATTR_SPELL_ERROR));
    return pAttrib ? &pAttrib->GetErrorDescription() : 0;
}
/*-- 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));
    if( pAttrib )
    {
        const SpellErrorDescription& rDesc = pAttrib->GetErrorDescription();
        if( !rDesc.sErrorText.equals( GetErrorText() ) )
            ChangeMarkedWord(rDesc.sErrorText, SvxLocaleToLanguage( rDesc.aLocale ));
    }
}
/*-- 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?");

	::rtl::OUString	aWord;
	lang::Locale	aLocale;
	uno::Sequence< ::rtl::OUString >	aAlts;
    ::rtl::OUString sServiceName;
	if (xAlt.is())
	{
		aWord	= xAlt->getWord();
		aLocale	= xAlt->getLocale();
		aAlts	= xAlt->getAlternatives();
        uno::Reference< container::XNamed > xNamed( xAlt, uno::UNO_QUERY );
		if (xNamed.is())
			sServiceName = xNamed->getName();
	}
    SpellErrorDescription aDesc( false, aWord, aLocale, aAlts, 0, sServiceName);
    GetTextEngine()->SetAttrib( SpellErrorAttrib(aDesc), 0, m_nErrorStart, m_nErrorEnd );
}

/*-- 10.09.2003 14:43:02---------------------------------------------------

  -----------------------------------------------------------------------*/
void SentenceEditWindow_Impl::SetAttrib( const TextAttrib& rAttr, sal_uLong nPara, sal_uInt16 nStart, sal_uInt16 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
{
    sal_uInt16          nPosition;
    LanguageType    eLanguage;

    LanguagePosition_Impl(sal_uInt16 nPos, LanguageType eLang) :
        nPosition(nPos),
        eLanguage(eLang)
        {}
};
typedef std::vector<LanguagePosition_Impl> LanguagePositions_Impl;

void lcl_InsertBreakPosition_Impl(
        LanguagePositions_Impl& rBreakPositions, sal_uInt16 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( bool bSetIgnoreFlag ) const
{
    svx::SpellPortions aRet;
    ExtTextEngine* pTextEngine = GetTextEngine();
    const sal_uInt16 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;
		const TextCharAttrib* pError = 0;
        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;
            }
            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;
            sal_uInt16 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)));
                bool bIsIgnoreError = m_aIgnoreErrorsAt.find( nStart ) != m_aIgnoreErrorsAt.end();
                if( bSetIgnoreFlag && bIsIgnoreError /*m_nErrorStart == nStart*/ )
                {
                    aPortion1.bIgnoreThisError = true;
                }
                aRet.push_back(aPortion1);
                nStart = aStart->nPosition;
                eLang = aStart->eLanguage;
                ++aStart;
            }
        }

		// quick partly fix of #i71318. Correct fix needs to patch the TextEngine itself...
		// this one will only prevent text from disappearing. It may to not have the
		// correct language and will probably not spell checked...
		sal_uLong nPara = pTextEngine->GetParagraphCount();
		if (nPara > 1)
		{
			String aLeftOverText;
			for (sal_uLong i = 1;  i < nPara;  ++i)
			{
				aLeftOverText.AppendAscii( "\x0a" );	// the manual line break...
				aLeftOverText += pTextEngine->GetText(i);
			}
			if (pError)
			{	// we need to add a new portion containing the left-over text
				svx::SpellPortion aPortion2;
				aPortion2.eLanguage = eLang;
				aPortion2.sText = aLeftOverText;
				aRet.push_back( aPortion2 );
			}
			else
			{	// we just need to append the left-over text to the last portion (which had no errors)
				aRet[ aRet.size() - 1 ].sText += aLeftOverText;
			}
		}
   }
    return aRet;
}

/*-- 06.11.2003 11:30:10---------------------------------------------------

  -----------------------------------------------------------------------*/
void SentenceEditWindow_Impl::Undo()
{
    ::svl::IUndoManager& rUndoMgr = GetTextEngine()->GetUndoManager();
    DBG_ASSERT(GetUndoActionCount(), "no undo actions available" );
    if(!GetUndoActionCount())
        return;
    bool bSaveUndoEdit = IsUndoEditMode();
    sal_uInt16 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, sal_Bool bTryMerg )
{
    ::svl::IUndoManager& rUndoMgr = GetTextEngine()->GetUndoManager();
    rUndoMgr.AddUndoAction(pAction, bTryMerg);
    GetSpellDialog()->aUndoPB.Enable();
}
/*-- 06.11.2003 12:38:44---------------------------------------------------

  -----------------------------------------------------------------------*/
sal_uInt16 SentenceEditWindow_Impl::GetUndoActionCount()
{
    return GetTextEngine()->GetUndoManager().GetUndoActionCount();
}

/*-- 12.11.2003 12:12:38---------------------------------------------------

  -----------------------------------------------------------------------*/
void SentenceEditWindow_Impl::UndoActionStart( sal_uInt16 nId )
{
    GetTextEngine()->UndoActionStart(nId);
}
/*-- 12.11.2003 12:12:38---------------------------------------------------

  -----------------------------------------------------------------------*/
void SentenceEditWindow_Impl::UndoActionEnd()
{
    GetTextEngine()->UndoActionEnd();
}
/*-- 12.11.2003 12:12:38---------------------------------------------------

  -----------------------------------------------------------------------*/
void SentenceEditWindow_Impl::MoveErrorEnd(long nOffset)
{
    if(nOffset > 0)
        m_nErrorEnd = m_nErrorEnd - (sal_uInt16)nOffset;
    else
        m_nErrorEnd = m_nErrorEnd -(sal_uInt16)- 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->aExplainPB,
        &pSpellDialog->aIgnoreAllPB,
        &pSpellDialog->aIgnoreRulePB,
        &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, (sal_uInt16)TEXTATTR_FONTCOLOR, sal_True );
    pTextEngine->RemoveAttribs( 0, (sal_uInt16)TEXTATTR_FONTWEIGHT, sal_True );

    //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();
}

/*-- 30.06.2008 14:15:19---------------------------------------------------

  -----------------------------------------------------------------------*/
ExplainButton::~ExplainButton()
{
}
/*-- 30.06.2008 14:15:19---------------------------------------------------

  -----------------------------------------------------------------------*/
void ExplainButton::RequestHelp( const HelpEvent& )
{
    Help::ShowBalloon( this, GetPosPixel(), m_sExplanation );
}

void ExplainButton::Click()
{
    RequestHelp( HelpEvent() );
}
