[Libreoffice-commits] core.git: include/vcl sw/source vcl/source vcl/unx
Pranav Kant
pranavk at collabora.co.uk
Fri Mar 9 04:44:09 UTC 2018
include/vcl/abstdlg.hxx | 3 +
include/vcl/dialog.hxx | 2 -
include/vcl/weld.hxx | 34 +++++++++++++++++
sw/source/uibase/docvw/edtwin.cxx | 5 +-
vcl/source/app/salvtables.cxx | 23 ++++++++++++
vcl/source/window/dialog.cxx | 3 +
vcl/unx/gtk3/gtk3gtkinst.cxx | 72 +++++++++++++++++++++++++++++++-------
7 files changed, 125 insertions(+), 17 deletions(-)
New commits:
commit 0b573eac85b3100eb8d40dcaf25c510f50cfd62f
Author: Pranav Kant <pranavk at collabora.co.uk>
Date: Thu Mar 1 20:15:58 2018 +0530
lokdialog: run async for weld dialogs
Change-Id: Ieb06beada435bc47a39295acb5ea2dcef10ca454
Reviewed-on: https://gerrit.libreoffice.org/50874
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Caolán McNamara <caolanm at redhat.com>
Tested-by: Caolán McNamara <caolanm at redhat.com>
Reviewed-by: pranavk <pranavk at collabora.co.uk>
Tested-by: pranavk <pranavk at collabora.co.uk>
diff --git a/include/vcl/abstdlg.hxx b/include/vcl/abstdlg.hxx
index 542930084e37..af676785b295 100644
--- a/include/vcl/abstdlg.hxx
+++ b/include/vcl/abstdlg.hxx
@@ -26,10 +26,12 @@
#include <vcl/vclreferencebase.hxx>
#include <vector>
#include <functional>
+#include <memory>
namespace vcl { class Window; }
class Dialog;
class Bitmap;
+namespace weld { class DialogController; }
/**
* Some things multiple-inherit from VclAbstractDialog and OutputDevice,
@@ -45,6 +47,7 @@ public:
struct AsyncContext {
VclPtr<VclReferenceBase> mxOwner;
+ std::shared_ptr<weld::DialogController> mxOwnerDialog;
std::function<void(sal_Int32)> maEndDialogFn;
bool isSet() { return !!maEndDialogFn; }
};
diff --git a/include/vcl/dialog.hxx b/include/vcl/dialog.hxx
index 243d071b101f..0b98901e32bb 100644
--- a/include/vcl/dialog.hxx
+++ b/include/vcl/dialog.hxx
@@ -149,7 +149,7 @@ private:
public:
// FIXME: Need to remove old StartExecuteModal in favour of this one.
- /// Returns true of the dialog successfully starts
+ /// Returns true if the dialog successfully starts
bool StartExecuteAsync(const std::function<void(sal_Int32)> &rEndDialogFn)
{
VclAbstractDialog::AsyncContext aCtx;
diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx
index b861b848e84c..ff3a1e8c346e 100644
--- a/include/vcl/weld.hxx
+++ b/include/vcl/weld.hxx
@@ -20,6 +20,7 @@
namespace weld
{
class Container;
+class DialogController;
class VCL_DLLPUBLIC Widget
{
@@ -120,6 +121,12 @@ public:
class VCL_DLLPUBLIC Dialog : virtual public Window
{
+private:
+ friend DialogController;
+ virtual bool runAsync(std::shared_ptr<DialogController>,
+ const std::function<void(sal_Int32)>& func)
+ = 0;
+
public:
virtual int run() = 0;
virtual void response(int response) = 0;
@@ -534,8 +541,33 @@ public:
virtual DrawingArea* weld_drawing_area(const OString& id, bool bTakeOwnership = false) = 0;
virtual ~Builder() {}
};
-}
+class VCL_DLLPUBLIC DialogController
+{
+private:
+ virtual Dialog* getDialog() = 0;
+
+public:
+ short run() { return getDialog()->run(); }
+ static bool runAsync(const std::shared_ptr<DialogController>& rController,
+ const std::function<void(sal_Int32)>&);
+ virtual ~DialogController() {}
+};
+
+class VCL_DLLPUBLIC GenericDialogController : public DialogController
+{
+private:
+ virtual Dialog* getDialog() override { return m_xDialog.get(); }
+
+protected:
+ std::unique_ptr<weld::Builder> m_xBuilder;
+ std::unique_ptr<weld::Dialog> m_xDialog;
+
+public:
+ GenericDialogController(weld::Widget* pParent, const OUString& rUIFile,
+ const OString& rDialogId);
+};
+}
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx
index 8c33ce4e5ba3..a6334cd57e60 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -2474,9 +2474,8 @@ KEYINPUT_CHECKTABLE_INSDEL:
}
else
{
- std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "modules/swriter/ui/inforeadonlydialog.ui"));
- std::unique_ptr<weld::MessageDialog> xInfo(xBuilder->weld_message_dialog("InfoReadonlyDialog"));
- xInfo->run();
+ auto xInfo(std::make_shared<weld::GenericDialogController>(GetFrameWeld(), "modules/swriter/ui/inforeadonlydialog.ui", "InfoReadonlyDialog"));
+ weld::DialogController::runAsync(xInfo, [](int) {});
eKeyState = SwKeyState::End;
}
break;
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index bb304d2dc811..3f95a7589849 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -17,6 +17,7 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+#include <comphelper/lok.hxx>
#include <salframe.hxx>
#include <salinst.hxx>
#include <salvd.hxx>
@@ -430,6 +431,14 @@ public:
{
}
+ virtual bool runAsync(std::shared_ptr<weld::DialogController> aOwner, const std::function<void(sal_Int32)> &rEndDialogFn) override
+ {
+ VclAbstractDialog::AsyncContext aCtx;
+ aCtx.mxOwnerDialog = aOwner;
+ aCtx.maEndDialogFn = rEndDialogFn;
+ return m_xDialog->StartExecuteAsync(aCtx);
+ }
+
virtual int run() override
{
VclButtonBox* pActionArea = m_xDialog->get_action_area();
@@ -1458,4 +1467,18 @@ weld::Window* SalFrame::GetFrameWeld() const
return m_xFrameWeld.get();
}
+namespace weld
+{
+ bool DialogController::runAsync(const std::shared_ptr<DialogController>& rController, const std::function<void(sal_Int32)>& func)
+ {
+ return rController->getDialog()->runAsync(rController, func);
+ }
+
+ GenericDialogController::GenericDialogController(weld::Widget* pParent, const OUString &rUIFile, const OString& rDialogId)
+ : m_xBuilder(Application::CreateBuilder(pParent, rUIFile))
+ , m_xDialog(m_xBuilder->weld_dialog(rDialogId))
+ {
+ }
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index 75d31d1f17b4..11670c6459b6 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -1036,6 +1036,7 @@ bool Dialog::StartExecuteAsync( VclAbstractDialog::AsyncContext &rCtx )
if ( !ImplStartExecuteModal() )
{
rCtx.mxOwner.disposeAndClear();
+ rCtx.mxOwnerDialog.reset();
return false;
}
@@ -1103,7 +1104,9 @@ void Dialog::EndDialog( long nResult )
mbInExecute = false;
// Destroy ourselves (if we have a context with VclPtr owner)
+ std::shared_ptr<weld::DialogController> xOwnerDialog = std::move(mpDialogImpl->maEndCtx.mxOwnerDialog);
mpDialogImpl->maEndCtx.mxOwner.disposeAndClear();
+ xOwnerDialog.reset();
}
long Dialog::GetResult() const
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index 4a8912594e45..031f012c8152 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -1499,21 +1499,77 @@ class GtkInstanceDialog : public GtkInstanceWindow, public virtual weld::Dialog
{
private:
GtkDialog* m_pDialog;
+ std::shared_ptr<weld::DialogController> m_xDialogController;
+ std::function<void(sal_Int32)> m_aFunc;
gulong m_nCloseSignalId;
+ gulong m_nResponseSignalId;
- static void signalClose(GtkWidget *, gpointer widget)
+ static void signalClose(GtkWidget*, gpointer widget)
{
GtkInstanceDialog* pThis = static_cast<GtkInstanceDialog*>(widget);
pThis->response(RET_CANCEL);
}
+
+ static void signalAsyncResponse(GtkWidget*, gint ret, gpointer widget)
+ {
+ GtkInstanceDialog* pThis = static_cast<GtkInstanceDialog*>(widget);
+ pThis->asyncresponse(ret);
+ }
+
+ static int GtkToVcl(int ret)
+ {
+ if (ret == GTK_RESPONSE_OK)
+ ret = RET_OK;
+ else if (ret == GTK_RESPONSE_CANCEL)
+ ret = RET_CANCEL;
+ else if (ret == GTK_RESPONSE_CLOSE)
+ ret = RET_CLOSE;
+ else if (ret == GTK_RESPONSE_YES)
+ ret = RET_YES;
+ else if (ret == GTK_RESPONSE_NO)
+ ret = RET_NO;
+ return ret;
+ }
+
+ void asyncresponse(gint ret)
+ {
+ if (ret == GTK_RESPONSE_HELP)
+ {
+ help();
+ return;
+ }
+
+ hide();
+ m_aFunc(GtkToVcl(ret));
+ m_xDialogController.reset();
+ }
public:
GtkInstanceDialog(GtkDialog* pDialog, bool bTakeOwnership)
: GtkInstanceWindow(GTK_WINDOW(pDialog), bTakeOwnership)
, m_pDialog(pDialog)
, m_nCloseSignalId(g_signal_connect(m_pDialog, "close", G_CALLBACK(signalClose), this))
+ , m_nResponseSignalId(0)
{
}
+ virtual bool runAsync(std::shared_ptr<weld::DialogController> rDialogController, const std::function<void(sal_Int32)>& func) override
+ {
+ assert(!m_nResponseSignalId);
+
+ m_xDialogController = rDialogController;
+ m_aFunc = func;
+
+ if (!gtk_widget_get_visible(m_pWidget))
+ {
+ sort_native_button_order(GTK_BOX(gtk_dialog_get_action_area(m_pDialog)));
+ gtk_widget_show(m_pWidget);
+ }
+
+ m_nResponseSignalId = g_signal_connect(m_pDialog, "response", G_CALLBACK(signalAsyncResponse), this);
+
+ return true;
+ }
+
virtual int run() override
{
sort_native_button_order(GTK_BOX(gtk_dialog_get_action_area(m_pDialog)));
@@ -1526,20 +1582,10 @@ public:
help();
continue;
}
- else if (ret == GTK_RESPONSE_OK)
- ret = RET_OK;
- else if (ret == GTK_RESPONSE_CANCEL)
- ret = RET_CANCEL;
- else if (ret == GTK_RESPONSE_CLOSE)
- ret = RET_CLOSE;
- else if (ret == GTK_RESPONSE_YES)
- ret = RET_YES;
- else if (ret == GTK_RESPONSE_NO)
- ret = RET_NO;
break;
}
hide();
- return ret;
+ return GtkToVcl(ret);
}
static int VclToGtk(int nResponse)
@@ -1577,6 +1623,8 @@ public:
virtual ~GtkInstanceDialog() override
{
g_signal_handler_disconnect(m_pDialog, m_nCloseSignalId);
+ if (m_nResponseSignalId)
+ g_signal_handler_disconnect(m_pDialog, m_nResponseSignalId);
}
};
More information about the Libreoffice-commits
mailing list