diff options
-rw-r--r-- | desktop/source/lib/init.cxx | 21 | ||||
-rw-r--r-- | include/LibreOfficeKit/LibreOfficeKit.h | 2 | ||||
-rw-r--r-- | include/LibreOfficeKit/LibreOfficeKitEnums.h | 20 | ||||
-rw-r--r-- | include/sfx2/lokhelper.hxx | 2 | ||||
-rw-r--r-- | include/vcl/IDialogRenderable.hxx | 5 | ||||
-rw-r--r-- | include/vcl/dialog.hxx | 3 | ||||
-rw-r--r-- | libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx | 1 | ||||
-rw-r--r-- | libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx | 67 | ||||
-rw-r--r-- | libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.hxx | 4 | ||||
-rw-r--r-- | libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx | 24 | ||||
-rw-r--r-- | libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx | 1 | ||||
-rw-r--r-- | libreofficekit/source/gtk/lokdocview.cxx | 37 | ||||
-rw-r--r-- | sfx2/source/view/lokhelper.cxx | 18 | ||||
-rw-r--r-- | sw/inc/unotxdoc.hxx | 3 | ||||
-rw-r--r-- | sw/source/uibase/uno/unotxdoc.cxx | 26 | ||||
-rw-r--r-- | vcl/source/window/dialog.cxx | 41 | ||||
-rw-r--r-- | vcl/source/window/floatwin.cxx | 20 |
17 files changed, 286 insertions, 9 deletions
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 | |