[Libreoffice-commits] core.git: desktop/source include/LibreOfficeKit include/sfx2 include/vcl libreofficekit/qa sfx2/source sw/inc sw/source vcl/source

Pranav Kant pranavk at collabora.co.uk
Thu Nov 9 03:14:04 UTC 2017


 desktop/source/lib/init.cxx                                         |   13 ++++-
 include/LibreOfficeKit/LibreOfficeKit.h                             |    6 ++
 include/LibreOfficeKit/LibreOfficeKit.hxx                           |   14 +++++-
 include/sfx2/lokhelper.hxx                                          |    2 
 include/vcl/IDialogRenderable.hxx                                   |    2 
 libreofficekit/qa/gtktiledviewer/gtv-helpers.cxx                    |   19 ++++++++
 libreofficekit/qa/gtktiledviewer/gtv-helpers.hxx                    |    2 
 libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx                 |   22 +++++++---
 libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.hxx                 |    2 
 libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx |   21 ++++++++-
 sfx2/source/view/lokhelper.cxx                                      |   11 +++--
 sw/inc/unotxdoc.hxx                                                 |    2 
 sw/source/uibase/uno/unotxdoc.cxx                                   |    4 -
 vcl/source/control/ctrl.cxx                                         |    4 +
 vcl/source/window/dialog.cxx                                        |    6 +-
 15 files changed, 100 insertions(+), 30 deletions(-)

New commits:
commit 446a37ece35dbe4c442f0679dd1cb4df79ed87a7
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Sun Nov 5 14:01:42 2017 +0530

    lokdialog: Support painting parts of the dialog
    
    Pass the dimensions of the region to the paintDialog call to paint only
    that much of the region in the dialog.
    
    The DIALOG_INVALIDATE callback also returns a 'rectangle' field now in
    the payload that tells the region of the dialog invalidated. It can be
    used in combination with the new paintDialog call then to paint only the
    invalidated region in the dialog.
    
    Change-Id: Iebb228865c71684e0f75dd01271b71ae41a0f906
    Reviewed-on: https://gerrit.libreoffice.org/44472
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: pranavk <pranavk at collabora.co.uk>

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 891911429438..d126da925b2b 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -610,7 +610,7 @@ static unsigned char* doc_renderFont(LibreOfficeKitDocument* pThis,
                           int* pFontHeight);
 static char* doc_getPartHash(LibreOfficeKitDocument* pThis, int nPart);
 
-static void doc_paintDialog(LibreOfficeKitDocument* pThis, const char* pDialogId, unsigned char* pBuffer, char** pDialogTitle, int* nWidth, int* nHeight);
+static void doc_paintDialog(LibreOfficeKitDocument* pThis, const char* pDialogId, const int x, const int y, unsigned char* pBuffer, char** pDialogTitle, int* nWidth, int* nHeight);
 
 static void doc_paintActiveFloatingWindow(LibreOfficeKitDocument* pThis, const char* pDialogId, unsigned char* pBuffer, int* nWidth, int* nHeight);
 
@@ -3091,7 +3091,11 @@ unsigned char* doc_renderFont(SAL_UNUSED_PARAMETER LibreOfficeKitDocument* /*pTh
     return nullptr;
 }
 
-static void doc_paintDialog(LibreOfficeKitDocument* pThis, const char* pDialogId, unsigned char* pBuffer, char** pDialogTitle, int* nWidth, int* nHeight)
+static void doc_paintDialog(LibreOfficeKitDocument* pThis, const char* pDialogId,
+                            const int x, const int y,
+                            unsigned char* pBuffer,
+                            char** pDialogTitle,
+                            int* nWidth, int* nHeight)
 {
     SolarMutexGuard aGuard;
 
@@ -3104,8 +3108,11 @@ static void doc_paintDialog(LibreOfficeKitDocument* pThis, const char* pDialogId
 
     vcl::DialogID aDialogID = OUString::createFromAscii(pDialogId);
 
-    comphelper::LibreOfficeKit::setDialogPainting(true);
+    MapMode aMapMode(pDevice->GetMapMode());
+    aMapMode.SetOrigin(Point(-x, -y));
+    pDevice->SetMapMode(aMapMode);
 
+    comphelper::LibreOfficeKit::setDialogPainting(true);
     // copy the title of the dialog to outparam
     OUString aDialogTitle;
     pDialogRenderable->paintDialog(aDialogID, *pDevice.get(), aDialogTitle, *nWidth, *nHeight);
diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h
index cc4752e04ab2..cb0f17a41655 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/include/LibreOfficeKit/LibreOfficeKit.h
@@ -268,7 +268,11 @@ struct _LibreOfficeKitDocumentClass
 
     /// Paints dialog with given dialog id to the buffer
     /// @see lok::Document::paintDialog().
-    void (*paintDialog) (LibreOfficeKitDocument* pThis, const char* pDialogId, unsigned char* pBuffer, char** pDialogTitle, int* nWidth, int* nHeight);
+    void (*paintDialog) (LibreOfficeKitDocument* pThis, const char* pDialogId,
+                         const int x, const int y,
+                         unsigned char* pBuffer,
+                         char** pDialogTitle,
+                         int* nWidth, int* nHeight);
 
     /// @see lok::Document::paintActiveFloatingWindow().
     void (*paintActiveFloatingWindow) (LibreOfficeKitDocument* pThis, const char* pDialogId, unsigned char* pBuffer, int* nWidth, int* nHeight);
diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx
index ad5e6d74e878..586637f6606e 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.hxx
+++ b/include/LibreOfficeKit/LibreOfficeKit.hxx
@@ -161,19 +161,27 @@ public:
      * Client must truncate pBuffer according to the nWidth and nHeight returned after the call.
      *
      * @param pDialogId Unique dialog id to be painted
+     * @param x x-coordinate from where the dialog should start painting
+     * @param y y-coordinate from where the dialog should start painting
      * @param pBuffer Buffer with enough memory allocated to render any dialog
      * @param pDialogTitle output parameter pointing to a dialog title
      * string. Should be freed by the caller.
-     * @param nWidth output parameter returning the width of the rendered dialog.
-     * @param nHeight output parameter returning the height of the rendered dialog
+     * @param nWidth in/out parameter returning the width of the rendered
+     * dialog. The input width value is used to determined the size of the
+     * image to be painted.
+     * @param nHeight in/out parameter returning the height of the rendered
+     * dialog. The input height value is used to determine the size of the
+     * image to be painted.
      */
     void paintDialog(const char* pDialogId,
+                     const int x,
+                     const int y,
                      unsigned char* pBuffer,
                      char** pDialogTitle,
                      int& nWidth,
                      int& nHeight)
     {
-        return mpDoc->pClass->paintDialog(mpDoc, pDialogId, pBuffer,
+        return mpDoc->pClass->paintDialog(mpDoc, pDialogId, x, y, pBuffer,
                                           pDialogTitle, &nWidth, &nHeight);
     }
 
diff --git a/include/sfx2/lokhelper.hxx b/include/sfx2/lokhelper.hxx
index a4733c2d2854..b14c35fa3956 100644
--- a/include/sfx2/lokhelper.hxx
+++ b/include/sfx2/lokhelper.hxx
@@ -41,7 +41,7 @@ public:
     /// Same as notifyOtherViews(), but works on a selected "other" view, not on all of them.
     static void notifyOtherView(SfxViewShell* pThisView, SfxViewShell const* pOtherView, int nType, const OString& rKey, const OString& rPayload);
     /// Emits a LOK_CALLBACK_DIALOG
-    static void notifyDialog(const OUString& rPayload, const OUString& rAction);
+    static void notifyDialog(const OUString& rPayload, const OUString& rAction, const tools::Rectangle* rRect);
     /// Emits a LOK_CALLBACK_DIALOG_CHILD
     static void notifyDialogChild(const OUString& rDialogID, const OUString& rAction, const Point& rPos);
     /// Emits a LOK_CALLBACK_INVALIDATE_TILES, but tweaks it according to setOptionalFeatures() if needed.
diff --git a/include/vcl/IDialogRenderable.hxx b/include/vcl/IDialogRenderable.hxx
index 645ceef643b5..2574cf5430db 100644
--- a/include/vcl/IDialogRenderable.hxx
+++ b/include/vcl/IDialogRenderable.hxx
@@ -44,7 +44,7 @@ public:
                                            int nCount, int nButtons, int nModifier) = 0;
 
     // Callbacks
-    virtual void notifyDialog(const DialogID& rDialogID, const OUString& rAction) = 0;
+    virtual void notifyDialog(const DialogID& rDialogID, const OUString& rAction, const tools::Rectangle* rRect) = 0;
 
     virtual void notifyDialogChild(const DialogID& rDialogID, const OUString& rAction, const Point& rPos) = 0;
 };
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-helpers.cxx b/libreofficekit/qa/gtktiledviewer/gtv-helpers.cxx
index 5dca746d5f25..9dee02a0ac45 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-helpers.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-helpers.cxx
@@ -148,4 +148,23 @@ const std::string GtvHelpers::getDirPath(const std::string& filePath)
     return dirPath;
 }
 
+const std::vector<int> GtvHelpers::splitIntoIntegers(const std::string& aPayload, const std::string& aDelim, const int nItems)
+{
+    std::vector<int> aRet;
+
+    if (!aPayload.empty())
+    {
+        gchar** ppCoordinates = g_strsplit(aPayload.c_str(), aDelim.c_str(), nItems);
+        gchar** ppCoordinate  = ppCoordinates;
+        while (*ppCoordinate)
+        {
+            aRet.push_back(atoi(*ppCoordinate));
+            ++ppCoordinate;
+        }
+        g_strfreev(ppCoordinates);
+    }
+
+    return aRet;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-helpers.hxx b/libreofficekit/qa/gtktiledviewer/gtv-helpers.hxx
index e0a2defa72d9..9e984846f0ab 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-helpers.hxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-helpers.hxx
@@ -38,6 +38,8 @@ namespace GtvHelpers
     GtkWidget* createCommentBox(const boost::property_tree::ptree& aComment);
 
     const std::string getDirPath(const std::string& filePath);
+
+    const std::vector<int> splitIntoIntegers(const std::string& aPayload, const std::string& aDelim, const int nItems);
 }
 
 #endif
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
index 2a3d1a9d9cd9..1614c157ae7c 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
@@ -87,14 +87,22 @@ gtv_lok_dialog_draw(GtkWidget* pDialogDrawingArea, cairo_t* pCairo, gpointer)
     GtvLokDialog* pDialog = GTV_LOK_DIALOG(gtk_widget_get_toplevel(pDialogDrawingArea));
     GtvLokDialogPrivate* priv = getPrivate(pDialog);
 
-    g_info("painting dialog");
+    GdkRectangle aRect;
+    gdk_cairo_get_clip_rectangle(pCairo, &aRect);
+    g_info("Painting dialog region: %d, %d, %d, %d", aRect.x, aRect.y, aRect.width, aRect.height);
     int nWidth = 1024;
     int nHeight = 768;
+    if (aRect.width != 0 && aRect.height != 0)
+    {
+        nWidth = aRect.width;
+        nHeight = aRect.height;
+    }
+
     cairo_surface_t* pSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, nWidth, nHeight);
     unsigned char* pBuffer = cairo_image_surface_get_data(pSurface);
     LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(LOK_DOC_VIEW(priv->lokdocview));
     char* pDialogTitle = nullptr;
-    pDocument->pClass->paintDialog(pDocument, priv->dialogid, pBuffer, &pDialogTitle, &nWidth, &nHeight);
+    pDocument->pClass->paintDialog(pDocument, priv->dialogid, aRect.x, aRect.y, pBuffer, &pDialogTitle, &nWidth, &nHeight);
     if (pDialogTitle)
     {
         gtk_window_set_title(GTK_WINDOW(pDialog), pDialogTitle);
@@ -106,7 +114,7 @@ gtv_lok_dialog_draw(GtkWidget* pDialogDrawingArea, cairo_t* pCairo, gpointer)
     cairo_surface_flush(pSurface);
     cairo_surface_mark_dirty(pSurface);
 
-    cairo_set_source_surface(pCairo, pSurface, 0, 0);
+    cairo_set_source_surface(pCairo, pSurface, aRect.x, aRect.y);
     cairo_paint(pCairo);
 }
 
@@ -474,11 +482,13 @@ gtv_lok_dialog_floating_win_draw(GtkWidget* pDrawingArea, cairo_t* pCairo, gpoin
 }
 
 void
-gtv_lok_dialog_invalidate(GtvLokDialog* dialog)
+gtv_lok_dialog_invalidate(GtvLokDialog* dialog, const GdkRectangle& aRectangle)
 {
     GtvLokDialogPrivate* priv = getPrivate(dialog);
-
-    gtk_widget_queue_draw(priv->pDialogDrawingArea);
+    if (aRectangle.width != 0 && aRectangle.height != 0)
+        gtk_widget_queue_draw_area(priv->pDialogDrawingArea, aRectangle.x, aRectangle.y, aRectangle.width, aRectangle.height);
+    else
+        gtk_widget_queue_draw(priv->pDialogDrawingArea);
 }
 
 static gboolean
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.hxx b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.hxx
index ba565b4cebb0..619005635b60 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.hxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.hxx
@@ -37,7 +37,7 @@ GType gtv_lok_dialog_get_type               (void) G_GNUC_CONST;
 
 GtkWidget* gtv_lok_dialog_new(LOKDocView* pDocView, const gchar* dialogId);
 
-void gtv_lok_dialog_invalidate(GtvLokDialog* dialog);
+void gtv_lok_dialog_invalidate(GtvLokDialog* dialog, const GdkRectangle& aRectangle);
 
 void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog, int nX, int nY);
 
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
index 415c3d6526c4..dfdbc3bc6ca6 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
@@ -20,6 +20,8 @@
 #include <boost/property_tree/json_parser.hpp>
 #include <boost/optional.hpp>
 
+#include <iostream>
+
 void LOKDocViewSigHandlers::editChanged(LOKDocView* pDocView, gboolean bWasEdit, gpointer)
 {
     GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(pDocView)));
@@ -288,8 +290,8 @@ void LOKDocViewSigHandlers::dialog(LOKDocView* pDocView, gchar* pPayload, gpoint
     std::stringstream aStream(pPayload);
     boost::property_tree::ptree aRoot;
     boost::property_tree::read_json(aStream, aRoot);
-    std::string aDialogId = aRoot.get<std::string>("dialogId");
-    std::string aAction = aRoot.get<std::string>("action");
+    const std::string aDialogId = aRoot.get<std::string>("dialogId");
+    const std::string aAction = aRoot.get<std::string>("action");
 
     // we only understand 'invalidate' and 'close' as of now
     if (aAction != "invalidate" && aAction != "close")
@@ -306,7 +308,20 @@ void LOKDocViewSigHandlers::dialog(LOKDocView* pDocView, gchar* pPayload, gpoint
             if (aAction == "close")
                 gtk_widget_destroy(GTK_WIDGET(pIt->data));
             else if (aAction == "invalidate")
-                gtv_lok_dialog_invalidate(GTV_LOK_DIALOG(pIt->data));
+            {
+                GdkRectangle aGdkRectangle = {0, 0, 0, 0};
+                try
+                {
+                    const std::string aRectangle = aRoot.get<std::string>("rectangle");
+                    std::vector<int> aRectPoints = GtvHelpers::splitIntoIntegers(aRectangle, ", ", 4);
+                    if (aRectPoints.size() == 4)
+                        aGdkRectangle = {aRectPoints[0], aRectPoints[1], aRectPoints[2], aRectPoints[3]};
+                }
+                catch(const std::exception& e)
+                {}
+
+                gtv_lok_dialog_invalidate(GTV_LOK_DIALOG(pIt->data), aGdkRectangle);
+            }
         }
         g_free(pChildDialogId);
     }
diff --git a/sfx2/source/view/lokhelper.cxx b/sfx2/source/view/lokhelper.cxx
index eccb3b1bf1f0..633e221e4f86 100644
--- a/sfx2/source/view/lokhelper.cxx
+++ b/sfx2/source/view/lokhelper.cxx
@@ -144,15 +144,18 @@ void SfxLokHelper::notifyOtherViews(SfxViewShell* pThisView, int nType, const OS
     }
 }
 
-void SfxLokHelper::notifyDialog(const OUString& rDialogID, const OUString& rAction)
+void SfxLokHelper::notifyDialog(const OUString& rDialogID, const OUString& rAction, const tools::Rectangle* rRect)
 {
     if (SfxLokHelper::getViewsCount() <= 0 || rDialogID.isEmpty())
         return;
 
     SfxViewShell* pViewShell = SfxViewShell::GetFirst();
-    const OString aPayload = OString("{ \"dialogId\": \"") + OUStringToOString(rDialogID, RTL_TEXTENCODING_UTF8).getStr() +
-        OString("\", \"action\": \"") + OUStringToOString(rAction, RTL_TEXTENCODING_UTF8).getStr() +
-        + "\" }";
+    OString aPayload = OString("{ \"dialogId\": \"") + OUStringToOString(rDialogID, RTL_TEXTENCODING_UTF8).getStr() + OString("\"");
+    aPayload += OString(", \"action\": \"") + OUStringToOString(rAction, RTL_TEXTENCODING_UTF8).getStr() + OString("\"");
+    if (!rAction.isEmpty() && rRect && !rRect->IsEmpty())
+        aPayload += OString(", \"rectangle\": \"") + rRect->toString() + OString("\"");
+
+    aPayload += "}";
 
     while (pViewShell)
     {
diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx
index a35610e71e12..3d886beda8e3 100644
--- a/sw/inc/unotxdoc.hxx
+++ b/sw/inc/unotxdoc.hxx
@@ -442,7 +442,7 @@ public:
     void postDialogChildMouseEvent(const vcl::DialogID& rDialogID, int nType, int nX, int nY,
                                    int nCount, int nButtons, int nModifier) override;
 
-    void notifyDialog(const vcl::DialogID& rDialogID, const OUString& rAction) override;
+    void notifyDialog(const vcl::DialogID& rDialogID, const OUString& rAction, const tools::Rectangle* rRect) override;
 
     void notifyDialogChild(const vcl::DialogID& rDialogID, const OUString& rAction, const Point& rPos) override;
 
diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx
index a587975c694c..63a7e609766f 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -3786,9 +3786,9 @@ void SwXTextDocument::postDialogChildMouseEvent(const vcl::DialogID& rDialogID,
     }
 }
 
-void SwXTextDocument::notifyDialog(const vcl::DialogID& rDialogID, const OUString& rAction)
+void SwXTextDocument::notifyDialog(const vcl::DialogID& rDialogID, const OUString& rAction, const tools::Rectangle* rRect)
 {
-    SfxLokHelper::notifyDialog(rDialogID, rAction);
+    SfxLokHelper::notifyDialog(rDialogID, rAction, rRect);
 }
 
 void SwXTextDocument::notifyDialogChild(const vcl::DialogID& rDialogID, const OUString& rAction, const Point& rPos)
diff --git a/vcl/source/control/ctrl.cxx b/vcl/source/control/ctrl.cxx
index 736722387122..b62c90563d46 100644
--- a/vcl/source/control/ctrl.cxx
+++ b/vcl/source/control/ctrl.cxx
@@ -436,8 +436,10 @@ void Control::LogicInvalidate(const tools::Rectangle* /*pRectangle*/)
 
         // otherwise, for now, just invalidate the whole dialog
         Dialog* pParentDlg = GetParentDialog();
+
+        const tools::Rectangle aRect(Point(GetOutOffXPixel(), GetOutOffYPixel()), Size(GetOutputWidthPixel(), GetOutputHeightPixel()));
         if (pParentDlg)
-            pParentDlg->LogicInvalidate(nullptr);
+            pParentDlg->LogicInvalidate(&aRect);
     }
 }
 
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index 9be733fbb4d0..0adb46c59d07 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -596,7 +596,7 @@ void Dialog::dispose()
 
     if (comphelper::LibreOfficeKit::isActive() && mpDialogRenderable)
     {
-        mpDialogRenderable->notifyDialog(maID, "close");
+        mpDialogRenderable->notifyDialog(maID, "close", nullptr);
     }
 
     SystemWindow::dispose();
@@ -969,11 +969,11 @@ void Dialog::CloseFloatingWindow()
     }
 }
 
-void Dialog::LogicInvalidate(const tools::Rectangle* /*pRectangle*/)
+void Dialog::LogicInvalidate(const tools::Rectangle* pRectangle)
 {
     if (!comphelper::LibreOfficeKit::isDialogPainting() && mpDialogRenderable && !maID.isEmpty())
     {
-        mpDialogRenderable->notifyDialog(maID, "invalidate");
+        mpDialogRenderable->notifyDialog(maID, "invalidate", pRectangle);
     }
 }
 


More information about the Libreoffice-commits mailing list