[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-5.1' - 3 commits - include/svx sd/qa sd/source svx/source

Miklos Vajna vmiklos at collabora.co.uk
Thu Jul 28 07:23:48 UTC 2016


 include/svx/svdedxv.hxx                        |    8 +-
 sd/qa/unit/tiledrendering/data/title-shape.odp |binary
 sd/qa/unit/tiledrendering/tiledrendering.cxx   |   36 ++++++++--
 sd/source/ui/inc/View.hxx                      |    1 
 sd/source/ui/view/sdview.cxx                   |   10 ++
 svx/source/svdraw/svdedxv.cxx                  |   88 ++++++++++++++++++++++++-
 6 files changed, 134 insertions(+), 9 deletions(-)

New commits:
commit 63e4cdedb18f1c9b2263186c6c36c5a9c2706ac7
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Thu Jul 28 08:23:51 2016 +0200

    svx: fix loplugin:nullptr
    
    Change-Id: Iff5fbb5c8b2885b0ba84c08f1357fdfc82ecf016
    (cherry picked from commit 66dd26659e7c4bb731a88e7dbc809c5b53cb79c3)

diff --git a/include/svx/svdedxv.hxx b/include/svx/svdedxv.hxx
index 0511789..628faee 100644
--- a/include/svx/svdedxv.hxx
+++ b/include/svx/svdedxv.hxx
@@ -111,7 +111,7 @@ protected:
 
     // Create a new OutlinerView at the heap and initialize all required parameters.
     // pTextEditObj, pTextEditPV and pTextEditOutliner have to be initialized
-    OutlinerView* ImpMakeOutlinerView(vcl::Window* pWin, bool bNoPaint, OutlinerView* pGivenView, SfxViewShell* pViewShell = 0) const;
+    OutlinerView* ImpMakeOutlinerView(vcl::Window* pWin, bool bNoPaint, OutlinerView* pGivenView, SfxViewShell* pViewShell = nullptr) const;
     void ImpPaintOutlinerView(OutlinerView& rOutlView, const Rectangle& rRect, OutputDevice& rTargetDevice) const;
     void ImpInvalidateOutlinerView(OutlinerView& rOutlView) const;
 
commit 9931331e5e9cdd4e581962e332024af572f7f90e
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed Jul 27 17:07:47 2016 +0200

    svx lok: fix handling of text edit drawing when view/page changes
    
    This is a follow-up to commit 9d91d371e92548c7f75a7d0155eecaf3769fdee6
    (svx lok: draw text edits in all views, 2016-07-26). Two corner-cases
    are now handled:
    
    1) When the SfxViewShell is created after begin text edit and
    2) When the other draw view is already created, but at the time begin
    text edit happens, the other draw view shows a different page.
    
    And the opposite of these: switching away from a page were we observe a
    text edit done in an other view or destroying a view that observes a
    text edit.
    
    When the complete view goes away, then SdrObjEditView::HideSdrPage() is
    not called, so also try to destroy the outliner view of the text edit
    from SdrObjEditView::DeleteWindowFromPaintView(). The GetSfxViewShell()
    call in SdrObjEditView::ShowSdrPage() is important, because we let the
    other draw view create the outliner view, but the outliner view should
    invoke our view shell, not the view shell of the other draw view.
    
    Also improve the SdTiledRenderingTest::testCursorViews() testcase, so
    that it asserts it managed to begin text edit and use a test document
    that still has a single slide and shape, but the shape is not
    auto-sized; otherwise invalidations happen even if outliner views are
    not created in all draw views, so the test would pass even without the
    fixes.
    
    Change-Id: I2c3bb27826c6887115366db818599fc8adabc5a5
    Reviewed-on: https://gerrit.libreoffice.org/27583
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>
    (cherry picked from commit 5f65ca15a2297f298536d07cfa8564a1f7c67abb)

diff --git a/include/svx/svdedxv.hxx b/include/svx/svdedxv.hxx
index dc3a9bb..0511789 100644
--- a/include/svx/svdedxv.hxx
+++ b/include/svx/svdedxv.hxx
@@ -111,7 +111,7 @@ protected:
 
     // Create a new OutlinerView at the heap and initialize all required parameters.
     // pTextEditObj, pTextEditPV and pTextEditOutliner have to be initialized
-    OutlinerView* ImpMakeOutlinerView(vcl::Window* pWin, bool bNoPaint, OutlinerView* pGivenView) const;
+    OutlinerView* ImpMakeOutlinerView(vcl::Window* pWin, bool bNoPaint, OutlinerView* pGivenView, SfxViewShell* pViewShell = 0) const;
     void ImpPaintOutlinerView(OutlinerView& rOutlView, const Rectangle& rRect, OutputDevice& rTargetDevice) const;
     void ImpInvalidateOutlinerView(OutlinerView& rOutlView) const;
 
@@ -157,6 +157,8 @@ public:
     virtual void BckAction() override;
     virtual void TakeActionRect(Rectangle& rRect) const override;
 
+    SdrPageView* ShowSdrPage(SdrPage* pPage) override;
+    void HideSdrPage() override;
     /// Get access to the view shell owning this draw view, if any.
     virtual SfxViewShell* GetSfxViewShell() const;
 
diff --git a/sd/qa/unit/tiledrendering/data/title-shape.odp b/sd/qa/unit/tiledrendering/data/title-shape.odp
new file mode 100644
index 0000000..15d39d6
Binary files /dev/null and b/sd/qa/unit/tiledrendering/data/title-shape.odp differ
diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx
index 93b2272..8823924 100644
--- a/sd/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx
@@ -824,13 +824,15 @@ public:
     int m_nPart;
     bool m_bCursorVisibleChanged;
     bool m_bViewLock;
+    bool m_bTilesInvalidated;
 
     ViewCallback()
         : m_bGraphicSelectionInvalidated(false),
           m_bGraphicViewSelectionInvalidated(false),
           m_nPart(0),
           m_bCursorVisibleChanged(false),
-          m_bViewLock(false)
+          m_bViewLock(false),
+          m_bTilesInvalidated(false)
     {
     }
 
@@ -843,6 +845,11 @@ public:
     {
         switch (nType)
         {
+        case LOK_CALLBACK_INVALIDATE_TILES:
+        {
+            m_bTilesInvalidated = true;
+        }
+        break;
         case LOK_CALLBACK_GRAPHIC_SELECTION:
         {
             m_bGraphicSelectionInvalidated = true;
@@ -951,17 +958,20 @@ void SdTiledRenderingTest::testCursorViews()
     comphelper::LibreOfficeKit::setActive();
 
     // Create the first view.
-    SdXImpressDocument* pXImpressDocument = createDoc("shape.odp");
+    SdXImpressDocument* pXImpressDocument = createDoc("title-shape.odp");
     ViewCallback aView1;
+    int nView1 = SfxLokHelper::getView();
     SfxViewShell::Current()->registerLibreOfficeKitViewCallback(&ViewCallback::callback, &aView1);
 
     // Begin text edit on the only object on the slide.
     sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
-    SdPage* pActualPage = pViewShell->GetActualPage();
-    SdrObject* pObject = pActualPage->GetObj(0);
     SdrView* pView = pViewShell->GetView();
-    pView->MarkObj(pObject, pView->GetSdrPageView());
-    pView->SdrBeginTextEdit(pObject);
+    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::TAB);
+    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::TAB);
+    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0);
+    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0);
+    Scheduler::ProcessEventsToIdle();
+    CPPUNIT_ASSERT(pView->IsTextEdit());
 
     // Make sure that cursor state is not changed just because we create a second view.
     aView1.m_bCursorVisibleChanged = false;
@@ -970,6 +980,20 @@ void SdTiledRenderingTest::testCursorViews()
     Scheduler::ProcessEventsToIdle();
     CPPUNIT_ASSERT(!aView1.m_bCursorVisibleChanged);
 
+    // Make sure that typing in the first view causes an invalidation in the
+    // second view as well, even if the second view was created after begin
+    // text edit in the first view.
+    ViewCallback aView2;
+    SfxViewShell::Current()->registerLibreOfficeKitViewCallback(&ViewCallback::callback, &aView2);
+    SfxLokHelper::setView(nView1);
+    aView2.m_bTilesInvalidated = false;
+    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0);
+    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0);
+    Scheduler::ProcessEventsToIdle();
+    // This failed: the second view was not invalidated when pressing a key in
+    // the first view.
+    CPPUNIT_ASSERT(aView2.m_bTilesInvalidated);
+
     mxComponent->dispose();
     mxComponent.clear();
     comphelper::LibreOfficeKit::setActive(false);
diff --git a/svx/source/svdraw/svdedxv.cxx b/svx/source/svdraw/svdedxv.cxx
index cd315af..0731dfd 100644
--- a/svx/source/svdraw/svdedxv.cxx
+++ b/svx/source/svdraw/svdedxv.cxx
@@ -134,6 +134,76 @@ void SdrObjEditView::BrkAction()
     SdrGlueEditView::BrkAction();
 }
 
+SdrPageView* SdrObjEditView::ShowSdrPage(SdrPage* pPage)
+{
+    SdrPageView* pPageView = SdrGlueEditView::ShowSdrPage(pPage);
+
+    if (comphelper::LibreOfficeKit::isActive() && pPageView)
+    {
+        // Check if other views have an active text edit on the same page as
+        // this one.
+        SdrViewIter aIter(pPageView->GetPage());
+        for (SdrView* pView = aIter.FirstView(); pView; pView = aIter.NextView())
+        {
+            if (pView == this || !pView->IsTextEdit())
+                continue;
+
+            OutputDevice* pOutDev = GetFirstOutputDevice();
+            if (!pOutDev || pOutDev->GetOutDevType() != OUTDEV_WINDOW)
+                continue;
+
+            // Found one, so create an outliner view, to get invalidations when
+            // the text edit changes.
+            bool bEmpty = pView->GetTextEditObject()->GetOutlinerParaObject() == nullptr;
+            // Call GetSfxViewShell() to make sure ImpMakeOutlinerView()
+            // registers the view shell of this draw view, and not the view
+            // shell of pView.
+            OutlinerView* pOutlinerView = pView->ImpMakeOutlinerView(static_cast<vcl::Window*>(pOutDev), !bEmpty, nullptr, GetSfxViewShell());
+            pView->GetTextEditOutliner()->InsertView(pOutlinerView);
+        }
+    }
+
+    return pPageView;
+}
+
+/// Removes outliner views registered in other draw views that use pOutputDevice.
+void lcl_RemoveTextEditOutlinerViews(SdrObjEditView* pThis, SdrPageView* pPageView, OutputDevice* pOutputDevice)
+{
+    if (!comphelper::LibreOfficeKit::isActive())
+        return;
+
+    if (!pPageView)
+        return;
+
+    if (!pOutputDevice || pOutputDevice->GetOutDevType() != OUTDEV_WINDOW)
+        return;
+
+    SdrViewIter aIter(pPageView->GetPage());
+    for (SdrView* pView = aIter.FirstView(); pView; pView = aIter.NextView())
+    {
+        if (pView == pThis || !pView->IsTextEdit())
+            continue;
+
+        SdrOutliner* pOutliner = pView->GetTextEditOutliner();
+        for (size_t nView = 0; nView < pOutliner->GetViewCount(); ++nView)
+        {
+            OutlinerView* pOutlinerView = pOutliner->GetView(nView);
+            if (pOutlinerView->GetWindow() != pOutputDevice)
+                continue;
+
+            pOutliner->RemoveView(pOutlinerView);
+            delete pOutlinerView;
+        }
+    }
+}
+
+void SdrObjEditView::HideSdrPage()
+{
+    lcl_RemoveTextEditOutlinerViews(this, GetSdrPageView(), GetFirstOutputDevice());
+
+    SdrGlueEditView::HideSdrPage();
+}
+
 void SdrObjEditView::TakeActionRect(Rectangle& rRect) const
 {
     if (IsMacroObj()) {
@@ -443,7 +513,7 @@ void SdrObjEditView::ImpInvalidateOutlinerView(OutlinerView& rOutlView) const
     }
 }
 
-OutlinerView* SdrObjEditView::ImpMakeOutlinerView(vcl::Window* pWin, bool /*bNoPaint*/, OutlinerView* pGivenView) const
+OutlinerView* SdrObjEditView::ImpMakeOutlinerView(vcl::Window* pWin, bool /*bNoPaint*/, OutlinerView* pGivenView, SfxViewShell* pViewShell) const
 {
     // background
     Color aBackground(GetTextEditBackgroundColor(*this));
@@ -472,7 +542,7 @@ OutlinerView* SdrObjEditView::ImpMakeOutlinerView(vcl::Window* pWin, bool /*bNoP
     // SfxViewShell::Current() may still point to the old one. So if possible,
     // depend on the application owning this draw view to provide the view
     // shell.
-    SfxViewShell* pSfxViewShell = GetSfxViewShell();
+    SfxViewShell* pSfxViewShell = pViewShell ? pViewShell : GetSfxViewShell();
     pOutlView->registerLibreOfficeKitViewCallback(pSfxViewShell ? pSfxViewShell : SfxViewShell::Current());
 
     if (pText!=nullptr)
@@ -1854,6 +1924,8 @@ void SdrObjEditView::DeleteWindowFromPaintView(OutputDevice* pOldWin)
             }
         }
     }
+
+    lcl_RemoveTextEditOutlinerViews(this, GetSdrPageView(), pOldWin);
 }
 
 bool SdrObjEditView::IsTextEditInSelectionMode() const
commit 0f83ff712a6253066b758d39d92ac528bdb2f5d3
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Wed Jul 27 10:03:28 2016 +0200

    svx lok: avoid SfxViewShell::Current() during constructing a new view shell
    
    Currently when a text edit is started, then in the LOK case if there is
    an other view that shows the same page, then both draw views will have
    an outliner view showing the text edit. This means that in case a view
    shell is created after starting the text edit, that won't have an
    outliner view for the text edit.
    
    Before fixing this, calls to SfxViewShell::Current() has to be avoided
    when we're in the process of setting up a new LOK view. In case of
    Impress, this is a double initialization, and by the time
    SdrObjEditView::ImpMakeOutlinerView() is called, we're already in the
    process of setting up the second SfxViewShell (as part of
    SdXImpressDocument::initializeForTiledRendering()), but
    SfxViewShell::Current() still points to the old view shell.  Which means
    that the outliner view would refer to a view shell that's deleted soon,
    and we crash as soon as it tries to invoke a LOK callback.
    
    Fix this by adding a virtual member function to SdrObjEditView, and
    override it in sd, so in case applications want to provide a more
    precise way of giving the view shell owning a draw view, then they can.
    
    Change-Id: Ie0005f73237d4ff9cf576bf16fa5b46280f13759
    Reviewed-on: https://gerrit.libreoffice.org/27561
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>
    (cherry picked from commit c0f1c0da77cf9f148b3f29aaf0965dfb43b8a32c)

diff --git a/include/svx/svdedxv.hxx b/include/svx/svdedxv.hxx
index 58db6bd..dc3a9bb 100644
--- a/include/svx/svdedxv.hxx
+++ b/include/svx/svdedxv.hxx
@@ -35,6 +35,7 @@ class ImpSdrEditPara;
 struct PasteOrDropInfos;
 class SdrUndoManager;
 class TextChainCursorManager;
+class SfxViewShell;
 
 namespace com { namespace sun { namespace star { namespace uno {
     class Any;
@@ -156,6 +157,9 @@ public:
     virtual void BckAction() override;
     virtual void TakeActionRect(Rectangle& rRect) const override;
 
+    /// Get access to the view shell owning this draw view, if any.
+    virtual SfxViewShell* GetSfxViewShell() const;
+
     virtual void Notify(SfxBroadcaster& rBC, const SfxHint& rHint) override;
     virtual void ModelHasChanged() override;
 
diff --git a/sd/source/ui/inc/View.hxx b/sd/source/ui/inc/View.hxx
index fc16663..887c84c 100644
--- a/sd/source/ui/inc/View.hxx
+++ b/sd/source/ui/inc/View.hxx
@@ -122,6 +122,7 @@ public:
     inline DrawDocShell* GetDocSh() const { return mpDocSh; }
     inline SdDrawDocument& GetDoc() const;
     inline ViewShell* GetViewShell() const { return mpViewSh; }
+    SfxViewShell* GetSfxViewShell() const override;
 
     virtual bool SdrBeginTextEdit(SdrObject* pObj, SdrPageView* pPV = nullptr, vcl::Window* pWin = nullptr, bool bIsNewObj = false,
         SdrOutliner* pGivenOutliner = nullptr, OutlinerView* pGivenOutlinerView = nullptr,
diff --git a/sd/source/ui/view/sdview.cxx b/sd/source/ui/view/sdview.cxx
index 01a23f0..d5caa2e 100644
--- a/sd/source/ui/view/sdview.cxx
+++ b/sd/source/ui/view/sdview.cxx
@@ -651,6 +651,16 @@ void OutlinerMasterViewFilter::End()
     }
 }
 
+SfxViewShell* View::GetSfxViewShell() const
+{
+    SfxViewShell* pRet = nullptr;
+
+    if (mpViewSh)
+        pRet = &mpViewSh->GetViewShellBase();
+
+    return pRet;
+}
+
 bool View::SdrBeginTextEdit(
     SdrObject* pObj, SdrPageView* pPV, vcl::Window* pWin,
     bool bIsNewObj,
diff --git a/svx/source/svdraw/svdedxv.cxx b/svx/source/svdraw/svdedxv.cxx
index 6467463..cd315af 100644
--- a/svx/source/svdraw/svdedxv.cxx
+++ b/svx/source/svdraw/svdedxv.cxx
@@ -143,6 +143,11 @@ void SdrObjEditView::TakeActionRect(Rectangle& rRect) const
     }
 }
 
+SfxViewShell* SdrObjEditView::GetSfxViewShell() const
+{
+    return nullptr;
+}
+
 void SdrObjEditView::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
 {
     SdrGlueEditView::Notify(rBC,rHint);
@@ -462,7 +467,14 @@ OutlinerView* SdrObjEditView::ImpMakeOutlinerView(vcl::Window* pWin, bool /*bNoP
     }
     pOutlView->SetControlWord(nStat);
     pOutlView->SetBackgroundColor( aBackground );
-    pOutlView->registerLibreOfficeKitViewCallback(SfxViewShell::Current());
+
+    // In case we're in the process of constructing a new view shell,
+    // SfxViewShell::Current() may still point to the old one. So if possible,
+    // depend on the application owning this draw view to provide the view
+    // shell.
+    SfxViewShell* pSfxViewShell = GetSfxViewShell();
+    pOutlView->registerLibreOfficeKitViewCallback(pSfxViewShell ? pSfxViewShell : SfxViewShell::Current());
+
     if (pText!=nullptr)
     {
         pOutlView->SetAnchorMode((EVAnchorMode)(pText->GetOutlinerViewAnchorMode()));


More information about the Libreoffice-commits mailing list