Kaydet (Commit) bf359d01 authored tarafından Noel Grandin's avatar Noel Grandin

add a Dialog::runAsync for the non-controller case

.. and use it to make the solver warning dialogs async

Change-Id: I3589a1d3ae58190bf545bac1e2a95f81a114d44f
Reviewed-on: https://gerrit.libreoffice.org/66896
Tested-by: Jenkins
Reviewed-by: 's avatarNoel Grandin <noel.grandin@collabora.co.uk>
üst 8968e648
......@@ -37,6 +37,7 @@ class Dialog;
class BitmapEx;
namespace weld
{
class Dialog;
class DialogController;
class Window;
}
......@@ -54,8 +55,12 @@ public:
virtual short Execute() = 0;
struct AsyncContext {
// for the case where the owner is the dialog itself, and the dialog is an unwelded VclPtr based dialog
VclPtr<VclReferenceBase> mxOwner;
std::shared_ptr<weld::DialogController> mxOwnerDialog;
// for the case where the dialog is welded, and owned by a DialogController
std::shared_ptr<weld::DialogController> mxOwnerDialogController;
// for the case where the dialog is welded, and is running async without a DialogController
std::shared_ptr<weld::Dialog> mxOwnerSelf;
std::function<void(sal_Int32)> maEndDialogFn;
bool isSet() { return !!maEndDialogFn; }
};
......
......@@ -305,6 +305,8 @@ private:
public:
virtual int run() = 0;
// Run async without a controller
virtual bool runAsync(const std::function<void(sal_Int32)>& func) = 0;
virtual void response(int response) = 0;
virtual void add_button(const OUString& rText, int response, const OString& rHelpId = OString())
= 0;
......
......@@ -33,12 +33,12 @@
namespace
{
void lclErrorDialog(weld::Window* pParent, const OUString& rString)
void lclErrorDialog(weld::Window* pParent, const OUString& rString, const std::function<void(sal_Int32)>& func)
{
std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(pParent,
std::shared_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(pParent,
VclMessageType::Warning, VclButtonsType::Ok,
rString));
xBox->run();
xBox->runAsync(func);
}
}
......@@ -166,23 +166,31 @@ void ScSolverDlg::RaiseError( ScSolverErr eError )
switch ( eError )
{
case SOLVERR_NOFORMULA:
lclErrorDialog(GetFrameWeld() , errMsgNoFormula);
m_pEdFormulaCell->GrabFocus();
lclErrorDialog(GetFrameWeld(), errMsgNoFormula,
[this](sal_Int32 /*nResult*/) {
m_pEdFormulaCell->GrabFocus();
});
break;
case SOLVERR_INVALID_FORMULA:
lclErrorDialog(GetFrameWeld(), errMsgInvalidForm);
m_pEdFormulaCell->GrabFocus();
lclErrorDialog(GetFrameWeld(), errMsgInvalidForm,
[this](sal_Int32 /*nResult*/) {
m_pEdFormulaCell->GrabFocus();
});
break;
case SOLVERR_INVALID_VARIABLE:
lclErrorDialog(GetFrameWeld(), errMsgInvalidVar);
m_pEdVariableCell->GrabFocus();
lclErrorDialog(GetFrameWeld(), errMsgInvalidVar,
[this](sal_Int32 /*nResult*/) {
m_pEdVariableCell->GrabFocus();
});
break;
case SOLVERR_INVALID_TARGETVALUE:
lclErrorDialog(GetFrameWeld(), errMsgInvalidVal);
m_pEdTargetVal->GrabFocus();
lclErrorDialog(GetFrameWeld(), errMsgInvalidVal,
[this](sal_Int32 /*nResult*/) {
m_pEdTargetVal->GrabFocus();
});
break;
}
}
......
......@@ -883,7 +883,15 @@ 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.mxOwnerDialogController = aOwner;
aCtx.maEndDialogFn = rEndDialogFn;
return m_xDialog->StartExecuteAsync(aCtx);
}
virtual bool runAsync(const std::function<void(sal_Int32)> &rEndDialogFn) override
{
VclAbstractDialog::AsyncContext aCtx;
aCtx.mxOwnerSelf.reset(this);
aCtx.maEndDialogFn = rEndDialogFn;
return m_xDialog->StartExecuteAsync(aCtx);
}
......
......@@ -1071,7 +1071,8 @@ bool Dialog::StartExecuteAsync( VclAbstractDialog::AsyncContext &rCtx )
if (!ImplStartExecute())
{
rCtx.mxOwner.disposeAndClear();
rCtx.mxOwnerDialog.reset();
rCtx.mxOwnerDialogController.reset();
rCtx.mxOwnerSelf.reset();
return false;
}
......@@ -1149,9 +1150,11 @@ 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);
std::shared_ptr<weld::DialogController> xOwnerDialogController = std::move(mpDialogImpl->maEndCtx.mxOwnerDialogController);
std::shared_ptr<weld::Dialog> xOwnerSelf = std::move(mpDialogImpl->maEndCtx.mxOwnerSelf);
mpDialogImpl->maEndCtx.mxOwner.disposeAndClear();
xOwnerDialog.reset();
xOwnerDialogController.reset();
xOwnerSelf.reset();
}
void Dialog::EndAllDialogs( vcl::Window const * pParent )
......
......@@ -2367,6 +2367,8 @@ private:
GtkDialog* m_pDialog;
DialogRunner m_aDialogRun;
std::shared_ptr<weld::DialogController> m_xDialogController;
// Used to keep ourself alive during a runAsync(when doing runAsync without a DialogController)
std::shared_ptr<GtkInstanceDialog> m_xRunAsyncSelf;
std::function<void(sal_Int32)> m_aFunc;
gulong m_nCloseSignalId;
gulong m_nResponseSignalId;
......@@ -2414,6 +2416,7 @@ private:
m_aFunc(GtkToVcl(ret));
m_aFunc = nullptr;
m_xDialogController.reset();
m_xRunAsyncSelf.reset();
}
public:
......@@ -2440,6 +2443,20 @@ public:
return true;
}
virtual bool runAsync(const std::function<void(sal_Int32)>& func) override
{
assert(!m_nResponseSignalId);
m_xRunAsyncSelf.reset(this);
m_aFunc = func;
show();
m_nResponseSignalId = g_signal_connect(m_pDialog, "response", G_CALLBACK(signalAsyncResponse), this);
return true;
}
bool has_click_handler(int nResponse);
virtual int run() override
......
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