office-gobmx/vcl/inc/qt5/QtInstanceMessageDialog.hxx
Michael Weghorn a54abf77c4 tdf#130857 qt weld: Support asnyc running of msg dialogs
Implement methods required to run a welded Qt message dialog
asynchronously: `QtInstanceMessageDialog::runAsync` and
`QtInstanceMessageDialog::response`.

Run the dialog asynchronously using `QDialog::open` and
connect to the `QDialog::finished` signal to be notified
when the dialog gets closed.

Similar to how the gtk-based implementation, use local
variables for the `std::shared_ptr`s and reset the members
right away, not only at the end of the slot, since resetting
the relevant one set in the corresponding `runAsync` overload
will result in the object getting deallocated, thus the members
can no longer be accessed safely.

Take the solar mutex before calling the callback function
as that seems to be expected (e.g. otherwise triggers an assert
for the below example where the callback functions
modifies VCL widgets).

With this in place, running welded Qt message dialogs
asynchronously works instead of not showing up at all, e.g.

1) start Writer with qt6 VCL plugin and without
   `SAL_VCL_QT_NO_WELDED_WIDGETS` set
2) open "File" -> "Properties" -> "Security"
3) click the "Protect..." button
4) enter 2 different passwords and press "OK" button

Change-Id: Ic1b1bfc7d89c1be8a9f9dee59bc86cf3da37a280
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162948
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-02-04 07:01:14 +01:00

57 lines
2 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#pragma once
#include "QtInstanceDialog.hxx"
#include <QtWidgets/QMessageBox>
class QtInstanceMessageDialog : public QObject,
public QtInstanceDialog,
public virtual weld::MessageDialog
{
Q_OBJECT;
private:
QMessageBox* m_pMessageDialog;
// the DialogController/Dialog/function passed to the runAsync variants
std::shared_ptr<weld::DialogController> m_xRunAsyncDialogController;
std::shared_ptr<weld::Dialog> m_xRunAsyncDialog;
std::function<void(sal_Int32)> m_aRunAsyncFunc;
public:
QtInstanceMessageDialog(QMessageBox* pMessageDialog);
virtual void set_primary_text(const rtl::OUString& rText) override;
virtual void set_secondary_text(const rtl::OUString& rText) override;
virtual Container* weld_message_area() override;
virtual OUString get_primary_text() const override;
virtual OUString get_secondary_text() const override;
// weld::Dialog overrides
virtual void add_button(const OUString& rText, int nResponse,
const OUString& rHelpId = {}) override;
virtual void set_default_response(int nResponse) override;
virtual int run() override;
virtual bool runAsync(std::shared_ptr<weld::DialogController> const& rxOwner,
const std::function<void(sal_Int32)>& func) override;
virtual bool runAsync(std::shared_ptr<Dialog> const& rxSelf,
const std::function<void(sal_Int32)>& func) override;
virtual void response(int nResponse) override;
private slots:
void dialogFinished(int nResult);
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */