Android: add support for custom buttons in native MessageDialog helper

New API in QMessageDialogOptions and implementation on Android.

Task-number: QTBUG-35545
Change-Id: I59567251199f220862d01ba76979266379eecd86
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This commit is contained in:
Shawn Rutledge 2016-02-09 14:19:46 +01:00 committed by Ulf Hermann
parent 2d587a03eb
commit 4c631c0bf9
4 changed files with 91 additions and 7 deletions

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
@ -44,6 +44,7 @@
#include <QtCore/QSharedData>
#include <QtCore/QSettings>
#include <QtCore/QUrl>
#include <QtCore/QVector>
#include <QtGui/QColor>
#include <algorithm>
@ -786,7 +787,8 @@ class QMessageDialogOptionsPrivate : public QSharedData
public:
QMessageDialogOptionsPrivate() :
icon(QMessageDialogOptions::NoIcon),
buttons(QPlatformDialogHelper::Ok)
buttons(QPlatformDialogHelper::Ok),
nextCustomButtonId(QPlatformDialogHelper::LastButton + 1)
{}
QString windowTitle;
@ -795,6 +797,8 @@ public:
QString informativeText;
QString detailedText;
QPlatformDialogHelper::StandardButtons buttons;
QVector<QMessageDialogOptions::CustomButton> customButtons;
int nextCustomButtonId;
};
QMessageDialogOptions::QMessageDialogOptions(QMessageDialogOptionsPrivate *dd)
@ -886,6 +890,35 @@ QPlatformDialogHelper::StandardButtons QMessageDialogOptions::standardButtons()
return d->buttons;
}
int QMessageDialogOptions::addButton(const QString &label, QPlatformDialogHelper::ButtonRole role,
void *buttonImpl)
{
const CustomButton b(d->nextCustomButtonId++, label, role, buttonImpl);
d->customButtons.append(b);
return b.id;
}
static inline bool operator==(const QMessageDialogOptions::CustomButton &a,
const QMessageDialogOptions::CustomButton &b) {
return a.id == b.id;
}
void QMessageDialogOptions::removeButton(int id)
{
d->customButtons.removeOne(CustomButton(id));
}
const QVector<QMessageDialogOptions::CustomButton> &QMessageDialogOptions::customButtons()
{
return d->customButtons;
}
const QMessageDialogOptions::CustomButton *QMessageDialogOptions::customButton(int id)
{
int i = d->customButtons.indexOf(CustomButton(id));
return (i < 0 ? nullptr : &d->customButtons.at(i));
}
QPlatformDialogHelper::ButtonRole QPlatformDialogHelper::buttonRole(QPlatformDialogHelper::StandardButton button)
{
switch (button) {

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
@ -460,6 +460,26 @@ public:
void setStandardButtons(QPlatformDialogHelper::StandardButtons buttons);
QPlatformDialogHelper::StandardButtons standardButtons() const;
struct CustomButton {
explicit CustomButton(
int id = -1, const QString &label = QString(),
QPlatformDialogHelper::ButtonRole role = QPlatformDialogHelper::InvalidRole,
void *button = nullptr) :
label(label), role(role), id(id), button(button)
{}
QString label;
QPlatformDialogHelper::ButtonRole role;
int id;
void *button; // strictly internal use only
};
int addButton(const QString &label, QPlatformDialogHelper::ButtonRole role,
void *buttonImpl = nullptr);
void removeButton(int id);
const QVector<CustomButton> &customButtons();
const CustomButton *customButton(int id);
private:
QMessageDialogOptionsPrivate *d;
};

View File

@ -1,5 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Copyright (C) 2013 BogDan Vatra <bogdan@kde.org>
** Contact: https://www.qt.io/licensing/
**
@ -117,6 +118,15 @@ bool QAndroidPlatformMessageDialogHelper::show(Qt::WindowFlags windowFlags
void QAndroidPlatformMessageDialogHelper::addButtons(QSharedPointer<QMessageDialogOptions> opt, ButtonRole role)
{
for (const QMessageDialogOptions::CustomButton &b : opt->customButtons()) {
if (b.role == role) {
QString label = b.label;
label.remove(QChar('&'));
m_javaMessageDialog.callMethod<void>("addButton", "(ILjava/lang/String;)V", b.id,
QJNIObjectPrivate::fromString(label).object());
}
}
for (int i = QPlatformDialogHelper::FirstButton; i < QPlatformDialogHelper::LastButton; i<<=1) {
StandardButton b = static_cast<StandardButton>(i);
if (buttonRole(b) == role && (opt->standardButtons() & i)) {
@ -144,6 +154,12 @@ void QAndroidPlatformMessageDialogHelper::dialogResult(int buttonID)
QPlatformDialogHelper::StandardButton standardButton = static_cast<QPlatformDialogHelper::StandardButton>(buttonID);
QPlatformDialogHelper::ButtonRole role = QPlatformDialogHelper::buttonRole(standardButton);
if (buttonID > QPlatformDialogHelper::LastButton) {
const QMessageDialogOptions::CustomButton *custom = options()->customButton(buttonID);
Q_ASSERT(custom);
role = custom->role;
}
emit clicked(standardButton, role);
}

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
@ -64,6 +64,7 @@
#include <QtGui/qfont.h>
#include <QtGui/qfontmetrics.h>
#include <QtGui/qclipboard.h>
#include "private/qabstractbutton_p.h"
#include <private/qdesktopwidget_p.h>
#ifdef Q_OS_WIN
@ -492,9 +493,17 @@ void QMessageBoxPrivate::_q_buttonClicked(QAbstractButton *button)
void QMessageBoxPrivate::_q_clicked(QPlatformDialogHelper::StandardButton button, QPlatformDialogHelper::ButtonRole role)
{
Q_UNUSED(role);
Q_Q(QMessageBox);
q->done(button);
if (button > QPlatformDialogHelper::LastButton) {
// It's a custom button, and the QPushButton in options is just a proxy
// for the button on the platform dialog. Simulate the user clicking it.
clickedButton = static_cast<QAbstractButton *>(options->customButton(button)->button);
Q_ASSERT(clickedButton);
clickedButton->click();
q->done(role);
} else {
q->done(button);
}
}
/*!
@ -831,6 +840,8 @@ void QMessageBox::addButton(QAbstractButton *button, ButtonRole role)
if (!button)
return;
removeButton(button);
d->options->addButton(button->text(), static_cast<QPlatformDialogHelper::ButtonRole>(role),
button);
d->buttonBox->addButton(button, (QDialogButtonBox::ButtonRole)role);
d->customButtonList.append(button);
d->autoAddOkButton = false;
@ -2678,7 +2689,11 @@ void QMessageBoxPrivate::helperPrepareShow(QPlatformDialogHelper *)
void QMessageBoxPrivate::helperDone(QDialog::DialogCode code, QPlatformDialogHelper *)
{
Q_Q(QMessageBox);
clickedButton = q->button(QMessageBox::StandardButton(code));
QAbstractButton *button = q->button(QMessageBox::StandardButton(code));
// If it was a custom button, a custom ID was used, so we won't get a valid pointer here.
// In that case, clickedButton has already been set in _q_buttonClicked.
if (button)
clickedButton = button;
}
/*!