Separate misspelled ranges when entering a new cell value.

And store them at appropriate locations.

Change-Id: Iaf38c0cd01e9b3dc9dc98f7ccc1951d572a422e9
diff --git a/editeng/source/editeng/editdoc.cxx b/editeng/source/editeng/editdoc.cxx
index 8cd17b7..3fefacb 100644
--- a/editeng/source/editeng/editdoc.cxx
+++ b/editeng/source/editeng/editdoc.cxx
@@ -1893,6 +1893,14 @@ public:
    }
};

struct ClearSpellErrorsHandler : std::unary_function<ContentNode, void>
{
    void operator() (ContentNode& rNode)
    {
        rNode.DestroyWrongList();
    }
};

}

void EditDoc::ImplDestroyContents()
@@ -2215,6 +2223,11 @@ EditPaM EditDoc::Clear()
    return aPaM;
}

void EditDoc::ClearSpellErrors()
{
    std::for_each(maContents.begin(), maContents.end(), ClearSpellErrorsHandler());
}

void EditDoc::SetModified( bool b )
{
    bModified = b;
diff --git a/editeng/source/editeng/editdoc.hxx b/editeng/source/editeng/editdoc.hxx
index 1a6d1d0..b2928a6 100644
--- a/editeng/source/editeng/editdoc.hxx
+++ b/editeng/source/editeng/editdoc.hxx
@@ -750,6 +750,8 @@ public:
                    EditDoc( SfxItemPool* pItemPool );
                    ~EditDoc();

    void ClearSpellErrors();

    bool            IsModified() const      { return bModified; }
    void            SetModified( bool b );

diff --git a/editeng/source/editeng/editeng.cxx b/editeng/source/editeng/editeng.cxx
index 4e34071..e3309d4 100644
--- a/editeng/source/editeng/editeng.cxx
+++ b/editeng/source/editeng/editeng.cxx
@@ -2327,6 +2327,11 @@ EESpellState EditEngine::HasSpellErrors()
    return pImpEditEngine->HasSpellErrors();
}

void EditEngine::ClearSpellErrors()
{
    pImpEditEngine->ClearSpellErrors();
}

void EditEngine::StartSpelling(EditView& rEditView, sal_Bool bMultipleDoc)
{
    DBG_CHKTHIS( EditEngine, 0 );
diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx
index b62bc02..34075af 100644
--- a/editeng/source/editeng/impedit.hxx
+++ b/editeng/source/editeng/impedit.hxx
@@ -907,6 +907,7 @@ public:
    void DoOnlineSpelling( ContentNode* pThisNodeOnly = 0, bool bSpellAtCursorPos = false, bool bInteruptable = true );
    EESpellState        Spell( EditView* pEditView, sal_Bool bMultipleDoc );
    EESpellState        HasSpellErrors();
    void ClearSpellErrors();
    EESpellState        StartThesaurus( EditView* pEditView );
    ::com::sun::star::uno::Reference<
        ::com::sun::star::linguistic2::XSpellAlternatives >
diff --git a/editeng/source/editeng/impedit4.cxx b/editeng/source/editeng/impedit4.cxx
index 99a9101..72bfa895 100644
--- a/editeng/source/editeng/impedit4.cxx
+++ b/editeng/source/editeng/impedit4.cxx
@@ -2484,6 +2484,11 @@ EESpellState ImpEditEngine::HasSpellErrors()
    return EE_SPELL_ERRORFOUND;
}

void ImpEditEngine::ClearSpellErrors()
{
    aEditDoc.ClearSpellErrors();
}

EESpellState ImpEditEngine::StartThesaurus( EditView* pEditView )
{
    EditSelection aCurSel( pEditView->pImpEditView->GetEditSelection() );
diff --git a/include/editeng/editeng.hxx b/include/editeng/editeng.hxx
index 7545317..c7debc4 100644
--- a/include/editeng/editeng.hxx
+++ b/include/editeng/editeng.hxx
@@ -416,6 +416,7 @@ public:

    // For fast Pre-Test without view:
    EESpellState    HasSpellErrors();
    void ClearSpellErrors();
    sal_Bool            HasText( const SvxSearchItem& rSearchItem );

    //initialize sentence spelling
diff --git a/sc/inc/spellcheckcontext.hxx b/sc/inc/spellcheckcontext.hxx
index 5d81ad5..e3f3f74 100644
--- a/sc/inc/spellcheckcontext.hxx
+++ b/sc/inc/spellcheckcontext.hxx
@@ -49,6 +49,7 @@ struct SpellCheckContext

    bool isMisspelled( SCCOL nCol, SCROW nRow ) const;
    const std::vector<editeng::MisspellRanges>* getMisspellRanges( SCCOL nCol, SCROW nRow ) const;
    void setMisspellRanges( SCCOL nCol, SCROW nRow, const std::vector<editeng::MisspellRanges>* pRanges );

    void reset();
};
diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx
index 42cbbb1..7454a74 100644
--- a/sc/source/ui/app/inputhdl.cxx
+++ b/sc/source/ui/app/inputhdl.cxx
@@ -38,6 +38,7 @@
#include <editeng/unolingu.hxx>
#include <editeng/wghtitem.hxx>
#include <editeng/justifyitem.hxx>
#include "editeng/misspellrange.hxx"
#include <sfx2/bindings.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/dispatch.hxx>
@@ -2557,6 +2558,7 @@ void ScInputHandler::EnterHandler( sal_uInt8 nBlockMode )
        }
    }

    std::vector<editeng::MisspellRanges> aMisspellRanges;
    pEngine->CompleteOnlineSpelling();
    bool bSpellErrors = !bFormulaMode && pEngine->HasOnlineSpellErrors();
    if ( bSpellErrors )
@@ -2646,7 +2648,7 @@ void ScInputHandler::EnterHandler( sal_uInt8 nBlockMode )
        bool bAttrib = false;    // Formatierung vorhanden ?
        //  check if EditObject is needed

        if ( bSpellErrors || nParCnt > 1 )
        if (nParCnt > 1)
            bAttrib = true;
        else
        {
@@ -2683,15 +2685,15 @@ void ScInputHandler::EnterHandler( sal_uInt8 nBlockMode )
            //  (der Test vorher ist trotzdem noetig wegen Zell-Attributen)
        }

        if (bSpellErrors)
            pEngine->GetAllMisspellRanges(aMisspellRanges);

        if (bMatrix)
            bAttrib = false;

        if (bAttrib)
        {
            sal_uLong nCtrl = pEngine->GetControlWord();
            sal_uLong nWantBig = bSpellErrors ? EE_CNTRL_ALLOWBIGOBJS : 0;
            if ( ( nCtrl & EE_CNTRL_ALLOWBIGOBJS ) != nWantBig )
                pEngine->SetControlWord( (nCtrl & ~EE_CNTRL_ALLOWBIGOBJS) | nWantBig );
            pEngine->ClearSpellErrors();
            pObject = pEngine->CreateTextObject();
        }
        else if (bAutoComplete)         // Gross-/Kleinschreibung anpassen
@@ -2797,6 +2799,10 @@ void ScInputHandler::EnterHandler( sal_uInt8 nBlockMode )
            ScInputStatusItem aItem( FID_INPUTLINE_STATUS,
                                     aCursorPos, aCursorPos, aCursorPos,
                                     aString, pObject );

            if (!aMisspellRanges.empty())
                aItem.SetMisspellRanges(&aMisspellRanges);

            const SfxPoolItem* aArgs[2];
            aArgs[0] = &aItem;
            aArgs[1] = NULL;
diff --git a/sc/source/ui/app/uiitems.cxx b/sc/source/ui/app/uiitems.cxx
index d26337d..ab83063 100644
--- a/sc/source/ui/app/uiitems.cxx
+++ b/sc/source/ui/app/uiitems.cxx
@@ -45,28 +45,27 @@ TYPEINIT1(ScIndexHint,          SfxHint);
//      ScInputStatusItem - Status-Update fuer Eingabezeile
// -----------------------------------------------------------------------

ScInputStatusItem::ScInputStatusItem( sal_uInt16 nWhichP,
                                      const ScAddress& rCurPos,
                                      const ScAddress& rStartPos,
                                      const ScAddress& rEndPos,
                                      const OUString& rString,
                                      const EditTextObject* pData )
    :   SfxPoolItem ( nWhichP ),
        aCursorPos  ( rCurPos ),
        aStartPos   ( rStartPos ),
        aEndPos     ( rEndPos ),
        aString     ( rString ),
        pEditData   ( pData ? pData->Clone() : NULL )
ScInputStatusItem::ScInputStatusItem(
    sal_uInt16 nWhichP, const ScAddress& rCurPos, const ScAddress& rStartPos,
    const ScAddress& rEndPos, const OUString& rString, const EditTextObject* pData ) :
    SfxPoolItem ( nWhichP ),
    aCursorPos  ( rCurPos ),
    aStartPos   ( rStartPos ),
    aEndPos     ( rEndPos ),
    aString     ( rString ),
    pEditData   ( pData ? pData->Clone() : NULL ),
    mpMisspellRanges(NULL)
{
}

ScInputStatusItem::ScInputStatusItem( const ScInputStatusItem& rItem )
    :   SfxPoolItem ( rItem ),
        aCursorPos  ( rItem.aCursorPos ),
        aStartPos   ( rItem.aStartPos ),
        aEndPos     ( rItem.aEndPos ),
        aString     ( rItem.aString ),
        pEditData   ( rItem.pEditData ? rItem.pEditData->Clone() : NULL )
ScInputStatusItem::ScInputStatusItem( const ScInputStatusItem& rItem ) :
    SfxPoolItem ( rItem ),
    aCursorPos  ( rItem.aCursorPos ),
    aStartPos   ( rItem.aStartPos ),
    aEndPos     ( rItem.aEndPos ),
    aString     ( rItem.aString ),
    pEditData   ( rItem.pEditData ? rItem.pEditData->Clone() : NULL ),
    mpMisspellRanges(rItem.mpMisspellRanges)
{
}

@@ -96,6 +95,16 @@ SfxPoolItem* ScInputStatusItem::Clone( SfxItemPool * ) const
    return new ScInputStatusItem( *this );
}

void ScInputStatusItem::SetMisspellRanges( const std::vector<editeng::MisspellRanges>* pRanges )
{
    mpMisspellRanges = pRanges;
}

const std::vector<editeng::MisspellRanges>* ScInputStatusItem::GetMisspellRanges() const
{
    return mpMisspellRanges;
}

//
//  ScPaintHint ist nach schints.cxx verschoben
//
diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx
index cbb774b..4288342 100644
--- a/sc/source/ui/inc/gridwin.hxx
+++ b/sc/source/ui/inc/gridwin.hxx
@@ -394,6 +394,7 @@ public:
    bool ContinueOnlineSpelling();
    void EnableAutoSpell( bool bEnable );
    void ResetAutoSpell();
    void SetAutoSpellData( SCCOL nPosX, SCROW nPosY, const std::vector<editeng::MisspellRanges>* pRanges );

    void            DeleteCopySourceOverlay();
    void            UpdateCopySourceOverlay();
diff --git a/sc/source/ui/inc/tabview.hxx b/sc/source/ui/inc/tabview.hxx
index cb94eb8..4964e6d 100644
--- a/sc/source/ui/inc/tabview.hxx
+++ b/sc/source/ui/inc/tabview.hxx
@@ -30,6 +30,10 @@
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>

namespace editeng {
    struct MisspellRanges;
}

class ScEditEngineDefaulter;
class ScGridWindow;
class ScOutlineWindow;
@@ -524,6 +528,7 @@ public:
    bool ContinueOnlineSpelling();
    void EnableAutoSpell( bool bEnable );
    void ResetAutoSpell();
    void SetAutoSpellData( SCCOL nPosX, SCROW nPosY, const std::vector<editeng::MisspellRanges>* pRanges );
};


diff --git a/sc/source/ui/inc/uiitems.hxx b/sc/source/ui/inc/uiitems.hxx
index d475289..a74a08d 100644
--- a/sc/source/ui/inc/uiitems.hxx
+++ b/sc/source/ui/inc/uiitems.hxx
@@ -27,8 +27,13 @@
#include "paramisc.hxx"
#include <svl/poolitem.hxx>

#include <vector>
#include <boost/scoped_ptr.hpp>

namespace editeng {
    struct MisspellRanges;
}

class ScEditEngineDefaulter;
class EditTextObject;
class ScViewData;
@@ -46,6 +51,7 @@ class ScInputStatusItem : public SfxPoolItem
    ScAddress           aEndPos;
    OUString            aString;
    EditTextObject*     pEditData;
    const std::vector<editeng::MisspellRanges>* mpMisspellRanges;

public:
                            TYPEINFO();
@@ -77,6 +83,9 @@ public:

    const OUString&         GetString() const   { return aString; }
    const EditTextObject*   GetEditData() const { return pEditData; }

    void SetMisspellRanges( const std::vector<editeng::MisspellRanges>* pRanges );
    const std::vector<editeng::MisspellRanges>* GetMisspellRanges() const;
};


diff --git a/sc/source/ui/view/cellsh3.cxx b/sc/source/ui/view/cellsh3.cxx
index 5830838..aa1aeea 100644
--- a/sc/source/ui/view/cellsh3.cxx
+++ b/sc/source/ui/view/cellsh3.cxx
@@ -232,6 +232,7 @@ void ScCellShell::Execute( SfxRequest& rReq )
                ScAddress aCursorPos = pStatusItem->GetPos();
                String aString = pStatusItem->GetString();
                const EditTextObject* pData = pStatusItem->GetEditData();

                if (pData)
                {
                    if (nSlot == FID_INPUTLINE_BLOCK)
@@ -285,9 +286,11 @@ void ScCellShell::Execute( SfxRequest& rReq )
                        pTabViewShell->EnterMatrix( aString, pDoc->GetGrammar() );
                        rReq.Done();
                    }

                }

                pTabViewShell->SetAutoSpellData(
                    aCursorPos.Col(), aCursorPos.Row(), pStatusItem->GetMisspellRanges());

                //  no GrabFocus here, as otherwise on a Mac the tab jumps before the
                //  sideview, when the input was not finished
                //  (GrabFocus is called in KillEditView)
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index 6949b8f..692fcec 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -5533,6 +5533,17 @@ void ScGridWindow::ResetAutoSpell()
    }
}

void ScGridWindow::SetAutoSpellData( SCCOL nPosX, SCROW nPosY, const std::vector<editeng::MisspellRanges>* pRanges )
{
    if (!mpSpellCheckCxt)
        return;

    if (!maVisibleRange.isInside(nPosX, nPosY))
        return;

    mpSpellCheckCxt->setMisspellRanges(nPosX, nPosY, pRanges);
}

// #114409#
void ScGridWindow::CursorChanged()
{
diff --git a/sc/source/ui/view/spellcheckcontext.cxx b/sc/source/ui/view/spellcheckcontext.cxx
index d6cec232e..66c218e 100644
--- a/sc/source/ui/view/spellcheckcontext.cxx
+++ b/sc/source/ui/view/spellcheckcontext.cxx
@@ -71,6 +71,26 @@ const std::vector<editeng::MisspellRanges>* SpellCheckContext::getMisspellRanges
    return &it->second;
}

void SpellCheckContext::setMisspellRanges(
    SCCOL nCol, SCROW nRow, const std::vector<editeng::MisspellRanges>* pRanges )
{
    CellPos aPos(nCol, nRow);
    CellMapType::iterator it = maMisspellCells.find(aPos);

    if (pRanges)
    {
        if (it == maMisspellCells.end())
            maMisspellCells.insert(CellMapType::value_type(aPos, *pRanges));
        else
            it->second = *pRanges;
    }
    else
    {
        if (it != maMisspellCells.end())
            maMisspellCells.erase(it);
    }
}

void SpellCheckContext::reset()
{
    maPos.reset();
diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx
index 2e9e612..7feb1b7 100644
--- a/sc/source/ui/view/tabview.cxx
+++ b/sc/source/ui/view/tabview.cxx
@@ -2369,4 +2369,15 @@ void ScTabView::ResetAutoSpell()
    }
}

void ScTabView::SetAutoSpellData( SCCOL nPosX, SCROW nPosY, const std::vector<editeng::MisspellRanges>* pRanges )
{
    for (int i = 0; i < 4; ++i)
    {
        if (!pGridWin[i])
            continue;

        pGridWin[i]->SetAutoSpellData(nPosX, nPosY, pRanges);
    }
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */