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));
if (style != QApplication::style()) // Propagate style
button->setStyle(style);
standardButtonHash.insert(button, sbutton);
standardButtonMap.insert(button, sbutton);
QPlatformDialogHelper::ButtonRole role = QPlatformDialogHelper::buttonRole(static_cast<QPlatformDialogHelper::StandardButton>(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<QAbstractButton *> &list = d->buttonLists[i];
for (auto button : std::as_const(list)) {
@ -680,7 +680,11 @@ QList<QAbstractButton *> QDialogButtonBoxPrivate::visibleButtons() 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.
\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<QPushButton *>(button));
standardButtonMap.remove(reinterpret_cast<QPushButton *>(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<QPushButton *, StandardButton>::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<QPushButton *>(button));
return d->standardButtonMap.value(static_cast<QPushButton *>(button));
}
void QDialogButtonBoxPrivate::handleButtonClicked()
@ -965,16 +972,13 @@ bool QDialogButtonBox::centerButtons() const
*/
void QDialogButtonBox::changeEvent(QEvent *event)
{
typedef QHash<QPushButton *, QDialogButtonBox::StandardButton> 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();

View File

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