summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--desktop/source/lib/init.cxx21
-rw-r--r--include/LibreOfficeKit/LibreOfficeKit.h2
-rw-r--r--include/LibreOfficeKit/LibreOfficeKitEnums.h20
-rw-r--r--include/sfx2/lokhelper.hxx2
-rw-r--r--include/vcl/IDialogRenderable.hxx5
-rw-r--r--include/vcl/dialog.hxx3
-rw-r--r--libreofficekit/qa/gtktiledviewer/gtv-application-window.cxx1
-rw-r--r--libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.cxx67
-rw-r--r--libreofficekit/qa/gtktiledviewer/gtv-lok-dialog.hxx4
-rw-r--r--libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.cxx24
-rw-r--r--libreofficekit/qa/gtktiledviewer/gtv-lokdocview-signal-handlers.hxx1
-rw-r--r--libreofficekit/source/gtk/lokdocview.cxx37
-rw-r--r--sfx2/source/view/lokhelper.cxx18
-rw-r--r--sw/inc/unotxdoc.hxx3
-rw-r--r--sw/source/uibase/uno/unotxdoc.cxx26
-rw-r--r--vcl/source/window/dialog.cxx41
-rw-r--r--vcl/source/window/floatwin.cxx20
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 |