[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