Kaydet (Commit) 0b573eac authored tarafından Pranav Kant's avatar Pranav Kant Kaydeden (comit) pranavk

lokdialog: run async for weld dialogs

Change-Id: Ieb06beada435bc47a39295acb5ea2dcef10ca454
Reviewed-on: https://gerrit.libreoffice.org/50874Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarCaolán McNamara <caolanm@redhat.com>
Tested-by: 's avatarCaolán McNamara <caolanm@redhat.com>
Reviewed-by: 's avatarpranavk <pranavk@collabora.co.uk>
Tested-by: 's avatarpranavk <pranavk@collabora.co.uk>
üst b48dc80c
......@@ -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; }
};
......
......@@ -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;
......
......@@ -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: */
......@@ -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;
......
......@@ -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: */
......@@ -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
......
......@@ -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);
}
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment