From a8011cbe2a6c5608347f842e0b4d37a337568f49 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Fri, 3 May 2024 17:55:33 +0200 Subject: [PATCH] QDialogButtonBox: use QFlatMap instead QHash Use QFlatMap for standardButtonMap and hiddenButtons - these two container normally don't hold more than 5 elements so QFlatMap suits much better. Change-Id: I70f1a0471ec3cb118120805973bab28568d48317 Reviewed-by: Axel Spoerl --- src/widgets/widgets/qdialogbuttonbox.cpp | 54 +++++++++++++----------- src/widgets/widgets/qdialogbuttonbox_p.h | 5 ++- 2 files changed, 32 insertions(+), 27 deletions(-) diff --git a/src/widgets/widgets/qdialogbuttonbox.cpp b/src/widgets/widgets/qdialogbuttonbox.cpp index 30c68ad18bb..0b6a4df41aa 100644 --- a/src/widgets/widgets/qdialogbuttonbox.cpp +++ b/src/widgets/widgets/qdialogbuttonbox.cpp @@ -374,7 +374,7 @@ QPushButton *QDialogButtonBoxPrivate::createButton(QDialogButtonBox::StandardBut button->setIcon(style->standardIcon(QStyle::StandardPixmap(icon), nullptr, q)); if (style != QApplication::style()) // Propagate style button->setStyle(style); - standardButtonHash.insert(button, sbutton); + standardButtonMap.insert(button, sbutton); QPlatformDialogHelper::ButtonRole role = QPlatformDialogHelper::buttonRole(static_cast(sbutton)); if (Q_UNLIKELY(role == QPlatformDialogHelper::InvalidRole)) qWarning("QDialogButtonBox::createButton: Invalid ButtonRole, button not added"); @@ -426,10 +426,10 @@ void QDialogButtonBoxPrivate::createStandardButtons(QDialogButtonBox::StandardBu void QDialogButtonBoxPrivate::retranslateStrings() { - for (auto &&[key, value] : std::as_const(standardButtonHash).asKeyValueRange()) { - const QString text = QGuiApplicationPrivate::platformTheme()->standardButtonText(value); + for (const auto &it : std::as_const(standardButtonMap)) { + const QString text = QGuiApplicationPrivate::platformTheme()->standardButtonText(it.second); if (!text.isEmpty()) - key->setText(text); + it.first->setText(text); } } @@ -644,7 +644,7 @@ void QDialogButtonBox::clear() Q_D(QDialogButtonBox); // Remove the created standard buttons, they should be in the other lists, which will // do the deletion - d->standardButtonHash.clear(); + d->standardButtonMap.clear(); for (int i = 0; i < NRoles; ++i) { QList &list = d->buttonLists[i]; for (auto button : std::as_const(list)) { @@ -680,7 +680,11 @@ QList QDialogButtonBoxPrivate::visibleButtons() const QList QDialogButtonBoxPrivate::allButtons() const { - return visibleButtons() << hiddenButtons.keys(); + QList ret(visibleButtons()); + ret.reserve(ret.size() + hiddenButtons.size()); + for (const auto &it : hiddenButtons) + ret.push_back(it.first); + return ret; } /*! @@ -718,9 +722,9 @@ void QDialogButtonBox::removeButton(QAbstractButton *button) Removes \param button. \param reason determines the behavior following the removal: \list - \li \c ManualRemove disconnects all signals and removes the button from standardButtonHash. - \li \c HideEvent keeps connections alive, standard buttons remain in standardButtonHash. - \li \c Destroyed removes the button from standardButtonHash. Signals remain untouched, because + \li \c ManualRemove disconnects all signals and removes the button from standardButtonMap. + \li \c HideEvent keeps connections alive, standard buttons remain in standardButtonMap. + \li \c Destroyed removes the button from standardButtonMap. Signals remain untouched, because the button might already be only a QObject, the destructor of which handles disconnecting. \endlist */ @@ -744,7 +748,7 @@ void QDialogButtonBoxPrivate::removeButton(QAbstractButton *button, RemoveReason button->removeEventFilter(filter.get()); Q_FALLTHROUGH(); case RemoveReason::Destroyed: - standardButtonHash.remove(reinterpret_cast(button)); + standardButtonMap.remove(reinterpret_cast(button)); break; case RemoveReason::HideEvent: break; @@ -818,8 +822,9 @@ void QDialogButtonBox::setStandardButtons(StandardButtons buttons) { Q_D(QDialogButtonBox); // Clear out all the old standard buttons, then recreate them. - const auto toDelete = std::exchange(d->standardButtonHash, {}); - qDeleteAll(toDelete.keyBegin(), toDelete.keyEnd()); + const auto oldButtons = d->standardButtonMap.keys(); + d->standardButtonMap.clear(); + qDeleteAll(oldButtons); d->createStandardButtons(buttons); } @@ -828,11 +833,8 @@ QDialogButtonBox::StandardButtons QDialogButtonBox::standardButtons() const { Q_D(const QDialogButtonBox); StandardButtons standardButtons = NoButton; - QHash::const_iterator it = d->standardButtonHash.constBegin(); - while (it != d->standardButtonHash.constEnd()) { - standardButtons |= it.value(); - ++it; - } + for (const auto value : d->standardButtonMap.values()) + standardButtons |= value; return standardButtons; } @@ -845,7 +847,12 @@ QDialogButtonBox::StandardButtons QDialogButtonBox::standardButtons() const QPushButton *QDialogButtonBox::button(StandardButton which) const { Q_D(const QDialogButtonBox); - return d->standardButtonHash.key(which); + + for (const auto &it : std::as_const(d->standardButtonMap)) { + if (it.second == which) + return it.first; + } + return nullptr; } /*! @@ -857,7 +864,7 @@ QPushButton *QDialogButtonBox::button(StandardButton which) const QDialogButtonBox::StandardButton QDialogButtonBox::standardButton(QAbstractButton *button) const { Q_D(const QDialogButtonBox); - return d->standardButtonHash.value(static_cast(button)); + return d->standardButtonMap.value(static_cast(button)); } void QDialogButtonBoxPrivate::handleButtonClicked() @@ -965,16 +972,13 @@ bool QDialogButtonBox::centerButtons() const */ void QDialogButtonBox::changeEvent(QEvent *event) { - typedef QHash StandardButtonHash; - Q_D(QDialogButtonBox); switch (event->type()) { case QEvent::StyleChange: // Propagate style - if (!d->standardButtonHash.empty()) { + if (!d->standardButtonMap.empty()) { QStyle *newStyle = style(); - const StandardButtonHash::iterator end = d->standardButtonHash.end(); - for (StandardButtonHash::iterator it = d->standardButtonHash.begin(); it != end; ++it) - it.key()->setStyle(newStyle); + for (auto key : d->standardButtonMap.keys()) + key->setStyle(newStyle); } #ifdef Q_OS_MAC Q_FALLTHROUGH(); diff --git a/src/widgets/widgets/qdialogbuttonbox_p.h b/src/widgets/widgets/qdialogbuttonbox_p.h index c3d7e034894..e439819c49b 100644 --- a/src/widgets/widgets/qdialogbuttonbox_p.h +++ b/src/widgets/widgets/qdialogbuttonbox_p.h @@ -16,6 +16,7 @@ // #include +#include #include QT_BEGIN_NAMESPACE @@ -42,8 +43,8 @@ public: QDialogButtonBoxPrivate(Qt::Orientation orient); QList buttonLists[QDialogButtonBox::NRoles]; - QHash standardButtonHash; - QHash hiddenButtons; + QVarLengthFlatMap standardButtonMap; + QVarLengthFlatMap hiddenButtons; Qt::Orientation orientation; QDialogButtonBox::ButtonLayout layoutPolicy;