[Libreoffice-commits] core.git: Branch 'feature/lok_dialog' - 3 commits - desktop/source include/LibreOfficeKit include/sfx2 include/vcl libreofficekit/qa libreofficekit/source sfx2/source sw/inc sw/source vcl/source
Pranav Kant
pranavk at collabora.co.uk
Thu Aug 3 16:21:50 UTC 2017
desktop/source/lib/init.cxx | 21 +++
include/LibreOfficeKit/LibreOfficeKit.h | 2
include/LibreOfficeKit/LibreOfficeKitEnums.h | 20 ++
include/sfx2/basedlgs.hxx | 2
include/sfx2/lokhelper.hxx | 4
include/vcl/IDialogRenderable.hxx | 8 +
include/vcl/dialog.hxx | 12 +
libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx | 1
libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx | 67 +++++++++-
libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.hxx | 4
libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx | 24 +++
libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx | 1
libreofficekit/source/gtk/lokdocview.cxx | 37 +++++
sfx2/source/dialog/basedlgs.cxx | 8 -
sfx2/source/view/lokhelper.cxx | 18 ++
sw/inc/unotxdoc.hxx | 5
sw/source/uibase/uno/unotxdoc.cxx | 35 +++++
vcl/source/window/dialog.cxx | 58 ++++++++
vcl/source/window/floatwin.cxx | 22 ++-
19 files changed, 328 insertions(+), 21 deletions(-)
New commits:
commit 40aca344d280920d8d5e21270b732c5d15ce8e6a
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 20face8e65ae..e69627ba0e99 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -598,6 +598,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)
{
@@ -647,6 +649,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;
}
@@ -2976,6 +2979,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 ebb6587a373e..8781b1c78722 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/include/LibreOfficeKit/LibreOfficeKit.h
@@ -257,6 +257,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 3905cb26ce19..4744eb6a4084 100644
--- a/include/LibreOfficeKit/LibreOfficeKitEnums.h
+++ b/include/LibreOfficeKit/LibreOfficeKitEnums.h
@@ -508,8 +508,26 @@ typedef enum
/**
* Dialog invalidation
*/
- LOK_CALLBACK_DIALOG_INVALIDATE = 35
+ LOK_CALLBACK_DIALOG_INVALIDATE = 35,
+ /**
+ * 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 = 36
}
LibreOfficeKitCallbackType;
diff --git a/include/sfx2/lokhelper.hxx b/include/sfx2/lokhelper.hxx
index b37480df9da1..b57f30a0ccba 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
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* 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 e0e3bba35b27..126d358552c3 100644
--- a/include/vcl/dialog.hxx
+++ b/include/vcl/dialog.hxx
@@ -70,6 +70,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..d0778cef473d 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 d3bd91eced2a..1259b221e4e8 100644
--- a/libreofficekit/source/gtk/lokdocview.cxx
+++ b/libreofficekit/source/gtk/lokdocview.cxx
@@ -279,6 +279,7 @@ enum
PASSWORD_REQUIRED,
COMMENT,
DIALOG_INVALIDATE,
+ DIALOG_CHILD,
LAST_SIGNAL
};
@@ -436,6 +437,8 @@ callbackTypeToString (int nType)
return "LOK_CALLBACK_COMMENT";
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;
@@ -1409,6 +1412,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;
@@ -3210,6 +3216,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 46d736206ddf..c6e9d57027b2 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* pThisView, const OString& rPayload)
{
OStringBuffer aBuf;
diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx
index c1f575bbee86..5fc7d32c95a2 100644
--- a/sw/inc/unotxdoc.hxx
+++ b/sw/inc/unotxdoc.hxx
@@ -427,6 +427,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;
@@ -435,6 +436,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 c277ce3153dd..830e8acc9629 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -3662,6 +3662,33 @@ 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);
+ SAL_DEBUG("Size of the floating window : " << aSize);
+ 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 65bb09305752..a0e8aebb152e 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -873,10 +873,51 @@ 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)
{
+ SAL_DEBUG("Dialog:: Invalidate Floating window");
if (comphelper::LibreOfficeKit::isActive() && mpDialogRenderable && !maID.isEmpty())
{
+ mpDialogRenderable->notifyDialogChild(maID, "invalidate", rPos);
+ }
+}
+
+void Dialog::CloseFloatingWindow()
+{
+ SAL_DEBUG("Dialog:: close Floating window");
+ 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..44ce96c42843 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()
@@ -593,6 +594,17 @@ void FloatingWindow::StateChanged( StateChangedType nType )
SystemWindow::StateChanged( nType );
+ if (nType == StateChangedType::InitShow && IsVisible())
+ {
+ Dialog* pParentDlg = GetParentDialog();
+ pParentDlg->InvalidateFloatingWindow(mpImplData->maPos);
+ }
+ else if (!IsVisible())
+ {
+ Dialog* pParentDlg = GetParentDialog();
+ pParentDlg->CloseFloatingWindow();
+ }
+
if ( nType == StateChangedType::ControlBackground )
{
ImplInitSettings();
@@ -667,8 +679,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 +726,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 565fcf36297b0a633454b7f3ca8dc383c3f38e46
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 f0425a961cf3..e0e3bba35b27 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;
@@ -49,6 +49,8 @@ private:
VclPtr<VclButtonBox> mpActionArea;
VclPtr<VclBox> mpContentArea;
+ vcl::IDialogRenderable* mpDialogRenderable; // to emit LOK callbacks
+
SAL_DLLPRIVATE void ImplInitDialogData();
SAL_DLLPRIVATE void ImplInitSettings();
@@ -67,7 +69,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 d140c571ab62..8862b0795e92 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 330ead910606..c1f575bbee86 100644
--- a/sw/inc/unotxdoc.hxx
+++ b/sw/inc/unotxdoc.hxx
@@ -433,6 +433,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 3be26d0f28b6..c277ce3153dd 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>
@@ -3575,6 +3576,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();
@@ -3654,6 +3657,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 897bc8f74543..65bb09305752 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;
@@ -853,6 +854,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();
@@ -864,6 +873,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 867312490af7461e1892ecb1184d9c48d8e4a96a
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Wed Aug 2 18:01:45 2017 +0530
Fix a comment
Change-Id: Icbd16aebf3ddabd1b0ffd310f1aab3641d5c40b4
diff --git a/include/sfx2/lokhelper.hxx b/include/sfx2/lokhelper.hxx
index 65cd5964af97..b37480df9da1 100644
--- a/include/sfx2/lokhelper.hxx
+++ b/include/sfx2/lokhelper.hxx
@@ -40,7 +40,7 @@ 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_INVALIDATE_TILES, but tweaks it according to setOptionalFeatures() if needed.
+ /// Emits a LOK_CALLBACK_DIALOG_INVALIDATE
static void notifyDialogInvalidation(const OUString& rPayload);
/// Emits a LOK_CALLBACK_INVALIDATE_TILES, but tweaks it according to setOptionalFeatures() if needed.
static void notifyInvalidation(SfxViewShell* pThisView, const OString& rPayload);
More information about the Libreoffice-commits
mailing list