diff options
| author | Axel Spoerl <axel.spoerl@qt.io> | 2023-08-21 15:43:12 +0200 |
|---|---|---|
| committer | Axel Spoerl <axel.spoerl@qt.io> | 2023-08-23 14:56:16 +0200 |
| commit | aff0915352dda0cfaa11a249b665fbe47be21d69 (patch) | |
| tree | f8d06cfa0119a17f21c1285eb731ab84603f7de6 | |
| parent | 2da366fbba66b472f2c78264efadb036723fd89b (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.cpp | 47 | ||||
| -rw-r--r-- | src/widgets/widgets/qdialogbuttonbox.h | 2 | ||||
| -rw-r--r-- | src/widgets/widgets/qdialogbuttonbox_p.h | 4 |
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); |
