QDialogButtonBox: Use separate eventFilter class
bbb71e7e80
added an eventFilter override
to QDialogButtonBox, in order to fix QTBUG-114377. The approach added
a symbol to QDialogButtonBox, which breaks binary compatibility between
patch releases.
=> Use a separate class to install an event filter
=> Remove the symbol (eventFilter override) in QDialogButtonBox
Fixes: QTBUG-116287
Pick-to: 6.6 6.5
Change-Id: I920deca9f45f6246ed1fcbf5346f681dd5dd12f6
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
parent
2da366fbba
commit
aff0915352
@ -115,6 +115,22 @@ QT_BEGIN_NAMESPACE
|
|||||||
QDialogButtonBoxPrivate::QDialogButtonBoxPrivate(Qt::Orientation orient)
|
QDialogButtonBoxPrivate::QDialogButtonBoxPrivate(Qt::Orientation orient)
|
||||||
: orientation(orient), buttonLayout(nullptr), center(false)
|
: orientation(orient), buttonLayout(nullptr), center(false)
|
||||||
{
|
{
|
||||||
|
struct EventFilter : public QObject
|
||||||
|
{
|
||||||
|
EventFilter(QDialogButtonBoxPrivate *d) : d(d) {};
|
||||||
|
|
||||||
|
bool eventFilter(QObject *obj, QEvent *event) override
|
||||||
|
{
|
||||||
|
QAbstractButton *button = qobject_cast<QAbstractButton *>(obj);
|
||||||
|
return button ? d->handleButtonShowAndHide(button, event) : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QDialogButtonBoxPrivate *d;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
filter.reset(new EventFilter(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
void QDialogButtonBoxPrivate::initLayout()
|
void QDialogButtonBoxPrivate::initLayout()
|
||||||
@ -171,7 +187,7 @@ void QDialogButtonBoxPrivate::layoutButtons()
|
|||||||
Q_Q(QDialogButtonBox);
|
Q_Q(QDialogButtonBox);
|
||||||
const int MacGap = 36 - 8; // 8 is the default gap between a widget and a spacer item
|
const int MacGap = 36 - 8; // 8 is the default gap between a widget and a spacer item
|
||||||
|
|
||||||
QBoolBlocker blocker(byPassEventFilter);
|
QBoolBlocker blocker(ignoreShowAndHide);
|
||||||
for (int i = buttonLayout->count() - 1; i >= 0; --i) {
|
for (int i = buttonLayout->count() - 1; i >= 0; --i) {
|
||||||
QLayoutItem *item = buttonLayout->takeAt(i);
|
QLayoutItem *item = buttonLayout->takeAt(i);
|
||||||
if (QWidget *widget = item->widget())
|
if (QWidget *widget = item->widget())
|
||||||
@ -369,7 +385,6 @@ QPushButton *QDialogButtonBoxPrivate::createButton(QDialogButtonBox::StandardBut
|
|||||||
void QDialogButtonBoxPrivate::addButton(QAbstractButton *button, QDialogButtonBox::ButtonRole role,
|
void QDialogButtonBoxPrivate::addButton(QAbstractButton *button, QDialogButtonBox::ButtonRole role,
|
||||||
LayoutRule layoutRule, AddRule addRule)
|
LayoutRule layoutRule, AddRule addRule)
|
||||||
{
|
{
|
||||||
Q_Q(QDialogButtonBox);
|
|
||||||
buttonLists[role].append(button);
|
buttonLists[role].append(button);
|
||||||
switch (addRule) {
|
switch (addRule) {
|
||||||
case AddRule::Connect:
|
case AddRule::Connect:
|
||||||
@ -377,7 +392,7 @@ void QDialogButtonBoxPrivate::addButton(QAbstractButton *button, QDialogButtonBo
|
|||||||
this, &QDialogButtonBoxPrivate::handleButtonClicked);
|
this, &QDialogButtonBoxPrivate::handleButtonClicked);
|
||||||
QObjectPrivate::connect(button, &QAbstractButton::destroyed,
|
QObjectPrivate::connect(button, &QAbstractButton::destroyed,
|
||||||
this, &QDialogButtonBoxPrivate::handleButtonDestroyed);
|
this, &QDialogButtonBoxPrivate::handleButtonDestroyed);
|
||||||
button->installEventFilter(q);
|
button->installEventFilter(filter.get());
|
||||||
break;
|
break;
|
||||||
case AddRule::SkipConnect:
|
case AddRule::SkipConnect:
|
||||||
break;
|
break;
|
||||||
@ -466,7 +481,7 @@ QDialogButtonBox::~QDialogButtonBox()
|
|||||||
{
|
{
|
||||||
Q_D(QDialogButtonBox);
|
Q_D(QDialogButtonBox);
|
||||||
|
|
||||||
d->byPassEventFilter = true;
|
d->ignoreShowAndHide = true;
|
||||||
|
|
||||||
// QObjectPrivate::connect requires explicit disconnect in destructor
|
// QObjectPrivate::connect requires explicit disconnect in destructor
|
||||||
// otherwise the connection may kick in on child destruction and reach
|
// otherwise the connection may kick in on child destruction and reach
|
||||||
@ -694,7 +709,6 @@ void QDialogButtonBox::removeButton(QAbstractButton *button)
|
|||||||
|
|
||||||
void QDialogButtonBoxPrivate::removeButton(QAbstractButton *button, RemoveRule rule)
|
void QDialogButtonBoxPrivate::removeButton(QAbstractButton *button, RemoveRule rule)
|
||||||
{
|
{
|
||||||
Q_Q(QDialogButtonBox);
|
|
||||||
if (!button)
|
if (!button)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -713,7 +727,7 @@ void QDialogButtonBoxPrivate::removeButton(QAbstractButton *button, RemoveRule r
|
|||||||
this, &QDialogButtonBoxPrivate::handleButtonClicked);
|
this, &QDialogButtonBoxPrivate::handleButtonClicked);
|
||||||
QObjectPrivate::disconnect(button, &QAbstractButton::destroyed,
|
QObjectPrivate::disconnect(button, &QAbstractButton::destroyed,
|
||||||
this, &QDialogButtonBoxPrivate::handleButtonDestroyed);
|
this, &QDialogButtonBoxPrivate::handleButtonDestroyed);
|
||||||
button->removeEventFilter(q);
|
button->removeEventFilter(filter.get());
|
||||||
break;
|
break;
|
||||||
case RemoveRule::KeepConnections:
|
case RemoveRule::KeepConnections:
|
||||||
break;
|
break;
|
||||||
@ -870,30 +884,15 @@ void QDialogButtonBoxPrivate::handleButtonDestroyed()
|
|||||||
removeButton(reinterpret_cast<QAbstractButton *>(object), RemoveRule::KeepConnections);
|
removeButton(reinterpret_cast<QAbstractButton *>(object), RemoveRule::KeepConnections);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QDialogButtonBox::eventFilter(QObject *object, QEvent *event)
|
|
||||||
{
|
|
||||||
Q_D(QDialogButtonBox);
|
|
||||||
if (d->byPassEventFilter)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
QAbstractButton *button = qobject_cast<QAbstractButton *>(object);
|
|
||||||
if (!button)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
|
|
||||||
const QEvent::Type type = event->type();
|
|
||||||
if (type == QEvent::HideToParent || type == QEvent::ShowToParent)
|
|
||||||
return d->handleButtonShowAndHide(button, event);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QDialogButtonBoxPrivate::handleButtonShowAndHide(QAbstractButton *button, QEvent *event)
|
bool QDialogButtonBoxPrivate::handleButtonShowAndHide(QAbstractButton *button, QEvent *event)
|
||||||
{
|
{
|
||||||
Q_Q(QDialogButtonBox);
|
Q_Q(QDialogButtonBox);
|
||||||
|
|
||||||
const QEvent::Type type = event->type();
|
const QEvent::Type type = event->type();
|
||||||
|
|
||||||
|
if ((type != QEvent::HideToParent && type != QEvent::ShowToParent) || ignoreShowAndHide)
|
||||||
|
return false;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case QEvent::HideToParent: {
|
case QEvent::HideToParent: {
|
||||||
const QDialogButtonBox::ButtonRole role = q->buttonRole(button);
|
const QDialogButtonBox::ButtonRole role = q->buttonRole(button);
|
||||||
|
@ -107,8 +107,6 @@ public:
|
|||||||
void setCenterButtons(bool center);
|
void setCenterButtons(bool center);
|
||||||
bool centerButtons() const;
|
bool centerButtons() const;
|
||||||
|
|
||||||
bool eventFilter(QObject *object, QEvent *event) override;
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void clicked(QAbstractButton *button);
|
void clicked(QAbstractButton *button);
|
||||||
void accepted();
|
void accepted();
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include <qdialogbuttonbox.h>
|
#include <qdialogbuttonbox.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class Q_AUTOTEST_EXPORT QDialogButtonBoxPrivate : public QWidgetPrivate
|
class Q_AUTOTEST_EXPORT QDialogButtonBoxPrivate : public QWidgetPrivate
|
||||||
{
|
{
|
||||||
Q_DECLARE_PUBLIC(QDialogButtonBox)
|
Q_DECLARE_PUBLIC(QDialogButtonBox)
|
||||||
@ -46,8 +47,9 @@ public:
|
|||||||
Qt::Orientation orientation;
|
Qt::Orientation orientation;
|
||||||
QDialogButtonBox::ButtonLayout layoutPolicy;
|
QDialogButtonBox::ButtonLayout layoutPolicy;
|
||||||
QBoxLayout *buttonLayout;
|
QBoxLayout *buttonLayout;
|
||||||
|
std::unique_ptr<QObject> filter;
|
||||||
bool center;
|
bool center;
|
||||||
bool byPassEventFilter = false;
|
bool ignoreShowAndHide = false;
|
||||||
|
|
||||||
void createStandardButtons(QDialogButtonBox::StandardButtons buttons);
|
void createStandardButtons(QDialogButtonBox::StandardButtons buttons);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user