mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-21 00:55:09 -07:00
[Filters] Pass CardSearchLanguage as a single struct
This commit is contained in:
parent
2191ce9c75
commit
0967644640
18 changed files with 187 additions and 196 deletions
|
|
@ -47,12 +47,7 @@ static std::once_flag init;
|
|||
// per-instance state. The card language that the nested [[card name]] search matches
|
||||
// against is passed through this thread-local context, which is live only while a
|
||||
// DeckFilterString is being parsed, and copied into the nested FilterString closures.
|
||||
struct DeckSearchLanguageContext
|
||||
{
|
||||
QString searchLanguage;
|
||||
SearchLanguageMode searchLanguageMode = SearchLanguageMode::English;
|
||||
};
|
||||
thread_local DeckSearchLanguageContext deckSearchLanguageContext;
|
||||
thread_local CardSearchLanguage deckSearchLanguageContext;
|
||||
|
||||
static void setupParserRules()
|
||||
{
|
||||
|
|
@ -127,9 +122,7 @@ static void setupParserRules()
|
|||
|
||||
// actual functionality
|
||||
search["DeckContentQuery"] = [](const peg::SemanticValues &sv) -> DeckFilter {
|
||||
const QString searchLanguage = deckSearchLanguageContext.searchLanguage;
|
||||
const SearchLanguageMode searchLanguageMode = deckSearchLanguageContext.searchLanguageMode;
|
||||
auto cardFilter = FilterString(std::any_cast<QString>(sv[0]), searchLanguage, searchLanguageMode);
|
||||
auto cardFilter = FilterString(std::any_cast<QString>(sv[0]), deckSearchLanguageContext);
|
||||
auto numberMatcher = sv.size() > 1 ? std::any_cast<NumberMatcher>(sv[1]) : [](int count) { return count > 0; };
|
||||
|
||||
return [=](const DeckSearchData &data) -> bool {
|
||||
|
|
@ -199,9 +192,7 @@ DeckFilterString::DeckFilterString()
|
|||
_error = "Not initialized";
|
||||
}
|
||||
|
||||
DeckFilterString::DeckFilterString(const QString &expr,
|
||||
const QString &searchLanguage,
|
||||
SearchLanguageMode searchLanguageMode)
|
||||
DeckFilterString::DeckFilterString(const QString &expr, const CardSearchLanguage &searchLanguage)
|
||||
{
|
||||
QByteArray ba = expr.simplified().toUtf8();
|
||||
|
||||
|
|
@ -214,7 +205,7 @@ DeckFilterString::DeckFilterString(const QString &expr,
|
|||
return;
|
||||
}
|
||||
|
||||
deckSearchLanguageContext = DeckSearchLanguageContext{searchLanguage, searchLanguageMode};
|
||||
deckSearchLanguageContext = searchLanguage;
|
||||
|
||||
search.set_logger([&](size_t /*ln*/, size_t col, const std::string &msg) {
|
||||
_error = QString("Error at position %1: %2").arg(col).arg(QString::fromStdString(msg));
|
||||
|
|
|
|||
|
|
@ -36,9 +36,7 @@ class DeckFilterString
|
|||
{
|
||||
public:
|
||||
DeckFilterString();
|
||||
explicit DeckFilterString(const QString &expr,
|
||||
const QString &searchLanguage = QString(),
|
||||
SearchLanguageMode searchLanguageMode = SearchLanguageMode::English);
|
||||
explicit DeckFilterString(const QString &expr, const CardSearchLanguage &searchLanguage = {});
|
||||
bool check(const DeckSearchData &data) const
|
||||
{
|
||||
return filter(data);
|
||||
|
|
|
|||
|
|
@ -92,8 +92,8 @@ DlgCreateToken::DlgCreateToken(const QStringList &_predefinedTokens, QWidget *pa
|
|||
|
||||
CardsDisplaySettings *cardsDisplay = &SettingsCache::instance().cardsDisplay();
|
||||
const auto applyCardSearchLanguage = [this, cardsDisplay]() {
|
||||
cardDatabaseDisplayModel->setSearchLanguage(
|
||||
cardsDisplay->getCardLang(), static_cast<SearchLanguageMode>(cardsDisplay->getCardSearchLanguage()));
|
||||
cardDatabaseDisplayModel->setSearchLanguage(CardSearchLanguage{
|
||||
cardsDisplay->getCardLang(), static_cast<SearchLanguageMode>(cardsDisplay->getCardSearchLanguage())});
|
||||
};
|
||||
applyCardSearchLanguage();
|
||||
connect(cardsDisplay, &CardsDisplaySettings::cardLangChanged, this, applyCardSearchLanguage);
|
||||
|
|
|
|||
|
|
@ -257,8 +257,9 @@ ZoneViewZone::GridSize ZoneViewZone::positionCardsForDisplay(CardList &cards, Ca
|
|||
void ZoneViewZone::setFilterString(const QString &_filterString)
|
||||
{
|
||||
const CardsDisplaySettings &cardsDisplay = SettingsCache::instance().cardsDisplay();
|
||||
filterString = FilterString(_filterString, cardsDisplay.getCardLang(),
|
||||
static_cast<SearchLanguageMode>(cardsDisplay.getCardSearchLanguage()));
|
||||
filterString = FilterString(
|
||||
_filterString, CardSearchLanguage{cardsDisplay.getCardLang(),
|
||||
static_cast<SearchLanguageMode>(cardsDisplay.getCardSearchLanguage())});
|
||||
reorganizeCards();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ DeckEditorDatabaseDisplayWidget::DeckEditorDatabaseDisplayWidget(QWidget *parent
|
|||
|
||||
CardsDisplaySettings *cardsDisplay = &SettingsCache::instance().cardsDisplay();
|
||||
const auto applyCardSearchLanguage = [this, cardsDisplay]() {
|
||||
databaseDisplayModel->setSearchLanguage(cardsDisplay->getCardLang(),
|
||||
static_cast<SearchLanguageMode>(cardsDisplay->getCardSearchLanguage()));
|
||||
databaseDisplayModel->setSearchLanguage(CardSearchLanguage{
|
||||
cardsDisplay->getCardLang(), static_cast<SearchLanguageMode>(cardsDisplay->getCardSearchLanguage())});
|
||||
};
|
||||
applyCardSearchLanguage();
|
||||
connect(cardsDisplay, &CardsDisplaySettings::cardLangChanged, this, applyCardSearchLanguage);
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ namespace
|
|||
{
|
||||
void applyCardSearchLanguage(CardSearchModel *searchModel)
|
||||
{
|
||||
const auto &cardsDisplay = SettingsCache::instance().cardsDisplay();
|
||||
searchModel->setSearchLanguage(cardsDisplay.getCardLang(),
|
||||
static_cast<SearchLanguageMode>(cardsDisplay.getCardSearchLanguage()));
|
||||
const CardsDisplaySettings &cardsDisplay = SettingsCache::instance().cardsDisplay();
|
||||
searchModel->setSearchLanguage(CardSearchLanguage{
|
||||
cardsDisplay.getCardLang(), static_cast<SearchLanguageMode>(cardsDisplay.getCardSearchLanguage())});
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@ VisualDatabaseDisplayWidget::VisualDatabaseDisplayWidget(QWidget *parent,
|
|||
|
||||
CardsDisplaySettings *cardsDisplay = &SettingsCache::instance().cardsDisplay();
|
||||
const auto applyCardSearchLanguage = [this, cardsDisplay]() {
|
||||
databaseDisplayModel->setSearchLanguage(cardsDisplay->getCardLang(),
|
||||
static_cast<SearchLanguageMode>(cardsDisplay->getCardSearchLanguage()));
|
||||
databaseDisplayModel->setSearchLanguage(CardSearchLanguage{
|
||||
cardsDisplay->getCardLang(), static_cast<SearchLanguageMode>(cardsDisplay->getCardSearchLanguage())});
|
||||
};
|
||||
applyCardSearchLanguage();
|
||||
connect(cardsDisplay, &CardsDisplaySettings::cardLangChanged, this, applyCardSearchLanguage);
|
||||
|
|
|
|||
|
|
@ -191,8 +191,9 @@ void VisualDeckStorageSortFilterProxyModel::updateSearchMatches()
|
|||
}
|
||||
|
||||
const auto &cardsDisplay = SettingsCache::instance().cardsDisplay();
|
||||
DeckFilterString filterString(searchText, cardsDisplay.getCardLang(),
|
||||
static_cast<SearchLanguageMode>(cardsDisplay.getCardSearchLanguage()));
|
||||
DeckFilterString filterString(
|
||||
searchText, CardSearchLanguage{cardsDisplay.getCardLang(),
|
||||
static_cast<SearchLanguageMode>(cardsDisplay.getCardSearchLanguage())});
|
||||
for (int row = 0; row < count; ++row) {
|
||||
const DeckPreviewData &data = source->dataForRow(row);
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,32 @@ enum class SearchLanguageMode
|
|||
Both ///< Search both the English and the selected card language names and texts.
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The card language and matching mode searches run against.
|
||||
*
|
||||
* Bundles the card language code configured in the settings with the
|
||||
* SearchLanguageMode, so entry points take one value instead of two related
|
||||
* parameters.
|
||||
*/
|
||||
struct CardSearchLanguage
|
||||
{
|
||||
QString language; ///< Card language code (e.g. "de"); empty means the English fallback.
|
||||
SearchLanguageMode mode = SearchLanguageMode::English; ///< How the language participates in the search.
|
||||
|
||||
/**
|
||||
* @brief Whether only the English card data is searched.
|
||||
*
|
||||
* @return True when no card language is selected or English itself is selected.
|
||||
*/
|
||||
[[nodiscard]] bool isEnglishOnly() const
|
||||
{
|
||||
return language.isEmpty() || language == QLatin1String("en");
|
||||
}
|
||||
|
||||
bool operator==(const CardSearchLanguage &) const = default;
|
||||
bool operator!=(const CardSearchLanguage &) const = default;
|
||||
};
|
||||
|
||||
/**
|
||||
* @namespace CardLocalization
|
||||
* @ingroup Cards
|
||||
|
|
|
|||
|
|
@ -80,34 +80,27 @@ static std::once_flag init;
|
|||
// and OracleQuery rule actions through this thread-local context, which is live only
|
||||
// while a FilterString is being parsed. The rule actions copy it into the filter
|
||||
// closures they produce, so card evaluation never reads process-global state.
|
||||
struct SearchLanguageContext
|
||||
{
|
||||
QString searchLanguage;
|
||||
SearchLanguageMode searchLanguageMode = SearchLanguageMode::English;
|
||||
};
|
||||
thread_local SearchLanguageContext searchLanguageContext;
|
||||
thread_local CardSearchLanguage searchLanguageContext;
|
||||
|
||||
namespace
|
||||
{
|
||||
bool matchesInSearchLanguage(const QString &english,
|
||||
const QString &localized,
|
||||
const QString &searchLanguage,
|
||||
SearchLanguageMode searchLanguageMode,
|
||||
const CardSearchLanguage &searchLanguage,
|
||||
const StringMatcher &matcher)
|
||||
{
|
||||
if (searchLanguageMode == SearchLanguageMode::English) {
|
||||
if (searchLanguage.mode == SearchLanguageMode::English) {
|
||||
return matcher(english);
|
||||
}
|
||||
|
||||
if (searchLanguageMode == SearchLanguageMode::Both && matcher(english)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (searchLanguage.isEmpty() || searchLanguage == "en") {
|
||||
if (searchLanguage.mode == SearchLanguageMode::Both) {
|
||||
if (!searchLanguage.isEnglishOnly() && matcher(localized)) {
|
||||
return true;
|
||||
}
|
||||
return matcher(english);
|
||||
}
|
||||
|
||||
return matcher(localized);
|
||||
return searchLanguage.isEnglishOnly() ? matcher(english) : matcher(localized);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
|
@ -370,11 +363,10 @@ static void setupParserRules()
|
|||
|
||||
search["OracleQuery"] = [](const peg::SemanticValues &sv) -> Filter {
|
||||
const auto matcher = std::any_cast<StringMatcher>(sv[0]);
|
||||
const QString searchLanguage = searchLanguageContext.searchLanguage;
|
||||
const SearchLanguageMode searchLanguageMode = searchLanguageContext.searchLanguageMode;
|
||||
const CardSearchLanguage searchLanguage = searchLanguageContext;
|
||||
return [=](const CardData &x) {
|
||||
return matchesInSearchLanguage(x->getText(), x->getLocalizedText(searchLanguage), searchLanguage,
|
||||
searchLanguageMode, matcher);
|
||||
return matchesInSearchLanguage(x->getText(), x->getLocalizedText(searchLanguage.language), searchLanguage,
|
||||
matcher);
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -452,11 +444,10 @@ static void setupParserRules()
|
|||
};
|
||||
search["GenericQuery"] = [](const peg::SemanticValues &sv) -> Filter {
|
||||
const auto matcher = std::any_cast<StringMatcher>(sv[0]);
|
||||
const QString searchLanguage = searchLanguageContext.searchLanguage;
|
||||
const SearchLanguageMode searchLanguageMode = searchLanguageContext.searchLanguageMode;
|
||||
const CardSearchLanguage searchLanguage = searchLanguageContext;
|
||||
return [=](const CardData &x) {
|
||||
return matchesInSearchLanguage(x->getName(), x->getLocalizedName(searchLanguage), searchLanguage,
|
||||
searchLanguageMode, matcher);
|
||||
return matchesInSearchLanguage(x->getName(), x->getLocalizedName(searchLanguage.language), searchLanguage,
|
||||
matcher);
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -472,7 +463,7 @@ FilterString::FilterString()
|
|||
_error = "Not initialized";
|
||||
}
|
||||
|
||||
FilterString::FilterString(const QString &expr, const QString &searchLanguage, SearchLanguageMode searchLanguageMode)
|
||||
FilterString::FilterString(const QString &expr, const CardSearchLanguage &searchLanguage)
|
||||
{
|
||||
QByteArray ba = expr.simplified().toUtf8();
|
||||
|
||||
|
|
@ -485,7 +476,7 @@ FilterString::FilterString(const QString &expr, const QString &searchLanguage, S
|
|||
return;
|
||||
}
|
||||
|
||||
searchLanguageContext = SearchLanguageContext{searchLanguage, searchLanguageMode};
|
||||
searchLanguageContext = searchLanguage;
|
||||
|
||||
search.set_logger([&](size_t /*ln*/, size_t col, const std::string &msg) {
|
||||
_error = QString("Error at position %1: %2").arg(col).arg(QString::fromStdString(msg));
|
||||
|
|
|
|||
|
|
@ -36,9 +36,7 @@ class FilterString
|
|||
{
|
||||
public:
|
||||
FilterString();
|
||||
explicit FilterString(const QString &exp,
|
||||
const QString &searchLanguage = QString(),
|
||||
SearchLanguageMode searchLanguageMode = SearchLanguageMode::English);
|
||||
explicit FilterString(const QString &exp, const CardSearchLanguage &searchLanguage = {});
|
||||
[[nodiscard]] bool check(const CardData &card) const
|
||||
{
|
||||
if (card.isNull()) {
|
||||
|
|
|
|||
|
|
@ -102,15 +102,14 @@ FilterTreeNode *FilterItemList::termNode(const QString &term)
|
|||
|
||||
bool FilterItemList::testTypeAnd(const CardInfoPtr info,
|
||||
CardFilter::Attr attr,
|
||||
const QString &searchLanguage,
|
||||
SearchLanguageMode searchLanguageMode) const
|
||||
const CardSearchLanguage &searchLanguage) const
|
||||
{
|
||||
for (auto i = childNodes.constBegin(); i != childNodes.constEnd(); i++) {
|
||||
if (!(*i)->isEnabled()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(*i)->acceptCardAttr(info, attr, searchLanguage, searchLanguageMode)) {
|
||||
if (!(*i)->acceptCardAttr(info, attr, searchLanguage)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -120,17 +119,15 @@ bool FilterItemList::testTypeAnd(const CardInfoPtr info,
|
|||
|
||||
bool FilterItemList::testTypeAndNot(const CardInfoPtr info,
|
||||
CardFilter::Attr attr,
|
||||
const QString &searchLanguage,
|
||||
SearchLanguageMode searchLanguageMode) const
|
||||
const CardSearchLanguage &searchLanguage) const
|
||||
{
|
||||
// if any one in the list is true, return false
|
||||
return !testTypeOr(info, attr, searchLanguage, searchLanguageMode);
|
||||
return !testTypeOr(info, attr, searchLanguage);
|
||||
}
|
||||
|
||||
bool FilterItemList::testTypeOr(const CardInfoPtr info,
|
||||
CardFilter::Attr attr,
|
||||
const QString &searchLanguage,
|
||||
SearchLanguageMode searchLanguageMode) const
|
||||
const CardSearchLanguage &searchLanguage) const
|
||||
{
|
||||
bool noChildEnabledChild = true;
|
||||
|
||||
|
|
@ -143,7 +140,7 @@ bool FilterItemList::testTypeOr(const CardInfoPtr info,
|
|||
noChildEnabledChild = false;
|
||||
}
|
||||
|
||||
if ((*i)->acceptCardAttr(info, attr, searchLanguage, searchLanguageMode)) {
|
||||
if ((*i)->acceptCardAttr(info, attr, searchLanguage)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -153,49 +150,56 @@ bool FilterItemList::testTypeOr(const CardInfoPtr info,
|
|||
|
||||
bool FilterItemList::testTypeOrNot(const CardInfoPtr info,
|
||||
CardFilter::Attr attr,
|
||||
const QString &searchLanguage,
|
||||
SearchLanguageMode searchLanguageMode) const
|
||||
const CardSearchLanguage &searchLanguage) const
|
||||
{
|
||||
// if any one in the list is false, return true
|
||||
return !testTypeAnd(info, attr, searchLanguage, searchLanguageMode);
|
||||
return !testTypeAnd(info, attr, searchLanguage);
|
||||
}
|
||||
|
||||
bool FilterItem::acceptName(const CardInfoPtr info,
|
||||
const QString &searchLanguage,
|
||||
SearchLanguageMode searchLanguageMode) const
|
||||
bool FilterItem::acceptName(const CardInfoPtr info, const CardSearchLanguage &searchLanguage) const
|
||||
{
|
||||
if (searchLanguageMode == SearchLanguageMode::English) {
|
||||
return info->getName().contains(term, Qt::CaseInsensitive);
|
||||
const QString &englishName = info->getName();
|
||||
const QString &localizedName = info->getLocalizedName(searchLanguage.language);
|
||||
|
||||
switch (searchLanguage.mode) {
|
||||
case SearchLanguageMode::English:
|
||||
return englishName.contains(term, Qt::CaseInsensitive);
|
||||
case SearchLanguageMode::Both:
|
||||
if (englishName.contains(term, Qt::CaseInsensitive)) {
|
||||
return true;
|
||||
}
|
||||
return !searchLanguage.isEnglishOnly() && localizedName.contains(term, Qt::CaseInsensitive);
|
||||
case SearchLanguageMode::Selected:
|
||||
if (searchLanguage.isEnglishOnly()) {
|
||||
return englishName.contains(term, Qt::CaseInsensitive);
|
||||
}
|
||||
return localizedName.contains(term, Qt::CaseInsensitive);
|
||||
}
|
||||
|
||||
if (searchLanguageMode == SearchLanguageMode::Both && info->getName().contains(term, Qt::CaseInsensitive)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (searchLanguage.isEmpty() || searchLanguage == "en") {
|
||||
return info->getName().contains(term, Qt::CaseInsensitive);
|
||||
}
|
||||
|
||||
return info->getLocalizedName(searchLanguage).contains(term, Qt::CaseInsensitive);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FilterItem::acceptNameExact(const CardInfoPtr info,
|
||||
const QString &searchLanguage,
|
||||
SearchLanguageMode searchLanguageMode) const
|
||||
bool FilterItem::acceptNameExact(const CardInfoPtr info, const CardSearchLanguage &searchLanguage) const
|
||||
{
|
||||
if (searchLanguageMode == SearchLanguageMode::English) {
|
||||
return info->getName() == term;
|
||||
const QString &englishName = info->getName();
|
||||
const QString &localizedName = info->getLocalizedName(searchLanguage.language);
|
||||
|
||||
switch (searchLanguage.mode) {
|
||||
case SearchLanguageMode::English:
|
||||
return englishName == term;
|
||||
case SearchLanguageMode::Both:
|
||||
if (englishName == term) {
|
||||
return true;
|
||||
}
|
||||
return !searchLanguage.isEnglishOnly() && localizedName == term;
|
||||
case SearchLanguageMode::Selected:
|
||||
if (searchLanguage.isEnglishOnly()) {
|
||||
return englishName == term;
|
||||
}
|
||||
return localizedName == term;
|
||||
}
|
||||
|
||||
if (searchLanguageMode == SearchLanguageMode::Both && info->getName() == term) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (searchLanguage.isEmpty() || searchLanguage == "en") {
|
||||
return info->getName() == term;
|
||||
}
|
||||
|
||||
return info->getLocalizedName(searchLanguage) == term;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FilterItem::acceptType(const CardInfoPtr info) const
|
||||
|
|
@ -253,23 +257,27 @@ bool FilterItem::acceptColor(const CardInfoPtr info) const
|
|||
return match_count == converted_term.length();
|
||||
}
|
||||
|
||||
bool FilterItem::acceptText(const CardInfoPtr info,
|
||||
const QString &searchLanguage,
|
||||
SearchLanguageMode searchLanguageMode) const
|
||||
bool FilterItem::acceptText(const CardInfoPtr info, const CardSearchLanguage &searchLanguage) const
|
||||
{
|
||||
if (searchLanguageMode == SearchLanguageMode::English) {
|
||||
return info->getText().contains(term, Qt::CaseInsensitive);
|
||||
const QString &englishText = info->getText();
|
||||
const QString &localizedText = info->getLocalizedText(searchLanguage.language);
|
||||
|
||||
switch (searchLanguage.mode) {
|
||||
case SearchLanguageMode::English:
|
||||
return englishText.contains(term, Qt::CaseInsensitive);
|
||||
case SearchLanguageMode::Both:
|
||||
if (englishText.contains(term, Qt::CaseInsensitive)) {
|
||||
return true;
|
||||
}
|
||||
return !searchLanguage.isEnglishOnly() && localizedText.contains(term, Qt::CaseInsensitive);
|
||||
case SearchLanguageMode::Selected:
|
||||
if (searchLanguage.isEnglishOnly()) {
|
||||
return englishText.contains(term, Qt::CaseInsensitive);
|
||||
}
|
||||
return localizedText.contains(term, Qt::CaseInsensitive);
|
||||
}
|
||||
|
||||
if (searchLanguageMode == SearchLanguageMode::Both && info->getText().contains(term, Qt::CaseInsensitive)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (searchLanguage.isEmpty() || searchLanguage == "en") {
|
||||
return info->getText().contains(term, Qt::CaseInsensitive);
|
||||
}
|
||||
|
||||
return info->getLocalizedText(searchLanguage).contains(term, Qt::CaseInsensitive);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FilterItem::acceptSet(const CardInfoPtr info) const
|
||||
|
|
@ -458,20 +466,19 @@ bool FilterItem::relationCheck(int cardInfo) const
|
|||
|
||||
bool FilterItem::acceptCardAttr(const CardInfoPtr info,
|
||||
CardFilter::Attr attr,
|
||||
const QString &searchLanguage,
|
||||
SearchLanguageMode searchLanguageMode) const
|
||||
const CardSearchLanguage &searchLanguage) const
|
||||
{
|
||||
switch (attr) {
|
||||
case CardFilter::AttrName:
|
||||
return acceptName(info, searchLanguage, searchLanguageMode);
|
||||
return acceptName(info, searchLanguage);
|
||||
case CardFilter::AttrNameExact:
|
||||
return acceptNameExact(info, searchLanguage, searchLanguageMode);
|
||||
return acceptNameExact(info, searchLanguage);
|
||||
case CardFilter::AttrType:
|
||||
return acceptType(info);
|
||||
case CardFilter::AttrColor:
|
||||
return acceptColor(info);
|
||||
case CardFilter::AttrText:
|
||||
return acceptText(info, searchLanguage, searchLanguageMode);
|
||||
return acceptText(info, searchLanguage);
|
||||
case CardFilter::AttrSet:
|
||||
return acceptSet(info);
|
||||
case CardFilter::AttrManaCost:
|
||||
|
|
@ -541,21 +548,18 @@ FilterTreeNode *FilterTree::termNode(const CardFilter *f)
|
|||
return termNode(f->attr(), f->type(), f->term());
|
||||
}
|
||||
|
||||
bool FilterTree::testAttr(const CardInfoPtr info,
|
||||
const LogicMap *lm,
|
||||
const QString &searchLanguage,
|
||||
SearchLanguageMode searchLanguageMode) const
|
||||
bool FilterTree::testAttr(const CardInfoPtr info, const LogicMap *lm, const CardSearchLanguage &searchLanguage) const
|
||||
{
|
||||
const FilterItemList *fil;
|
||||
bool status = true;
|
||||
|
||||
fil = lm->findTypeList(CardFilter::TypeAnd);
|
||||
if (fil && fil->isEnabled() && !fil->testTypeAnd(info, lm->attr, searchLanguage, searchLanguageMode)) {
|
||||
if (fil && fil->isEnabled() && !fil->testTypeAnd(info, lm->attr, searchLanguage)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fil = lm->findTypeList(CardFilter::TypeAndNot);
|
||||
if (fil && fil->isEnabled() && !fil->testTypeAndNot(info, lm->attr, searchLanguage, searchLanguageMode)) {
|
||||
if (fil && fil->isEnabled() && !fil->testTypeAndNot(info, lm->attr, searchLanguage)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -564,25 +568,23 @@ bool FilterTree::testAttr(const CardInfoPtr info,
|
|||
status = false;
|
||||
|
||||
// if this is true we can return because it is OR'd with the OrNot list
|
||||
if (fil->testTypeOr(info, lm->attr, searchLanguage, searchLanguageMode)) {
|
||||
if (fil->testTypeOr(info, lm->attr, searchLanguage)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
fil = lm->findTypeList(CardFilter::TypeOrNot);
|
||||
if (fil && fil->isEnabled() && fil->testTypeOrNot(info, lm->attr, searchLanguage, searchLanguageMode)) {
|
||||
if (fil && fil->isEnabled() && fil->testTypeOrNot(info, lm->attr, searchLanguage)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
bool FilterTree::acceptsCard(const CardInfoPtr info,
|
||||
const QString &searchLanguage,
|
||||
SearchLanguageMode searchLanguageMode) const
|
||||
bool FilterTree::acceptsCard(const CardInfoPtr info, const CardSearchLanguage &searchLanguage) const
|
||||
{
|
||||
for (auto i = childNodes.constBegin(); i != childNodes.constEnd(); i++) {
|
||||
if ((*i)->isEnabled() && !testAttr(info, *i, searchLanguage, searchLanguageMode)) {
|
||||
if ((*i)->isEnabled() && !testAttr(info, *i, searchLanguage)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -168,22 +168,14 @@ public:
|
|||
return CardFilter::typeName(type);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool testTypeAnd(CardInfoPtr info,
|
||||
CardFilter::Attr attr,
|
||||
const QString &searchLanguage,
|
||||
SearchLanguageMode searchLanguageMode) const;
|
||||
[[nodiscard]] bool testTypeAndNot(CardInfoPtr info,
|
||||
CardFilter::Attr attr,
|
||||
const QString &searchLanguage,
|
||||
SearchLanguageMode searchLanguageMode) const;
|
||||
[[nodiscard]] bool testTypeOr(CardInfoPtr info,
|
||||
CardFilter::Attr attr,
|
||||
const QString &searchLanguage,
|
||||
SearchLanguageMode searchLanguageMode) const;
|
||||
[[nodiscard]] bool testTypeOrNot(CardInfoPtr info,
|
||||
CardFilter::Attr attr,
|
||||
const QString &searchLanguage,
|
||||
SearchLanguageMode searchLanguageMode) const;
|
||||
[[nodiscard]] bool
|
||||
testTypeAnd(CardInfoPtr info, CardFilter::Attr attr, const CardSearchLanguage &searchLanguage) const;
|
||||
[[nodiscard]] bool
|
||||
testTypeAndNot(CardInfoPtr info, CardFilter::Attr attr, const CardSearchLanguage &searchLanguage) const;
|
||||
[[nodiscard]] bool
|
||||
testTypeOr(CardInfoPtr info, CardFilter::Attr attr, const CardSearchLanguage &searchLanguage) const;
|
||||
[[nodiscard]] bool
|
||||
testTypeOrNot(CardInfoPtr info, CardFilter::Attr attr, const CardSearchLanguage &searchLanguage) const;
|
||||
};
|
||||
|
||||
class FilterItem : public FilterTreeNode
|
||||
|
|
@ -220,26 +212,21 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool
|
||||
acceptName(CardInfoPtr info, const QString &searchLanguage, SearchLanguageMode searchLanguageMode) const;
|
||||
[[nodiscard]] bool
|
||||
acceptNameExact(CardInfoPtr info, const QString &searchLanguage, SearchLanguageMode searchLanguageMode) const;
|
||||
[[nodiscard]] bool acceptName(CardInfoPtr info, const CardSearchLanguage &searchLanguage) const;
|
||||
[[nodiscard]] bool acceptNameExact(CardInfoPtr info, const CardSearchLanguage &searchLanguage) const;
|
||||
[[nodiscard]] bool acceptType(CardInfoPtr info) const;
|
||||
[[nodiscard]] bool acceptMainType(CardInfoPtr info) const;
|
||||
[[nodiscard]] bool acceptSubType(CardInfoPtr info) const;
|
||||
[[nodiscard]] bool acceptColor(CardInfoPtr info) const;
|
||||
[[nodiscard]] bool
|
||||
acceptText(CardInfoPtr info, const QString &searchLanguage, SearchLanguageMode searchLanguageMode) const;
|
||||
[[nodiscard]] bool acceptText(CardInfoPtr info, const CardSearchLanguage &searchLanguage) const;
|
||||
[[nodiscard]] bool acceptSet(CardInfoPtr info) const;
|
||||
[[nodiscard]] bool acceptManaCost(CardInfoPtr info) const;
|
||||
[[nodiscard]] bool acceptCmc(CardInfoPtr info) const;
|
||||
[[nodiscard]] bool acceptPowerToughness(CardInfoPtr info, CardFilter::Attr attr) const;
|
||||
[[nodiscard]] bool acceptLoyalty(CardInfoPtr info) const;
|
||||
[[nodiscard]] bool acceptRarity(CardInfoPtr info) const;
|
||||
[[nodiscard]] bool acceptCardAttr(CardInfoPtr info,
|
||||
CardFilter::Attr attr,
|
||||
const QString &searchLanguage,
|
||||
SearchLanguageMode searchLanguageMode) const;
|
||||
[[nodiscard]] bool
|
||||
acceptCardAttr(CardInfoPtr info, CardFilter::Attr attr, const CardSearchLanguage &searchLanguage) const;
|
||||
[[nodiscard]] bool acceptFormat(CardInfoPtr info) const;
|
||||
[[nodiscard]] bool relationCheck(int cardInfo) const;
|
||||
};
|
||||
|
|
@ -259,10 +246,7 @@ private:
|
|||
LogicMap *attrLogicMap(CardFilter::Attr attr);
|
||||
FilterItemList *attrTypeList(CardFilter::Attr attr, CardFilter::Type type);
|
||||
|
||||
bool testAttr(CardInfoPtr info,
|
||||
const LogicMap *lm,
|
||||
const QString &searchLanguage,
|
||||
SearchLanguageMode searchLanguageMode) const;
|
||||
bool testAttr(CardInfoPtr info, const LogicMap *lm, const CardSearchLanguage &searchLanguage) const;
|
||||
|
||||
void nodeChanged() const override
|
||||
{
|
||||
|
|
@ -301,8 +285,7 @@ public:
|
|||
return 0;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool
|
||||
acceptsCard(CardInfoPtr info, const QString &searchLanguage, SearchLanguageMode searchLanguageMode) const;
|
||||
[[nodiscard]] bool acceptsCard(CardInfoPtr info, const CardSearchLanguage &searchLanguage) const;
|
||||
void removeFiltersByAttr(CardFilter::Attr filterType);
|
||||
void removeFilter(const CardFilter *toRemove);
|
||||
void clear();
|
||||
|
|
|
|||
|
|
@ -68,8 +68,8 @@ 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 (searchLanguageMode != SearchLanguageMode::English && !searchLanguage.isEmpty() && searchLanguage != "en") {
|
||||
matchName = card->getLocalizedName(searchLanguage);
|
||||
if (searchLanguage.mode != SearchLanguageMode::English && !searchLanguage.isEnglishOnly()) {
|
||||
matchName = card->getLocalizedName(searchLanguage.language);
|
||||
}
|
||||
const QString lowerName = matchName.toLower();
|
||||
if (!lowerName.contains(lowerQuery)) {
|
||||
|
|
@ -88,9 +88,9 @@ void CardSearchModel::updateSearchResults(const QString &query)
|
|||
auto sortByDistanceThenLength = [this](const SearchResult &a, const SearchResult &b) {
|
||||
QString nameA = a.card->getName();
|
||||
QString nameB = b.card->getName();
|
||||
if (searchLanguageMode != SearchLanguageMode::English && !searchLanguage.isEmpty() && searchLanguage != "en") {
|
||||
nameA = a.card->getLocalizedName(searchLanguage);
|
||||
nameB = b.card->getLocalizedName(searchLanguage);
|
||||
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;
|
||||
|
|
@ -112,4 +112,4 @@ void CardSearchModel::updateSearchResults(const QString &query)
|
|||
}
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
}
|
||||
|
|
@ -27,13 +27,12 @@ public:
|
|||
|
||||
void updateSearchResults(const QString &query); // Update results based on input
|
||||
|
||||
void setSearchLanguage(const QString &searchLang, SearchLanguageMode mode)
|
||||
void setSearchLanguage(const CardSearchLanguage &searchLang)
|
||||
{
|
||||
if (searchLanguage == searchLang && searchLanguageMode == mode) {
|
||||
if (searchLanguage == searchLang) {
|
||||
return;
|
||||
}
|
||||
searchLanguage = searchLang;
|
||||
searchLanguageMode = mode;
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
@ -45,8 +44,7 @@ private:
|
|||
|
||||
CardDatabaseDisplayModel *sourceModel;
|
||||
QList<SearchResult> searchResults;
|
||||
QString searchLanguage;
|
||||
SearchLanguageMode searchLanguageMode = SearchLanguageMode::English;
|
||||
CardSearchLanguage searchLanguage;
|
||||
};
|
||||
|
||||
#endif // CARD_SEARCH_MODEL_H
|
||||
#endif // CARD_SEARCH_MODEL_H
|
||||
|
|
@ -179,7 +179,7 @@ bool CardDatabaseDisplayModel::filterAcceptsRow(int sourceRow, const QModelIndex
|
|||
}
|
||||
|
||||
if (filterString != nullptr) {
|
||||
if (filterTree != nullptr && !filterTree->acceptsCard(info, searchLanguage, searchLanguageMode)) {
|
||||
if (filterTree != nullptr && !filterTree->acceptsCard(info, searchLanguage)) {
|
||||
return false;
|
||||
}
|
||||
return filterString->check(info);
|
||||
|
|
@ -190,10 +190,14 @@ bool CardDatabaseDisplayModel::filterAcceptsRow(int sourceRow, const QModelIndex
|
|||
|
||||
bool CardDatabaseDisplayModel::rowMatchesCardName(CardInfoPtr info) const
|
||||
{
|
||||
if (!cardName.isEmpty() && !info->getName().contains(cardName, Qt::CaseInsensitive) &&
|
||||
searchLanguageMode != SearchLanguageMode::English && !searchLanguage.isEmpty() && searchLanguage != "en" &&
|
||||
!info->getLocalizedName(searchLanguage).contains(cardName, Qt::CaseInsensitive)) {
|
||||
return false;
|
||||
if (!cardName.isEmpty()) {
|
||||
const bool matchesEnglish = info->getName().contains(cardName, Qt::CaseInsensitive);
|
||||
const bool matchesLocalized =
|
||||
!searchLanguage.isEnglishOnly() &&
|
||||
info->getLocalizedName(searchLanguage.language).contains(cardName, Qt::CaseInsensitive);
|
||||
if (!matchesEnglish && !matchesLocalized) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cardNameSet.isEmpty() && !cardNameSet.contains(info->getName())) {
|
||||
|
|
@ -201,7 +205,7 @@ bool CardDatabaseDisplayModel::rowMatchesCardName(CardInfoPtr info) const
|
|||
}
|
||||
|
||||
if (filterTree != nullptr) {
|
||||
return filterTree->acceptsCard(info, searchLanguage, searchLanguageMode);
|
||||
return filterTree->acceptsCard(info, searchLanguage);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -241,18 +245,17 @@ void CardDatabaseDisplayModel::setStringFilter(const QString &_src)
|
|||
{
|
||||
searchText = _src;
|
||||
delete filterString;
|
||||
filterString = new FilterString(_src, searchLanguage, searchLanguageMode);
|
||||
filterString = new FilterString(_src, searchLanguage);
|
||||
dirty();
|
||||
}
|
||||
|
||||
void CardDatabaseDisplayModel::setSearchLanguage(const QString &searchLang, SearchLanguageMode mode)
|
||||
void CardDatabaseDisplayModel::setSearchLanguage(const CardSearchLanguage &searchLang)
|
||||
{
|
||||
if (searchLanguage == searchLang && searchLanguageMode == mode) {
|
||||
if (searchLanguage == searchLang) {
|
||||
return;
|
||||
}
|
||||
|
||||
searchLanguage = searchLang;
|
||||
searchLanguageMode = mode;
|
||||
|
||||
if (filterString != nullptr) {
|
||||
setStringFilter(searchText);
|
||||
|
|
|
|||
|
|
@ -33,8 +33,7 @@ private:
|
|||
FilterString *filterString;
|
||||
int loadedRowCount;
|
||||
QTimer dirtyTimer;
|
||||
QString searchLanguage;
|
||||
SearchLanguageMode searchLanguageMode = SearchLanguageMode::English;
|
||||
CardSearchLanguage searchLanguage;
|
||||
QString searchText;
|
||||
|
||||
/** The translation table that will be used for sanitizeCardName. */
|
||||
|
|
@ -65,7 +64,7 @@ public:
|
|||
cardNameSet = _cardNameSet;
|
||||
dirty();
|
||||
}
|
||||
void setSearchLanguage(const QString &searchLang, SearchLanguageMode mode);
|
||||
void setSearchLanguage(const CardSearchLanguage &searchLang);
|
||||
|
||||
void dirty()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -84,42 +84,42 @@ CardInfoPtr localizedCat()
|
|||
TEST_F(CardQuery, SearchLanguageEnglishMatchesOnlyEnglish)
|
||||
{
|
||||
const CardData localized = localizedCat();
|
||||
ASSERT_TRUE(FilterString("Cat", "de", SearchLanguageMode::English).check(localized));
|
||||
ASSERT_FALSE(FilterString("Kater", "de", SearchLanguageMode::English).check(localized));
|
||||
ASSERT_TRUE(FilterString("Cat", CardSearchLanguage{"de", SearchLanguageMode::English}).check(localized));
|
||||
ASSERT_FALSE(FilterString("Kater", CardSearchLanguage{"de", SearchLanguageMode::English}).check(localized));
|
||||
}
|
||||
|
||||
TEST_F(CardQuery, SearchLanguageSelectedMatchesLocalizedNameAndText)
|
||||
{
|
||||
const CardData localized = localizedCat();
|
||||
ASSERT_TRUE(FilterString("Kater", "de", SearchLanguageMode::Selected).check(localized));
|
||||
ASSERT_TRUE(FilterString("o:miaut", "de", SearchLanguageMode::Selected).check(localized));
|
||||
ASSERT_FALSE(FilterString("Cat", "de", SearchLanguageMode::Selected).check(localized));
|
||||
ASSERT_TRUE(FilterString("Kater", CardSearchLanguage{"de", SearchLanguageMode::Selected}).check(localized));
|
||||
ASSERT_TRUE(FilterString("o:miaut", CardSearchLanguage{"de", SearchLanguageMode::Selected}).check(localized));
|
||||
ASSERT_FALSE(FilterString("Cat", CardSearchLanguage{"de", SearchLanguageMode::Selected}).check(localized));
|
||||
}
|
||||
|
||||
TEST_F(CardQuery, SearchLanguageSelectedFallsBackToEnglishForUntranslatedCards)
|
||||
{
|
||||
const CardData localized = localizedCat();
|
||||
ASSERT_TRUE(FilterString("Cat", "fr", SearchLanguageMode::Selected).check(localized));
|
||||
ASSERT_FALSE(FilterString("Kater", "fr", SearchLanguageMode::Selected).check(localized));
|
||||
ASSERT_TRUE(FilterString("Cat", CardSearchLanguage{"fr", SearchLanguageMode::Selected}).check(localized));
|
||||
ASSERT_FALSE(FilterString("Kater", CardSearchLanguage{"fr", SearchLanguageMode::Selected}).check(localized));
|
||||
}
|
||||
|
||||
TEST_F(CardQuery, SearchLanguageBothMatchesEitherLanguage)
|
||||
{
|
||||
const CardData localized = localizedCat();
|
||||
ASSERT_TRUE(FilterString("Cat", "de", SearchLanguageMode::Both).check(localized));
|
||||
ASSERT_TRUE(FilterString("Kater", "de", SearchLanguageMode::Both).check(localized));
|
||||
ASSERT_TRUE(FilterString("Cat", CardSearchLanguage{"de", SearchLanguageMode::Both}).check(localized));
|
||||
ASSERT_TRUE(FilterString("Kater", CardSearchLanguage{"de", SearchLanguageMode::Both}).check(localized));
|
||||
}
|
||||
|
||||
TEST_F(CardQuery, SearchLanguageIsBoundPerInstance)
|
||||
{
|
||||
const CardData localized = localizedCat();
|
||||
|
||||
FilterString germanQuery("Kater", "de", SearchLanguageMode::Selected);
|
||||
FilterString germanQuery("Kater", CardSearchLanguage{"de", SearchLanguageMode::Selected});
|
||||
ASSERT_TRUE(germanQuery.check(localized));
|
||||
|
||||
// Constructing an English-bound instance afterwards must not change the
|
||||
// language the earlier instance searches in.
|
||||
FilterString englishQuery("Kater", "", SearchLanguageMode::English);
|
||||
FilterString englishQuery("Kater", CardSearchLanguage{"", SearchLanguageMode::English});
|
||||
ASSERT_FALSE(englishQuery.check(localized));
|
||||
ASSERT_TRUE(germanQuery.check(localized));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue