[Libreoffice-commits] core.git: desktop/source include/LibreOfficeKit libreofficekit/source sd/qa sfx2/source svx/source

Miklos Vajna vmiklos at collabora.co.uk
Fri Jul 1 17:20:48 UTC 2016


 desktop/source/lib/init.cxx                  |    2 
 include/LibreOfficeKit/LibreOfficeKitEnums.h |   16 ++++++
 libreofficekit/source/gtk/lokdocview.cxx     |   43 +++++++++++++++--
 sd/qa/unit/tiledrendering/tiledrendering.cxx |   68 +++++++++++++++++++++++++++
 sfx2/source/view/viewsh.cxx                  |    2 
 svx/source/svdraw/svdmrkv.cxx                |   10 +++
 6 files changed, 137 insertions(+), 4 deletions(-)

New commits:
commit 3ebfc5b95559a9bcb2fc0508b51fd00e8eb20260
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Fri Jul 1 18:05:43 2016 +0200

    svx lok: add LOK_CALLBACK_GRAPHIC_VIEW_SELECTION
    
    So a view can be aware where the graphic selections of other views are.
    
    Change-Id: I0cc420cfe4bf3824fbfa1a58da889cac5e9a7b60
    Reviewed-on: https://gerrit.libreoffice.org/26863
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 581eb89..9762cd82 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -446,6 +446,7 @@ CallbackFlushHandler::CallbackFlushHandler(LibreOfficeKitDocument* pDocument, Li
     m_states.emplace(LOK_CALLBACK_TEXT_SELECTION_END, "NIL");
     m_states.emplace(LOK_CALLBACK_TEXT_SELECTION, "NIL");
     m_states.emplace(LOK_CALLBACK_GRAPHIC_SELECTION, "NIL");
+    m_states.emplace(LOK_CALLBACK_GRAPHIC_VIEW_SELECTION, "NIL");
     m_states.emplace(LOK_CALLBACK_INVALIDATE_VISIBLE_CURSOR, "NIL");
     m_states.emplace(LOK_CALLBACK_INVALIDATE_VIEW_CURSOR , "NIL");
     m_states.emplace(LOK_CALLBACK_STATE_CHANGED, "NIL");
@@ -552,6 +553,7 @@ void CallbackFlushHandler::queue(const int type, const char* data)
         case LOK_CALLBACK_TEXT_SELECTION_END:
         case LOK_CALLBACK_TEXT_SELECTION:
         case LOK_CALLBACK_GRAPHIC_SELECTION:
+        case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION:
         case LOK_CALLBACK_MOUSE_POINTER:
         case LOK_CALLBACK_CELL_CURSOR:
         case LOK_CALLBACK_CELL_VIEW_CURSOR:
diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h
index c687879..d8e46db 100644
--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h
+++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h
@@ -358,6 +358,22 @@ typedef enum
      */
     LOK_CALLBACK_CELL_VIEW_CURSOR,
 
+    /**
+     * The size and/or the position of a graphic selection in one of the other
+     * views has changed.
+     *
+     * The payload format:
+     *
+     * {
+     *     "viewId": "..."
+     *     "selection": "..."
+     * }
+     *
+     * - viewId is a value returned earlier by lok::Document::createView()
+     * - selection uses the format of LOK_CALLBACK_INVALIDATE_TILES.
+     */
+    LOK_CALLBACK_GRAPHIC_VIEW_SELECTION,
+
 }
 LibreOfficeKitCallbackType;
 
diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index 502ae5d..8bf889f 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -101,9 +101,12 @@ struct LOKDocViewPrivateImpl
     /// Position and size of the selection end.
     GdkRectangle m_aTextSelectionEnd;
     GdkRectangle m_aGraphicSelection;
+    /// Position and size of the graphic view selections. The current view can only
+    /// see them, can't modify them. Key is the view id.
+    std::map<int, GdkRectangle> m_aGraphicViewSelections;
     GdkRectangle m_aCellCursor;
     /// Position and size of the cell view cursors. The current view can only
-    //see / them, can't modify them. Key is the view id.
+    /// see them, can't modify them. Key is the view id.
     std::map<int, GdkRectangle> m_aCellViewCursors;
     gboolean m_bInDragGraphicSelection;
 
@@ -323,6 +326,8 @@ callbackTypeToString (int nType)
         return "LOK_CALLBACK_CURSOR_VISIBLE";
     case LOK_CALLBACK_GRAPHIC_SELECTION:
         return "LOK_CALLBACK_GRAPHIC_SELECTION";
+    case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION:
+        return "LOK_CALLBACK_GRAPHIC_VIEW_SELECTION";
     case LOK_CALLBACK_CELL_CURSOR:
         return "LOK_CALLBACK_CELL_CURSOR";
     case LOK_CALLBACK_HYPERLINK_CLICKED:
@@ -1108,6 +1113,25 @@ callback (gpointer pData)
         gtk_widget_queue_draw(GTK_WIDGET(pDocView));
     }
     break;
+    case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION:
+    {
+        std::stringstream aStream(pCallback->m_aPayload);
+        boost::property_tree::ptree aTree;
+        boost::property_tree::read_json(aStream, aTree);
+        int nViewId = aTree.get<int>("viewId");
+        const std::string& rRectangle = aTree.get<std::string>("selection");
+        if (rRectangle != "EMPTY")
+            priv->m_aGraphicViewSelections[nViewId] = payloadToRectangle(pDocView, rRectangle.c_str());
+        else
+        {
+            auto it = priv->m_aGraphicViewSelections.find(nViewId);
+            if (it != priv->m_aGraphicViewSelections.end())
+                priv->m_aGraphicViewSelections.erase(it);
+        }
+        gtk_widget_queue_draw(GTK_WIDGET(pDocView));
+        break;
+    }
+    break;
     case LOK_CALLBACK_CELL_CURSOR:
     {
         if (pCallback->m_aPayload != "EMPTY")
@@ -1271,7 +1295,8 @@ renderHandle(LOKDocView* pDocView,
 static void
 renderGraphicHandle(LOKDocView* pDocView,
                     cairo_t* pCairo,
-                    const GdkRectangle& rSelection)
+                    const GdkRectangle& rSelection,
+                    const GdkRGBA& rColor)
 {
     LOKDocViewPrivate& priv = getPrivate(pDocView);
     int nHandleWidth = 9, nHandleHeight = 9;
@@ -1325,7 +1350,7 @@ renderGraphicHandle(LOKDocView* pDocView,
         priv->m_aGraphicHandleRects[i].width = nHandleWidth;
         priv->m_aGraphicHandleRects[i].height = nHandleHeight;
 
-        cairo_set_source_rgb(pCairo, 0, 0, 0);
+        cairo_set_source_rgb(pCairo, rColor.red, rColor.green, rColor.blue);
         cairo_rectangle(pCairo, x, y, nHandleWidth, nHandleHeight);
         cairo_fill(pCairo);
     }
@@ -1586,7 +1611,17 @@ renderOverlay(LOKDocView* pDocView, cairo_t* pCairo)
     }
 
     if (!isEmptyRectangle(priv->m_aGraphicSelection))
-        renderGraphicHandle(pDocView, pCairo, priv->m_aGraphicSelection);
+    {
+        GdkRGBA aBlack{0, 0, 0, 0};
+        renderGraphicHandle(pDocView, pCairo, priv->m_aGraphicSelection, aBlack);
+    }
+
+    // Graphic selections of other views.
+    for (std::pair<const int, GdkRectangle>& rPair : priv->m_aGraphicViewSelections)
+    {
+        const GdkRGBA& rDark = getDarkColor(rPair.first);
+        renderGraphicHandle(pDocView, pCairo, rPair.second, rDark);
+    }
 
     // Draw the cell cursor.
     if (!isEmptyRectangle(priv->m_aCellCursor))
diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx
index 4d3ed11..a465b63 100644
--- a/sd/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx
@@ -12,6 +12,7 @@
 #include <test/xmltesttools.hxx>
 #include <boost/property_tree/json_parser.hpp>
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
+#include <sfx2/lokhelper.hxx>
 #include <com/sun/star/frame/Desktop.hpp>
 #include <comphelper/dispatchcommand.hxx>
 #include <comphelper/processfactory.hxx>
@@ -62,6 +63,7 @@ public:
     void testPartHash();
     void testResizeTable();
     void testResizeTableColumn();
+    void testViewCursors();
 
     CPPUNIT_TEST_SUITE(SdTiledRenderingTest);
     CPPUNIT_TEST(testRegisterCallback);
@@ -81,6 +83,7 @@ public:
     CPPUNIT_TEST(testPartHash);
     CPPUNIT_TEST(testResizeTable);
     CPPUNIT_TEST(testResizeTableColumn);
+    CPPUNIT_TEST(testViewCursors);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -806,6 +809,71 @@ void SdTiledRenderingTest::testResizeTableColumn()
     comphelper::LibreOfficeKit::setActive(false);
 }
 
+class ViewCallback
+{
+public:
+    bool m_bGraphicSelectionInvalidated;
+    bool m_bGraphicViewSelectionInvalidated;
+
+    ViewCallback()
+        : m_bGraphicSelectionInvalidated(false),
+          m_bGraphicViewSelectionInvalidated(false)
+    {
+    }
+
+    static void callback(int nType, const char* pPayload, void* pData)
+    {
+        static_cast<ViewCallback*>(pData)->callbackImpl(nType, pPayload);
+    }
+
+    void callbackImpl(int nType, const char* /*pPayload*/)
+    {
+        switch (nType)
+        {
+        case LOK_CALLBACK_GRAPHIC_SELECTION:
+        {
+            m_bGraphicSelectionInvalidated = true;
+        }
+        break;
+        case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION:
+        {
+            m_bGraphicViewSelectionInvalidated = true;
+        }
+        break;
+        }
+    }
+};
+
+void SdTiledRenderingTest::testViewCursors()
+{
+    comphelper::LibreOfficeKit::setActive();
+
+    // Create two views.
+    SdXImpressDocument* pXImpressDocument = createDoc("shape.odp");
+    ViewCallback aView1;
+    SfxViewShell::Current()->registerLibreOfficeKitViewCallback(&ViewCallback::callback, &aView1);
+    SfxLokHelper::createView();
+    ViewCallback aView2;
+    SfxViewShell::Current()->registerLibreOfficeKitViewCallback(&ViewCallback::callback, &aView2);
+
+    // Select the shape in the second view.
+    sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
+    SdPage* pActualPage = pViewShell->GetActualPage();
+    SdrObject* pObject = pActualPage->GetObj(0);
+    SdrView* pView = pViewShell->GetView();
+    pView->MarkObj(pObject, pView->GetSdrPageView());
+    Scheduler::ProcessEventsToIdle();
+
+    // First view notices that there was a selection change in the other view.
+    CPPUNIT_ASSERT(aView1.m_bGraphicViewSelectionInvalidated);
+    // Second view notices that there was a selection change in its own view.
+    CPPUNIT_ASSERT(aView2.m_bGraphicSelectionInvalidated);
+    mxComponent->dispose();
+    mxComponent.clear();
+
+    comphelper::LibreOfficeKit::setActive(false);
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SdTiledRenderingTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sfx2/source/view/viewsh.cxx b/sfx2/source/view/viewsh.cxx
index b4b8ad1..6ee1942 100644
--- a/sfx2/source/view/viewsh.cxx
+++ b/sfx2/source/view/viewsh.cxx
@@ -1473,9 +1473,11 @@ void SfxViewShell::libreOfficeKitViewCallback(int nType, const char* pPayload) c
         switch (nType)
         {
         case LOK_CALLBACK_TEXT_SELECTION:
+        case LOK_CALLBACK_TEXT_VIEW_SELECTION:
         case LOK_CALLBACK_TEXT_SELECTION_START:
         case LOK_CALLBACK_TEXT_SELECTION_END:
         case LOK_CALLBACK_GRAPHIC_SELECTION:
+        case LOK_CALLBACK_GRAPHIC_VIEW_SELECTION:
             return;
         }
     }
diff --git a/svx/source/svdraw/svdmrkv.cxx b/svx/source/svdraw/svdmrkv.cxx
index 2c5535e..2e495ff 100644
--- a/svx/source/svdraw/svdmrkv.cxx
+++ b/svx/source/svdraw/svdmrkv.cxx
@@ -53,6 +53,7 @@
 #include <editeng/editdata.hxx>
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
 #include <comphelper/lok.hxx>
+#include <sfx2/lokhelper.hxx>
 #include <sfx2/viewsh.hxx>
 
 using namespace com::sun::star;
@@ -705,7 +706,10 @@ void SdrMarkView::SetMarkHandles()
                     {
                         // Suppress handles -> empty graphic selection.
                         if(SfxViewShell* pViewShell = SfxViewShell::Current())
+                        {
                             pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_GRAPHIC_SELECTION, "EMPTY");
+                            SfxLokHelper::notifyOtherViews(pViewShell, LOK_CALLBACK_GRAPHIC_VIEW_SELECTION, "selection", "EMPTY");
+                        }
                     }
                     return;
                 }
@@ -726,7 +730,10 @@ void SdrMarkView::SetMarkHandles()
                 {
                     // The table shape has selected cells, which provide text selection already -> no graphic selection.
                     if(SfxViewShell* pViewShell = SfxViewShell::Current())
+                    {
                         pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_GRAPHIC_SELECTION, "EMPTY");
+                        SfxLokHelper::notifyOtherViews(pViewShell, LOK_CALLBACK_GRAPHIC_VIEW_SELECTION, "selection", "EMPTY");
+                    }
                     return;
                 }
             }
@@ -759,7 +766,10 @@ void SdrMarkView::SetMarkHandles()
                     pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_TEXT_SELECTION, "");
             }
             if(SfxViewShell* pViewShell = SfxViewShell::Current())
+            {
                 pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_GRAPHIC_SELECTION, sSelection.getStr());
+                SfxLokHelper::notifyOtherViews(pViewShell, LOK_CALLBACK_GRAPHIC_VIEW_SELECTION, "selection", sSelection);
+            }
         }
 
         if (bFrmHdl)


More information about the Libreoffice-commits mailing list