[Libreoffice-commits] core.git: 23 commits - comphelper/source desktop/source include/comphelper include/LibreOfficeKit include/sfx2 include/vcl libreofficekit/Executable_gtktiledviewer.mk libreofficekit/qa libreofficekit/source sfx2/source sw/inc sw/source vcl/source
Pranav Kant
pranavk at collabora.co.uk
Mon Oct 2 05:37:20 UTC 2017
comphelper/source/misc/lok.cxx | 12
desktop/source/lib/init.cxx | 94 +
include/LibreOfficeKit/LibreOfficeKit.h | 33
include/LibreOfficeKit/LibreOfficeKit.hxx | 35
include/LibreOfficeKit/LibreOfficeKitEnums.h | 24
include/comphelper/lok.hxx | 4
include/sfx2/lokhelper.hxx | 4
include/vcl/IDialogRenderable.hxx | 19
include/vcl/ctrl.hxx | 2
include/vcl/dialog.hxx | 26
include/vcl/floatwin.hxx | 1
libreofficekit/Executable_gtktiledviewer.mk | 5
libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx | 60
libreofficekit/qa/gtktiledviewer/gtv-application-window.hxx | 8
libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx | 663 ++++++++++
libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.hxx | 50
libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx | 64
libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx | 2
libreofficekit/qa/gtktiledviewer/gtv-main-toolbar.cxx | 26
libreofficekit/qa/gtktiledviewer/gtv-signal-handlers.cxx | 35
libreofficekit/qa/gtktiledviewer/gtv-signal-handlers.hxx | 2
libreofficekit/qa/gtktiledviewer/gtv.ui | 17
libreofficekit/source/gtk/lokdocview.cxx | 99 +
sfx2/source/dialog/basedlgs.cxx | 5
sfx2/source/view/lokhelper.cxx | 35
sw/inc/unotxdoc.hxx | 16
sw/source/uibase/uno/unotxdoc.cxx | 149 ++
vcl/source/control/ctrl.cxx | 29
vcl/source/window/dialog.cxx | 140 ++
vcl/source/window/floatwin.cxx | 29
30 files changed, 1633 insertions(+), 55 deletions(-)
New commits:
commit 3d81ec3365cb327c73696892c8edd6eea9d52220
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Fri Aug 18 15:26:26 2017 +0530
lokdialog: Add dialog APIs to lok::Document class
Change-Id: I1947dc84c91e2e01072fbff3e97aa94d514ecb5a
diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h
index 05c8eff15316..cf030a7f69e8 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/include/LibreOfficeKit/LibreOfficeKit.h
@@ -266,19 +266,21 @@ struct _LibreOfficeKitDocumentClass
int* pArray,
size_t nSize);
- /// WIP
+ /// Paints dialog with given dialog id to the buffer
+ /// @see lok::Document::paintDialog().
void (*paintDialog) (LibreOfficeKitDocument* pThis, const char* pDialogId, unsigned char* pBuffer, int* nWidth, int* nHeight);
+ /// @see lok::Document::paintActiveFloatingWindow().
void (*paintActiveFloatingWindow) (LibreOfficeKitDocument* pThis, const char* pDialogId, unsigned char* pBuffer, int* nWidth, int* nHeight);
- /// WIP
+ /// @see lok::Document::postDialogKeyEvent().
void (*postDialogKeyEvent) (LibreOfficeKitDocument* pThis,
const char* pDialogId,
int nType,
int nCharCode,
int nKeyCode);
- /// WIP
+ /// @see lok::Document::postDialogMouseEvent().
void (*postDialogMouseEvent) (LibreOfficeKitDocument* pThis,
const char* pDialogId,
int nType,
@@ -288,7 +290,7 @@ struct _LibreOfficeKitDocumentClass
int nButtons,
int nModifier);
- /// WIP
+ /// @see lok::Document::postDialogChildMouseEvent().
void (*postDialogChildMouseEvent) (LibreOfficeKitDocument* pThis,
const char* pDialogId,
int nType,
diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx
index 10e0f0f199d0..d4e891af218a 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.hxx
+++ b/include/LibreOfficeKit/LibreOfficeKit.hxx
@@ -156,6 +156,25 @@ public:
}
/**
+ * Renders a dialog with give dialog id and writes the width and height of the rendered dialog
+ *
+ * Client must truncate pBuffer according to the nWidth and nHeight returned after the call.
+ *
+ * @param pDialogId Unique dialog id to be painted
+ * @param pBuffer Buffer with enough memory allocated to render any dialog
+ * @param nWidth output parameter returning the width of the rendered dialog.
+ * @param nHeight output parameter returning the height of the rendered dialog
+ */
+ void paintDialog(const char* pDialogId,
+ unsigned char* pBuffer,
+ int& nWidth,
+ int& nHeight)
+ {
+ return mpDoc->pClass->paintDialog(mpDoc, pDialogId, pBuffer,
+ &nWidth, &nHeight);
+ }
+
+ /**
* Gets the tile mode: the pixel format used for the pBuffer of paintTile().
*
* @return an element of the LibreOfficeKitTileMode enum.
@@ -236,6 +255,22 @@ public:
}
/**
+ * Posts a mouse event to the dialog with given id.
+ *
+ * @param aDialogId Dialog id where mouse event is to be posted
+ * @param nType Event type, like down, move or up.
+ * @param nX horizontal position in document coordinates
+ * @param nY vertical position in document coordinates
+ * @param nCount number of clicks: 1 for single click, 2 for double click
+ * @param nButtons: which mouse buttons: 1 for left, 2 for middle, 4 right
+ * @param nModifier: which keyboard modifier: (see include/vcl/vclenum.hxx for possible values)
+ */
+ void postDialogMouseEvent(const char* pDialogId, int nType, int nX, int nY, int nCount, int nButtons, int nModifier)
+ {
+ mpDoc->pClass->postDialogMouseEvent(mpDoc, pDialogId, nType, nX, nY, nCount, nButtons, nModifier);
+ }
+
+ /**
* Posts an UNO command to the document.
*
* Example argument string:
commit fa02b6361f582d67efaaadc4e8664617b69340e0
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Tue Aug 15 18:54:02 2017 +0530
lokdialog: Smoother mouse move on floating windows
Do away with an early hack to create the floating window with every
invalidate.
This gets rid of persistent blinking when moving the mouse over a
listbox, for example.
Change-Id: Ida9367156605edc9835529f83529363ad97beaee
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
index b711c3bc034e..c7f5bfe39e10 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
@@ -598,34 +598,34 @@ void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog, int nX, int nY)
GtvLokDialogPrivate* priv = getPrivate(dialog);
// remove any existing floating windows, for now
- if (priv->pFloatingWin)
- gtk_widget_destroy(priv->pFloatingWin);
-
- priv->pFloatingWin = gtk_window_new(GTK_WINDOW_POPUP);
- GtkWidget* pDrawingArea = gtk_drawing_area_new();
- gtk_container_add(GTK_CONTAINER(priv->pFloatingWin), pDrawingArea);
-
- gtk_window_set_transient_for(GTK_WINDOW(priv->pFloatingWin), GTK_WINDOW(dialog));
- gtk_window_set_destroy_with_parent(GTK_WINDOW(priv->pFloatingWin), true);
-
- gtk_widget_add_events(pDrawingArea,
- GDK_BUTTON_PRESS_MASK
- |GDK_POINTER_MOTION_MASK
- |GDK_BUTTON_RELEASE_MASK
- |GDK_BUTTON_MOTION_MASK);
-
- g_signal_connect(G_OBJECT(pDrawingArea), "draw", G_CALLBACK(gtv_lok_dialog_floating_win_draw), dialog);
- g_signal_connect(G_OBJECT(pDrawingArea), "button-press-event", G_CALLBACK(gtv_lok_dialog_floating_win_signal_button), dialog);
- g_signal_connect(G_OBJECT(pDrawingArea), "button-release-event", G_CALLBACK(gtv_lok_dialog_floating_win_signal_button), dialog);
- g_signal_connect(G_OBJECT(pDrawingArea), "motion-notify-event", G_CALLBACK(gtv_lok_dialog_floating_win_signal_motion), dialog);
-
- gtk_widget_set_size_request(priv->pFloatingWin, 1, 1);
- gtk_window_set_type_hint(GTK_WINDOW(priv->pFloatingWin), GDK_WINDOW_TYPE_HINT_POPUP_MENU);
- gtk_window_set_screen(GTK_WINDOW(priv->pFloatingWin), gtk_window_get_screen(GTK_WINDOW(dialog)));
-
- gtk_widget_show_all(priv->pFloatingWin);
- gtk_window_present(GTK_WINDOW(priv->pFloatingWin));
- gtk_widget_grab_focus(pDrawingArea);
+ if (!priv->pFloatingWin)
+ {
+ priv->pFloatingWin = gtk_window_new(GTK_WINDOW_POPUP);
+ GtkWidget* pDrawingArea = gtk_drawing_area_new();
+ gtk_container_add(GTK_CONTAINER(priv->pFloatingWin), pDrawingArea);
+
+ gtk_window_set_transient_for(GTK_WINDOW(priv->pFloatingWin), GTK_WINDOW(dialog));
+ gtk_window_set_destroy_with_parent(GTK_WINDOW(priv->pFloatingWin), true);
+
+ gtk_widget_add_events(pDrawingArea,
+ GDK_BUTTON_PRESS_MASK
+ |GDK_POINTER_MOTION_MASK
+ |GDK_BUTTON_RELEASE_MASK
+ |GDK_BUTTON_MOTION_MASK);
+
+ g_signal_connect(G_OBJECT(pDrawingArea), "draw", G_CALLBACK(gtv_lok_dialog_floating_win_draw), dialog);
+ g_signal_connect(G_OBJECT(pDrawingArea), "button-press-event", G_CALLBACK(gtv_lok_dialog_floating_win_signal_button), dialog);
+ g_signal_connect(G_OBJECT(pDrawingArea), "button-release-event", G_CALLBACK(gtv_lok_dialog_floating_win_signal_button), dialog);
+ g_signal_connect(G_OBJECT(pDrawingArea), "motion-notify-event", G_CALLBACK(gtv_lok_dialog_floating_win_signal_motion), dialog);
+
+ gtk_widget_set_size_request(priv->pFloatingWin, 1, 1);
+ gtk_window_set_type_hint(GTK_WINDOW(priv->pFloatingWin), GDK_WINDOW_TYPE_HINT_POPUP_MENU);
+ gtk_window_set_screen(GTK_WINDOW(priv->pFloatingWin), gtk_window_get_screen(GTK_WINDOW(dialog)));
+
+ gtk_widget_show_all(priv->pFloatingWin);
+ gtk_window_present(GTK_WINDOW(priv->pFloatingWin));
+ gtk_widget_grab_focus(pDrawingArea);
+ }
// Get the root coords of our new floating window
GdkWindow* pGdkWin = gtk_widget_get_window(GTK_WIDGET(dialog));
@@ -633,6 +633,8 @@ void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog, int nX, int nY)
int nrY = 0;
gdk_window_get_root_coords(pGdkWin, nX, nY, &nrX, &nrY);
gtk_window_move(GTK_WINDOW(priv->pFloatingWin), nrX, nrY);
+
+ gtk_widget_queue_draw(priv->pFloatingWin);
}
void gtv_lok_dialog_child_close(GtvLokDialog* dialog)
commit 81c00c9b47fd5a8ca03829386ee97342fb6aa847
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Tue Aug 15 14:23:26 2017 +0530
lokdialog: button press type debug info
Change-Id: I193e0ab82e998905b670f7de73daae784de3ef00
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
index 1149f50230b6..b711c3bc034e 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
@@ -113,7 +113,14 @@ gtv_lok_dialog_signal_button(GtkWidget* pDialogDrawingArea, GdkEventButton* pEve
GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(pDialog)));
LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(LOK_DOC_VIEW(window->lokdocview));
- g_info("lok_dialog_signal_button: %d, %d (in twips: %d, %d)",
+ std::string aEventType = "unknown";
+ if (pEvent->type == GDK_BUTTON_PRESS)
+ aEventType = "BUTTON_PRESS";
+ else if (pEvent->type == GDK_BUTTON_RELEASE)
+ aEventType = "BUTTON_RELEASE";
+
+ g_info("lok_dialog_signal_button (type: %s): %d, %d (in twips: %d, %d)",
+ aEventType.c_str(),
(int)pEvent->x, (int)pEvent->y,
(int)pixelToTwip(pEvent->x),
(int)pixelToTwip(pEvent->y));
@@ -197,7 +204,7 @@ gtv_lok_dialog_signal_motion(GtkWidget* pDialogDrawingArea, GdkEventButton* pEve
GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(pDialog)));
LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(LOK_DOC_VIEW(window->lokdocview));
- g_info("lok_dialog_signal_button: %d, %d (in twips: %d, %d)",
+ g_info("lok_dialog_signal_motion: %d, %d (in twips: %d, %d)",
(int)pEvent->x, (int)pEvent->y,
(int)pixelToTwip(pEvent->x),
(int)pixelToTwip(pEvent->y));
@@ -478,7 +485,14 @@ gtv_lok_dialog_floating_win_signal_button(GtkWidget* /*pDialogChildDrawingArea*/
GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(pDialog)));
LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(LOK_DOC_VIEW(window->lokdocview));
- g_info("lok_dialog_floating_win_signal_button: %d, %d (in twips: %d, %d)",
+ std::string aEventType = "unknown";
+ if (pEvent->type == GDK_BUTTON_PRESS)
+ aEventType = "BUTTON_PRESS";
+ else if (pEvent->type == GDK_BUTTON_RELEASE)
+ aEventType = "BUTTON_RELEASE";
+
+ g_info("lok_dialog_floating_win_signal_button (type: %s): %d, %d (in twips: %d, %d)",
+ aEventType.c_str(),
(int)pEvent->x, (int)pEvent->y,
(int)pixelToTwip(pEvent->x),
(int)pixelToTwip(pEvent->y));
commit a0f36b458c00f2e6fc79b8c4a71e8b0b7cc6b6e0
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Thu Aug 10 17:24:40 2017 +0530
lokdialog: Emit dialog close callback upon dialog close
Change-Id: I4ccef76cc3b2926dd8916f825671bb732e101027
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
index 9fe49aaf350e..8ad25f42a98c 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
@@ -291,8 +291,8 @@ void LOKDocViewSigHandlers::dialog(LOKDocView* pDocView, gchar* pPayload, gpoint
//std::string aDialogId = aRoot.get<std::string>("dialogId");
std::string aAction = aRoot.get<std::string>("action");
- // we only understand 'invalidate' as of now
- if (aAction != "invalidate")
+ // we only understand 'invalidate' and 'close' as of now
+ if (aAction != "invalidate" && aAction != "close")
return;
// temporary hack to invalidate all open dialogs
@@ -300,43 +300,48 @@ void LOKDocViewSigHandlers::dialog(LOKDocView* pDocView, gchar* pPayload, gpoint
GList* pIt = nullptr;
for (pIt = pChildWins; pIt != nullptr; pIt = pIt->next)
{
- gtv_lok_dialog_invalidate(GTV_LOK_DIALOG(pIt->data));
+ if (aAction == "close")
+ {
+ gtk_widget_destroy(GTK_WIDGET(pIt->data));
+ }
+ else if (aAction == "invalidate")
+ gtv_lok_dialog_invalidate(GTV_LOK_DIALOG(pIt->data));
}
}
void LOKDocViewSigHandlers::dialogChild(LOKDocView* pDocView, gchar* pPayload, gpointer)
{
- GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(pDocView)));
-
- 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");
- std::string aPos = aRoot.get<std::string>("position");
- gchar** ppCoordinates = g_strsplit(aPos.c_str(), ", ", 2);
- gchar** ppCoordinate = ppCoordinates;
- int nX = 0;
- int nY = 0;
-
- if (*ppCoordinate)
- nX = atoi(*ppCoordinate);
- ++ppCoordinate;
- if (*ppCoordinate)
- nY = atoi(*ppCoordinate);
-
- g_strfreev(ppCoordinates);
-
- // temporary hack to invalidate/close floating window of all opened dialogs
- GList* pChildWins = gtv_application_window_get_all_child_windows(window);
- GList* pIt = nullptr;
- for (pIt = pChildWins; pIt != nullptr; pIt = pIt->next)
- {
- if (aAction == "invalidate")
- gtv_lok_dialog_child_invalidate(GTV_LOK_DIALOG(pIt->data), nX, nY);
- else if (aAction == "close")
- gtv_lok_dialog_child_close(GTV_LOK_DIALOG(pIt->data));
- }
+ GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(pDocView)));
+
+ 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");
+ std::string aPos = aRoot.get<std::string>("position");
+ gchar** ppCoordinates = g_strsplit(aPos.c_str(), ", ", 2);
+ gchar** ppCoordinate = ppCoordinates;
+ int nX = 0;
+ int nY = 0;
+
+ if (*ppCoordinate)
+ nX = atoi(*ppCoordinate);
+ ++ppCoordinate;
+ if (*ppCoordinate)
+ nY = atoi(*ppCoordinate);
+
+ g_strfreev(ppCoordinates);
+
+ // temporary hack to invalidate/close floating window of all opened dialogs
+ GList* pChildWins = gtv_application_window_get_all_child_windows(window);
+ GList* pIt = nullptr;
+ for (pIt = pChildWins; pIt != nullptr; pIt = pIt->next)
+ {
+ if (aAction == "invalidate")
+ gtv_lok_dialog_child_invalidate(GTV_LOK_DIALOG(pIt->data), nX, nY);
+ else if (aAction == "close")
+ gtv_lok_dialog_child_close(GTV_LOK_DIALOG(pIt->data));
+ }
}
gboolean LOKDocViewSigHandlers::configureEvent(GtkWidget* pWidget, GdkEventConfigure* /*pEvent*/, gpointer /*pData*/)
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-signal-handlers.cxx b/libreofficekit/qa/gtktiledviewer/gtv-signal-handlers.cxx
index b871d93667f9..6ca78a61a2b2 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-signal-handlers.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-signal-handlers.cxx
@@ -293,6 +293,16 @@ void changePartMode( GtkWidget* pSelector, gpointer /* pItem */ )
static gboolean deleteLokDialog(GtkWidget* pWidget, GdkEvent* /*event*/, gpointer userdata)
{
GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(userdata);
+ g_info("deletLokDialog");
+ gtv_application_window_unregister_child_window(window, GTK_WINDOW(pWidget));
+
+ return FALSE;
+}
+
+static gboolean destroyLokDialog(GtkWidget* pWidget, gpointer userdata)
+{
+ GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(userdata);
+ g_info("destroyLokDialog");
gtv_application_window_unregister_child_window(window, GTK_WINDOW(pWidget));
return FALSE;
@@ -304,9 +314,11 @@ void openLokDialog( GtkWidget* pSelector, gpointer /*pItem*/ )
gchar* pDialogId = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(pSelector));
GtkWidget* pDialog = gtv_lok_dialog_new(LOK_DOC_VIEW(window->lokdocview), pDialogId);
gtv_application_window_register_child_window(window, GTK_WINDOW(pDialog));
+ g_signal_connect(pDialog, "destroy", G_CALLBACK(destroyLokDialog), window);
g_signal_connect(pDialog, "delete-event", G_CALLBACK(deleteLokDialog), window);
g_free(pDialogId);
+ g_info("openLokDialog");
gtk_window_set_resizable(GTK_WINDOW(pDialog), false);
gtk_widget_show_all(GTK_WIDGET(pDialog));
gtk_window_present(GTK_WINDOW(pDialog));
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index 7e5962645d9d..48e24b9b6bff 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -588,6 +588,11 @@ void Dialog::dispose()
xEventBroadcaster->documentEventOccured(aObject);
UITestLogger::getInstance().log("DialogClosed");
+ if (comphelper::LibreOfficeKit::isActive() && mpDialogRenderable)
+ {
+ mpDialogRenderable->notifyDialog(maID, "close");
+ }
+
SystemWindow::dispose();
}
commit 3ebaaebf544be4f7f39b7fcbbbc377418a897442
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Thu Aug 10 16:44:06 2017 +0530
Change CB_DIALOG_INVALIDATE to CB_DIALOG
We can specify whether it is an invalidation or something else in the
payload.
Change-Id: I95c5fc0a0a88b5277eaa93c8d1f9b937bddce7b3
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index c3f44114741b..48f08bb57ccd 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -785,7 +785,7 @@ void CallbackFlushHandler::queue(const int type, const char* data)
case LOK_CALLBACK_SET_PART:
case LOK_CALLBACK_TEXT_VIEW_SELECTION:
case LOK_CALLBACK_INVALIDATE_HEADER:
- case LOK_CALLBACK_DIALOG_INVALIDATE:
+ case LOK_CALLBACK_DIALOG:
{
const auto& pos = std::find_if(m_queue.rbegin(), m_queue.rend(),
[type] (const queue_type::value_type& elem) { return (elem.first == type); });
diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h
index 4c70560690da..62b9faf7ecb4 100644
--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h
+++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h
@@ -525,7 +525,7 @@ typedef enum
/**
* Dialog invalidation
*/
- LOK_CALLBACK_DIALOG_INVALIDATE = 36,
+ LOK_CALLBACK_DIALOG = 36,
/**
* Invalidation corresponding to dialog's children.
diff --git a/include/sfx2/lokhelper.hxx b/include/sfx2/lokhelper.hxx
index 8cf1fc5cb89d..a4733c2d2854 100644
--- a/include/sfx2/lokhelper.hxx
+++ b/include/sfx2/lokhelper.hxx
@@ -40,8 +40,8 @@ public:
static void notifyOtherViews(SfxViewShell* pThisView, int nType, const OString& rKey, const OString& rPayload);
/// 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_INVALIDATE with 'invalidate' action
- static void notifyDialogInvalidation(const OUString& rPayload);
+ /// Emits a LOK_CALLBACK_DIALOG
+ static void notifyDialog(const OUString& rPayload, const OUString& rAction);
/// 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 561f910987c6..02e959ea6fad 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 notifyDialogInvalidation(const DialogID& rDialogID) = 0;
+ virtual void notifyDialog(const DialogID& rDialogID, const OUString& rAction) = 0;
virtual void notifyDialogChild(const DialogID& rDialogID, const OUString& rAction, const Point& rPos) = 0;
};
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx b/libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx
index 8a5ff9a56d37..85c5b38466af 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx
@@ -314,7 +314,7 @@ static void setupDocView(GtvApplicationWindow* window)
g_signal_connect(window->lokdocview, "formula-changed", G_CALLBACK(LOKDocViewSigHandlers::formulaChanged), nullptr);
g_signal_connect(window->lokdocview, "password-required", G_CALLBACK(LOKDocViewSigHandlers::passwordRequired), nullptr);
g_signal_connect(window->lokdocview, "comment", G_CALLBACK(LOKDocViewSigHandlers::comment), nullptr);
- g_signal_connect(window->lokdocview, "dialog-invalidate", G_CALLBACK(LOKDocViewSigHandlers::dialogInvalidate), nullptr);
+ g_signal_connect(window->lokdocview, "dialog", G_CALLBACK(LOKDocViewSigHandlers::dialog), nullptr);
g_signal_connect(window->lokdocview, "dialog-child", G_CALLBACK(LOKDocViewSigHandlers::dialogChild), nullptr);
g_signal_connect(window->lokdocview, "configure-event", G_CALLBACK(LOKDocViewSigHandlers::configureEvent), nullptr);
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
index 3acd6b78e234..9fe49aaf350e 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
@@ -281,10 +281,19 @@ void LOKDocViewSigHandlers::comment(LOKDocView* pDocView, gchar* pComment, gpoin
}
}
-void LOKDocViewSigHandlers::dialogInvalidate(LOKDocView* pDocView, gchar* pPayload, gpointer)
+void LOKDocViewSigHandlers::dialog(LOKDocView* pDocView, gchar* pPayload, gpointer)
{
GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(pDocView)));
-// GtkWindow* pDialog = gtv_application_window_get_child_window_by_id(window, pDialogId);
+
+ 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");
+
+ // we only understand 'invalidate' as of now
+ if (aAction != "invalidate")
+ return;
// temporary hack to invalidate all open dialogs
GList* pChildWins = gtv_application_window_get_all_child_windows(window);
@@ -293,11 +302,6 @@ void LOKDocViewSigHandlers::dialogInvalidate(LOKDocView* pDocView, gchar* pPaylo
{
gtv_lok_dialog_invalidate(GTV_LOK_DIALOG(pIt->data));
}
-/* if (pDialog)
- {
- gtv_lok_dialog_invalidate(GTV_LOK_DIALOG(pDialog));
- }
-*/
}
void LOKDocViewSigHandlers::dialogChild(LOKDocView* pDocView, gchar* pPayload, gpointer)
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx
index a455c3f1fc4c..54f54b396bf3 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx
@@ -25,7 +25,7 @@ namespace LOKDocViewSigHandlers {
void formulaChanged(LOKDocView* pDocView, char* pPayload, gpointer);
void passwordRequired(LOKDocView* pDocView, char* pUrl, gboolean bModify, gpointer);
void comment(LOKDocView* pDocView, gchar* pComment, gpointer);
- void dialogInvalidate(LOKDocView* pDocView, gchar* pDialogId, gpointer);
+ void dialog(LOKDocView* pDocView, gchar* pDialogId, gpointer);
void dialogChild(LOKDocView* pDocView, gchar* pPayload, gpointer);
gboolean configureEvent(GtkWidget* pWidget, GdkEventConfigure* pEvent, gpointer pData);
diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index 1bdb80c754ed..d2bfefcc089e 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -279,7 +279,7 @@ enum
PASSWORD_REQUIRED,
COMMENT,
RULER,
- DIALOG_INVALIDATE,
+ DIALOG,
DIALOG_CHILD,
LAST_SIGNAL
@@ -438,8 +438,8 @@ callbackTypeToString (int nType)
return "LOK_CALLBACK_COMMENT";
case LOK_CALLBACK_RULER_UPDATE:
return "LOK_CALLBACK_RULER_UPDATE";
- case LOK_CALLBACK_DIALOG_INVALIDATE:
- return "LOK_CALLBACK_DIALOG_INVALIDATE";
+ case LOK_CALLBACK_DIALOG:
+ return "LOK_CALLBACK_DIALOG";
case LOK_CALLBACK_DIALOG_CHILD:
return "LOK_CALLBACK_DIALOG_CHILD";
}
@@ -1414,8 +1414,9 @@ callback (gpointer pData)
break;
case LOK_CALLBACK_RULER_UPDATE:
g_signal_emit(pCallback->m_pDocView, doc_view_signals[RULER], 0, pCallback->m_aPayload.c_str());
- case LOK_CALLBACK_DIALOG_INVALIDATE:
- g_signal_emit(pCallback->m_pDocView, doc_view_signals[DIALOG_INVALIDATE], 0, pCallback->m_aPayload.c_str());
+ break;
+ case LOK_CALLBACK_DIALOG:
+ g_signal_emit(pCallback->m_pDocView, doc_view_signals[DIALOG], 0, pCallback->m_aPayload.c_str());
break;
case LOK_CALLBACK_DIALOG_CHILD:
g_signal_emit(pCallback->m_pDocView, doc_view_signals[DIALOG_CHILD], 0, pCallback->m_aPayload.c_str());
@@ -3222,8 +3223,8 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass)
* @pDocView: the #LOKDocView on which the signal is emitted
* @pDialogId: The uno command for the dialog (dialog ID)
*/
- doc_view_signals[DIALOG_INVALIDATE] =
- g_signal_new("dialog-invalidate",
+ doc_view_signals[DIALOG] =
+ g_signal_new("dialog",
G_TYPE_FROM_CLASS(pGObjectClass),
G_SIGNAL_RUN_FIRST,
0,
diff --git a/sfx2/source/view/lokhelper.cxx b/sfx2/source/view/lokhelper.cxx
index 85b1815c57a8..702e88d09cf0 100644
--- a/sfx2/source/view/lokhelper.cxx
+++ b/sfx2/source/view/lokhelper.cxx
@@ -144,15 +144,19 @@ void SfxLokHelper::notifyOtherViews(SfxViewShell* pThisView, int nType, const OS
}
}
-void SfxLokHelper::notifyDialogInvalidation(const OUString& rDialogID)
+void SfxLokHelper::notifyDialog(const OUString& rDialogID, const OUString& rAction)
{
if (SfxLokHelper::getViewsCount() <= 0)
return;
SfxViewShell* pViewShell = SfxViewShell::GetFirst();
+ const OString aPayload = OString("{ \"dialogId\": \"") + OUStringToOString(rDialogID, RTL_TEXTENCODING_UTF8).getStr() +
+ OString("\", \"action\": \"") + OUStringToOString(rAction, RTL_TEXTENCODING_UTF8).getStr() +
+ + "\" }";
+
while (pViewShell)
{
- pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_DIALOG_INVALIDATE, OUStringToOString(rDialogID, RTL_TEXTENCODING_UTF8).getStr());
+ pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_DIALOG, aPayload.getStr());
pViewShell = SfxViewShell::GetNext(*pViewShell);
}
}
diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx
index a803a6aa8e16..868dbabbcb72 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 notifyDialogInvalidation(const vcl::DialogID& rDialogID) override;
+ void notifyDialog(const vcl::DialogID& rDialogID, const OUString& rAction) 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 c148f09ef873..ec2d09c9d915 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -3783,9 +3783,9 @@ void SwXTextDocument::postDialogChildMouseEvent(const vcl::DialogID& rDialogID,
}
}
-void SwXTextDocument::notifyDialogInvalidation(const vcl::DialogID& rDialogID)
+void SwXTextDocument::notifyDialog(const vcl::DialogID& rDialogID, const OUString& rAction)
{
- SfxLokHelper::notifyDialogInvalidation(rDialogID);
+ SfxLokHelper::notifyDialog(rDialogID, rAction);
}
void SwXTextDocument::notifyDialogChild(const vcl::DialogID& rDialogID, const OUString& rAction, const Point& rPos)
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index c34e9382d16e..7e5962645d9d 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -962,7 +962,7 @@ void Dialog::LogicInvalidate(const tools::Rectangle* /*pRectangle*/)
{
if (!comphelper::LibreOfficeKit::isDialogPainting() && mpDialogRenderable && !maID.isEmpty())
{
- mpDialogRenderable->notifyDialogInvalidation(maID);
+ mpDialogRenderable->notifyDialog(maID, "invalidate");
}
}
commit 77bb77aedee4b4596f769df8e334b8063c5846b0
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Fri Aug 4 11:17:06 2017 +0530
lokdialog: Mouse events for dialog floating child windows
Change-Id: I06a081835d246f752e57f8cc289162ed31fc91d4
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index c5ca3666f9e7..c3f44114741b 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -564,6 +564,14 @@ static void doc_postDialogMouseEvent (LibreOfficeKitDocument* pThis,
int nCount,
int nButtons,
int nModifier);
+static void doc_postDialogChildMouseEvent (LibreOfficeKitDocument* pThis,
+ const char* pDialogId,
+ int nType,
+ int nX,
+ int nY,
+ int nCount,
+ int nButtons,
+ int nModifier);
static void doc_postUnoCommand(LibreOfficeKitDocument* pThis,
const char* pCommand,
const char* pArguments,
@@ -636,6 +644,7 @@ LibLODocument_Impl::LibLODocument_Impl(const uno::Reference <css::lang::XCompone
m_pDocumentClass->postDialogKeyEvent = doc_postDialogKeyEvent;
m_pDocumentClass->postMouseEvent = doc_postMouseEvent;
m_pDocumentClass->postDialogMouseEvent = doc_postDialogMouseEvent;
+ m_pDocumentClass->postDialogChildMouseEvent = doc_postDialogChildMouseEvent;
m_pDocumentClass->postUnoCommand = doc_postUnoCommand;
m_pDocumentClass->setTextSelection = doc_setTextSelection;
m_pDocumentClass->getTextSelection = doc_getTextSelection;
@@ -2323,6 +2332,21 @@ static void doc_postDialogMouseEvent(LibreOfficeKitDocument* pThis, const char*
pDoc->postDialogMouseEvent(aDialogID, nType, nX, nY, nCount, nButtons, nModifier);
}
+static void doc_postDialogChildMouseEvent(LibreOfficeKitDocument* pThis, const char* pDialogId, int nType, int nX, int nY, int nCount, int nButtons, int nModifier)
+{
+ SolarMutexGuard aGuard;
+
+ IDialogRenderable* pDoc = getDialogRenderable(pThis);
+ if (!pDoc)
+ {
+ gImpl->maLastExceptionMsg = "Document doesn't support dialog rendering";
+ return;
+ }
+
+ vcl::DialogID aDialogID = OUString::createFromAscii(pDialogId);
+ pDoc->postDialogChildMouseEvent(aDialogID, nType, nX, nY, nCount, nButtons, nModifier);
+}
+
static void doc_setTextSelection(LibreOfficeKitDocument* pThis, int nType, int nX, int nY)
{
SolarMutexGuard aGuard;
diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h
index 529a1336ca76..05c8eff15316 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/include/LibreOfficeKit/LibreOfficeKit.h
@@ -288,6 +288,16 @@ struct _LibreOfficeKitDocumentClass
int nButtons,
int nModifier);
+ /// WIP
+ void (*postDialogChildMouseEvent) (LibreOfficeKitDocument* pThis,
+ const char* pDialogId,
+ int nType,
+ int nX,
+ int nY,
+ int nCount,
+ int nButtons,
+ int nModifier);
+
#endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
};
diff --git a/include/vcl/IDialogRenderable.hxx b/include/vcl/IDialogRenderable.hxx
index 351839e46d02..561f910987c6 100644
--- a/include/vcl/IDialogRenderable.hxx
+++ b/include/vcl/IDialogRenderable.hxx
@@ -42,6 +42,9 @@ public:
virtual void postDialogMouseEvent(const DialogID& rDialogID, int nType, int nX, int nY,
int nCount, int nButtons, int nModifier) = 0;
+ virtual void postDialogChildMouseEvent(const DialogID& rDialogID, int nType, int nX, int nY,
+ int nCount, int nButtons, int nModifier) = 0;
+
// Callbacks
virtual void notifyDialogInvalidation(const DialogID& rDialogID) = 0;
diff --git a/include/vcl/dialog.hxx b/include/vcl/dialog.hxx
index 5ab85be1842e..6cea3b193ec2 100644
--- a/include/vcl/dialog.hxx
+++ b/include/vcl/dialog.hxx
@@ -91,6 +91,9 @@ public:
void LogicMouseButtonDown(const MouseEvent& rMouseEvent);
void LogicMouseButtonUp(const MouseEvent& rMouseEvent);
void LogicMouseMove(const MouseEvent& rMouseEvent);
+ void LogicMouseButtonDownChild(const MouseEvent& rMouseEvent);
+ void LogicMouseButtonUpChild(const MouseEvent& rMouseEvent);
+ void LogicMouseMoveChild(const MouseEvent& rMouseEvent);
void LOKKeyInput(const KeyEvent& rKeyEvent);
void LOKKeyUp(const KeyEvent& rKeyEvent);
diff --git a/include/vcl/floatwin.hxx b/include/vcl/floatwin.hxx
index fc7df3ada424..f0faa3c3e260 100644
--- a/include/vcl/floatwin.hxx
+++ b/include/vcl/floatwin.hxx
@@ -129,6 +129,7 @@ public:
SAL_DLLPRIVATE tools::Rectangle& ImplGetItemEdgeClipRect();
SAL_DLLPRIVATE bool ImplIsInPrivatePopupMode() const { return mbInPopupMode; }
virtual void doDeferredInit(WinBits nBits) override;
+ virtual void LogicInvalidate(const tools::Rectangle* pRectangle) override;
public:
explicit FloatingWindow(vcl::Window* pParent, WinBits nStyle);
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
index e37f9f274062..1149f50230b6 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
@@ -34,11 +34,18 @@ struct GtvLokDialogPrivate
GtkWidget* pDialogDrawingArea;
GtkWidget* pFloatingWin;
+ // state for dialog
guint32 m_nLastButtonPressTime;
guint32 m_nLastButtonReleaseTime;
guint32 m_nKeyModifier;
guint32 m_nLastButtonPressed;
+ // state for child floating windows
+ guint32 m_nChildLastButtonPressTime;
+ guint32 m_nChildLastButtonReleaseTime;
+ guint32 m_nChildKeyModifier;
+ guint32 m_nChildLastButtonPressed;
+
gchar* dialogid;
};
@@ -462,6 +469,115 @@ gtv_lok_dialog_invalidate(GtvLokDialog* dialog)
gtk_widget_queue_draw(priv->pDialogDrawingArea);
}
+static gboolean
+gtv_lok_dialog_floating_win_signal_button(GtkWidget* /*pDialogChildDrawingArea*/, GdkEventButton* pEvent, gpointer userdata)
+{
+ GtvLokDialog* pDialog = GTV_LOK_DIALOG(userdata);
+ GtvLokDialogPrivate* priv = getPrivate(pDialog);
+
+ GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(pDialog)));
+ LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(LOK_DOC_VIEW(window->lokdocview));
+
+ g_info("lok_dialog_floating_win_signal_button: %d, %d (in twips: %d, %d)",
+ (int)pEvent->x, (int)pEvent->y,
+ (int)pixelToTwip(pEvent->x),
+ (int)pixelToTwip(pEvent->y));
+
+ switch (pEvent->type)
+ {
+ case GDK_BUTTON_PRESS:
+ {
+ int nCount = 1;
+ if ((pEvent->time - priv->m_nChildLastButtonPressTime) < 250)
+ nCount++;
+ priv->m_nChildLastButtonPressTime = pEvent->time;
+ int nEventButton = 0;
+ switch (pEvent->button)
+ {
+ case 1:
+ nEventButton = MOUSE_LEFT;
+ break;
+ case 2:
+ nEventButton = MOUSE_MIDDLE;
+ break;
+ case 3:
+ nEventButton = MOUSE_RIGHT;
+ break;
+ }
+ priv->m_nChildLastButtonPressed = nEventButton;
+ pDocument->pClass->postDialogChildMouseEvent(pDocument,
+ priv->dialogid,
+ LOK_MOUSEEVENT_MOUSEBUTTONDOWN,
+ (pEvent->x),
+ (pEvent->y),
+ nCount,
+ nEventButton,
+ priv->m_nChildKeyModifier);
+
+ break;
+ }
+ case GDK_BUTTON_RELEASE:
+ {
+ int nCount = 1;
+ if ((pEvent->time - priv->m_nChildLastButtonReleaseTime) < 250)
+ nCount++;
+ priv->m_nChildLastButtonReleaseTime = pEvent->time;
+ int nEventButton = 0;
+ switch (pEvent->button)
+ {
+ case 1:
+ nEventButton = MOUSE_LEFT;
+ break;
+ case 2:
+ nEventButton = MOUSE_MIDDLE;
+ break;
+ case 3:
+ nEventButton = MOUSE_RIGHT;
+ break;
+ }
+ priv->m_nChildLastButtonPressed = nEventButton;
+ pDocument->pClass->postDialogChildMouseEvent(pDocument,
+ priv->dialogid,
+ LOK_MOUSEEVENT_MOUSEBUTTONUP,
+ (pEvent->x),
+ (pEvent->y),
+ nCount,
+ nEventButton,
+ priv->m_nChildKeyModifier);
+ break;
+ }
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+static gboolean
+gtv_lok_dialog_floating_win_signal_motion(GtkWidget* /*pDialogDrawingArea*/, GdkEventButton* pEvent, gpointer userdata)
+{
+ GtvLokDialog* pDialog = GTV_LOK_DIALOG(userdata);
+ GtvLokDialogPrivate* priv = getPrivate(pDialog);
+
+ GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(pDialog)));
+ LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(LOK_DOC_VIEW(window->lokdocview));
+
+ g_info("lok_dialog_floating_win_signal_motion: %d, %d (in twips: %d, %d)",
+ (int)pEvent->x, (int)pEvent->y,
+ (int)pixelToTwip(pEvent->x),
+ (int)pixelToTwip(pEvent->y));
+
+ pDocument->pClass->postDialogChildMouseEvent(pDocument,
+ priv->dialogid,
+ LOK_MOUSEEVENT_MOUSEMOVE,
+ (pEvent->x),
+ (pEvent->y),
+ 1,
+ priv->m_nChildLastButtonPressed,
+ priv->m_nChildKeyModifier);
+
+ return FALSE;
+}
+
void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog, int nX, int nY)
{
g_info("Dialog's floating window invalidate");
@@ -477,7 +593,17 @@ void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog, int nX, int nY)
gtk_window_set_transient_for(GTK_WINDOW(priv->pFloatingWin), GTK_WINDOW(dialog));
gtk_window_set_destroy_with_parent(GTK_WINDOW(priv->pFloatingWin), true);
+
+ gtk_widget_add_events(pDrawingArea,
+ GDK_BUTTON_PRESS_MASK
+ |GDK_POINTER_MOTION_MASK
+ |GDK_BUTTON_RELEASE_MASK
+ |GDK_BUTTON_MOTION_MASK);
+
g_signal_connect(G_OBJECT(pDrawingArea), "draw", G_CALLBACK(gtv_lok_dialog_floating_win_draw), dialog);
+ g_signal_connect(G_OBJECT(pDrawingArea), "button-press-event", G_CALLBACK(gtv_lok_dialog_floating_win_signal_button), dialog);
+ g_signal_connect(G_OBJECT(pDrawingArea), "button-release-event", G_CALLBACK(gtv_lok_dialog_floating_win_signal_button), dialog);
+ g_signal_connect(G_OBJECT(pDrawingArea), "motion-notify-event", G_CALLBACK(gtv_lok_dialog_floating_win_signal_motion), dialog);
gtk_widget_set_size_request(priv->pFloatingWin, 1, 1);
gtk_window_set_type_hint(GTK_WINDOW(priv->pFloatingWin), GDK_WINDOW_TYPE_HINT_POPUP_MENU);
@@ -485,6 +611,7 @@ void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog, int nX, int nY)
gtk_widget_show_all(priv->pFloatingWin);
gtk_window_present(GTK_WINDOW(priv->pFloatingWin));
+ gtk_widget_grab_focus(pDrawingArea);
// Get the root coords of our new floating window
GdkWindow* pGdkWin = gtk_widget_get_window(GTK_WIDGET(dialog));
diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx
index 3d269dcadc03..a803a6aa8e16 100644
--- a/sw/inc/unotxdoc.hxx
+++ b/sw/inc/unotxdoc.hxx
@@ -439,6 +439,9 @@ public:
void postDialogMouseEvent(const vcl::DialogID& rDialogID, int nType, int nX, int nY,
int nCount, int nButtons, int nModifier) override;
+ void postDialogChildMouseEvent(const vcl::DialogID& rDialogID, int nType, int nX, int nY,
+ int nCount, int nButtons, int nModifier) override;
+
void notifyDialogInvalidation(const vcl::DialogID& rDialogID) 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 9ab338fce7a0..c148f09ef873 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -3743,6 +3743,46 @@ void SwXTextDocument::postDialogMouseEvent(const vcl::DialogID& rDialogID, int n
}
}
+
+void SwXTextDocument::postDialogChildMouseEvent(const vcl::DialogID& rDialogID, int nType, int nX, int nY,
+ int nCount, int nButtons, int nModifier)
+{
+ SolarMutexGuard aGuard;
+
+ // check if dialog is already open
+ SfxViewFrame* pViewFrame = pDocShell->GetView()->GetViewFrame();
+ SfxSlotPool* pSlotPool = SW_MOD()->GetSlotPool();
+ const SfxSlot* pSlot = pSlotPool->GetUnoSlot(rDialogID);
+ if (!pSlot)
+ {
+ SAL_WARN("lok.dialog", "No slot found for " << rDialogID);
+ return;
+ }
+ SfxChildWindow* pChild = pViewFrame->GetChildWindow(pSlot->GetSlotId());
+ if (pChild)
+ {
+ Dialog* pDialog = static_cast<Dialog*>(pChild->GetWindow());
+ Point aPos(nX , nY);
+ MouseEvent aEvent(aPos, nCount, MouseEventModifiers::SIMPLECLICK, nButtons, nModifier);
+
+ switch (nType)
+ {
+ case LOK_MOUSEEVENT_MOUSEBUTTONDOWN:
+ pDialog->LogicMouseButtonDownChild(aEvent);
+ break;
+ case LOK_MOUSEEVENT_MOUSEBUTTONUP:
+ pDialog->LogicMouseButtonUpChild(aEvent);
+ break;
+ case LOK_MOUSEEVENT_MOUSEMOVE:
+ pDialog->LogicMouseMoveChild(aEvent);
+ break;
+ default:
+ assert(false);
+ break;
+ }
+ }
+}
+
void SwXTextDocument::notifyDialogInvalidation(const vcl::DialogID& rDialogID)
{
SfxLokHelper::notifyDialogInvalidation(rDialogID);
diff --git a/vcl/source/control/ctrl.cxx b/vcl/source/control/ctrl.cxx
index 3bd877ea7162..38509814f5b0 100644
--- a/vcl/source/control/ctrl.cxx
+++ b/vcl/source/control/ctrl.cxx
@@ -23,6 +23,7 @@
#include <vcl/svapp.hxx>
#include <vcl/event.hxx>
#include <vcl/ctrl.hxx>
+#include <vcl/floatwin.hxx>
#include <vcl/decoview.hxx>
#include <vcl/dialog.hxx>
#include <vcl/salnativewidgets.hxx>
@@ -420,7 +421,20 @@ void Control::LogicInvalidate(const tools::Rectangle* /*pRectangle*/)
// ignore all of those
if (comphelper::LibreOfficeKit::isActive() && !comphelper::LibreOfficeKit::isDialogPainting())
{
- // For now just invalidate the whole dialog
+ // If parent is a floating window, trigger an invalidate there
+ vcl::Window* pWindow = this;
+ while (pWindow)
+ {
+ if (pWindow->ImplIsFloatingWindow())
+ {
+ dynamic_cast<FloatingWindow*>(pWindow)->LogicInvalidate(nullptr);
+ return;
+ }
+
+ pWindow = pWindow->GetParent();
+ }
+
+ // otherwise, for now, just invalidate the whole dialog
Dialog* pParentDlg = GetParentDialog();
if (pParentDlg)
pParentDlg->LogicInvalidate(nullptr);
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index 29400ca55982..c34e9382d16e 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -906,6 +906,42 @@ Size Dialog::PaintActiveFloatingWindow(VirtualDevice& rDevice)
return aRet;
}
+void Dialog::LogicMouseButtonDownChild(const MouseEvent& rMouseEvent)
+{
+ assert(comphelper::LibreOfficeKit::isActive());
+
+ ImplSVData* pSVData = ImplGetSVData();
+ FloatingWindow* pFirstFloat = pSVData->maWinData.mpFirstFloat;
+ if (pFirstFloat && pFirstFloat->GetParentDialog() == this)
+ {
+ ImplWindowFrameProc(pFirstFloat->ImplGetBorderWindow(), SalEvent::ExternalMouseButtonDown, &rMouseEvent);
+ }
+}
+
+void Dialog::LogicMouseButtonUpChild(const MouseEvent& rMouseEvent)
+{
+ assert(comphelper::LibreOfficeKit::isActive());
+
+ ImplSVData* pSVData = ImplGetSVData();
+ FloatingWindow* pFirstFloat = pSVData->maWinData.mpFirstFloat;
+ if (pFirstFloat && pFirstFloat->GetParentDialog() == this)
+ {
+ ImplWindowFrameProc(pFirstFloat->ImplGetBorderWindow(), SalEvent::ExternalMouseButtonUp, &rMouseEvent);
+ }
+}
+
+void Dialog::LogicMouseMoveChild(const MouseEvent& rMouseEvent)
+{
+ assert(comphelper::LibreOfficeKit::isActive());
+
+ ImplSVData* pSVData = ImplGetSVData();
+ FloatingWindow* pFirstFloat = pSVData->maWinData.mpFirstFloat;
+ if (pFirstFloat && pFirstFloat->GetParentDialog() == this)
+ {
+ ImplWindowFrameProc(pFirstFloat->ImplGetBorderWindow(), SalEvent::ExternalMouseMove, &rMouseEvent);
+ }
+}
+
void Dialog::InvalidateFloatingWindow(const Point& rPos)
{
if (comphelper::LibreOfficeKit::isActive() && mpDialogRenderable && !maID.isEmpty())
diff --git a/vcl/source/window/floatwin.cxx b/vcl/source/window/floatwin.cxx
index 16bcb721a612..46b7b330efee 100644
--- a/vcl/source/window/floatwin.cxx
+++ b/vcl/source/window/floatwin.cxx
@@ -585,6 +585,15 @@ bool FloatingWindow::EventNotify( NotifyEvent& rNEvt )
return bRet;
}
+void FloatingWindow::LogicInvalidate(const tools::Rectangle* /*pRectangle*/)
+{
+ Dialog* pParentDlg = GetParentDialog();
+ if (pParentDlg)
+ {
+ pParentDlg->InvalidateFloatingWindow(mpImplData->maPos);
+ }
+}
+
void FloatingWindow::StateChanged( StateChangedType nType )
{
if (nType == StateChangedType::InitShow)
commit cce5bdbeee4828d7d052eef16644355783567cf7
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Fri Aug 4 00:02:48 2017 +0530
lokdialog: drawing area needs to have focus to capture key events
With this, key events successfully work now.
Change-Id: I6dc6aff91dea08fcbc7ab840a77e2542ab9048ce
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
index 6b19ddc506c0..e37f9f274062 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
@@ -110,7 +110,7 @@ gtv_lok_dialog_signal_button(GtkWidget* pDialogDrawingArea, GdkEventButton* pEve
(int)pEvent->x, (int)pEvent->y,
(int)pixelToTwip(pEvent->x),
(int)pixelToTwip(pEvent->y));
- gtk_widget_grab_focus(GTK_WIDGET(pDialog));
+ gtk_widget_grab_focus(pDialogDrawingArea);
switch (pEvent->type)
{
@@ -194,7 +194,6 @@ gtv_lok_dialog_signal_motion(GtkWidget* pDialogDrawingArea, GdkEventButton* pEve
(int)pEvent->x, (int)pEvent->y,
(int)pixelToTwip(pEvent->x),
(int)pixelToTwip(pEvent->y));
- gtk_widget_grab_focus(GTK_WIDGET(pDialog));
pDocument->pClass->postDialogMouseEvent(pDocument,
priv->dialogid,
@@ -216,6 +215,7 @@ gtv_lok_dialog_signal_key(GtkWidget* pDialogDrawingArea, GdkEventKey* pEvent)
GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(pDialog)));
LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(LOK_DOC_VIEW(window->lokdocview));
+ g_info("lok_dialog_signal_key");
int nCharCode = 0;
int nKeyCode = 0;
priv->m_nKeyModifier &= KEY_MOD2;
@@ -334,12 +334,14 @@ gtv_lok_dialog_init(GtvLokDialog* dialog)
priv->m_nKeyModifier = 0;
priv->m_nLastButtonPressed = 0;
- gtk_widget_add_events(GTK_WIDGET(priv->pDialogDrawingArea),
+ gtk_widget_add_events(priv->pDialogDrawingArea,
GDK_BUTTON_PRESS_MASK
|GDK_BUTTON_RELEASE_MASK
|GDK_BUTTON_MOTION_MASK
|GDK_KEY_PRESS_MASK
|GDK_KEY_RELEASE_MASK);
+ // This is required to be able to capture key events on the drawing area
+ gtk_widget_set_can_focus(priv->pDialogDrawingArea, true);
g_signal_connect(G_OBJECT(priv->pDialogDrawingArea), "draw", G_CALLBACK(gtv_lok_dialog_draw), nullptr);
g_signal_connect(G_OBJECT(priv->pDialogDrawingArea), "button-press-event", G_CALLBACK(gtv_lok_dialog_signal_button), nullptr);
commit d6490d3c7bb686ee07654f9d0ade6e145043c0f3
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Thu Aug 3 22:58:04 2017 +0530
lokdialog: Move the floating window to its actual position
gtk_window_move them to the position broadcasted to us by vcl
Change-Id: Id27b52a24e721b51d7a153cc7c0e03197a99ee2f
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
index 1bfb9d538ead..6b19ddc506c0 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
@@ -460,7 +460,7 @@ gtv_lok_dialog_invalidate(GtvLokDialog* dialog)
gtk_widget_queue_draw(priv->pDialogDrawingArea);
}
-void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog)
+void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog, int nX, int nY)
{
g_info("Dialog's floating window invalidate");
@@ -474,14 +474,22 @@ void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog)
gtk_container_add(GTK_CONTAINER(priv->pFloatingWin), pDrawingArea);
gtk_window_set_transient_for(GTK_WINDOW(priv->pFloatingWin), GTK_WINDOW(dialog));
- gtk_window_set_position(GTK_WINDOW(priv->pFloatingWin), GTK_WIN_POS_MOUSE);
gtk_window_set_destroy_with_parent(GTK_WINDOW(priv->pFloatingWin), true);
-
g_signal_connect(G_OBJECT(pDrawingArea), "draw", G_CALLBACK(gtv_lok_dialog_floating_win_draw), dialog);
gtk_widget_set_size_request(priv->pFloatingWin, 1, 1);
+ gtk_window_set_type_hint(GTK_WINDOW(priv->pFloatingWin), GDK_WINDOW_TYPE_HINT_POPUP_MENU);
+ gtk_window_set_screen(GTK_WINDOW(priv->pFloatingWin), gtk_window_get_screen(GTK_WINDOW(dialog)));
+
gtk_widget_show_all(priv->pFloatingWin);
gtk_window_present(GTK_WINDOW(priv->pFloatingWin));
+
+ // Get the root coords of our new floating window
+ GdkWindow* pGdkWin = gtk_widget_get_window(GTK_WIDGET(dialog));
+ int nrX = 0;
+ int nrY = 0;
+ gdk_window_get_root_coords(pGdkWin, nX, nY, &nrX, &nrY);
+ gtk_window_move(GTK_WINDOW(priv->pFloatingWin), nrX, nrY);
}
void gtv_lok_dialog_child_close(GtvLokDialog* dialog)
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.hxx b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.hxx
index bce9edbadba1..ba565b4cebb0 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.hxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.hxx
@@ -39,7 +39,7 @@ GtkWidget* gtv_lok_dialog_new(LOKDocView* pDocView, const gchar* dialogId);
void gtv_lok_dialog_invalidate(GtvLokDialog* dialog);
-void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog);
+void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog, int nX, int nY);
void gtv_lok_dialog_child_close(GtvLokDialog* dialog);
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
index 8896566499c1..3acd6b78e234 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
@@ -309,6 +309,19 @@ void LOKDocViewSigHandlers::dialogChild(LOKDocView* pDocView, gchar* pPayload, g
boost::property_tree::read_json(aStream, aRoot);
//std::string aDialogId = aRoot.get<std::string>("dialogId");
std::string aAction = aRoot.get<std::string>("action");
+ std::string aPos = aRoot.get<std::string>("position");
+ gchar** ppCoordinates = g_strsplit(aPos.c_str(), ", ", 2);
+ gchar** ppCoordinate = ppCoordinates;
+ int nX = 0;
+ int nY = 0;
+
+ if (*ppCoordinate)
+ nX = atoi(*ppCoordinate);
+ ++ppCoordinate;
+ if (*ppCoordinate)
+ nY = atoi(*ppCoordinate);
+
+ g_strfreev(ppCoordinates);
// temporary hack to invalidate/close floating window of all opened dialogs
GList* pChildWins = gtv_application_window_get_all_child_windows(window);
@@ -316,7 +329,7 @@ void LOKDocViewSigHandlers::dialogChild(LOKDocView* pDocView, gchar* pPayload, g
for (pIt = pChildWins; pIt != nullptr; pIt = pIt->next)
{
if (aAction == "invalidate")
- gtv_lok_dialog_child_invalidate(GTV_LOK_DIALOG(pIt->data));
+ gtv_lok_dialog_child_invalidate(GTV_LOK_DIALOG(pIt->data), nX, nY);
else if (aAction == "close")
gtv_lok_dialog_child_close(GTV_LOK_DIALOG(pIt->data));
}
commit 9cdaccc0cc5664ffb22035f65135b6be876de92f
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Thu Aug 3 14:42:55 2017 +0530
lokdialog: Support for rendering floating window dialog widgets
Now gtktiledviewer can show floating window dialog widgets when user
clicks any of such widget in the dialog.
Change-Id: I13d756f236379bc8b2041ed41cb7b502f7fd9b24
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 8246894e22dc..c5ca3666f9e7 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -606,6 +606,8 @@ static char* doc_getPartHash(LibreOfficeKitDocument* pThis, int nPart);
static void doc_paintDialog(LibreOfficeKitDocument* pThis, const char* pDialogId, unsigned char* pBuffer, int* nWidth, int* nHeight);
+static void doc_paintActiveFloatingWindow(LibreOfficeKitDocument* pThis, const char* pDialogId, unsigned char* pBuffer, int* nWidth, int* nHeight);
+
LibLODocument_Impl::LibLODocument_Impl(const uno::Reference <css::lang::XComponent> &xComponent)
: mxComponent(xComponent)
{
@@ -655,6 +657,7 @@ LibLODocument_Impl::LibLODocument_Impl(const uno::Reference <css::lang::XCompone
m_pDocumentClass->getPartHash = doc_getPartHash;
m_pDocumentClass->paintDialog = doc_paintDialog;
+ m_pDocumentClass->paintActiveFloatingWindow = doc_paintActiveFloatingWindow;
gDocumentClass = m_pDocumentClass;
}
@@ -3075,6 +3078,24 @@ static void doc_paintDialog(LibreOfficeKitDocument* pThis, const char* pDialogId
comphelper::LibreOfficeKit::setDialogPainting(false);
}
+static void doc_paintActiveFloatingWindow(LibreOfficeKitDocument* pThis, const char* pDialogId, unsigned char* pBuffer, int* nWidth, int* nHeight)
+{
+ SolarMutexGuard aGuard;
+
+ IDialogRenderable* pDialogRenderable = getDialogRenderable(pThis);
+
+ ScopedVclPtrInstance<VirtualDevice> pDevice(nullptr, Size(1, 1), DeviceFormat::DEFAULT);
+ pDevice->SetBackground(Wallpaper(Color(COL_TRANSPARENT)));
+
+ pDevice->SetOutputSizePixelScaleOffsetAndBuffer(Size(*nWidth, *nHeight), Fraction(1.0), Point(), pBuffer);
+
+ vcl::DialogID aDialogID = OUString::createFromAscii(pDialogId);
+
+ comphelper::LibreOfficeKit::setDialogPainting(true);
+ pDialogRenderable->paintActiveFloatingWindow(aDialogID, *pDevice.get(), *nWidth, *nHeight);
+ comphelper::LibreOfficeKit::setDialogPainting(false);
+}
+
static char* lo_getError (LibreOfficeKit *pThis)
{
SolarMutexGuard aGuard;
diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h
index 5a099f7c7f67..529a1336ca76 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/include/LibreOfficeKit/LibreOfficeKit.h
@@ -269,6 +269,8 @@ struct _LibreOfficeKitDocumentClass
/// WIP
void (*paintDialog) (LibreOfficeKitDocument* pThis, const char* pDialogId, unsigned char* pBuffer, int* nWidth, int* nHeight);
+ void (*paintActiveFloatingWindow) (LibreOfficeKitDocument* pThis, const char* pDialogId, unsigned char* pBuffer, int* nWidth, int* nHeight);
+
/// WIP
void (*postDialogKeyEvent) (LibreOfficeKitDocument* pThis,
const char* pDialogId,
diff --git a/include/LibreOfficeKit/LibreOfficeKitEnums.h b/include/LibreOfficeKit/LibreOfficeKitEnums.h
index fdad6919e0e1..4c70560690da 100644
--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h
+++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h
@@ -525,8 +525,26 @@ typedef enum
/**
* Dialog invalidation
*/
- LOK_CALLBACK_DIALOG_INVALIDATE = 36
+ LOK_CALLBACK_DIALOG_INVALIDATE = 36,
+ /**
+ * Invalidation corresponding to dialog's children.
+ * Eg: Floating window etc.
+ *
+ * Payload example:
+ * {
+ * "dialogID": "SpellDialog",
+ * "action": "close"
+ * }
+ *
+ * - dialogID is the UNO command of the dialog
+ * - action can be
+ * - close, means dialog child window is closed now
+ * - invalidate, means dialog child window is invalidated
+ * It also means that dialog child window is created if it's the first
+ * invalidate
+ */
+ LOK_CALLBACK_DIALOG_CHILD = 37
}
LibreOfficeKitCallbackType;
diff --git a/include/sfx2/lokhelper.hxx b/include/sfx2/lokhelper.hxx
index 514726ee1e0b..8cf1fc5cb89d 100644
--- a/include/sfx2/lokhelper.hxx
+++ b/include/sfx2/lokhelper.hxx
@@ -42,6 +42,8 @@ public:
static void notifyOtherView(SfxViewShell* pThisView, SfxViewShell const* pOtherView, int nType, const OString& rKey, const OString& rPayload);
/// Emits a LOK_CALLBACK_DIALOG_INVALIDATE with 'invalidate' action
static void notifyDialogInvalidation(const OUString& rPayload);
+ /// 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.
static void notifyInvalidation(SfxViewShell const* pThisView, const OString& rPayload);
/// A special value to signify 'infinity'.
diff --git a/include/vcl/IDialogRenderable.hxx b/include/vcl/IDialogRenderable.hxx
index b2c0dee552cd..351839e46d02 100644
--- a/include/vcl/IDialogRenderable.hxx
+++ b/include/vcl/IDialogRenderable.hxx
@@ -33,6 +33,9 @@ public:
virtual void paintDialog(const DialogID& rDialogID, VirtualDevice &rDevice,
int& nOutputWidth, int& nOutputHeight) = 0;
+ virtual void paintActiveFloatingWindow(const DialogID& rDialogID, VirtualDevice &rDevice,
+ int& nOutputWidth, int& nOutputHeight) = 0;
+
virtual void postDialogKeyEvent(const DialogID& rDialogID, int nType,
int nCharCode, int nKeyCode) = 0;
@@ -41,6 +44,8 @@ public:
// Callbacks
virtual void notifyDialogInvalidation(const DialogID& rDialogID) = 0;
+
+ virtual void notifyDialogChild(const DialogID& rDialogID, const OUString& rAction, const Point& rPos) = 0;
};
} // namespace vcl
diff --git a/include/vcl/dialog.hxx b/include/vcl/dialog.hxx
index ef3bcd5e8099..5ab85be1842e 100644
--- a/include/vcl/dialog.hxx
+++ b/include/vcl/dialog.hxx
@@ -80,6 +80,9 @@ public:
SAL_DLLPRIVATE bool IsInClose() const { return mbInClose; }
virtual void doDeferredInit(WinBits nBits) override;
virtual void LogicInvalidate(const tools::Rectangle* pRectangle) override;
+ void InvalidateFloatingWindow(const Point& rPos);
+ void CloseFloatingWindow();
+ Size PaintActiveFloatingWindow(VirtualDevice& rDevice);
/// Necessary to register dialog renderable instance to emit LOK callbacks
void registerDialogRenderable(vcl::IDialogRenderable* pDialogRenderable);
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx b/libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx
index 077e2577f384..8a5ff9a56d37 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx
@@ -315,6 +315,7 @@ static void setupDocView(GtvApplicationWindow* window)
g_signal_connect(window->lokdocview, "password-required", G_CALLBACK(LOKDocViewSigHandlers::passwordRequired), nullptr);
g_signal_connect(window->lokdocview, "comment", G_CALLBACK(LOKDocViewSigHandlers::comment), nullptr);
g_signal_connect(window->lokdocview, "dialog-invalidate", G_CALLBACK(LOKDocViewSigHandlers::dialogInvalidate), nullptr);
+ g_signal_connect(window->lokdocview, "dialog-child", G_CALLBACK(LOKDocViewSigHandlers::dialogChild), nullptr);
g_signal_connect(window->lokdocview, "configure-event", G_CALLBACK(LOKDocViewSigHandlers::configureEvent), nullptr);
}
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
index bb8800e3d734..1bfb9d538ead 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
@@ -32,6 +32,7 @@ struct GtvLokDialogPrivate
{
LOKDocView* lokdocview;
GtkWidget* pDialogDrawingArea;
+ GtkWidget* pFloatingWin;
guint32 m_nLastButtonPressTime;
guint32 m_nLastButtonReleaseTime;
@@ -79,6 +80,8 @@ 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");
int nWidth = 1024;
int nHeight = 768;
cairo_surface_t* pSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, nWidth, nHeight);
@@ -324,6 +327,7 @@ gtv_lok_dialog_init(GtvLokDialog* dialog)
GtkWidget* pContentArea = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
priv->pDialogDrawingArea = gtk_drawing_area_new();
+ priv->pFloatingWin = nullptr;
priv->m_nLastButtonPressTime = 0;
priv->m_nLastButtonReleaseTime = 0;
@@ -421,14 +425,75 @@ gtv_lok_dialog_class_init(GtvLokDialogClass* klass)
g_object_class_install_properties (G_OBJECT_CLASS(klass), PROP_LAST, properties);
}
+static void
+gtv_lok_dialog_floating_win_draw(GtkWidget* pDrawingArea, cairo_t* pCairo, gpointer userdata)
+{
+ GtvLokDialog* pDialog = GTV_LOK_DIALOG(userdata);
+ GtvLokDialogPrivate* priv = getPrivate(pDialog);
+
+ g_info("gtv_lok_dialog_floating_win_draw triggered");
+ int nWidth = 800;
+ int nHeight = 600;
+ 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));
+ pDocument->pClass->paintActiveFloatingWindow(pDocument, priv->dialogid, pBuffer, &nWidth, &nHeight);
+ g_info("Size of floating window: %d x %d", nWidth, nHeight);
+
+ gtk_widget_set_size_request(GTK_WIDGET(pDrawingArea), nWidth, nHeight);
+ gtk_widget_set_size_request(GTK_WIDGET(pDialog), nWidth, nHeight);
+ gtk_window_resize(GTK_WINDOW(pDialog), nWidth, nHeight);
+
+ cairo_surface_flush(pSurface);
+ cairo_surface_mark_dirty(pSurface);
+
+ cairo_set_source_surface(pCairo, pSurface, 0, 0);
+ cairo_paint(pCairo);
+}
+
void
gtv_lok_dialog_invalidate(GtvLokDialog* dialog)
{
- // trigger a draw on the drawing area
GtvLokDialogPrivate* priv = getPrivate(dialog);
+
+ // trigger a draw on the dialog drawing area
gtk_widget_queue_draw(priv->pDialogDrawingArea);
}
+void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog)
+{
+ g_info("Dialog's floating window invalidate");
+
+ GtvLokDialogPrivate* priv = getPrivate(dialog);
+ // remove any existing floating windows, for now
+ if (priv->pFloatingWin)
+ gtk_widget_destroy(priv->pFloatingWin);
+
+ priv->pFloatingWin = gtk_window_new(GTK_WINDOW_POPUP);
+ GtkWidget* pDrawingArea = gtk_drawing_area_new();
+ gtk_container_add(GTK_CONTAINER(priv->pFloatingWin), pDrawingArea);
+
+ gtk_window_set_transient_for(GTK_WINDOW(priv->pFloatingWin), GTK_WINDOW(dialog));
+ gtk_window_set_position(GTK_WINDOW(priv->pFloatingWin), GTK_WIN_POS_MOUSE);
+ gtk_window_set_destroy_with_parent(GTK_WINDOW(priv->pFloatingWin), true);
+
+ g_signal_connect(G_OBJECT(pDrawingArea), "draw", G_CALLBACK(gtv_lok_dialog_floating_win_draw), dialog);
+
+ gtk_widget_set_size_request(priv->pFloatingWin, 1, 1);
+ gtk_widget_show_all(priv->pFloatingWin);
+ gtk_window_present(GTK_WINDOW(priv->pFloatingWin));
+}
+
+void gtv_lok_dialog_child_close(GtvLokDialog* dialog)
+{
+ g_info("Dialog's floating window close");
+
+ GtvLokDialogPrivate* priv = getPrivate(dialog);
+ if (priv->pFloatingWin)
+ gtk_widget_destroy(priv->pFloatingWin);
+}
+
+
GtkWidget*
gtv_lok_dialog_new(LOKDocView* pDocView, const gchar* dialogId)
{
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.hxx b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.hxx
index 0205f2ede3f4..bce9edbadba1 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.hxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.hxx
@@ -39,6 +39,10 @@ GtkWidget* gtv_lok_dialog_new(LOKDocView* pDocView, const gchar* dialogId);
void gtv_lok_dialog_invalidate(GtvLokDialog* dialog);
+void gtv_lok_dialog_child_invalidate(GtvLokDialog* dialog);
+
+void gtv_lok_dialog_child_close(GtvLokDialog* dialog);
+
G_END_DECLS
#endif /* GTV_LOK_DIALOG_H */
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
index 8f86ecd43ca7..8896566499c1 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx
@@ -281,7 +281,7 @@ void LOKDocViewSigHandlers::comment(LOKDocView* pDocView, gchar* pComment, gpoin
}
}
-void LOKDocViewSigHandlers::dialogInvalidate(LOKDocView* pDocView, gchar* /*pDialogId*/, gpointer)
+void LOKDocViewSigHandlers::dialogInvalidate(LOKDocView* pDocView, gchar* pPayload, gpointer)
{
GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(pDocView)));
// GtkWindow* pDialog = gtv_application_window_get_child_window_by_id(window, pDialogId);
@@ -300,6 +300,28 @@ void LOKDocViewSigHandlers::dialogInvalidate(LOKDocView* pDocView, gchar* /*pDia
*/
}
+void LOKDocViewSigHandlers::dialogChild(LOKDocView* pDocView, gchar* pPayload, gpointer)
+{
+ GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(pDocView)));
+
+ 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");
+
+ // temporary hack to invalidate/close floating window of all opened dialogs
+ GList* pChildWins = gtv_application_window_get_all_child_windows(window);
+ GList* pIt = nullptr;
+ for (pIt = pChildWins; pIt != nullptr; pIt = pIt->next)
+ {
+ if (aAction == "invalidate")
+ gtv_lok_dialog_child_invalidate(GTV_LOK_DIALOG(pIt->data));
+ else if (aAction == "close")
+ gtv_lok_dialog_child_close(GTV_LOK_DIALOG(pIt->data));
+ }
+}
+
gboolean LOKDocViewSigHandlers::configureEvent(GtkWidget* pWidget, GdkEventConfigure* /*pEvent*/, gpointer /*pData*/)
{
GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(pWidget)));
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx
index 73bf9c2860ad..a455c3f1fc4c 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx
@@ -26,6 +26,7 @@ namespace LOKDocViewSigHandlers {
void passwordRequired(LOKDocView* pDocView, char* pUrl, gboolean bModify, gpointer);
void comment(LOKDocView* pDocView, gchar* pComment, gpointer);
void dialogInvalidate(LOKDocView* pDocView, gchar* pDialogId, gpointer);
+ void dialogChild(LOKDocView* pDocView, gchar* pPayload, gpointer);
gboolean configureEvent(GtkWidget* pWidget, GdkEventConfigure* pEvent, gpointer pData);
}
diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index b5fc11d82d9e..1bdb80c754ed 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -280,6 +280,7 @@ enum
COMMENT,
RULER,
DIALOG_INVALIDATE,
+ DIALOG_CHILD,
LAST_SIGNAL
};
@@ -439,6 +440,8 @@ callbackTypeToString (int nType)
return "LOK_CALLBACK_RULER_UPDATE";
case LOK_CALLBACK_DIALOG_INVALIDATE:
return "LOK_CALLBACK_DIALOG_INVALIDATE";
+ case LOK_CALLBACK_DIALOG_CHILD:
+ return "LOK_CALLBACK_DIALOG_CHILD";
}
g_assert(false);
return nullptr;
@@ -1414,6 +1417,9 @@ callback (gpointer pData)
case LOK_CALLBACK_DIALOG_INVALIDATE:
g_signal_emit(pCallback->m_pDocView, doc_view_signals[DIALOG_INVALIDATE], 0, pCallback->m_aPayload.c_str());
break;
+ case LOK_CALLBACK_DIALOG_CHILD:
+ g_signal_emit(pCallback->m_pDocView, doc_view_signals[DIALOG_CHILD], 0, pCallback->m_aPayload.c_str());
+ break;
default:
g_assert(false);
break;
@@ -3225,6 +3231,37 @@ static void lok_doc_view_class_init (LOKDocViewClass* pClass)
g_cclosure_marshal_generic,
G_TYPE_NONE, 1,
G_TYPE_STRING);
+
+ /**
+ * LOKDocView::dialog-child:
+ * @pDocView: the #LOKDocView on which the signal is emitted
+ * @pPayload: JSON described below:
+ *
+ * Invalidation corresponding to dialog's children.
+ * Eg: Floating window etc.
+ *
+ * Payload example:
+ * {
+ * "dialogID": "SpellDialog",
+ * "action": "close"
+ * }
+ *
+ * - dialogID is the UNO command of the dialog
+ * - action can be
+ * - close, means dialog child window is closed now
+ * - invalidate, means dialog child window is invalidated
+ * It also means that dialog child window is created if it's the first
+ * invalidate
+ */
+ doc_view_signals[DIALOG_CHILD] =
+ g_signal_new("dialog-child",
+ G_TYPE_FROM_CLASS(pGObjectClass),
+ G_SIGNAL_RUN_FIRST,
+ 0,
+ nullptr, nullptr,
+ g_cclosure_marshal_generic,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
}
SAL_DLLPUBLIC_EXPORT GtkWidget*
diff --git a/sfx2/source/view/lokhelper.cxx b/sfx2/source/view/lokhelper.cxx
index d63d0ad2fb4f..85b1815c57a8 100644
--- a/sfx2/source/view/lokhelper.cxx
+++ b/sfx2/source/view/lokhelper.cxx
@@ -157,6 +157,24 @@ void SfxLokHelper::notifyDialogInvalidation(const OUString& rDialogID)
}
}
+void SfxLokHelper::notifyDialogChild(const OUString& rDialogID, const OUString& rAction, const Point& rPos)
+{
+ if (SfxLokHelper::getViewsCount() <= 0)
+ 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("\", \"position\": \"") + OString::number(rPos.getX()) + OString(", ") + OString::number(rPos.getY()) +
+ + "\" }";
+
+ while (pViewShell)
+ {
+ pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_DIALOG_CHILD, aPayload.getStr());
+ pViewShell = SfxViewShell::GetNext(*pViewShell);
+ }
+}
+
void SfxLokHelper::notifyInvalidation(SfxViewShell const* pThisView, const OString& rPayload)
{
OStringBuffer aBuf;
diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx
index e93173451b3c..3d269dcadc03 100644
--- a/sw/inc/unotxdoc.hxx
+++ b/sw/inc/unotxdoc.hxx
@@ -432,6 +432,7 @@ public:
OUString getPostIts() override;
void paintDialog(const vcl::DialogID& rDialogID, VirtualDevice& rDevice, int& nWidth, int& nHeight) override;
+ void paintActiveFloatingWindow(const vcl::DialogID& rDialogID, VirtualDevice& rDevice, int& nWidth, int& nHeight) override;
void postDialogKeyEvent(const vcl::DialogID& rDialogID, int nType,
int nCharCode, int nKeyCode) override;
@@ -440,6 +441,8 @@ public:
void notifyDialogInvalidation(const vcl::DialogID& rDialogID) override;
+ void notifyDialogChild(const vcl::DialogID& rDialogID, const OUString& rAction, const Point& rPos) override;
+
// css::tiledrendering::XTiledRenderable
virtual void SAL_CALL paintTile( const ::css::uno::Any& Parent, ::sal_Int32 nOutputWidth, ::sal_Int32 nOutputHeight, ::sal_Int32 nTilePosX, ::sal_Int32 nTilePosY, ::sal_Int32 nTileWidth, ::sal_Int32 nTileHeight ) override;
diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx
index fbb5bf808957..9ab338fce7a0 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -3748,6 +3748,32 @@ void SwXTextDocument::notifyDialogInvalidation(const vcl::DialogID& rDialogID)
SfxLokHelper::notifyDialogInvalidation(rDialogID);
}
+void SwXTextDocument::notifyDialogChild(const vcl::DialogID& rDialogID, const OUString& rAction, const Point& rPos)
+{
+ SfxLokHelper::notifyDialogChild(rDialogID, rAction, rPos);
+}
+
+void SwXTextDocument::paintActiveFloatingWindow(const vcl::DialogID& rDialogID, VirtualDevice& rDevice, int& nWidth, int& nHeight)
+{
+ SfxViewFrame* pViewFrame = pDocShell->GetView()->GetViewFrame();
+ SfxSlotPool* pSlotPool = SW_MOD()->GetSlotPool();
+ const SfxSlot* pSlot = pSlotPool->GetUnoSlot(rDialogID);
+ if (!pSlot)
+ {
+ SAL_WARN("lok.dialog", "No slot found for " << rDialogID);
+ return;
+ }
+ SfxChildWindow* pChild = pViewFrame->GetChildWindow(pSlot->GetSlotId());
+ if (!pChild)
+ return;
+
+ Dialog* pDlg = static_cast<Dialog*>(pChild->GetWindow());
+ // register the instance so that vcl::Dialog can emit LOK callbacks
+ const Size aSize = pDlg->PaintActiveFloatingWindow(rDevice);
+ nWidth = aSize.getWidth();
+ nHeight = aSize.getHeight();
+}
+
void * SAL_CALL SwXTextDocument::operator new( size_t t) throw()
{
return SwXTextDocumentBaseClass::operator new(t);
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index e5d784e4f667..29400ca55982 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -883,10 +883,49 @@ void Dialog::paintDialog(VirtualDevice& rDevice)
PaintToDevice(&rDevice, Point(0, 0), Size());
}
-void Dialog::LogicInvalidate(const tools::Rectangle* /*pRectangle*/)
+Size Dialog::PaintActiveFloatingWindow(VirtualDevice& rDevice)
+{
+ Size aRet;
+ ImplSVData* pSVData = ImplGetSVData();
+ FloatingWindow* pFirstFloat = pSVData->maWinData.mpFirstFloat;
+ if (pFirstFloat)
+ {
+ // TODO:: run a while loop here and check all the active floating
+ // windows ( chained together, cf. pFirstFloat->mpNextFloat )
+ // For now just assume that the active floating window is the one we
+ // want to render
+ if (pFirstFloat->GetParentDialog() == this)
+ {
+ pFirstFloat->PaintToDevice(&rDevice, Point(0, 0), Size());
+ aRet = ::isLayoutEnabled(pFirstFloat) ? pFirstFloat->get_preferred_size() : pFirstFloat->GetSizePixel();
+ }
+
+ pFirstFloat = nullptr;
+ }
+
+ return aRet;
+}
+
+void Dialog::InvalidateFloatingWindow(const Point& rPos)
{
if (comphelper::LibreOfficeKit::isActive() && mpDialogRenderable && !maID.isEmpty())
{
+ mpDialogRenderable->notifyDialogChild(maID, "invalidate", rPos);
+ }
+}
+
+void Dialog::CloseFloatingWindow()
+{
+ if (comphelper::LibreOfficeKit::isActive() && mpDialogRenderable && !maID.isEmpty())
+ {
+ mpDialogRenderable->notifyDialogChild(maID, "close", Point(0, 0));
+ }
+}
+
+void Dialog::LogicInvalidate(const tools::Rectangle* /*pRectangle*/)
+{
+ if (!comphelper::LibreOfficeKit::isDialogPainting() && mpDialogRenderable && !maID.isEmpty())
+ {
mpDialogRenderable->notifyDialogInvalidation(maID);
}
}
diff --git a/vcl/source/window/floatwin.cxx b/vcl/source/window/floatwin.cxx
index 23e56ce6e669..16bcb721a612 100644
--- a/vcl/source/window/floatwin.cxx
+++ b/vcl/source/window/floatwin.cxx
@@ -38,6 +38,7 @@ public:
VclPtr<ToolBox> mpBox;
tools::Rectangle maItemEdgeClipRect; // used to clip the common edge between a toolbar item and the border of this window
+ Point maPos; // position of the floating window wrt. parent
};
FloatingWindow::ImplData::ImplData()
@@ -592,6 +593,15 @@ void FloatingWindow::StateChanged( StateChangedType nType )
}
SystemWindow::StateChanged( nType );
+ Dialog* pParentDlg = GetParentDialog();
+ if (pParentDlg && nType == StateChangedType::InitShow && IsVisible())
+ {
+ pParentDlg->InvalidateFloatingWindow(mpImplData->maPos);
+ }
+ else if (pParentDlg && !IsVisible())
+ {
+ pParentDlg->CloseFloatingWindow();
+ }
if ( nType == StateChangedType::ControlBackground )
{
@@ -667,8 +677,8 @@ void FloatingWindow::StartPopupMode( const tools::Rectangle& rRect, FloatWinPopu
// compute window position according to flags and arrangement
sal_uInt16 nArrangeIndex;
- Point aPos = ImplCalcPos( this, rRect, nFlags, nArrangeIndex );
- SetPosPixel( aPos );
+ mpImplData->maPos = ImplCalcPos( this, rRect, nFlags, nArrangeIndex );
+ SetPosPixel( mpImplData->maPos );
// set data and display window
// convert maFloatRect to absolute device coordinates
@@ -714,10 +724,10 @@ void FloatingWindow::StartPopupMode( ToolBox* pBox, FloatWinPopupFlags nFlags )
// retrieve some data from the ToolBox
tools::Rectangle aRect = nItemId ? pBox->GetItemRect( nItemId ) : pBox->GetOverflowRect();
- Point aPos;
+
// convert to parent's screen coordinates
- aPos = GetParent()->OutputToScreenPixel( GetParent()->AbsoluteScreenToOutputPixel( pBox->OutputToAbsoluteScreenPixel( aRect.TopLeft() ) ) );
- aRect.SetPos( aPos );
+ mpImplData->maPos = GetParent()->OutputToScreenPixel( GetParent()->AbsoluteScreenToOutputPixel( pBox->OutputToAbsoluteScreenPixel( aRect.TopLeft() ) ) );
+ aRect.SetPos( mpImplData->maPos );
nFlags |=
FloatWinPopupFlags::AllMouseButtonClose |
commit 44737be728c1d1afa23631e7576569ddf2d3016c
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Thu Aug 3 14:42:21 2017 +0530
lokdialog: Register IDIalogRenderable with vcl::Dialog
Change-Id: I344f5a9c7167abfde15dcd21c747819cc79b12b1
diff --git a/include/sfx2/basedlgs.hxx b/include/sfx2/basedlgs.hxx
index 7609229db2a6..cb403c78a075 100644
--- a/include/sfx2/basedlgs.hxx
+++ b/include/sfx2/basedlgs.hxx
@@ -105,8 +105,6 @@ public:
SfxBindings& GetBindings()
{ return *pBindings; }
- virtual void LogicInvalidate(const tools::Rectangle* pRectangle) override;
-
DECL_LINK(TimerHdl, Timer *, void);
};
diff --git a/include/vcl/IDialogRenderable.hxx b/include/vcl/IDialogRenderable.hxx
index cf9d41e54cde..b2c0dee552cd 100644
--- a/include/vcl/IDialogRenderable.hxx
+++ b/include/vcl/IDialogRenderable.hxx
@@ -38,6 +38,9 @@ public:
virtual void postDialogMouseEvent(const DialogID& rDialogID, int nType, int nX, int nY,
int nCount, int nButtons, int nModifier) = 0;
+
+ // Callbacks
+ virtual void notifyDialogInvalidation(const DialogID& rDialogID) = 0;
};
} // namespace vcl
diff --git a/include/vcl/dialog.hxx b/include/vcl/dialog.hxx
index 93f2080c8352..ef3bcd5e8099 100644
--- a/include/vcl/dialog.hxx
+++ b/include/vcl/dialog.hxx
@@ -25,7 +25,7 @@
#include <vcl/dllapi.h>
#include <vcl/syswin.hxx>
#include <vcl/vclptr.hxx>
-
+#include <vcl/IDialogRenderable.hxx>
struct DialogImpl;
class VclBox;
@@ -59,6 +59,8 @@ private:
VclPtr<VclButtonBox> mpActionArea;
VclPtr<VclBox> mpContentArea;
+ vcl::IDialogRenderable* mpDialogRenderable; // to emit LOK callbacks
+
SAL_DLLPRIVATE void ImplInitDialogData();
SAL_DLLPRIVATE void ImplInitSettings();
@@ -77,7 +79,10 @@ protected:
public:
SAL_DLLPRIVATE bool IsInClose() const { return mbInClose; }
virtual void doDeferredInit(WinBits nBits) override;
- virtual void LogicInvalidate(const tools::Rectangle* pRectangle) override { (void)pRectangle; }
+ virtual void LogicInvalidate(const tools::Rectangle* pRectangle) override;
+
+ /// Necessary to register dialog renderable instance to emit LOK callbacks
+ void registerDialogRenderable(vcl::IDialogRenderable* pDialogRenderable);
/// Paints the current dialog to the given virtual device
void paintDialog(VirtualDevice& rDevice);
void LogicMouseButtonDown(const MouseEvent& rMouseEvent);
diff --git a/sfx2/source/dialog/basedlgs.cxx b/sfx2/source/dialog/basedlgs.cxx
index 0d2d90d142de..bfc0ac45a39b 100644
--- a/sfx2/source/dialog/basedlgs.cxx
+++ b/sfx2/source/dialog/basedlgs.cxx
@@ -393,14 +393,6 @@ void SfxModelessDialog::FillInfo(SfxChildWinInfo& rInfo) const
rInfo.nFlags |= SfxChildWindowFlags::ZOOMIN;
}
-
-void SfxModelessDialog::LogicInvalidate(const tools::Rectangle* /*pRectangle*/)
-{
- if (!comphelper::LibreOfficeKit::isDialogPainting())
- SfxLokHelper::notifyDialogInvalidation(maID);
-}
-
-
bool SfxFloatingWindow::EventNotify( NotifyEvent& rEvt )
/* [Description]
diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx
index 3df958033c5e..e93173451b3c 100644
--- a/sw/inc/unotxdoc.hxx
+++ b/sw/inc/unotxdoc.hxx
@@ -438,6 +438,8 @@ public:
void postDialogMouseEvent(const vcl::DialogID& rDialogID, int nType, int nX, int nY,
int nCount, int nButtons, int nModifier) override;
+ void notifyDialogInvalidation(const vcl::DialogID& rDialogID) override;
+
// css::tiledrendering::XTiledRenderable
virtual void SAL_CALL paintTile( const ::css::uno::Any& Parent, ::sal_Int32 nOutputWidth, ::sal_Int32 nOutputHeight, ::sal_Int32 nTilePosX, ::sal_Int32 nTilePosY, ::sal_Int32 nTileWidth, ::sal_Int32 nTileHeight ) override;
diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx
index 8d2184a3bfa2..fbb5bf808957 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -31,6 +31,7 @@
#include <vcl/svapp.hxx>
#include <vcl/print.hxx>
#include <sfx2/viewfrm.hxx>
+#include <sfx2/lokhelper.hxx>
#include <sfx2/sfxbasecontroller.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/msg.hxx>
@@ -3661,6 +3662,8 @@ void SwXTextDocument::paintDialog(const vcl::DialogID& rDialogID, VirtualDevice&
}
Dialog* pDlg = static_cast<Dialog*>(pChild->GetWindow());
+ // register the instance so that vcl::Dialog can emit LOK callbacks
+ pDlg->registerDialogRenderable(this);
pDlg->paintDialog(rDevice);
const Size aSize = pDlg->GetOptimalSize();
nWidth = aSize.getWidth();
@@ -3740,6 +3743,11 @@ void SwXTextDocument::postDialogMouseEvent(const vcl::DialogID& rDialogID, int n
}
}
+void SwXTextDocument::notifyDialogInvalidation(const vcl::DialogID& rDialogID)
+{
+ SfxLokHelper::notifyDialogInvalidation(rDialogID);
+}
+
void * SAL_CALL SwXTextDocument::operator new( size_t t) throw()
{
return SwXTextDocumentBaseClass::operator new(t);
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index 3ca7fff70211..e5d784e4f667 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -348,6 +348,7 @@ struct DialogImpl
void Dialog::ImplInitDialogData()
{
+ mpDialogRenderable = nullptr;
mpWindowImpl->mbDialog = true;
mpPrevExecuteDlg = nullptr;
mbInExecute = false;
@@ -863,6 +864,14 @@ bool Dialog::selectPageByUIXMLDescription(const OString& /*rUIXMLDescription*/)
return true;
}
+void Dialog::registerDialogRenderable(vcl::IDialogRenderable* pDialogRenderable)
+{
+ if (pDialogRenderable && !mpDialogRenderable)
+ {
+ mpDialogRenderable = pDialogRenderable;
+ }
+}
+
void Dialog::paintDialog(VirtualDevice& rDevice)
{
setDeferredProperties();
@@ -874,6 +883,14 @@ void Dialog::paintDialog(VirtualDevice& rDevice)
PaintToDevice(&rDevice, Point(0, 0), Size());
}
+void Dialog::LogicInvalidate(const tools::Rectangle* /*pRectangle*/)
+{
+ if (comphelper::LibreOfficeKit::isActive() && mpDialogRenderable && !maID.isEmpty())
+ {
+ mpDialogRenderable->notifyDialogInvalidation(maID);
+ }
+}
+
void Dialog::LogicMouseButtonDown(const MouseEvent& rMouseEvent)
{
// When we're not doing tiled rendering, then positions must be passed as pixels.
commit d43ffd307a21af234576e8efc99f306b110765b1
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Sun Jul 30 06:06:56 2017 +0530
lokdialog: Handle key events in core
Change-Id: If84aaac87beebf69d92db5446fc713d8cc20421e
diff --git a/include/vcl/dialog.hxx b/include/vcl/dialog.hxx
index a38a6ebc6c6a..93f2080c8352 100644
--- a/include/vcl/dialog.hxx
+++ b/include/vcl/dialog.hxx
@@ -84,6 +84,9 @@ public:
void LogicMouseButtonUp(const MouseEvent& rMouseEvent);
void LogicMouseMove(const MouseEvent& rMouseEvent);
+ void LOKKeyInput(const KeyEvent& rKeyEvent);
+ void LOKKeyUp(const KeyEvent& rKeyEvent);
+
protected:
explicit Dialog( WindowType nType );
explicit Dialog( vcl::Window* pParent, const OUString& rID, const OUString& rUIXMLDescription, WindowType nType, InitFlag eFlag = InitFlag::Default );
diff --git a/sw/source/uibase/uno/unotxdoc.cxx b/sw/source/uibase/uno/unotxdoc.cxx
index 782d5f7f952c..8d2184a3bfa2 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -3667,9 +3667,38 @@ void SwXTextDocument::paintDialog(const vcl::DialogID& rDialogID, VirtualDevice&
nHeight = aSize.getHeight();
}
-void SwXTextDocument::postDialogKeyEvent(const vcl::DialogID& /*rDialogID*/, int /*nType*/, int /*nCharCode*/, int /*nKeyCode*/)
+void SwXTextDocument::postDialogKeyEvent(const vcl::DialogID& rDialogID, int nType, int nCharCode, int nKeyCode)
{
+ SolarMutexGuard aGuard;
+
+ // check if dialog is already open
+ SfxViewFrame* pViewFrame = pDocShell->GetView()->GetViewFrame();
+ SfxSlotPool* pSlotPool = SW_MOD()->GetSlotPool();
+ const SfxSlot* pSlot = pSlotPool->GetUnoSlot(rDialogID);
+ if (!pSlot)
+ {
+ SAL_WARN("lok.dialog", "No slot found for " << rDialogID);
+ return;
+ }
+ SfxChildWindow* pChild = pViewFrame->GetChildWindow(pSlot->GetSlotId());
+ if (pChild)
+ {
+ Dialog* pDialog = static_cast<Dialog*>(pChild->GetWindow());
+ KeyEvent aEvent(nCharCode, nKeyCode, 0);
+ switch (nType)
+ {
+ case LOK_KEYEVENT_KEYINPUT:
+ pDialog->LOKKeyInput(aEvent);
+ break;
+ case LOK_KEYEVENT_KEYUP:
+ pDialog->LOKKeyUp(aEvent);
+ break;
+ default:
+ assert(false);
+ break;
+ }
+ }
}
void SwXTextDocument::postDialogMouseEvent(const vcl::DialogID& rDialogID, int nType, int nX, int nY,
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index 375af4418abc..3ca7fff70211 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -898,6 +898,20 @@ void Dialog::LogicMouseMove(const MouseEvent& rMouseEvent)
ImplWindowFrameProc(this, SalEvent::ExternalMouseMove, &rMouseEvent);
}
+void Dialog::LOKKeyInput(const KeyEvent& rKeyEvent)
+{
+ assert(comphelper::LibreOfficeKit::isActive());
+
+ ImplWindowFrameProc(this, SalEvent::ExternalKeyInput, &rKeyEvent);
+}
+
+void Dialog::LOKKeyUp(const KeyEvent& rKeyEvent)
+{
+ assert(comphelper::LibreOfficeKit::isActive());
+
+ ImplWindowFrameProc(this, SalEvent::ExternalKeyUp, &rKeyEvent);
+}
+
void Dialog::ensureRepaint()
{
// ensure repaint
commit 522a9c0a4164caf82b17e9808636577ebe75bf67
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Sun Jul 30 05:18:33 2017 +0530
lokdialog: gtv: Forward key events on dialog to core
Change-Id: Icfc210b08c7f1d8ebaf9c731ed64bb128cfc4356
diff --git a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
index 7a9fa7712900..bb8800e3d734 100644
--- a/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx
@@ -8,9 +8,11 @@
*/
#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
#include <cmath>
#include <iostream>
+#include <sstream>
#include <LibreOfficeKit/LibreOfficeKitGtk.h>
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
@@ -136,7 +138,7 @@ gtv_lok_dialog_signal_button(GtkWidget* pDialogDrawingArea, GdkEventButton* pEve
(pEvent->y),
nCount,
nEventButton,
- 0/* Modifier */);
+ priv->m_nKeyModifier);
break;
}
@@ -167,7 +169,7 @@ gtv_lok_dialog_signal_button(GtkWidget* pDialogDrawingArea, GdkEventButton* pEve
(pEvent->y),
nCount,
nEventButton,
- 0/* Modifier */);
+ priv->m_nKeyModifier);
break;
}
default:
@@ -198,7 +200,119 @@ gtv_lok_dialog_signal_motion(GtkWidget* pDialogDrawingArea, GdkEventButton* pEve
(pEvent->y),
1,
priv->m_nLastButtonPressed,
- 0/* Modifier */);
+ priv->m_nKeyModifier);
+
+ return FALSE;
+}
+
+static gboolean
+gtv_lok_dialog_signal_key(GtkWidget* pDialogDrawingArea, GdkEventKey* pEvent)
+{
+ GtvLokDialog* pDialog = GTV_LOK_DIALOG(gtk_widget_get_toplevel(pDialogDrawingArea));
+ GtvLokDialogPrivate* priv = getPrivate(pDialog);
+ GtvApplicationWindow* window = GTV_APPLICATION_WINDOW(gtk_window_get_transient_for(GTK_WINDOW(pDialog)));
+ LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(LOK_DOC_VIEW(window->lokdocview));
+
+ int nCharCode = 0;
+ int nKeyCode = 0;
+ priv->m_nKeyModifier &= KEY_MOD2;
+ switch (pEvent->keyval)
+ {
+ case GDK_KEY_BackSpace:
+ nKeyCode = com::sun::star::awt::Key::BACKSPACE;
+ break;
+ case GDK_KEY_Delete:
+ nKeyCode = com::sun::star::awt::Key::DELETE;
+ break;
+ case GDK_KEY_Return:
+ case GDK_KEY_KP_Enter:
+ nKeyCode = com::sun::star::awt::Key::RETURN;
+ break;
+ case GDK_KEY_Escape:
+ nKeyCode = com::sun::star::awt::Key::ESCAPE;
+ break;
+ case GDK_KEY_Tab:
+ nKeyCode = com::sun::star::awt::Key::TAB;
+ break;
+ case GDK_KEY_Down:
+ nKeyCode = com::sun::star::awt::Key::DOWN;
+ break;
+ case GDK_KEY_Up:
+ nKeyCode = com::sun::star::awt::Key::UP;
+ break;
+ case GDK_KEY_Left:
+ nKeyCode = com::sun::star::awt::Key::LEFT;
+ break;
+ case GDK_KEY_Right:
+ nKeyCode = com::sun::star::awt::Key::RIGHT;
+ break;
+ case GDK_KEY_Page_Down:
+ nKeyCode = com::sun::star::awt::Key::PAGEDOWN;
+ break;
+ case GDK_KEY_Page_Up:
+ nKeyCode = com::sun::star::awt::Key::PAGEUP;
+ break;
+ case GDK_KEY_Insert:
+ nKeyCode = com::sun::star::awt::Key::INSERT;
+ break;
+ case GDK_KEY_Shift_L:
+ case GDK_KEY_Shift_R:
+ if (pEvent->type == GDK_KEY_PRESS)
+ priv->m_nKeyModifier |= KEY_SHIFT;
+ break;
+ case GDK_KEY_Control_L:
+ case GDK_KEY_Control_R:
+ if (pEvent->type == GDK_KEY_PRESS)
+ priv->m_nKeyModifier |= KEY_MOD1;
+ break;
+ case GDK_KEY_Alt_L:
+ case GDK_KEY_Alt_R:
+ if (pEvent->type == GDK_KEY_PRESS)
+ priv->m_nKeyModifier |= KEY_MOD2;
+ else
+ priv->m_nKeyModifier &= ~KEY_MOD2;
+ break;
+ default:
+ if (pEvent->keyval >= GDK_KEY_F1 && pEvent->keyval <= GDK_KEY_F26)
+ nKeyCode = com::sun::star::awt::Key::F1 + (pEvent->keyval - GDK_KEY_F1);
+ else
+ nCharCode = gdk_keyval_to_unicode(pEvent->keyval);
+ }
+
+ // rsc is not public API, but should be good enough for debugging purposes.
+ // If this is needed for real, then probably a new param of type
+ // css::awt::KeyModifier is needed in postKeyEvent().
+ if (pEvent->state & GDK_SHIFT_MASK)
+ nKeyCode |= KEY_SHIFT;
+
+ if (pEvent->state & GDK_CONTROL_MASK)
+ nKeyCode |= KEY_MOD1;
+
+ if (priv->m_nKeyModifier & KEY_MOD2)
+ nKeyCode |= KEY_MOD2;
+
+ if (nKeyCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2)) {
+ if (pEvent->keyval >= GDK_KEY_a && pEvent->keyval <= GDK_KEY_z)
+ {
+ nKeyCode |= 512 + (pEvent->keyval - GDK_KEY_a);
+ }
+ else if (pEvent->keyval >= GDK_KEY_A && pEvent->keyval <= GDK_KEY_Z) {
+ nKeyCode |= 512 + (pEvent->keyval - GDK_KEY_A);
+ }
+ else if (pEvent->keyval >= GDK_KEY_0 && pEvent->keyval <= GDK_KEY_9) {
+ nKeyCode |= 256 + (pEvent->keyval - GDK_KEY_0);
+ }
+ }
+
+ std::stringstream ss;
+ ss << "gtv_lok_dialog::postKey(" << pEvent->type << ", " << nCharCode << ", " << nKeyCode << ")";
+ g_info("%s", ss.str().c_str());
+
+ pDocument->pClass->postDialogKeyEvent(pDocument,
+ priv->dialogid,
+ pEvent->type == GDK_KEY_RELEASE ? LOK_KEYEVENT_KEYUP : LOK_KEYEVENT_KEYINPUT,
+ nCharCode,
+ nKeyCode);
return FALSE;
}
@@ -219,12 +333,16 @@ gtv_lok_dialog_init(GtvLokDialog* dialog)
gtk_widget_add_events(GTK_WIDGET(priv->pDialogDrawingArea),
GDK_BUTTON_PRESS_MASK
|GDK_BUTTON_RELEASE_MASK
- |GDK_BUTTON_MOTION_MASK);
+ |GDK_BUTTON_MOTION_MASK
+ |GDK_KEY_PRESS_MASK
+ |GDK_KEY_RELEASE_MASK);
g_signal_connect(G_OBJECT(priv->pDialogDrawingArea), "draw", G_CALLBACK(gtv_lok_dialog_draw), nullptr);
g_signal_connect(G_OBJECT(priv->pDialogDrawingArea), "button-press-event", G_CALLBACK(gtv_lok_dialog_signal_button), nullptr);
g_signal_connect(G_OBJECT(priv->pDialogDrawingArea), "button-release-event", G_CALLBACK(gtv_lok_dialog_signal_button), nullptr);
g_signal_connect(G_OBJECT(priv->pDialogDrawingArea), "motion-notify-event", G_CALLBACK(gtv_lok_dialog_signal_motion), nullptr);
+ g_signal_connect(G_OBJECT(priv->pDialogDrawingArea), "key-press-event", G_CALLBACK(gtv_lok_dialog_signal_key), nullptr);
+ g_signal_connect(G_OBJECT(priv->pDialogDrawingArea), "key-release-event", G_CALLBACK(gtv_lok_dialog_signal_key), nullptr);
gtk_container_add(GTK_CONTAINER(pContentArea), priv->pDialogDrawingArea);
}
commit fb09d4aa2ec33cd933fdef449f20c52fcad9ddca
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Sun Jul 30 05:16:39 2017 +0530
lokdocview: Remove unnecessary code
Change-Id: I1d744c91f01eb098e9273d2459b63a5444558f39
diff --git a/libreofficekit/source/gtk/lokdocview.cxx b/libreofficekit/source/gtk/lokdocview.cxx
index 9dd83bf518f5..b5fc11d82d9e 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -815,38 +815,19 @@ signalKey (GtkWidget* pWidget, GdkEventKey* pEvent)
}
}
- if (pEvent->type == GDK_KEY_RELEASE)
- {
- GTask* task = g_task_new(pDocView, nullptr, nullptr, nullptr);
- LOEvent* pLOEvent = new LOEvent(LOK_POST_KEY);
- pLOEvent->m_nKeyEvent = LOK_KEYEVENT_KEYUP;
... etc. - the rest is truncated
More information about the Libreoffice-commits
mailing list