diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_settings.cpp b/cockatrice/src/interface/widgets/dialogs/dlg_settings.cpp index 8b1d54608..8a8573818 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_settings.cpp +++ b/cockatrice/src/interface/widgets/dialogs/dlg_settings.cpp @@ -17,7 +17,6 @@ #include "../settings_page/sound_settings_page.h" #include "../settings_page/storage_settings_page.h" #include "../settings_page/user_interface_settings_page.h" -#include "../utility/custom_line_edit.h" #include "libcockatrice/card/database/card_database_loader.h" #include "libcockatrice/card/database/card_database_manager.h" @@ -29,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -63,6 +63,17 @@ static QScrollArea *makeScrollable(QWidget *widget) return scrollArea; } +/** + * @brief Returns the theme icon resources for each settings page, indexed by SettingsPage order + */ +static QStringList pageIconResources() +{ + return {QStringLiteral("theme:config/general"), QStringLiteral("theme:config/appearance"), + QStringLiteral("theme:config/interface"), QStringLiteral("theme:config/deckeditor"), + QStringLiteral("theme:config/storage"), QStringLiteral("theme:config/messages"), + QStringLiteral("theme:config/sound"), QStringLiteral("theme:config/shorcuts")}; +} + DlgSettings::DlgSettings(QWidget *parent) : QDialog(parent), currentTabIndex(0), searchActive(false) { auto rec = QGuiApplication::primaryScreen()->availableGeometry(); @@ -121,9 +132,11 @@ void DlgSettings::setupUi() pagesWidget->addWidget(makeScrollable(userInterfacePage)); pagesWidget->addWidget(makeScrollable(deckEditorPage)); pagesWidget->addWidget(makeScrollable(storagePage)); - pagesWidget->addWidget(makeScrollable(messagesPage)); - pagesWidget->addWidget(makeScrollable(soundPage)); - pagesWidget->addWidget(makeScrollable(shortcutsPage)); + pagesWidget->addWidget(messagesPage); + pagesWidget->addWidget(soundPage); + pagesWidget->addWidget(shortcutsPage); + + Q_ASSERT(pages.size() == NumPages); // Search results view (hidden by default) searchResultsView = new QListView; @@ -138,7 +151,12 @@ void DlgSettings::setupUi() searchDelegate = new SettingsSearchDelegate(this); searchResultsView->setModel(searchModel); searchResultsView->setItemDelegate(searchDelegate); - connect(searchResultsView, &QListView::activated, this, &DlgSettings::onSearchResultActivated); + connect(searchResultsView, &QListView::clicked, this, &DlgSettings::onSearchResultClicked); + + connect(&SettingsCache::instance(), &SettingsCache::themeChanged, this, [this] { + searchDelegate->setPageIcons(pageIconResources()); + searchResultsView->viewport()->update(); + }); // Build search index after pages are created buildSearchIndex(); @@ -152,13 +170,10 @@ void DlgSettings::setupUi() pagesContainer->setLayout(containerLayout); // Bottom buttons - resetButton = new QPushButton; - connect(resetButton, &QPushButton::clicked, this, &DlgSettings::onResetDefaultsClicked); - auto *buttonBox = new QHBoxLayout; - buttonBox->addWidget(resetButton); buttonBox->addStretch(); okButton = new QPushButton; + okButton->setDefault(true); connect(okButton, &QPushButton::clicked, this, &DlgSettings::close); buttonBox->addWidget(okButton); @@ -202,28 +217,19 @@ void DlgSettings::setupTabBar() tabLayout->setContentsMargins(0, 0, 0, 0); tabLayout->setSpacing(2); - struct TabInfo - { - QString iconResource; - int pageIndex; - }; + const QStringList iconResources = pageIconResources(); - const TabInfo tabInfos[] = {{"theme:config/general", 0}, {"theme:config/appearance", 1}, - {"theme:config/interface", 2}, {"theme:config/deckeditor", 3}, - {"theme:config/storage", 4}, {"theme:config/messages", 5}, - {"theme:config/sound", 6}, {"theme:config/shorcuts", 7}}; - - for (const auto &info : tabInfos) { + for (int i = 0; i < iconResources.size(); ++i) { auto *tabButton = new QToolButton; tabButton->setCheckable(true); - tabButton->setIcon(QPixmap(info.iconResource)); + tabButton->setIcon(QPixmap(iconResources[i])); tabButton->setIconSize(QSize(48, 48)); tabButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); tabButton->setAutoExclusive(true); tabButton->setMinimumHeight(85); tabButton->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - connect(tabButton, &QToolButton::clicked, this, [this, idx = info.pageIndex] { onTabClicked(idx); }); + connect(tabButton, &QToolButton::clicked, this, [this, idx = i] { onTabClicked(idx); }); tabButtons.append(tabButton); tabLayout->addWidget(tabButton); @@ -236,11 +242,9 @@ void DlgSettings::buildSearchIndex() { QList allEntries; - if (pageNames.isEmpty()) { - pageNames << tr("General") << tr("Appearance") << tr("User Interface") << tr("Card Sources") << tr("Storage") - << tr("Chat") << tr("Sound") << tr("Shortcuts"); - } + const QStringList pageNames = translatedPageNames(); searchDelegate->setPageNames(pageNames); + searchDelegate->setPageIcons(pageIconResources()); for (int i = 0; i < pages.size(); ++i) { QList pageEntries = pages[i]->getSearchEntries(); @@ -321,7 +325,7 @@ void DlgSettings::flashWidget(QWidget *widget) fadeOut->setEndValue(0.0); fadeOut->setEasingCurve(QEasingCurve::InCubic); - auto *group = new QSequentialAnimationGroup; + auto *group = new QSequentialAnimationGroup(overlay); group->addAnimation(flashIn); group->addAnimation(fadeOut); @@ -338,10 +342,11 @@ void DlgSettings::onSearchTextChanged(const QString &text) if (!searchActive) { switchToSearchMode(); } - } else { - if (searchActive) { - switchToTabMode(); + if (searchModel->rowCount(QModelIndex()) > 0) { + searchResultsView->setCurrentIndex(searchModel->index(0)); } + } else if (searchActive) { + switchToTabMode(); } } @@ -368,7 +373,7 @@ void DlgSettings::switchToTabMode() setActiveTab(currentTabIndex); } -void DlgSettings::onSearchResultActivated(const QModelIndex &index) +void DlgSettings::onSearchResultClicked(const QModelIndex &index) { navigateToSearchResult(index); } @@ -390,26 +395,11 @@ void DlgSettings::navigateToSearchResult(const QModelIndex &index) if (scrollArea) { scrollArea->ensureWidgetVisible(entry.widget); } + entry.widget->setFocus(); flashWidget(entry.widget); } } -void DlgSettings::onResetDefaultsClicked() -{ - if (QMessageBox::question(this, tr("Reset to Defaults"), - tr("Are you sure you want to reset all settings on this page to their defaults?")) != - QMessageBox::Yes) { - return; - } - - if (currentTabIndex >= 0 && currentTabIndex < pages.size()) { - pages[currentTabIndex]->resetToDefaults(); - } - - // Rebuild search index after reset - buildSearchIndex(); -} - void DlgSettings::setTab(int index) { if (index >= 0 && index < tabButtons.size()) { @@ -546,20 +536,21 @@ void DlgSettings::retranslateUi() retranslateTabNames(); searchEdit->setPlaceholderText(tr("Search settings...")); - resetButton->setText(tr("Reset to Defaults")); okButton->setText(tr("OK")); // Rebuild search index for translated text buildSearchIndex(); } +QStringList DlgSettings::translatedPageNames() +{ + return {tr("General"), tr("Appearance"), tr("User Interface"), tr("Card Sources"), + tr("Storage"), tr("Chat"), tr("Sound"), tr("Shortcuts")}; +} + void DlgSettings::retranslateTabNames() { - pageNames.clear(); - pageNames << tr("General") << tr("Appearance") << tr("User Interface") << tr("Card Sources") << tr("Storage") - << tr("Chat") << tr("Sound") << tr("Shortcuts"); - - const QStringList tabLabels = pageNames; + const QStringList tabLabels = translatedPageNames(); for (int i = 0; i < tabButtons.size() && i < tabLabels.size(); ++i) { tabButtons[i]->setText(tabLabels[i]); diff --git a/cockatrice/src/interface/widgets/dialogs/dlg_settings.h b/cockatrice/src/interface/widgets/dialogs/dlg_settings.h index 3ba3d2ea8..b700f7af9 100644 --- a/cockatrice/src/interface/widgets/dialogs/dlg_settings.h +++ b/cockatrice/src/interface/widgets/dialogs/dlg_settings.h @@ -33,14 +33,32 @@ class DlgSettings : public QDialog { Q_OBJECT public: + /** + * @brief Page order in the tab bar, matching the order pages are added in setupUi() + * + * Use these values instead of raw indices so reordering pages never silently + * breaks external callers like tab_room.cpp. + */ + enum SettingsPage + { + GeneralPage = 0, + AppearancePage, + UserInterfacePage, + DeckEditorPage, + StoragePage, + MessagesPage, + SoundPage, + ShortcutsPage, + NumPages + }; + explicit DlgSettings(QWidget *parent = nullptr); void setTab(int index); private slots: void onTabClicked(int index); void onSearchTextChanged(const QString &text); - void onSearchResultActivated(const QModelIndex &index); - void onResetDefaultsClicked(); + void onSearchResultClicked(const QModelIndex &index); void updateLanguage(); private: @@ -51,7 +69,6 @@ private: QStackedWidget *pagesWidget; ///< Stacked widget containing settings pages QListView *searchResultsView; ///< Search results list view QWidget *pagesContainer; ///< Container stacking pages and search results - QPushButton *resetButton; ///< Button to reset current page to defaults QPushButton *okButton; ///< Button to close the dialog // Data @@ -60,7 +77,6 @@ private: SettingsSearchDelegate *searchDelegate; ///< Delegate for search result rendering int currentTabIndex; ///< Currently active tab index bool searchActive; ///< Whether search mode is active - QStringList pageNames; ///< Translated page names for breadcrumb display void setupUi(); void setupTabBar(); @@ -69,7 +85,8 @@ private: void switchToSearchMode(); void navigateToSearchResult(const QModelIndex &index); void setActiveTab(int index); - void flashWidget(QWidget *widget); + static void flashWidget(QWidget *widget); + static QStringList translatedPageNames(); void retranslateUi(); void retranslateTabNames(); diff --git a/cockatrice/src/interface/widgets/settings_page/abstract_settings_page.cpp b/cockatrice/src/interface/widgets/settings_page/abstract_settings_page.cpp index e1c602d44..542d48c04 100644 --- a/cockatrice/src/interface/widgets/settings_page/abstract_settings_page.cpp +++ b/cockatrice/src/interface/widgets/settings_page/abstract_settings_page.cpp @@ -3,19 +3,129 @@ #include "settings_search_model.h" #include +#include +#include #include #include #include +#include +#include +#include + +/** + * @brief Recursively collects all widgets within a layout + * @param layout The layout to walk + * @param widgets Output list of (widget, containing layout) pairs + */ +static void collectWidgets(QLayout *layout, QList> &widgets) +{ + for (int i = 0; i < layout->count(); ++i) { + QLayoutItem *item = layout->itemAt(i); + if (!item) { + continue; + } + if (QWidget *widget = item->widget()) { + widgets.append({widget, layout}); + } else if (QLayout *subLayout = item->layout()) { + collectWidgets(subLayout, widgets); + } + } +} + +/** + * @brief Rejects QLabels that are not setting names + * + * HTML link labels, path values, and excessively long labels are filtered out. + */ +static bool isValidSettingLabel(const QLabel *label) +{ + const QString &text = label->text(); + if (Qt::mightBeRichText(text)) { + return false; + } + if (text.contains(QLatin1Char('/')) || text.contains(QLatin1Char('\\'))) { + return false; + } + if (text.size() > 60) { + return false; + } + return true; +} + +/** + * @brief Finds the control associated with a setting label + * + * Uses the explicit buddy if set, otherwise the widget in the cell (or slot) + * immediately following the label within the same layout. Falls back to the + * label itself when no obvious control is found. + */ +static QWidget *controlForLabel(QLabel *label, QLayout *containingLayout) +{ + if (QWidget *buddy = label->buddy()) { + return buddy; + } + + if (auto *grid = qobject_cast(containingLayout)) { + int index = grid->indexOf(label); + if (index != -1) { + int row = 0; + int column = 0; + int rowSpan = 1; + int columnSpan = 1; + grid->getItemPosition(index, &row, &column, &rowSpan, &columnSpan); + if (QLayoutItem *next = grid->itemAtPosition(row, column + columnSpan)) { + if (QWidget *nextWidget = next->widget()) { + return nextWidget; + } + } + } + } else { + int index = containingLayout->indexOf(label); + if (index != -1) { + for (int i = index + 1; i < containingLayout->count(); ++i) { + if (QLayoutItem *next = containingLayout->itemAt(i)) { + if (QWidget *nextWidget = next->widget()) { + return nextWidget; + } + } + } + } + } + + return label; +} + +/** + * @brief Builds the extended search text for an entry + * + * Combines the group title, label, and any extra searchable text derived from + * the associated control (tooltip, placeholder, prefix/suffix, combo text). + */ +static QString buildFullSearchText(const QString &groupTitle, const QString &cleanLabel, QWidget *control) +{ + QStringList parts = {groupTitle, cleanLabel}; + if (control) { + if (auto *lineEdit = qobject_cast(control)) { + parts.append(lineEdit->placeholderText()); + } else if (auto *spinBox = qobject_cast(control)) { + parts.append(spinBox->prefix()); + parts.append(spinBox->suffix()); + } else if (auto *comboBox = qobject_cast(control)) { + parts.append(comboBox->currentText()); + } + if (!control->toolTip().isEmpty()) { + parts.append(control->toolTip()); + } + } + parts.removeAll(QString()); + return parts.join(QLatin1Char(' ')); +} QList AbstractSettingsPage::getSearchEntries() { return autoDetectSearchEntries(this, -1); } -void AbstractSettingsPage::resetToDefaults() -{ -} - QList AbstractSettingsPage::autoDetectSearchEntries(QWidget *page, int pageIndex) { QList entries; @@ -37,107 +147,44 @@ QList AbstractSettingsPage::autoDetectSearchEntries(QWidget continue; } - for (int i = 0; i < groupLayout->count(); ++i) { - QLayoutItem *item = groupLayout->itemAt(i); - if (!item) { + QList> widgets; + collectWidgets(groupLayout, widgets); + + for (const auto &pair : widgets) { + QWidget *widget = pair.first; + QString label; + + auto *checkBox = qobject_cast(widget); + if (checkBox) { + label = checkBox->text(); + } else { + auto *labelWidget = qobject_cast(widget); + if (!labelWidget || labelWidget->text().isEmpty() || !isValidSettingLabel(labelWidget)) { + continue; + } + label = labelWidget->text(); + } + + if (label.isEmpty()) { continue; } - // Direct widget children (checkboxes, labels with buddies, etc.) - if (QWidget *widget = item->widget()) { - QString label; + // Strip accelerator markers (&) for search + QString cleanLabel = label; + cleanLabel.remove(QLatin1Char('&')); - auto *checkBox = qobject_cast(widget); - if (checkBox) { - label = checkBox->text(); - } else { - auto *labelWidget = qobject_cast(widget); - if (labelWidget && labelWidget->text().isEmpty()) { - continue; - } else if (labelWidget) { - label = labelWidget->text(); - } - } - - if (!label.isEmpty()) { - // Skip QLabels that are not setting names: HTML, path values, or excessively long - if (qobject_cast(widget)) { - auto *labelWidget = static_cast(widget); - if (labelWidget->textFormat() != Qt::PlainText) { - continue; - } - if (label.contains(QLatin1Char('/')) || label.contains(QLatin1Char('\\'))) { - continue; - } - if (label.size() > 60) { - continue; - } - } - - // Strip accelerator markers (&) for search - QString cleanLabel = label; - cleanLabel.remove(QLatin1Char('&')); - - SettingsSearchEntry entry; - entry.pageIndex = pageIndex; - entry.groupTitle = groupTitle; - entry.widgetLabel = cleanLabel; - entry.fullSearchText = QStringLiteral("%1 %2 %3").arg(groupTitle, cleanLabel, cleanLabel.toLower()); - entry.widget = widget; - entries.append(entry); - } + QWidget *control = widget; + if (auto *labelWidget = qobject_cast(widget)) { + control = controlForLabel(labelWidget, pair.second); } - // Layout items (nested grids, hboxes, vboxes) - if (item->layout()) { - for (int j = 0; j < item->layout()->count(); ++j) { - QLayoutItem *nestedItem = item->layout()->itemAt(j); - if (!nestedItem || !nestedItem->widget()) { - continue; - } - - QWidget *nestedWidget = nestedItem->widget(); - QString label; - - auto *checkBox = qobject_cast(nestedWidget); - if (checkBox) { - label = checkBox->text(); - } else { - auto *labelWidget = qobject_cast(nestedWidget); - if (labelWidget && !labelWidget->text().isEmpty()) { - label = labelWidget->text(); - } - } - - if (!label.isEmpty()) { - // Skip QLabels that are not setting names: HTML, path values, or excessively long - if (qobject_cast(nestedWidget)) { - auto *labelWidget = static_cast(nestedWidget); - if (labelWidget->textFormat() != Qt::PlainText) { - continue; - } - if (label.contains(QLatin1Char('/')) || label.contains(QLatin1Char('\\'))) { - continue; - } - if (label.size() > 60) { - continue; - } - } - - QString cleanLabel = label; - cleanLabel.remove(QLatin1Char('&')); - - SettingsSearchEntry entry; - entry.pageIndex = pageIndex; - entry.groupTitle = groupTitle; - entry.widgetLabel = cleanLabel; - entry.fullSearchText = - QStringLiteral("%1 %2 %3").arg(groupTitle, cleanLabel, cleanLabel.toLower()); - entry.widget = nestedWidget; - entries.append(entry); - } - } - } + SettingsSearchEntry entry; + entry.pageIndex = pageIndex; + entry.groupTitle = groupTitle; + entry.widgetLabel = cleanLabel; + entry.widget = control; + entry.fullSearchText = buildFullSearchText(groupTitle, cleanLabel, control); + entries.append(entry); } } diff --git a/cockatrice/src/interface/widgets/settings_page/abstract_settings_page.h b/cockatrice/src/interface/widgets/settings_page/abstract_settings_page.h index b6987ae01..3140f94f3 100644 --- a/cockatrice/src/interface/widgets/settings_page/abstract_settings_page.h +++ b/cockatrice/src/interface/widgets/settings_page/abstract_settings_page.h @@ -16,7 +16,6 @@ class AbstractSettingsPage : public QWidget public: virtual void retranslateUi() = 0; virtual QList getSearchEntries(); - virtual void resetToDefaults(); protected: static QList autoDetectSearchEntries(QWidget *page, int pageIndex); diff --git a/cockatrice/src/interface/widgets/settings_page/settings_search_delegate.cpp b/cockatrice/src/interface/widgets/settings_page/settings_search_delegate.cpp index 25b454969..2fdff3bce 100644 --- a/cockatrice/src/interface/widgets/settings_page/settings_search_delegate.cpp +++ b/cockatrice/src/interface/widgets/settings_page/settings_search_delegate.cpp @@ -18,6 +18,14 @@ void SettingsSearchDelegate::setPageNames(const QStringList &names) pageNames = names; } +void SettingsSearchDelegate::setPageIcons(const QStringList &iconResources) +{ + pageIcons.clear(); + for (const QString &resource : iconResources) { + pageIcons.append(QPixmap(resource)); + } +} + void SettingsSearchDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const @@ -35,6 +43,12 @@ void SettingsSearchDelegate::paint(QPainter *painter, : option.palette.color(QPalette::Base); painter->fillRect(option.rect, bgColor); + if (isSelected) { + // Accent bar on the left to make the selection unmistakable + painter->fillRect(QRect(option.rect.left(), option.rect.top(), 4, option.rect.height()), + option.palette.color(QPalette::Highlight).darker(150)); + } + int leftMargin = 12; int topMargin = 8; int rightMargin = 12; @@ -43,6 +57,19 @@ void SettingsSearchDelegate::paint(QPainter *painter, QRect contentRect = option.rect.adjusted(leftMargin, topMargin, -rightMargin, -bottomMargin); int yPos = contentRect.top(); + // Icon of the related settings page + const int iconSize = 24; + QPixmap pageIcon = + (entry.pageIndex >= 0 && entry.pageIndex < pageIcons.size()) ? pageIcons.at(entry.pageIndex) : QPixmap(); + int iconOffset = pageIcon.isNull() ? 0 : iconSize + 8; + if (!pageIcon.isNull()) { + QRect iconRect(contentRect.left(), contentRect.top() + (contentRect.height() - iconSize) / 2, iconSize, + iconSize); + painter->drawPixmap(iconRect, pageIcon); + } + + QRect textRect = contentRect.adjusted(iconOffset, 0, 0, 0); + // Breadcrumb: "Page > Group" QFont breadcrumbFont = option.font; breadcrumbFont.setPointSize(breadcrumbFont.pointSize() - 1); @@ -50,7 +77,9 @@ void SettingsSearchDelegate::paint(QPainter *painter, QColor breadcrumbColor = isSelected ? option.palette.color(QPalette::HighlightedText) : option.palette.color(QPalette::Text); - breadcrumbColor.setAlpha(180); + if (!isSelected) { + breadcrumbColor.setAlpha(180); + } QString pageName; if (entry.pageIndex >= 0 && entry.pageIndex < pageNames.size()) { @@ -62,20 +91,21 @@ void SettingsSearchDelegate::paint(QPainter *painter, QString breadcrumbText = QStringLiteral("%1 > %2").arg(pageName, entry.groupTitle); painter->setFont(breadcrumbFont); painter->setPen(breadcrumbColor); - painter->drawText(QRect(contentRect.left(), yPos, contentRect.width(), 20), Qt::AlignLeft | Qt::AlignVCenter, + painter->drawText(QRect(textRect.left(), yPos, textRect.width(), 20), Qt::AlignLeft | Qt::AlignVCenter, breadcrumbText); yPos += 20; // Setting label QFont labelFont = option.font; labelFont.setPointSize(labelFont.pointSize() + 1); + labelFont.setBold(isSelected); QColor labelColor = isSelected ? option.palette.color(QPalette::HighlightedText) : option.palette.color(QPalette::Text); painter->setFont(labelFont); painter->setPen(labelColor); - painter->drawText(QRect(contentRect.left(), yPos, contentRect.width(), 24), Qt::AlignLeft | Qt::AlignVCenter, + painter->drawText(QRect(textRect.left(), yPos, textRect.width(), 24), Qt::AlignLeft | Qt::AlignVCenter, entry.widgetLabel); yPos += 24; diff --git a/cockatrice/src/interface/widgets/settings_page/settings_search_delegate.h b/cockatrice/src/interface/widgets/settings_page/settings_search_delegate.h index 39249db16..aa296049a 100644 --- a/cockatrice/src/interface/widgets/settings_page/settings_search_delegate.h +++ b/cockatrice/src/interface/widgets/settings_page/settings_search_delegate.h @@ -6,6 +6,7 @@ #ifndef COCKATRICE_SETTINGS_SEARCH_DELEGATE_H #define COCKATRICE_SETTINGS_SEARCH_DELEGATE_H +#include #include /** @@ -26,8 +27,12 @@ public: /** @brief Sets the translated page names for breadcrumb display */ void setPageNames(const QStringList &names); + /** @brief Sets the icons shown in front of results, indexed by page position */ + void setPageIcons(const QStringList &iconResources); + private: - QStringList pageNames; ///< Translated page names indexed by page position + QStringList pageNames; ///< Translated page names indexed by page position + QList pageIcons; ///< Icons of the related settings pages }; #endif // COCKATRICE_SETTINGS_SEARCH_DELEGATE_H diff --git a/cockatrice/src/interface/widgets/settings_page/settings_search_model.cpp b/cockatrice/src/interface/widgets/settings_page/settings_search_model.cpp index 828ee57dc..71f859d4b 100644 --- a/cockatrice/src/interface/widgets/settings_page/settings_search_model.cpp +++ b/cockatrice/src/interface/widgets/settings_page/settings_search_model.cpp @@ -5,7 +5,8 @@ */ #include "settings_search_model.h" -#include +#include +#include SettingsSearchModel::SettingsSearchModel(QObject *parent) : QAbstractListModel(parent) { @@ -88,7 +89,12 @@ void SettingsSearchModel::rebuildFilter() } else { QList> scored; // for (int i = 0; i < sourceEntries.size(); ++i) { - int score = relevanceScore(sourceEntries[i], filterQuery, filterRegex); + const SettingsSearchEntry &entry = sourceEntries[i]; + // Skip conditional settings that are currently disabled or hidden + if (entry.widget && (!entry.widget->isEnabled() || entry.widget->isHidden())) { + continue; + } + int score = relevanceScore(entry, filterQuery, filterRegex); if (score > 0) { scored.append({-score, i}); // negative for descending sort } @@ -120,12 +126,6 @@ QVariant SettingsSearchModel::data(const QModelIndex &index, int role) const switch (role) { case EntryRole: return QVariant::fromValue(entry); - case PageIndexRole: - return entry.pageIndex; - case GroupTitleRole: - return entry.groupTitle; - case WidgetLabelRole: - return entry.widgetLabel; case Qt::DisplayRole: return entry.widgetLabel; case Qt::ToolTipRole: @@ -143,14 +143,3 @@ SettingsSearchEntry SettingsSearchModel::entryForIndex(const QModelIndex &index) } return sourceEntries[filteredIndices[index.row()]]; } - -QList SettingsSearchModel::filteredPageIndices() const -{ - QSet pages; - for (int idx : filteredIndices) { - pages.insert(sourceEntries[idx].pageIndex); - } - QList result = pages.values(); - std::sort(result.begin(), result.end()); - return result; -} diff --git a/cockatrice/src/interface/widgets/settings_page/settings_search_model.h b/cockatrice/src/interface/widgets/settings_page/settings_search_model.h index 9a8c1f5d3..0b590f180 100644 --- a/cockatrice/src/interface/widgets/settings_page/settings_search_model.h +++ b/cockatrice/src/interface/widgets/settings_page/settings_search_model.h @@ -22,7 +22,7 @@ struct SettingsSearchEntry int pageIndex; ///< Index of the settings page this entry belongs to QString groupTitle; ///< Title of the group/section within the page QString widgetLabel; ///< Display label for the setting widget - QString fullSearchText; ///< Extended search text for full-text matching + QString fullSearchText; ///< Extended search text (label, control text, tooltip) for full-text matching QWidget *widget; ///< Pointer to the setting widget for focus/scrolling }; @@ -38,16 +38,11 @@ class SettingsSearchModel : public QAbstractListModel Q_OBJECT public: /** - * @brief Custom data roles for accessing entry fields + * @brief Custom data role for accessing the full entry */ enum Roles { EntryRole = Qt::UserRole + 1, ///< Full SettingsSearchEntry object - PageIndexRole, ///< Entry's page index (int) - GroupTitleRole, ///< Entry's group title (QString) - WidgetLabelRole, ///< Entry's widget label (QString) - HighlightStartRole, ///< Start of highlight range - HighlightEndRole, ///< End of highlight range }; explicit SettingsSearchModel(QObject *parent = nullptr); @@ -64,8 +59,6 @@ public: /** @brief Returns the full entry for a given model index */ SettingsSearchEntry entryForIndex(const QModelIndex &index) const; - /** @brief Returns sorted list of page indices present in filtered results */ - QList filteredPageIndices() const; private: QList sourceEntries; ///< Complete unfiltered entry list diff --git a/cockatrice/src/interface/widgets/tabs/tab_room.cpp b/cockatrice/src/interface/widgets/tabs/tab_room.cpp index 181da22a9..5705c184e 100644 --- a/cockatrice/src/interface/widgets/tabs/tab_room.cpp +++ b/cockatrice/src/interface/widgets/tabs/tab_room.cpp @@ -242,7 +242,7 @@ void TabRoom::actClearChat() void TabRoom::actOpenChatSettings() { DlgSettings settings(this); - settings.setTab(5); + settings.setTab(DlgSettings::MessagesPage); settings.exec(); }