From a640ada8cc260dd315222a52b51655fb5ab5513a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20Br=C3=BCbach?= Date: Mon, 21 Sep 2026 00:09:51 +0200 Subject: [PATCH] [CardSearchModel] Match English and localized names in Both mode Card names are stored in both English and localized forms, so search for matches in both during the 'Both' search mode instead of checking only the localized name. --- .../database/card/card_search_model.cpp | 60 ++++++++++++------- .../models/database/card/card_search_model.h | 8 ++- 2 files changed, 45 insertions(+), 23 deletions(-) diff --git a/libcockatrice_models/libcockatrice/models/database/card/card_search_model.cpp b/libcockatrice_models/libcockatrice/models/database/card/card_search_model.cpp index 5d4e0ec9b..3a734ed37 100644 --- a/libcockatrice_models/libcockatrice/models/database/card/card_search_model.cpp +++ b/libcockatrice_models/libcockatrice/models/database/card/card_search_model.cpp @@ -66,36 +66,30 @@ void CardSearchModel::updateSearchResults(const QString &query) } // The completer suggestions match against the same languages the card - // search uses, so typing a localized name finds the card. - QString matchName = card->getName(); - if (searchLanguage.mode != SearchLanguageMode::English && !searchLanguage.isEnglishOnly()) { - matchName = card->getLocalizedName(searchLanguage.language); - } - const QString lowerName = matchName.toLower(); - if (!lowerName.contains(lowerQuery)) { - continue; - } + // search uses, so typing a localized name finds the card. In Both mode + // either language can match. + for (const QString &matchName : searchableNames(card)) { + const QString lowerName = matchName.toLower(); + if (!lowerName.contains(lowerQuery)) { + continue; + } - const int distance = levenshteinDistance(lowerQuery, lowerName); + const int distance = levenshteinDistance(lowerQuery, lowerName); - if (lowerName.startsWith(lowerQuery)) { - prefixMatches.append({card, distance}); - } else { - containsMatches.append({card, distance}); + if (lowerName.startsWith(lowerQuery)) { + prefixMatches.append({card, distance}); + } else { + containsMatches.append({card, distance}); + } + break; } } auto sortByDistanceThenLength = [this](const SearchResult &a, const SearchResult &b) { - QString nameA = a.card->getName(); - QString nameB = b.card->getName(); - if (searchLanguage.mode != SearchLanguageMode::English && !searchLanguage.isEnglishOnly()) { - nameA = a.card->getLocalizedName(searchLanguage.language); - nameB = b.card->getLocalizedName(searchLanguage.language); - } if (a.distance != b.distance) { return a.distance < b.distance; } - return nameA.size() < nameB.size(); + return sortableName(a.card).size() < sortableName(b.card).size(); }; std::sort(prefixMatches.begin(), prefixMatches.end(), sortByDistanceThenLength); @@ -112,4 +106,26 @@ void CardSearchModel::updateSearchResults(const QString &query) } endResetModel(); -} \ No newline at end of file +} + +QStringList CardSearchModel::searchableNames(const CardInfoPtr &card) const +{ + if (searchLanguage.isEnglishOnly()) { + return {card->getName()}; + } + + const QString localizedName = card->getLocalizedName(searchLanguage.language); + if (searchLanguage.mode == SearchLanguageMode::Selected) { + return {localizedName}; + } + + return {card->getName(), localizedName}; +} + +QString CardSearchModel::sortableName(const CardInfoPtr &card) const +{ + if (searchLanguage.isEnglishOnly()) { + return card->getName(); + } + return card->getLocalizedName(searchLanguage.language); +} diff --git a/libcockatrice_models/libcockatrice/models/database/card/card_search_model.h b/libcockatrice_models/libcockatrice/models/database/card/card_search_model.h index 5e810dffd..b877a9385 100644 --- a/libcockatrice_models/libcockatrice/models/database/card/card_search_model.h +++ b/libcockatrice_models/libcockatrice/models/database/card/card_search_model.h @@ -42,9 +42,15 @@ private: int distance; }; + /** @brief The names a card is searched by with the current search language. */ + [[nodiscard]] QStringList searchableNames(const CardInfoPtr &card) const; + + /** @brief The name used to break distance ties when sorting suggestions. */ + [[nodiscard]] QString sortableName(const CardInfoPtr &card) const; + CardDatabaseDisplayModel *sourceModel; QList searchResults; CardSearchLanguage searchLanguage; }; -#endif // CARD_SEARCH_MODEL_H \ No newline at end of file +#endif // CARD_SEARCH_MODEL_H