[Libreoffice-commits] core.git: 3 commits - editeng/source include/editeng sc/qa sc/source

Marco Cecchetti marco.cecchetti at collabora.com
Fri Oct 14 15:08:04 UTC 2016


 editeng/source/editeng/editview.cxx          |   30 +++++
 editeng/source/editeng/impedit.cxx           |    6 -
 editeng/source/editeng/impedit.hxx           |   19 +--
 editeng/source/editeng/impedit3.cxx          |    7 +
 include/editeng/editview.hxx                 |   10 +
 sc/qa/unit/tiledrendering/tiledrendering.cxx |   17 +++
 sc/source/ui/inc/tabview.hxx                 |   40 ++-----
 sc/source/ui/view/gridwin4.cxx               |  140 +++++++++++++--------------
 sc/source/ui/view/tabview3.cxx               |   68 +++----------
 sc/source/ui/view/viewdata.cxx               |    4 
 10 files changed, 180 insertions(+), 161 deletions(-)

New commits:
commit cec94a4ecaad666f7222598fd1e2ad9ac05fb878
Author: Marco Cecchetti <marco.cecchetti at collabora.com>
Date:   Sun Oct 9 22:06:40 2016 +0200

    LOK: Calc: an edit view may be not displayed when a 2nd one is killed
    
    - description: when in view #1 text editing of a cell is over (edit
    view killed) a cell still text edited in view #2 can stop to be
    painted correctly;
    
    - reason: when an edit view is killed an
    ScTabViewShell::UpdateFormulas is broadcasted to all views which in
    turn ends by invoking ScViewData::SetEditEngine for already existent
    edit views: if the needed output area size for the actual text content
    is less then the actual output area size (once grown, output area is
    never shrunk) leads to this issue;
    
    - solution: skip to invoke ScViewData::SetEditEngine when LOK is
    active and the related view is not the current view.
    
    Change-Id: I2a97966c7c04701f0a5443aaaeb74760b622045d
    Reviewed-on: https://gerrit.libreoffice.org/29627
    Reviewed-by: Marco Cecchetti <mrcekets at gmail.com>
    Tested-by: Marco Cecchetti <mrcekets at gmail.com>
    Reviewed-on: https://gerrit.libreoffice.org/29660

diff --git a/sc/source/ui/view/viewdata.cxx b/sc/source/ui/view/viewdata.cxx
index 4eb61f0..d14d721 100644
--- a/sc/source/ui/view/viewdata.cxx
+++ b/sc/source/ui/view/viewdata.cxx
@@ -970,6 +970,10 @@ void ScViewData::SetEditEngine( ScSplitPos eWhich,
                                 ScEditEngineDefaulter* pNewEngine,
                                 vcl::Window* pWin, SCCOL nNewX, SCROW nNewY )
 {
+    if (comphelper::LibreOfficeKit::isActive()
+        && GetViewShell() != SfxViewShell::Current())
+        return;
+
     bool bLayoutRTL = pDoc->IsLayoutRTL( nTabNo );
     ScHSplitPos eHWhich = WhichH(eWhich);
 
commit 606b69a5d3885ccda91a4dccbf0b22c634b2f2a9
Author: Marco Cecchetti <marco.cecchetti at collabora.com>
Date:   Sun Oct 9 21:58:40 2016 +0200

    LOK: Calc: if text of 2 cells overlaps, painting occurs in wrong order
    
    - description: when text content of two near cells (edited in 2
    different views) overlaps, the input content showed is the one entered
    in the other view;
    
    - reason: the edit view of other views was painted after the edit view
    owned by the current view;
    
    Change-Id: I7c47f63bc46f7ce43fc494f018167918d44314b6
    Reviewed-on: https://gerrit.libreoffice.org/29626
    Reviewed-by: Marco Cecchetti <mrcekets at gmail.com>
    Tested-by: Marco Cecchetti <mrcekets at gmail.com>
    Reviewed-on: https://gerrit.libreoffice.org/29659

diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx
index 6d329cb..15edd26 100644
--- a/sc/source/ui/view/gridwin4.cxx
+++ b/sc/source/ui/view/gridwin4.cxx
@@ -902,76 +902,6 @@ void ScGridWindow::DrawContent(OutputDevice &rDevice, const ScTableInfo& rTableI
         }
     }
 
-    // In-place editing - when the user is typing, we need to paint the text
-    // using the editeng.
-    // It's being done after EndDrawLayers() to get it outside the overlay
-    // buffer and on top of everything.
-    if ( bEditMode && (pViewData->GetRefTabNo() == pViewData->GetTabNo()) )
-    {
-        // get the coordinates of the area we need to clear (overpaint by
-        // the background)
-        SCCOL nCol1 = pViewData->GetEditStartCol();
-        SCROW nRow1 = pViewData->GetEditStartRow();
-        SCCOL nCol2 = pViewData->GetEditEndCol();
-        SCROW nRow2 = pViewData->GetEditEndRow();
-        rDevice.SetLineColor();
-        rDevice.SetFillColor(pEditView->GetBackgroundColor());
-        Point aStart = pViewData->GetScrPos( nCol1, nRow1, eWhich );
-        Point aEnd = pViewData->GetScrPos( nCol2+1, nRow2+1, eWhich );
-
-        // don't overwrite grid
-        long nLayoutSign = bLayoutRTL ? -1 : 1;
-        aEnd.X() -= 2 * nLayoutSign;
-        aEnd.Y() -= 2;
-
-        // toggle the cursor off if its on to ensure the cursor invert
-        // background logic remains valid after the background is cleared on
-        // the next cursor flash
-        vcl::Cursor* pCrsr = pEditView->GetCursor();
-        const bool bVisCursor = pCrsr && pCrsr->IsVisible();
-        if (bVisCursor)
-            pCrsr->Hide();
-
-        // set the correct mapmode
-        Rectangle aBackground(aStart, aEnd);
-        if (bIsTiledRendering)
-        {
-            // Need to draw the background in absolute coords.
-            auto aOrigin = aOriginalMode.GetOrigin();
-            aOrigin.setX(aOrigin.getX() / TWIPS_PER_PIXEL + nScrX);
-            aOrigin.setY(aOrigin.getY() / TWIPS_PER_PIXEL + nScrY);
-            aBackground += aOrigin;
-            rDevice.SetMapMode(aDrawMode);
-        }
-        else
-            rDevice.SetMapMode(pViewData->GetLogicMode());
-
-        if (bIsTiledRendering)
-        {
-            auto aOrigin = aOriginalMode.GetOrigin();
-            aOrigin.setX(aOrigin.getX() / TWIPS_PER_PIXEL + nScrX);
-            aOrigin.setY(aOrigin.getY() / TWIPS_PER_PIXEL + nScrY);
-            static const double twipFactor = 15 * 1.76388889; // 26.45833335
-            aOrigin = Point(aOrigin.getX() * twipFactor,
-                            aOrigin.getY() * twipFactor);
-            MapMode aNew = rDevice.GetMapMode();
-            aNew.SetOrigin(aOrigin);
-            rDevice.SetMapMode(aNew);
-        }
-
-        // paint the background
-        rDevice.DrawRect(rDevice.PixelToLogic(aBackground));
-
-        // paint the editeng text
-        Rectangle aEditRect(Point(nScrX, nScrY), Size(aOutputData.GetScrW(), aOutputData.GetScrH()));
-        pEditView->Paint(rDevice.PixelToLogic(aEditRect), &rDevice);
-        rDevice.SetMapMode(MapUnit::MapPixel);
-
-        // restore the cursor it was originally visible
-        if (bVisCursor)
-            pCrsr->Show();
-    }
-
     // paint in-place editing on other views
     if (bIsTiledRendering)
     {
@@ -1047,6 +977,76 @@ void ScGridWindow::DrawContent(OutputDevice &rDevice, const ScTableInfo& rTableI
 
     }
 
+    // In-place editing - when the user is typing, we need to paint the text
+    // using the editeng.
+    // It's being done after EndDrawLayers() to get it outside the overlay
+    // buffer and on top of everything.
+    if ( bEditMode && (pViewData->GetRefTabNo() == pViewData->GetTabNo()) )
+    {
+        // get the coordinates of the area we need to clear (overpaint by
+        // the background)
+        SCCOL nCol1 = pViewData->GetEditStartCol();
+        SCROW nRow1 = pViewData->GetEditStartRow();
+        SCCOL nCol2 = pViewData->GetEditEndCol();
+        SCROW nRow2 = pViewData->GetEditEndRow();
+        rDevice.SetLineColor();
+        rDevice.SetFillColor(pEditView->GetBackgroundColor());
+        Point aStart = pViewData->GetScrPos( nCol1, nRow1, eWhich );
+        Point aEnd = pViewData->GetScrPos( nCol2+1, nRow2+1, eWhich );
+
+        // don't overwrite grid
+        long nLayoutSign = bLayoutRTL ? -1 : 1;
+        aEnd.X() -= 2 * nLayoutSign;
+        aEnd.Y() -= 2;
+
+        // toggle the cursor off if its on to ensure the cursor invert
+        // background logic remains valid after the background is cleared on
+        // the next cursor flash
+        vcl::Cursor* pCrsr = pEditView->GetCursor();
+        const bool bVisCursor = pCrsr && pCrsr->IsVisible();
+        if (bVisCursor)
+            pCrsr->Hide();
+
+        // set the correct mapmode
+        Rectangle aBackground(aStart, aEnd);
+        if (bIsTiledRendering)
+        {
+            // Need to draw the background in absolute coords.
+            auto aOrigin = aOriginalMode.GetOrigin();
+            aOrigin.setX(aOrigin.getX() / TWIPS_PER_PIXEL + nScrX);
+            aOrigin.setY(aOrigin.getY() / TWIPS_PER_PIXEL + nScrY);
+            aBackground += aOrigin;
+            rDevice.SetMapMode(aDrawMode);
+        }
+        else
+            rDevice.SetMapMode(pViewData->GetLogicMode());
+
+        if (bIsTiledRendering)
+        {
+            auto aOrigin = aOriginalMode.GetOrigin();
+            aOrigin.setX(aOrigin.getX() / TWIPS_PER_PIXEL + nScrX);
+            aOrigin.setY(aOrigin.getY() / TWIPS_PER_PIXEL + nScrY);
+            static const double twipFactor = 15 * 1.76388889; // 26.45833335
+            aOrigin = Point(aOrigin.getX() * twipFactor,
+                            aOrigin.getY() * twipFactor);
+            MapMode aNew = rDevice.GetMapMode();
+            aNew.SetOrigin(aOrigin);
+            rDevice.SetMapMode(aNew);
+        }
+
+        // paint the background
+        rDevice.DrawRect(rDevice.PixelToLogic(aBackground));
+
+        // paint the editeng text
+        Rectangle aEditRect(Point(nScrX, nScrY), Size(aOutputData.GetScrW(), aOutputData.GetScrH()));
+        pEditView->Paint(rDevice.PixelToLogic(aEditRect), &rDevice);
+        rDevice.SetMapMode(MapUnit::MapPixel);
+
+        // restore the cursor it was originally visible
+        if (bVisCursor)
+            pCrsr->Show();
+    }
+
     if (pViewData->HasEditView(eWhich))
     {
         // flush OverlayManager before changing the MapMode
commit 6c9337866d9b4fe4870c3ab2729c6837d07473ff
Author: Marco Cecchetti <marco.cecchetti at collabora.com>
Date:   Sun Oct 9 21:50:55 2016 +0200

    LOK: Calc: missing invalidate when ending larger-than-cell edit text
    
    - reason: when text content goes further than the cell border the
    output area of the edit view is grown (extended to an adjacent cell),
    on the contrary the output area of edit views used only for
    invalidating windows of other view shells is never updated, so, in
    other views, only the tile where the edit cell is placed is
    invalidated;
    
    - solution: instead of adding fake edit views for invalidation porpuse
    (and having to updated the output area of each of them when required),
    the new solution provides each new edit view, created on cell editing,
    with a set of `foreign` windows related to other views, they are added
    and removed to this collection owned by an edit view still using the
    ScExtraEditViewManager, which has been in turn simplified; when
    EdiEngine::UpdateViews is invoked not only the window where the edit
    view lives is invalidated but also all `foreign` windows in the owned
    set;
    
    - note: ScTiledRenderingTest::testTextEditViewInvalidations unit test
    has been enhanced in order to test correct invalidation when text
    content goes out of the starting tile.
    
    Change-Id: Id223fb1a032d3b18d2cf70df31f704abd245b3ac
    Reviewed-on: https://gerrit.libreoffice.org/29625
    Reviewed-by: Marco Cecchetti <mrcekets at gmail.com>
    Tested-by: Marco Cecchetti <mrcekets at gmail.com>
    Reviewed-on: https://gerrit.libreoffice.org/29658

diff --git a/editeng/source/editeng/editview.cxx b/editeng/source/editeng/editview.cxx
index 3c256ba..63b7b30 100644
--- a/editeng/source/editeng/editview.cxx
+++ b/editeng/source/editeng/editview.cxx
@@ -294,6 +294,36 @@ vcl::Window* EditView::GetWindow() const
     return pImpEditView->pOutWin;
 }
 
+EditView::OutWindowSet&  EditView::GetOtherViewWindows()
+{
+    return pImpEditView->aOutWindowSet;
+}
+
+bool EditView::HasOtherViewWindow( vcl::Window* pWin )
+{
+    OutWindowSet& rOutWindowSet = pImpEditView->aOutWindowSet;
+    auto found = std::find(rOutWindowSet.begin(), rOutWindowSet.end(), pWin);
+    return (found != rOutWindowSet.end());
+}
+
+bool EditView::AddOtherViewWindow( vcl::Window* pWin )
+{
+    if (HasOtherViewWindow(pWin))
+        return false;
+    pImpEditView->aOutWindowSet.emplace_back(pWin);
+    return true;
+}
+
+bool EditView::RemoveOtherViewWindow( vcl::Window* pWin )
+{
+    OutWindowSet& rOutWindowSet = pImpEditView->aOutWindowSet;
+    auto found = std::find(rOutWindowSet.begin(), rOutWindowSet.end(), pWin);
+    if (found == rOutWindowSet.end())
+        return false;
+    rOutWindowSet.erase(found);
+    return true;
+}
+
 void EditView::SetVisArea( const Rectangle& rRect )
 {
     pImpEditView->SetVisDocStartPos( rRect.TopLeft() );
diff --git a/editeng/source/editeng/impedit.cxx b/editeng/source/editeng/impedit.cxx
index 84491fe..7426862 100644
--- a/editeng/source/editeng/impedit.cxx
+++ b/editeng/source/editeng/impedit.cxx
@@ -79,13 +79,13 @@ ImpEditView::ImpEditView( EditView* pView, EditEngine* pEng, vcl::Window* pWindo
     pOutWin             = pWindow;
     pPointer            = nullptr;
     pBackgroundColor    = nullptr;
-    mpViewShell = nullptr;
-    mpOtherShell = nullptr;
+    mpViewShell         = nullptr;
+    mpOtherShell        = nullptr;
     nScrollDiffX        = 0;
     nExtraCursorFlags   = 0;
     nCursorBidiLevel    = CURSOR_BIDILEVEL_DONTKNOW;
     pCursor             = nullptr;
-       pDragAndDropInfo = nullptr;
+    pDragAndDropInfo    = nullptr;
     bReadOnly           = false;
     bClickedInSelection = false;
     eSelectionMode      = EE_SELMODE_TXTONLY;
diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx
index 6143dfa..0a9dfb5 100644
--- a/editeng/source/editeng/impedit.hxx
+++ b/editeng/source/editeng/impedit.hxx
@@ -218,17 +218,18 @@ class ImpEditView : public vcl::unohelper::DragAndDropClient
     using vcl::unohelper::DragAndDropClient::dragOver;
 
 private:
-    EditView*           pEditView;
-    vcl::Cursor*        pCursor;
-    Color*              pBackgroundColor;
+    EditView*                 pEditView;
+    vcl::Cursor*              pCursor;
+    Color*                    pBackgroundColor;
     /// Containing view shell, if any.
-    OutlinerViewShell* mpViewShell;
+    OutlinerViewShell*        mpViewShell;
     /// An other shell, just listening to our state, if any.
-    OutlinerViewShell* mpOtherShell;
-    EditEngine*         pEditEngine;
-    VclPtr<vcl::Window> pOutWin;
-    Pointer*            pPointer;
-    DragAndDropInfo*    pDragAndDropInfo;
+    OutlinerViewShell*        mpOtherShell;
+    EditEngine*               pEditEngine;
+    VclPtr<vcl::Window>       pOutWin;
+    EditView::OutWindowSet    aOutWindowSet;
+    Pointer*                  pPointer;
+    DragAndDropInfo*          pDragAndDropInfo;
 
     css::uno::Reference< css::datatransfer::dnd::XDragSourceListener > mxDnDListener;
 
diff --git a/editeng/source/editeng/impedit3.cxx b/editeng/source/editeng/impedit3.cxx
index ad5ba38..7d30eda 100644
--- a/editeng/source/editeng/impedit3.cxx
+++ b/editeng/source/editeng/impedit3.cxx
@@ -289,6 +289,13 @@ void ImpEditEngine::UpdateViews( EditView* pCurView )
             // convert to window coordinates ....
             aClipRect = pView->pImpEditView->GetWindowPos( aClipRect );
             pView->GetWindow()->Invalidate( aClipRect );
+
+            EditView::OutWindowSet& rOutWindowSet = pView->GetOtherViewWindows();
+            for (auto pWin: rOutWindowSet)
+            {
+                if (pWin)
+                    pWin->Invalidate(aClipRect);
+            }
         }
     }
 
diff --git a/include/editeng/editview.hxx b/include/editeng/editview.hxx
index 0f3c2de..b66486d 100644
--- a/include/editeng/editview.hxx
+++ b/include/editeng/editview.hxx
@@ -85,6 +85,9 @@ class EDITENG_DLLPUBLIC EditView
     friend class ImpEditEngine;
     friend class EditSelFunctionSet;
 
+public:
+    typedef std::vector<VclPtr<vcl::Window>> OutWindowSet;
+
 public: // Needed for Undo
     ImpEditView*    GetImpEditView() const      { return pImpEditView; }
     ImpEditEngine*  GetImpEditEngine() const;
@@ -104,7 +107,12 @@ public:
     EditEngine*     GetEditEngine() const;
 
     void            SetWindow( vcl::Window* pWin );
-    vcl::Window*         GetWindow() const;
+    vcl::Window*    GetWindow() const;
+
+    OutWindowSet&   GetOtherViewWindows();
+    bool            HasOtherViewWindow( vcl::Window* pWin );
+    bool            AddOtherViewWindow( vcl::Window* pWin );
+    bool            RemoveOtherViewWindow( vcl::Window* pWin );
 
     void            Paint( const Rectangle& rRect, OutputDevice* pTargetDevice = nullptr );
     void            Invalidate();
diff --git a/sc/qa/unit/tiledrendering/tiledrendering.cxx b/sc/qa/unit/tiledrendering/tiledrendering.cxx
index dac54bf..83db147 100644
--- a/sc/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sc/qa/unit/tiledrendering/tiledrendering.cxx
@@ -738,6 +738,23 @@ void ScTiledRenderingTest::testTextEditViewInvalidations()
     CPPUNIT_ASSERT(lcl_hasEditView(*pViewData));
     CPPUNIT_ASSERT(aView2.m_bInvalidateTiles);
 
+    // text edit a cell in view #1 until
+    // we can be sure we are out of the initial tile
+    for (int i = 0; i < 40; ++i)
+    {
+        pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0);
+        pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0);
+    }
+    Scheduler::ProcessEventsToIdle();
+
+    // text edit a cell in view #1 inside the new tile and
+    // check that view #2 receive a tile invalidate message
+    aView2.m_bInvalidateTiles = false;
+    pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0);
+    pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0);
+    Scheduler::ProcessEventsToIdle();
+    CPPUNIT_ASSERT(aView2.m_bInvalidateTiles);
+
     // view #3
     SfxLokHelper::createView();
     ViewCallback aView3;
diff --git a/sc/source/ui/inc/tabview.hxx b/sc/source/ui/inc/tabview.hxx
index f1f9431..c04d027 100644
--- a/sc/source/ui/inc/tabview.hxx
+++ b/sc/source/ui/inc/tabview.hxx
@@ -79,59 +79,41 @@ public:
 
 class ScExtraEditViewManager
 {
+private:
+    enum ModifierTagType { Adder, Remover };
+
 public:
     ScExtraEditViewManager(ScTabViewShell* pThisViewShell, VclPtr<ScGridWindow>* pGridWin)
         : mpThisViewShell(pThisViewShell)
         , mpGridWin(pGridWin)
         , mpOtherEditView(nullptr)
-        , mpOtherEngine(nullptr)
-        , maSameEditViewChecker()
-        , nTotalActiveEditViews(0)
+        , nTotalWindows(0)
     {}
 
     ~ScExtraEditViewManager();
 
     void Add(SfxViewShell* pViewShell, ScSplitPos eWhich)
     {
-        Apply(pViewShell, eWhich, &ScExtraEditViewManager::Adder);
+        Apply<Adder>(pViewShell, eWhich);
     }
 
     void Remove(SfxViewShell* pViewShell, ScSplitPos eWhich)
     {
-        Apply(pViewShell, eWhich, &ScExtraEditViewManager::Remover);
+        Apply<Remover>(pViewShell, eWhich);
     }
 
 private:
-    class SameEditViewChecker
-    {
-    public:
-        SameEditViewChecker()
-            : mpOtherEditView(nullptr)
-            , mpWindow(nullptr)
-        {}
-        void SetEditView(EditView* pOtherEditView) { mpOtherEditView = pOtherEditView; }
-        void SetWindow(ScGridWindow* pWindow) { mpWindow = pWindow; }
-        bool operator() (const EditView* pView) const;
-
-    private:
-        EditView* mpOtherEditView;
-        ScGridWindow* mpWindow;
-    };
-
-private:
-    typedef void (ScExtraEditViewManager::* FuncType)(ScGridWindow* );
+    template<ModifierTagType ModifierTag>
+    void Apply(SfxViewShell* pViewShell, ScSplitPos eWhich);
 
-    void Apply(SfxViewShell* pViewShell, ScSplitPos eWhich, FuncType fHandler);
-    void Adder(ScGridWindow* pWin);
-    void Remover(ScGridWindow* pWin);
+    template<ModifierTagType ModifierTag>
+    void Modifier(ScGridWindow* pWin);
 
 private:
     ScTabViewShell* mpThisViewShell;
     VclPtr<ScGridWindow>* mpGridWin;
     EditView* mpOtherEditView;
-    EditEngine* mpOtherEngine;
-    SameEditViewChecker maSameEditViewChecker;
-    int nTotalActiveEditViews;
+    int nTotalWindows;
 };
 
 class ScTabView
diff --git a/sc/source/ui/view/tabview3.cxx b/sc/source/ui/view/tabview3.cxx
index 68a37a9..06ef0b9 100644
--- a/sc/source/ui/view/tabview3.cxx
+++ b/sc/source/ui/view/tabview3.cxx
@@ -100,10 +100,11 @@ using namespace com::sun::star;
 
 ScExtraEditViewManager::~ScExtraEditViewManager()
 {
-    assert(nTotalActiveEditViews == 0);
+    DBG_ASSERT(nTotalWindows == 0, "ScExtraEditViewManager dtor: some out window has not yet been removed!");
 }
 
-void ScExtraEditViewManager::Apply(SfxViewShell* pViewShell, ScSplitPos eWhich, FuncType fHandler)
+template<ScExtraEditViewManager::ModifierTagType ModifierTag>
+void ScExtraEditViewManager::Apply(SfxViewShell* pViewShell, ScSplitPos eWhich)
 {
     ScTabViewShell* pOtherViewShell = dynamic_cast<ScTabViewShell*>(pViewShell);
     if (pOtherViewShell != nullptr && pOtherViewShell != mpThisViewShell)
@@ -111,68 +112,37 @@ void ScExtraEditViewManager::Apply(SfxViewShell* pViewShell, ScSplitPos eWhich,
         mpOtherEditView = pOtherViewShell->GetViewData().GetEditView(eWhich);
         if (mpOtherEditView != nullptr)
         {
-            mpOtherEngine = mpOtherEditView->GetEditEngine();
-            if (mpOtherEngine != nullptr)
+            DBG_ASSERT(mpOtherEditView->GetEditEngine(), "Edit view has no valid engine.");
+            for (int i = 0; i < 4; ++i)
             {
-                maSameEditViewChecker.SetEditView(mpOtherEditView);
-                for (int i = 0; i < 4; ++i)
+                ScGridWindow* pWin = mpGridWin[i].get();
+                if (pWin != nullptr)
                 {
-                    (this->*fHandler)(mpGridWin[i].get());
+                    Modifier<ModifierTag>(pWin);
                 }
             }
         }
     }
 }
 
-void ScExtraEditViewManager::Adder(ScGridWindow* pWin)
+template<ScExtraEditViewManager::ModifierTagType ModifierTag>
+void ScExtraEditViewManager::Modifier(ScGridWindow* /*pWin*/)
 {
-    if (pWin != nullptr)
-    {
-        EditEngine::ViewsType& rEditViews = mpOtherEngine->GetEditViews();
-        maSameEditViewChecker.SetWindow(pWin);
-        auto found = std::find_if(rEditViews.begin(), rEditViews.end(), maSameEditViewChecker);
-        if (found == rEditViews.end())
-        {
-            EditView* pThisEditView = new EditView( mpOtherEngine, pWin );
-            if (pThisEditView != nullptr)
-            {
-                pThisEditView->SetOutputArea(mpOtherEditView->GetOutputArea());
-                pThisEditView->SetVisArea(mpOtherEditView->GetVisArea());
-                mpOtherEngine->InsertView(pThisEditView);
-                ++nTotalActiveEditViews;
-            }
-        }
-    }
+    SAL_WARN("sc", "ScExtraEditViewManager::Modifier<ModifierTag>: non-specialized version should not be invoked.");
 }
 
-void ScExtraEditViewManager::Remover(ScGridWindow* pWin)
+template<>
+void ScExtraEditViewManager::Modifier<ScExtraEditViewManager::Adder>(ScGridWindow* pWin)
 {
-    if (pWin != nullptr)
-    {
-        EditEngine::ViewsType& rEditViews = mpOtherEngine->GetEditViews();
-        maSameEditViewChecker.SetWindow(pWin);
-        auto found = std::find_if(rEditViews.begin(), rEditViews.end(), maSameEditViewChecker);
-        if (found != rEditViews.end())
-        {
-            EditView* pView = *found;
-            if (pView)
-            {
-                mpOtherEngine->RemoveView(pView);
-                delete pView;
-                pView = nullptr;
-                --nTotalActiveEditViews;
-            }
-        }
-    }
+    if (mpOtherEditView->AddOtherViewWindow(pWin))
+        ++nTotalWindows;
 }
 
-bool ScExtraEditViewManager::SameEditViewChecker::operator() (const EditView* pView) const
+template<>
+void ScExtraEditViewManager::Modifier<ScExtraEditViewManager::Remover>(ScGridWindow* pWin)
 {
-    return ( pView != nullptr
-          && pView->GetWindow() == mpWindow
-          && pView->GetEditEngine() == mpOtherEditView->GetEditEngine()
-          && pView->GetOutputArea() == mpOtherEditView->GetOutputArea()
-          && pView->GetVisArea() == mpOtherEditView->GetVisArea() );
+    if (mpOtherEditView->RemoveOtherViewWindow(pWin))
+        --nTotalWindows;
 }
 
 // ---  public functions


More information about the Libreoffice-commits mailing list