summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAxel Spoerl <axel.spoerl@qt.io>2023-08-21 15:43:12 +0200
committerAxel Spoerl <axel.spoerl@qt.io>2023-08-23 14:56:16 +0200
commitaff0915352dda0cfaa11a249b665fbe47be21d69 (patch)
treef8d06cfa0119a17f21c1285eb731ab84603f7de6
parent2da366fbba66b472f2c78264efadb036723fd89b (diff)
QDialogButtonBox: Use separate eventFilter class
bbb71e7e80f292c2e69faef81b1624832981147e 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>
-rw-r--r--src/widgets/widgets/qdialogbuttonbox.cpp47
-rw-r--r--src/widgets/widgets/qdialogbuttonbox.h2
-rw-r--r--src/widgets/widgets/qdialogbuttonbox_p.h4
3 files changed, 26 insertions, 27 deletions
diff --git a/src/widgets/widgets/qdialogbuttonbox.cpp b/src/widgets/widgets/qdialogbuttonbox.cpp
index f319db7e10f..69fea049145 100644
--- a/src/widgets/widgets/qdialogbuttonbox.cpp
+++ b/src/widgets/widgets/qdialogbuttonbox.cpp
@@ -115,6 +115,22 @@ QT_BEGIN_NAMESPACE
QDialogButtonBoxPrivate::QDialogButtonBoxPrivate(Qt::Orientation orient)
: 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()
@@ -171,7 +187,7 @@ void QDialogButtonBoxPrivate::layoutButtons()
Q_Q(QDialogButtonBox);
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) {
QLayoutItem *item = buttonLayout->takeAt(i);
if (QWidget *widget = item->widget())
@@ -369,7 +385,6 @@ QPushButton *QDialogButtonBoxPrivate::createButton(QDialogButtonBox::StandardBut
void QDialogButtonBoxPrivate::addButton(QAbstractButton *button, QDialogButtonBox::ButtonRole role,
LayoutRule layoutRule, AddRule addRule)
{
- Q_Q(QDialogButtonBox);
buttonLists[role].append(button);
switch (addRule) {
case AddRule::Connect:
@@ -377,7 +392,7 @@ void QDialogButtonBoxPrivate::addButton(QAbstractButton *button, QDialogButtonBo
this, &QDialogButtonBoxPrivate::handleButtonClicked);
QObjectPrivate::connect(button, &QAbstractButton::destroyed,
this, &QDialogButtonBoxPrivate::handleButtonDestroyed);
- button->installEventFilter(q);
+ button->installEventFilter(filter.get());
break;
case AddRule::SkipConnect:
break;
@@ -466,7 +481,7 @@ QDialogButtonBox::~QDialogButtonBox()
{
Q_D(QDialogButtonBox);
- d->byPassEventFilter = true;
+ d->ignoreShowAndHide = true;
// QObjectPrivate::connect requires explicit disconnect in destructor
// 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)
{
- Q_Q(QDialogButtonBox);
if (!button)
return;
@@ -713,7 +727,7 @@ void QDialogButtonBoxPrivate::removeButton(QAbstractButton *button, RemoveRule r
this, &QDialogButtonBoxPrivate::handleButtonClicked);
QObjectPrivate::disconnect(button, &QAbstractButton::destroyed,
this, &QDialogButtonBoxPrivate::handleButtonDestroyed);
- button->removeEventFilter(q);
+ button->removeEventFilter(filter.get());
break;
case RemoveRule::KeepConnections:
break;
@@ -870,30 +884,15 @@ void QDialogButtonBoxPrivate::handleButtonDestroyed()
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)
{
Q_Q(QDialogButtonBox);
const QEvent::Type type = event->type();
+ if ((type != QEvent::HideToParent && type != QEvent::ShowToParent) || ignoreShowAndHide)
+ return false;
+
switch (type) {
case QEvent::HideToParent: {
const QDialogButtonBox::ButtonRole role = q->buttonRole(button);
diff --git a/src/widgets/widgets/qdialogbuttonbox.h b/src/widgets/widgets/qdialogbuttonbox.h
index 4c116b5bab7..d967494d0df 100644
--- a/src/widgets/widgets/qdialogbuttonbox.h
+++ b/src/widgets/widgets/qdialogbuttonbox.h
@@ -107,8 +107,6 @@ public:
void setCenterButtons(bool center);
bool centerButtons() const;
- bool eventFilter(QObject *object, QEvent *event) override;
-
Q_SIGNALS:
void clicked(QAbstractButton *button);
void accepted();
diff --git a/src/widgets/widgets/qdialogbuttonbox_p.h b/src/widgets/widgets/qdialogbuttonbox_p.h
index 5911c96a469..1aa60712412 100644
--- a/src/widgets/widgets/qdialogbuttonbox_p.h
+++ b/src/widgets/widgets/qdialogbuttonbox_p.h
@@ -19,6 +19,7 @@
#include <qdialogbuttonbox.h>
QT_BEGIN_NAMESPACE
+
class Q_AUTOTEST_EXPORT QDialogButtonBoxPrivate : public QWidgetPrivate
{
Q_DECLARE_PUBLIC(QDialogButtonBox)
@@ -46,8 +47,9 @@ public:
Qt::Orientation orientation;
QDialogButtonBox::ButtonLayout layoutPolicy;
QBoxLayout *buttonLayout;
+ std::unique_ptr<QObject> filter;
bool center;
- bool byPassEventFilter = false;
+ bool ignoreShowAndHide = false;
void createStandardButtons(QDialogButtonBox::StandardButtons buttons);