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 <pran...@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 <pran...@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 <pran...@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); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits