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 <axel.spoerl@qt.io>
This commit is contained in:
Christian Ehrlicher 2024-05-03 17:55:33 +02:00
parent 062c538781
commit a8011cbe2a
2 changed files with 32 additions and 27 deletions

View File

@ -374,7 +374,7 @@ QPushButton *QDialogButtonBoxPrivate::createButton(QDialogButtonBox::StandardBut
button->setIcon(style->standardIcon(QStyle::StandardPixmap(icon), nullptr, q)); button->setIcon(style->standardIcon(QStyle::StandardPixmap(icon), nullptr, q));
if (style != QApplication::style()) // Propagate style if (style != QApplication::style()) // Propagate style
button->setStyle(style); button->setStyle(style);
standardButtonHash.insert(button, sbutton); standardButtonMap.insert(button, sbutton);
QPlatformDialogHelper::ButtonRole role = QPlatformDialogHelper::buttonRole(static_cast<QPlatformDialogHelper::StandardButton>(sbutton)); QPlatformDialogHelper::ButtonRole role = QPlatformDialogHelper::buttonRole(static_cast<QPlatformDialogHelper::StandardButton>(sbutton));
if (Q_UNLIKELY(role == QPlatformDialogHelper::InvalidRole)) if (Q_UNLIKELY(role == QPlatformDialogHelper::InvalidRole))
qWarning("QDialogButtonBox::createButton: Invalid ButtonRole, button not added"); qWarning("QDialogButtonBox::createButton: Invalid ButtonRole, button not added");
@ -426,10 +426,10 @@ void QDialogButtonBoxPrivate::createStandardButtons(QDialogButtonBox::StandardBu
void QDialogButtonBoxPrivate::retranslateStrings() void QDialogButtonBoxPrivate::retranslateStrings()
{ {
for (auto &&[key, value] : std::as_const(standardButtonHash).asKeyValueRange()) { for (const auto &it : std::as_const(standardButtonMap)) {
const QString text = QGuiApplicationPrivate::platformTheme()->standardButtonText(value); const QString text = QGuiApplicationPrivate::platformTheme()->standardButtonText(it.second);
if (!text.isEmpty()) if (!text.isEmpty())
key->setText(text); it.first->setText(text);
} }
} }
@ -644,7 +644,7 @@ void QDialogButtonBox::clear()
Q_D(QDialogButtonBox); Q_D(QDialogButtonBox);
// Remove the created standard buttons, they should be in the other lists, which will // Remove the created standard buttons, they should be in the other lists, which will
// do the deletion // do the deletion
d->standardButtonHash.clear(); d->standardButtonMap.clear();
for (int i = 0; i < NRoles; ++i) { for (int i = 0; i < NRoles; ++i) {
QList<QAbstractButton *> &list = d->buttonLists[i]; QList<QAbstractButton *> &list = d->buttonLists[i];
for (auto button : std::as_const(list)) { for (auto button : std::as_const(list)) {
@ -680,7 +680,11 @@ QList<QAbstractButton *> QDialogButtonBoxPrivate::visibleButtons() const
QList<QAbstractButton *> QDialogButtonBoxPrivate::allButtons() const QList<QAbstractButton *> QDialogButtonBoxPrivate::allButtons() const
{ {
return visibleButtons() << hiddenButtons.keys(); QList<QAbstractButton *> 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. Removes \param button.
\param reason determines the behavior following the removal: \param reason determines the behavior following the removal:
\list \list
\li \c ManualRemove disconnects all signals and removes the button from standardButtonHash. \li \c ManualRemove disconnects all signals and removes the button from standardButtonMap.
\li \c HideEvent keeps connections alive, standard buttons remain in standardButtonHash. \li \c HideEvent keeps connections alive, standard buttons remain in standardButtonMap.
\li \c Destroyed removes the button from standardButtonHash. Signals remain untouched, because \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. the button might already be only a QObject, the destructor of which handles disconnecting.
\endlist \endlist
*/ */
@ -744,7 +748,7 @@ void QDialogButtonBoxPrivate::removeButton(QAbstractButton *button, RemoveReason
button->removeEventFilter(filter.get()); button->removeEventFilter(filter.get());
Q_FALLTHROUGH(); Q_FALLTHROUGH();
case RemoveReason::Destroyed: case RemoveReason::Destroyed:
standardButtonHash.remove(reinterpret_cast<QPushButton *>(button)); standardButtonMap.remove(reinterpret_cast<QPushButton *>(button));
break; break;
case RemoveReason::HideEvent: case RemoveReason::HideEvent:
break; break;
@ -818,8 +822,9 @@ void QDialogButtonBox::setStandardButtons(StandardButtons buttons)
{ {
Q_D(QDialogButtonBox); Q_D(QDialogButtonBox);
// Clear out all the old standard buttons, then recreate them. // Clear out all the old standard buttons, then recreate them.
const auto toDelete = std::exchange(d->standardButtonHash, {}); const auto oldButtons = d->standardButtonMap.keys();
qDeleteAll(toDelete.keyBegin(), toDelete.keyEnd()); d->standardButtonMap.clear();
qDeleteAll(oldButtons);
d->createStandardButtons(buttons); d->createStandardButtons(buttons);
} }
@ -828,11 +833,8 @@ QDialogButtonBox::StandardButtons QDialogButtonBox::standardButtons() const
{ {
Q_D(const QDialogButtonBox); Q_D(const QDialogButtonBox);
StandardButtons standardButtons = NoButton; StandardButtons standardButtons = NoButton;
QHash<QPushButton *, StandardButton>::const_iterator it = d->standardButtonHash.constBegin(); for (const auto value : d->standardButtonMap.values())
while (it != d->standardButtonHash.constEnd()) { standardButtons |= value;
standardButtons |= it.value();
++it;
}
return standardButtons; return standardButtons;
} }
@ -845,7 +847,12 @@ QDialogButtonBox::StandardButtons QDialogButtonBox::standardButtons() const
QPushButton *QDialogButtonBox::button(StandardButton which) const QPushButton *QDialogButtonBox::button(StandardButton which) const
{ {
Q_D(const QDialogButtonBox); 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 QDialogButtonBox::StandardButton QDialogButtonBox::standardButton(QAbstractButton *button) const
{ {
Q_D(const QDialogButtonBox); Q_D(const QDialogButtonBox);
return d->standardButtonHash.value(static_cast<QPushButton *>(button)); return d->standardButtonMap.value(static_cast<QPushButton *>(button));
} }
void QDialogButtonBoxPrivate::handleButtonClicked() void QDialogButtonBoxPrivate::handleButtonClicked()
@ -965,16 +972,13 @@ bool QDialogButtonBox::centerButtons() const
*/ */
void QDialogButtonBox::changeEvent(QEvent *event) void QDialogButtonBox::changeEvent(QEvent *event)
{ {
typedef QHash<QPushButton *, QDialogButtonBox::StandardButton> StandardButtonHash;
Q_D(QDialogButtonBox); Q_D(QDialogButtonBox);
switch (event->type()) { switch (event->type()) {
case QEvent::StyleChange: // Propagate style case QEvent::StyleChange: // Propagate style
if (!d->standardButtonHash.empty()) { if (!d->standardButtonMap.empty()) {
QStyle *newStyle = style(); QStyle *newStyle = style();
const StandardButtonHash::iterator end = d->standardButtonHash.end(); for (auto key : d->standardButtonMap.keys())
for (StandardButtonHash::iterator it = d->standardButtonHash.begin(); it != end; ++it) key->setStyle(newStyle);
it.key()->setStyle(newStyle);
} }
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
Q_FALLTHROUGH(); Q_FALLTHROUGH();

View File

@ -16,6 +16,7 @@
// //
#include <private/qwidget_p.h> #include <private/qwidget_p.h>
#include <private/qflatmap_p.h>
#include <qdialogbuttonbox.h> #include <qdialogbuttonbox.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -42,8 +43,8 @@ public:
QDialogButtonBoxPrivate(Qt::Orientation orient); QDialogButtonBoxPrivate(Qt::Orientation orient);
QList<QAbstractButton *> buttonLists[QDialogButtonBox::NRoles]; QList<QAbstractButton *> buttonLists[QDialogButtonBox::NRoles];
QHash<QPushButton *, QDialogButtonBox::StandardButton> standardButtonHash; QVarLengthFlatMap<QPushButton *, QDialogButtonBox::StandardButton, 8> standardButtonMap;
QHash<QAbstractButton *, QDialogButtonBox::ButtonRole> hiddenButtons; QVarLengthFlatMap<QAbstractButton *, QDialogButtonBox::ButtonRole, 8> hiddenButtons;
Qt::Orientation orientation; Qt::Orientation orientation;
QDialogButtonBox::ButtonLayout layoutPolicy; QDialogButtonBox::ButtonLayout layoutPolicy;