#include "lts_message_dialog_helper.h" #include #include #include #include #include namespace LtsWidgets { LtsMessageDialogHelper::LtsMessageDialogHelper(QObject *parent) : QObject(parent) , m_result(Button::Cancel) , m_dialog(nullptr) {} Button LtsMessageDialogHelper::showMessage(QWidget *parent, const QString &message, const QString &title, Behaviour behaviour, Buttons buttons, const QHash &buttonTexts) { m_dialog = new LtsFramelessDialog(parent, behaviour); m_dialog->setAttribute(Qt::WA_DeleteOnClose); // Message Dialogs are loose instances that must delete theirselves, because noone keeps a pointer to the message dialog QVBoxLayout *mainLayout = new QVBoxLayout(m_dialog); QString text; if (!title.isEmpty()) // title given? { text = QStringLiteral("%1

").arg(title); } text += message; QLabel *messageLabel = new QLabel(text, m_dialog); messageLabel->setTextInteractionFlags(Qt::TextSelectableByMouse); // make text selectable by mouse mainLayout->addWidget(messageLabel); QHBoxLayout *buttonLayout = new QHBoxLayout; buttonLayout->setMargin(0); // TODO: FIXME: can this be called after the selection was made and the shadow just dies ? connect(m_dialog, &LtsFramelessDialog::rejected, this, &LtsMessageDialogHelper::slotCancel); // respect that non-modal dialogs can be closed by clicking outside of it if (buttons.testFlag(Button::Ok)) connect(addButton(buttonTexts.value(Button::Ok, tr("Ok")), buttonLayout, m_dialog, Button::Ok, parent), &QPushButton::clicked, this, &LtsMessageDialogHelper::slotOkay); if (buttons.testFlag(Button::Yes)) connect(addButton(buttonTexts.value(Button::Yes, tr("Yes")), buttonLayout, m_dialog, Button::Yes, parent), &QPushButton::clicked, this, &LtsMessageDialogHelper::slotYes); if (buttons.testFlag(Button::No)) connect(addButton(buttonTexts.value(Button::No, tr("No")), buttonLayout, m_dialog, Button::No, parent), &QPushButton::clicked, this, &LtsMessageDialogHelper::slotNo); if (buttons.testFlag(Button::Apply)) connect(addButton(buttonTexts.value(Button::Apply, tr("Apply")), buttonLayout, m_dialog, Button::Apply, parent), &QPushButton::clicked, this, &LtsMessageDialogHelper::slotApply); // same as yes if (buttons.testFlag(Button::Discard)) connect(addButton(buttonTexts.value(Button::Discard, tr("Discard")), buttonLayout, m_dialog, Button::Discard, parent), &QPushButton::clicked, this, &LtsMessageDialogHelper::slotDiscard); // same as no if (buttons.testFlag(Button::Cancel)) connect(addButton(buttonTexts.value(Button::Cancel, tr("Cancel")), buttonLayout, m_dialog, Button::Cancel, parent), &QPushButton::clicked, this, &LtsMessageDialogHelper::slotCancel); QWidget *buttonLayoutWidget = new QWidget; buttonLayoutWidget->setLayout(buttonLayout); mainLayout->addWidget(buttonLayoutWidget); m_dialog->show(); m_dialog->raise(); // this class is called a dialog, but is not a QDialog, so there is no event loop to wait for a result to return, so we create our own event loop QEventLoop loop; connect(this, &LtsMessageDialogHelper::signalQuitEventLoop, &loop, &QEventLoop::quit, Qt::QueuedConnection); loop.exec(); // now wait for new result value before returning return m_result; } void LtsMessageDialogHelper::slotOkay() { m_dialog->hide(); m_result = Button::Ok; emit signalQuitEventLoop(); } void LtsMessageDialogHelper::slotYes() { m_dialog->hide(); m_result = Button::Yes; emit signalQuitEventLoop(); } void LtsMessageDialogHelper::slotNo() { m_dialog->hide(); m_result = Button::No; emit signalQuitEventLoop(); } void LtsMessageDialogHelper::slotApply() { m_dialog->hide(); m_result = Button::Apply; emit signalQuitEventLoop(); } void LtsMessageDialogHelper::slotDiscard() { m_dialog->hide(); m_result = Button::Discard; emit signalQuitEventLoop(); } void LtsMessageDialogHelper::slotCancel() { m_dialog->hide(); m_result = Button::Cancel; emit signalQuitEventLoop(); } QPushButton* LtsMessageDialogHelper::addButton(const QString &text, QHBoxLayout *thatLayout, LtsFramelessDialog *dialog, const Button &button, QWidget *parent) { QPushButton* btn = new QPushButton(text, parent); connect(btn, &QPushButton::clicked, dialog, &LtsFramelessDialog::accept); thatLayout->addWidget(btn); if (button == Button::Ok || button == Button::Cancel) // ok and cancel should not be used together, so there is no check needed (as only one button can be the default button) { btn->setDefault(true); } return btn; } } // namespace LtsWidgets