summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPranav Kant <pranavk@collabora.co.uk>2017-11-05 14:01:42 +0530
committerJan Holesovsky <kendy@collabora.com>2017-11-15 17:07:17 +0100
commitf13dfb4c018080e94d8ed247984bf2f37e0653b8 (patch)
tree0307994500d53238cfd8a97954f1153dfd034b91
parentdd2c566b29b74d025761df77f5744c5b21e97625 (diff)
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@libreoffice.org> Reviewed-by: pranavk <pranavk@collabora.co.uk>
-rw-r--r--desktop/source/lib/init.cxx13
-rw-r--r--include/LibreOfficeKit/LibreOfficeKit.h6
-rw-r--r--include/LibreOfficeKit/LibreOfficeKit.hxx14
-rw-r--r--include/sfx2/lokhelper.hxx2
-rw-r--r--include/vcl/IDialogRenderable.hxx2
-rw-r--r--libreofficekit/qa/gtktiledviewer/gtv-helpers.cxx19
-rw-r--r--libreofficekit/qa/gtktiledviewer/gtv-helpers.hxx2
-rw-r--r--libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx22
-rw-r--r--libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.hxx2
-rw-r--r--libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx21
-rw-r--r--sfx2/source/view/lokhelper.cxx11
-rw-r--r--sw/inc/unotxdoc.hxx2
-rw-r--r--sw/source/uibase/uno/unotxdoc.cxx4
-rw-r--r--vcl/source/control/ctrl.cxx4
-rw-r--r--vcl/source/window/dialog.cxx6
15 files changed, 100 insertions, 30 deletions
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 6da4125ddf1d..55a9e18b27fa 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -631,7 +631,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);
@@ -3112,7 +3112,11 @@ unsigned char* doc_renderFont(LibreOfficeKitDocument* /*pThis*/,
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;
@@ -3125,8 +3129,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 de425f4f965e..3941b329a97d 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/include/LibreOfficeKit/LibreOfficeKit.h
@@ -254,7 +254,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 4c682cf6635a..b029aa001ad1 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.hxx
+++ b/include/LibreOfficeKit/LibreOfficeKit.hxx
@@ -160,19 +160,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 4738b3e65020..01d519173c2a 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* 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 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 539d2117f201..94d8a1f4e9e7 100644
--- a/include/vcl/IDialogRenderable.hxx
+++ b/include/vcl/IDialogRenderable.hxx
@@ -46,7 +46,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 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 eb3aebf97675..5122ad2c2c02 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 033b974f0fbd..a9c94d09a083 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 677245512821..2c9ae8b71003 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("panting 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 c177e6bf5e41..1ce1d3afbcb3 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 8128f88fef10..7e43b7ff0ce6 100644
--- a/sfx2/source/view/lokhelper.cxx
+++ b/sfx2/source/view/lokhelper.cxx
@@ -132,15 +132,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 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 7719f608a287..bb6dc4d6dbc5 100644
--- a/sw/inc/unotxdoc.hxx
+++ b/sw/inc/unotxdoc.hxx
@@ -463,7 +463,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 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 6510af9d016e..ee9413b1231c 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -3858,9 +3858,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 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 909cf170651a..b3d67d438961 100644
--- a/vcl/source/control/ctrl.cxx
+++ b/vcl/source/control/ctrl.cxx
@@ -440,8 +440,10 @@ void Control::LogicInvalidate(const Rectangle* /*pRectangle*/)
// otherwise, for now, just invalidate the whole dialog
Dialog* pParentDlg = GetParentDialog();
+
+ const 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 4ff9d42896a1..f08a22d188f9 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();
@@ -970,11 +970,11 @@ void Dialog::CloseFloatingWindow()
}
}
-void Dialog::LogicInvalidate(const Rectangle* /*pRectangle*/)
+void Dialog::LogicInvalidate(const Rectangle* pRectangle)
{
if (!comphelper::LibreOfficeKit::isDialogPainting() && mpDialogRenderable && !maID.isEmpty())
{
- mpDialogRenderable->notifyDialog(maID, "invalidate");
+ mpDialogRenderable->notifyDialog(maID, "invalidate", pRectangle);
}
}