editeng/source/editeng/editview.cxx            |    5 +++
 editeng/source/editeng/impedit.cxx             |   19 +++++++++++-
 editeng/source/editeng/impedit.hxx             |    4 ++
 include/editeng/editview.hxx                   |    2 +
 include/editeng/outliner.hxx                   |    2 +
 include/sfx2/viewsh.hxx                        |    2 +
 sfx2/source/view/viewsh.cxx                    |    9 ++++++
 sw/qa/extras/tiledrendering/tiledrendering.cxx |   37 +++++++++++++++++++++++++
 sw/source/core/crsr/crsrsh.cxx                 |   23 +++++++++++----
 9 files changed, 95 insertions(+), 8 deletions(-)

New commits:
commit 586789fe757c0eb350c360a49cf90431a0bd5b24
Author: Miklos Vajna <vmik...@collabora.co.uk>
Date:   Tue Sep 13 16:48:05 2016 +0200

    sw draw text: emit LOK_CALLBACK_INVALIDATE_VIEW_CURSOR from 
registerCallback()
    
    With this, in case the first view has an active text edit and a new view
    is created, then the cursor position is instantly visible in the second
    view, even if the first view's cursor does not move later.
    
    Change-Id: Ia82e7dc1ce9bb58c67a280179ecadc74d3b63026

diff --git a/editeng/source/editeng/editview.cxx 
b/editeng/source/editeng/editview.cxx
index 1bc28d3..f7f01f1 100644
--- a/editeng/source/editeng/editview.cxx
+++ b/editeng/source/editeng/editview.cxx
@@ -592,6 +592,11 @@ void EditView::RegisterViewShell(OutlinerViewShell* 
pViewShell)
     pImpEditView->RegisterViewShell(pViewShell);
 }
 
+void EditView::RegisterOtherShell(OutlinerViewShell* pOtherShell)
+{
+    pImpEditView->RegisterOtherShell(pOtherShell);
+}
+
 void EditView::SetControlWord( EVControlBits nWord )
 {
     pImpEditView->nControl = nWord;
diff --git a/editeng/source/editeng/impedit.cxx 
b/editeng/source/editeng/impedit.cxx
index 36b08eb..c0d9201 100644
--- a/editeng/source/editeng/impedit.cxx
+++ b/editeng/source/editeng/impedit.cxx
@@ -80,6 +80,7 @@ ImpEditView::ImpEditView( EditView* pView, EditEngine* pEng, 
vcl::Window* pWindo
     pPointer            = nullptr;
     pBackgroundColor    = nullptr;
     mpViewShell = nullptr;
+    mpOtherShell = nullptr;
     nScrollDiffX        = 0;
     nExtraCursorFlags   = 0;
     nCursorBidiLevel    = CURSOR_BIDILEVEL_DONTKNOW;
@@ -122,6 +123,11 @@ void ImpEditView::RegisterViewShell(OutlinerViewShell* 
pViewShell)
     mpViewShell = pViewShell;
 }
 
+void ImpEditView::RegisterOtherShell(OutlinerViewShell* pOtherShell)
+{
+    mpOtherShell = pOtherShell;
+}
+
 const OutlinerViewShell* ImpEditView::GetViewShell() const
 {
     return mpViewShell;
@@ -1005,8 +1011,17 @@ void ImpEditView::ShowCursor( bool bGotoCursor, bool 
bForceVisCursor )
             aRect.setWidth(0);
 
             OString sRect = aRect.toString();
-            
mpViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, 
sRect.getStr());
-            mpViewShell->NotifyOtherViews(LOK_CALLBACK_INVALIDATE_VIEW_CURSOR, 
"rectangle", sRect);
+            if (mpOtherShell)
+            {
+                // An other shell wants to know about our existing cursor.
+                if (mpViewShell != mpOtherShell)
+                    mpViewShell->NotifyOtherView(mpOtherShell, 
LOK_CALLBACK_INVALIDATE_VIEW_CURSOR, "rectangle", sRect);
+            }
+            else
+            {
+                
mpViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, 
sRect.getStr());
+                
mpViewShell->NotifyOtherViews(LOK_CALLBACK_INVALIDATE_VIEW_CURSOR, "rectangle", 
sRect);
+            }
         }
 
         CursorDirection nCursorDir = CursorDirection::NONE;
diff --git a/editeng/source/editeng/impedit.hxx 
b/editeng/source/editeng/impedit.hxx
index 612fe41..3daf331 100644
--- a/editeng/source/editeng/impedit.hxx
+++ b/editeng/source/editeng/impedit.hxx
@@ -223,6 +223,8 @@ private:
     Color*              pBackgroundColor;
     /// Containing view shell, if any.
     OutlinerViewShell* mpViewShell;
+    /// An other shell, just listening to our state, if any.
+    OutlinerViewShell* mpOtherShell;
     EditEngine*         pEditEngine;
     VclPtr<vcl::Window> pOutWin;
     Pointer*            pPointer;
@@ -370,6 +372,8 @@ public:
     /// Informs this edit view about which view shell contains it.
     void RegisterViewShell(OutlinerViewShell* pViewShell);
     const OutlinerViewShell* GetViewShell() const;
+    /// Informs this edit view about which other shell listens to it.
+    void RegisterOtherShell(OutlinerViewShell* pViewShell);
 
     bool            IsWrongSpelledWord( const EditPaM& rPaM, bool bMarkIfWrong 
);
     OUString        SpellIgnoreWord();
diff --git a/include/editeng/editview.hxx b/include/editeng/editview.hxx
index 7c28a75..df54444 100644
--- a/include/editeng/editview.hxx
+++ b/include/editeng/editview.hxx
@@ -184,6 +184,8 @@ public:
 
     /// Informs this edit view about which view shell contains it.
     void RegisterViewShell(OutlinerViewShell* pViewShell);
+    /// Informs this edit view about which other shell listens to it.
+    void RegisterOtherShell(OutlinerViewShell* pOtherShell);
 
     void            SetControlWord( EVControlBits nWord );
     EVControlBits   GetControlWord() const;
diff --git a/include/editeng/outliner.hxx b/include/editeng/outliner.hxx
index 984db79..a0eef10 100644
--- a/include/editeng/outliner.hxx
+++ b/include/editeng/outliner.hxx
@@ -379,6 +379,8 @@ public:
     virtual sal_uInt32 GetViewShellId() const = 0;
     /// Wrapper around SfxLokHelper::notifyOtherViews().
     virtual void NotifyOtherViews(int nType, const OString& rKey, const 
OString& rPayload) = 0;
+    /// Wrapper around SfxLokHelper::notifyOtherView().
+    virtual void NotifyOtherView(OutlinerViewShell* pOtherShell, int nType, 
const OString& rKey, const OString& rPayload) = 0;
 
 protected:
     ~OutlinerViewShell() throw () {}
diff --git a/include/sfx2/viewsh.hxx b/include/sfx2/viewsh.hxx
index c0a9be2..a1fea9b 100644
--- a/include/sfx2/viewsh.hxx
+++ b/include/sfx2/viewsh.hxx
@@ -342,6 +342,8 @@ public:
     sal_uInt32 GetViewShellId() const override;
     /// See OutlinerViewShell::NotifyOtherViews().
     void NotifyOtherViews(int nType, const OString& rKey, const OString& 
rPayload) override;
+    /// See OutlinerViewShell::NotifyOtherView().
+    void NotifyOtherView(OutlinerViewShell* pOtherShell, int nType, const 
OString& rKey, const OString& rPayload) override;
     /// Ask this view to send its cursor position to pViewShell.
     virtual void NotifyCursor(SfxViewShell* /*pViewShell*/) const;
 };
diff --git a/sfx2/source/view/viewsh.cxx b/sfx2/source/view/viewsh.cxx
index 9af6d8f..78bf0b6 100644
--- a/sfx2/source/view/viewsh.cxx
+++ b/sfx2/source/view/viewsh.cxx
@@ -1533,6 +1533,15 @@ void SfxViewShell::NotifyOtherViews(int nType, const 
OString& rKey, const OStrin
     SfxLokHelper::notifyOtherViews(this, nType, rKey, rPayload);
 }
 
+void SfxViewShell::NotifyOtherView(OutlinerViewShell* pOther, int nType, const 
OString& rKey, const OString& rPayload)
+{
+    auto pOtherShell = dynamic_cast<SfxViewShell*>(pOther);
+    if (!pOtherShell)
+        return;
+
+    SfxLokHelper::notifyOtherView(this, pOtherShell, nType, rKey, rPayload);
+}
+
 void SfxViewShell::dumpAsXml(xmlTextWriterPtr pWriter) const
 {
     xmlTextWriterStartElement(pWriter, BAD_CAST("sfxViewShell"));
diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx 
b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index a2a88e1..0424fea 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -602,7 +602,9 @@ class ViewCallback
 {
 public:
     bool m_bOwnCursorInvalidated;
+    Rectangle m_aOwnCursor;
     bool m_bViewCursorInvalidated;
+    Rectangle m_aViewCursor;
     bool m_bOwnSelectionSet;
     bool m_bViewSelectionSet;
     OString m_aViewSelection;
@@ -643,11 +645,33 @@ public:
         case LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR:
         {
             m_bOwnCursorInvalidated = true;
+
+            uno::Sequence<OUString> aSeq = 
comphelper::string::convertCommaSeparated(OUString::fromUtf8(aPayload));
+            if (OString("EMPTY") == pPayload)
+                return;
+            CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(4), aSeq.getLength());
+            m_aOwnCursor.setX(aSeq[0].toInt32());
+            m_aOwnCursor.setY(aSeq[1].toInt32());
+            m_aOwnCursor.setWidth(aSeq[2].toInt32());
+            m_aOwnCursor.setHeight(aSeq[3].toInt32());
         }
         break;
         case LOK_CALLBACK_INVALIDATE_VIEW_CURSOR:
         {
             m_bViewCursorInvalidated = true;
+            std::stringstream aStream(pPayload);
+            boost::property_tree::ptree aTree;
+            boost::property_tree::read_json(aStream, aTree);
+            OString aRect = 
aTree.get_child("rectangle").get_value<std::string>().c_str();
+
+            uno::Sequence<OUString> aSeq = 
comphelper::string::convertCommaSeparated(OUString::fromUtf8(aRect));
+            if (OString("EMPTY") == pPayload)
+                return;
+            CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(4), aSeq.getLength());
+            m_aViewCursor.setX(aSeq[0].toInt32());
+            m_aViewCursor.setY(aSeq[1].toInt32());
+            m_aViewCursor.setWidth(aSeq[2].toInt32());
+            m_aViewCursor.setHeight(aSeq[3].toInt32());
         }
         break;
         case LOK_CALLBACK_TEXT_SELECTION:
@@ -1148,6 +1172,8 @@ void SwTiledRenderingTest::testShapeTextUndoGroupShells()
     // Load a document and create a view.
     comphelper::LibreOfficeKit::setActive();
     SwXTextDocument* pXTextDocument = createDoc("shape.fodt");
+    ViewCallback aView1;
+    
SfxViewShell::Current()->registerLibreOfficeKitViewCallback(&ViewCallback::callback,
 &aView1);
     sal_Int32 nView1 = SfxLokHelper::getView();
 
     // Begin text edit.
@@ -1168,6 +1194,17 @@ void SwTiledRenderingTest::testShapeTextUndoGroupShells()
     // This was -1: the view shell id for the (top) undo list action wasn't 
known.
     CPPUNIT_ASSERT_EQUAL(nView1, 
rUndoManager.GetUndoAction()->GetViewShellId());
 
+    // Create a second view, and make sure that the new view sees the same
+    // cursor position as the old one.
+    SfxLokHelper::createView();
+    pXTextDocument->initializeForTiledRendering({});
+    ViewCallback aView2;
+    aView2.m_aViewCursor = Rectangle();
+    
SfxViewShell::Current()->registerLibreOfficeKitViewCallback(&ViewCallback::callback,
 &aView2);
+    // Difference was 935 twips, the new view didn't see the editeng cursor of
+    // the old one. The new difference should be <1px, but here we deal with 
twips.
+    CPPUNIT_ASSERT(std::abs(aView1.m_aOwnCursor.Top() - 
aView2.m_aViewCursor.Top()) < 10);
+
     mxComponent->dispose();
     mxComponent.clear();
     comphelper::LibreOfficeKit::setActive(false);
diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index 241d8d4..fabf153 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -66,6 +66,7 @@
 #include <comphelper/lok.hxx>
 #include <sfx2/lokhelper.hxx>
 #include <comphelper/string.hxx>
+#include <editeng/editview.hxx>
 #include <PostItMgr.hxx>
 #include <DocumentSettingManager.hxx>
 
@@ -1194,13 +1195,23 @@ OUString SwCursorShell::getPageRectangles()
 
 void SwCursorShell::NotifyCursor(SfxViewShell* pOtherShell) const
 {
-    // Cursor position and visibility.
-    m_pVisibleCursor->SetPosAndShow(pOtherShell);
-    // Text selection.
-    m_pCurrentCursor->Show(pOtherShell);
-    // Graphic selection.
     auto pView = const_cast<SdrView*>(GetDrawView());
-    pView->AdjustMarkHdl(pOtherShell);
+    if (pView->GetTextEditObject())
+    {
+        EditView& rEditView = pView->GetTextEditOutlinerView()->GetEditView();
+        rEditView.RegisterOtherShell(pOtherShell);
+        rEditView.ShowCursor();
+        rEditView.RegisterOtherShell(nullptr);
+    }
+    else
+    {
+        // Cursor position and visibility.
+        m_pVisibleCursor->SetPosAndShow(pOtherShell);
+        // Text selection.
+        m_pCurrentCursor->Show(pOtherShell);
+        // Graphic selection.
+        pView->AdjustMarkHdl(pOtherShell);
+    }
 }
 
 /// go to the next SSelection
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to