mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-11-10 03:53:26 -08:00
Added Exclude and Color Identity filter modes.
This commit is contained in:
parent
ea6af0048c
commit
286982350c
8 changed files with 107 additions and 98 deletions
|
|
@ -62,7 +62,9 @@ void VisualDatabaseDisplayColorFilterWidget::retranslateUi()
|
||||||
|
|
||||||
modeComboBox->addItem(tr("Exact match"), QVariant::fromValue(FilterMode::ExactMatch));
|
modeComboBox->addItem(tr("Exact match"), QVariant::fromValue(FilterMode::ExactMatch));
|
||||||
modeComboBox->addItem(tr("Includes"), QVariant::fromValue(FilterMode::Includes));
|
modeComboBox->addItem(tr("Includes"), QVariant::fromValue(FilterMode::Includes));
|
||||||
|
modeComboBox->addItem(tr("Excludes"), QVariant::fromValue(FilterMode::Excludes));
|
||||||
modeComboBox->addItem(tr("Include / Exclude"), QVariant::fromValue(FilterMode::IncludeExclude));
|
modeComboBox->addItem(tr("Include / Exclude"), QVariant::fromValue(FilterMode::IncludeExclude));
|
||||||
|
modeComboBox->addItem(tr("Commander"), QVariant::fromValue(FilterMode::Commander));
|
||||||
|
|
||||||
modeComboBox->setToolTip(tr("How selected and unselected colors are combined in the filter"));
|
modeComboBox->setToolTip(tr("How selected and unselected colors are combined in the filter"));
|
||||||
|
|
||||||
|
|
@ -84,75 +86,69 @@ void VisualDatabaseDisplayColorFilterWidget::handleColorToggled(QChar color, boo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualDatabaseDisplayColorFilterWidget::addFilter(QChar color)
|
static void removeFilters(FilterTreeModel *filterModel, QChar color, CardFilter::Attr attr)
|
||||||
{
|
{
|
||||||
QString colorString = color;
|
for (const CardFilter *filter : filterModel->getFiltersOfType(attr)) {
|
||||||
QString typeStr;
|
|
||||||
|
|
||||||
// Remove previous filters
|
|
||||||
|
|
||||||
QList<const CardFilter *> allColorFilters = filterModel->getFiltersOfType(CardFilter::Attr::AttrColor);
|
|
||||||
QList<const CardFilter *> matchingFilters;
|
|
||||||
|
|
||||||
for (const CardFilter *filter : allColorFilters) {
|
|
||||||
if (filter->term() == color) {
|
if (filter->term() == color) {
|
||||||
matchingFilters.append(filter);
|
filterModel->removeFilter(filter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (const CardFilter *filter : matchingFilters) {
|
void VisualDatabaseDisplayColorFilterWidget::addFilter(QChar color)
|
||||||
filterModel->removeFilter(filter);
|
{
|
||||||
}
|
|
||||||
|
|
||||||
// Add actual filter
|
|
||||||
|
|
||||||
switch (currentMode) {
|
switch (currentMode) {
|
||||||
case FilterMode::ExactMatch:
|
case FilterMode::ExactMatch:
|
||||||
filterModel->addFilter(new CardFilter(colorString, CardFilter::Type::TypeAnd, CardFilter::Attr::AttrColor));
|
removeFilters(filterModel, color, CardFilter::Attr::AttrColor);
|
||||||
|
filterModel->addFilter(new CardFilter(color, CardFilter::Type::TypeAnd, CardFilter::Attr::AttrColor));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FilterMode::Includes:
|
case FilterMode::Includes:
|
||||||
filterModel->addFilter(new CardFilter(colorString, CardFilter::Type::TypeOr, CardFilter::Attr::AttrColor));
|
removeFilters(filterModel, color, CardFilter::Attr::AttrColor);
|
||||||
|
filterModel->addFilter(new CardFilter(color, CardFilter::Type::TypeOr, CardFilter::Attr::AttrColor));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FilterMode::Excludes:
|
||||||
|
removeFilters(filterModel, color, CardFilter::Attr::AttrColor);
|
||||||
|
filterModel->addFilter(new CardFilter(color, CardFilter::Type::TypeAndNot, CardFilter::Attr::AttrColor));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FilterMode::IncludeExclude:
|
case FilterMode::IncludeExclude:
|
||||||
filterModel->addFilter(new CardFilter(colorString, CardFilter::Type::TypeOr, CardFilter::Attr::AttrColor));
|
removeFilters(filterModel, color, CardFilter::Attr::AttrColor);
|
||||||
|
filterModel->addFilter(new CardFilter(color, CardFilter::Type::TypeOr, CardFilter::Attr::AttrColor));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FilterMode::Commander:
|
||||||
|
removeFilters(filterModel, color, CardFilter::Attr::AttrColorIdentity);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualDatabaseDisplayColorFilterWidget::removeFilter(QChar color)
|
void VisualDatabaseDisplayColorFilterWidget::removeFilter(QChar color)
|
||||||
{
|
{
|
||||||
QString colorString = color;
|
|
||||||
|
|
||||||
// Remove inclusion filters
|
|
||||||
QList<const CardFilter *> allColorFilters = filterModel->getFiltersOfType(CardFilter::Attr::AttrColor);
|
|
||||||
QList<const CardFilter *> matchingFilters;
|
|
||||||
|
|
||||||
for (const CardFilter *filter : allColorFilters) {
|
|
||||||
if (filter->term() == color) {
|
|
||||||
matchingFilters.append(filter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const CardFilter *filter : matchingFilters) {
|
|
||||||
filterModel->removeFilter(filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add exclusion filters if the mode demands it
|
// Add exclusion filters if the mode demands it
|
||||||
switch (currentMode) {
|
switch (currentMode) {
|
||||||
case FilterMode::ExactMatch:
|
case FilterMode::ExactMatch:
|
||||||
filterModel->addFilter(
|
removeFilters(filterModel, color, CardFilter::Attr::AttrColor);
|
||||||
new CardFilter(colorString, CardFilter::Type::TypeAndNot, CardFilter::Attr::AttrColor));
|
filterModel->addFilter(new CardFilter(color, CardFilter::Type::TypeAndNot, CardFilter::Attr::AttrColor));
|
||||||
break;
|
|
||||||
|
|
||||||
case FilterMode::IncludeExclude:
|
|
||||||
filterModel->addFilter(
|
|
||||||
new CardFilter(colorString, CardFilter::Type::TypeAndNot, CardFilter::Attr::AttrColor));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FilterMode::Includes:
|
case FilterMode::Includes:
|
||||||
// No exclusion in Includes mode
|
removeFilters(filterModel, color, CardFilter::Attr::AttrColor);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FilterMode::Excludes:
|
||||||
|
removeFilters(filterModel, color, CardFilter::Attr::AttrColor);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FilterMode::IncludeExclude:
|
||||||
|
removeFilters(filterModel, color, CardFilter::Attr::AttrColor);
|
||||||
|
filterModel->addFilter(new CardFilter(color, CardFilter::Type::TypeAndNot, CardFilter::Attr::AttrColor));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FilterMode::Commander:
|
||||||
|
removeFilters(filterModel, color, CardFilter::Attr::AttrColorIdentity);
|
||||||
|
filterModel->addFilter(new CardFilter(color, CardFilter::Type::TypeAndNot, CardFilter::Attr::AttrColorIdentity));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -170,6 +166,7 @@ void VisualDatabaseDisplayColorFilterWidget::updateFilterMode()
|
||||||
filterModel->filterTree()->blockSignals(true);
|
filterModel->filterTree()->blockSignals(true);
|
||||||
|
|
||||||
filterModel->clearFiltersOfType(CardFilter::Attr::AttrColor);
|
filterModel->clearFiltersOfType(CardFilter::Attr::AttrColor);
|
||||||
|
filterModel->clearFiltersOfType(CardFilter::Attr::AttrColorIdentity);
|
||||||
|
|
||||||
const QList<ManaSymbolWidget *> manaSymbolWidgets = findChildren<ManaSymbolWidget *>();
|
const QList<ManaSymbolWidget *> manaSymbolWidgets = findChildren<ManaSymbolWidget *>();
|
||||||
|
|
||||||
|
|
@ -212,52 +209,42 @@ QList<QChar> VisualDatabaseDisplayColorFilterWidget::getActiveColors()
|
||||||
|
|
||||||
void VisualDatabaseDisplayColorFilterWidget::syncWithFilterModel()
|
void VisualDatabaseDisplayColorFilterWidget::syncWithFilterModel()
|
||||||
{
|
{
|
||||||
QList<const CardFilter *> allColorFilters = filterModel->getFiltersOfType(CardFilter::Attr::AttrColor);
|
QList<const CardFilter *> allColorFilters = filterModel->getFiltersOfType(
|
||||||
|
currentMode == FilterMode::Commander
|
||||||
|
? CardFilter::Attr::AttrColorIdentity
|
||||||
|
: CardFilter::Attr::AttrColor);
|
||||||
|
|
||||||
QList<ManaSymbolWidget *> manaSymbolWidgets = findChildren<ManaSymbolWidget *>();
|
QList<ManaSymbolWidget *> manaSymbolWidgets = findChildren<ManaSymbolWidget *>();
|
||||||
|
|
||||||
for (ManaSymbolWidget *manaSymbolWidget : manaSymbolWidgets) {
|
for (ManaSymbolWidget *manaSymbolWidget : manaSymbolWidgets) {
|
||||||
bool found = false;
|
QChar symbol = manaSymbolWidget->getSymbolChar();
|
||||||
|
bool found = currentMode == FilterMode::Commander;
|
||||||
for (const CardFilter *filter : allColorFilters) {
|
for (const CardFilter *filter : allColorFilters) {
|
||||||
if (manaSymbolWidget->getSymbolChar() == filter->term()) {
|
if (symbol == filter->term()) {
|
||||||
switch (currentMode) {
|
switch (currentMode) {
|
||||||
case FilterMode::ExactMatch:
|
case FilterMode::ExactMatch:
|
||||||
switch (filter->type()) {
|
if (filter->type() == CardFilter::Type::TypeAnd)
|
||||||
case CardFilter::Type::TypeAnd:
|
found = true;
|
||||||
setManaSymbolActive(filter->term().at(0), true);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
setManaSymbolActive(filter->term().at(0), false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case FilterMode::Includes:
|
case FilterMode::Includes:
|
||||||
switch (filter->type()) {
|
|
||||||
case CardFilter::Type::TypeOr:
|
|
||||||
setManaSymbolActive(filter->term().at(0), true);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
setManaSymbolActive(filter->term().at(0), false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case FilterMode::IncludeExclude:
|
case FilterMode::IncludeExclude:
|
||||||
switch (filter->type()) {
|
if (filter->type() == CardFilter::Type::TypeOr)
|
||||||
case CardFilter::Type::TypeOr:
|
found = true;
|
||||||
setManaSymbolActive(filter->term().at(0), true);
|
break;
|
||||||
break;
|
case FilterMode::Excludes:
|
||||||
default:
|
if (filter->type() == CardFilter::Type::TypeAndNot)
|
||||||
setManaSymbolActive(filter->term().at(0), false);
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
case FilterMode::Commander:
|
||||||
|
if (filter->type() == CardFilter::Type::TypeAndNot)
|
||||||
|
found = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
found = true;
|
if (found)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found) {
|
setManaSymbolActive(manaSymbolWidget->getSymbolChar(), found);
|
||||||
setManaSymbolActive(manaSymbolWidget->getSymbolChar(), false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,9 +39,11 @@ private:
|
||||||
|
|
||||||
enum class FilterMode
|
enum class FilterMode
|
||||||
{
|
{
|
||||||
ExactMatch, // Only selected colors are included, all others are excluded.
|
ExactMatch, // Only selected colors are included, all others are excluded.
|
||||||
Includes, // Include selected colors (OR condition).
|
Includes, // Include selected colors (OR condition).
|
||||||
IncludeExclude // Include selected colors (OR) and exclude unselected colors (AND NOT).
|
Excludes, // Exclude selected colors (OR).
|
||||||
|
IncludeExclude, // Include selected colors (OR) and exclude unselected colors (AND NOT).
|
||||||
|
Commander // Only include colors in the selected color identity.
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(FilterMode)
|
Q_DECLARE_METATYPE(FilterMode)
|
||||||
|
|
|
||||||
|
|
@ -285,6 +285,10 @@ void CardInfo::setColors(const QString &value)
|
||||||
{
|
{
|
||||||
setProperty(Mtg::Colors, value);
|
setProperty(Mtg::Colors, value);
|
||||||
}
|
}
|
||||||
|
QString CardInfo::getColorIdentity() const
|
||||||
|
{
|
||||||
|
return getProperty(Mtg::ColorIdentity);
|
||||||
|
}
|
||||||
QString CardInfo::getLoyalty() const
|
QString CardInfo::getLoyalty() const
|
||||||
{
|
{
|
||||||
return getProperty(Mtg::Loyalty);
|
return getProperty(Mtg::Loyalty);
|
||||||
|
|
|
||||||
|
|
@ -454,6 +454,7 @@ public:
|
||||||
[[nodiscard]] QString getCmc() const;
|
[[nodiscard]] QString getCmc() const;
|
||||||
[[nodiscard]] QString getColors() const;
|
[[nodiscard]] QString getColors() const;
|
||||||
void setColors(const QString &value);
|
void setColors(const QString &value);
|
||||||
|
[[nodiscard]] QString getColorIdentity() const;
|
||||||
[[nodiscard]] QString getLoyalty() const;
|
[[nodiscard]] QString getLoyalty() const;
|
||||||
[[nodiscard]] QString getMainCardType() const;
|
[[nodiscard]] QString getMainCardType() const;
|
||||||
[[nodiscard]] QString getManaCost() const;
|
[[nodiscard]] QString getManaCost() const;
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,8 @@ const QString CardFilter::attrName(Attr a)
|
||||||
return tr("Type");
|
return tr("Type");
|
||||||
case AttrColor:
|
case AttrColor:
|
||||||
return tr("Color");
|
return tr("Color");
|
||||||
|
case AttrColorIdentity:
|
||||||
|
return tr("Color Identity");
|
||||||
case AttrText:
|
case AttrText:
|
||||||
return tr("Text");
|
return tr("Text");
|
||||||
case AttrSet:
|
case AttrSet:
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ public:
|
||||||
{
|
{
|
||||||
AttrCmc = 0,
|
AttrCmc = 0,
|
||||||
AttrColor,
|
AttrColor,
|
||||||
|
AttrColorIdentity,
|
||||||
AttrLoyalty,
|
AttrLoyalty,
|
||||||
AttrManaCost,
|
AttrManaCost,
|
||||||
AttrName,
|
AttrName,
|
||||||
|
|
@ -54,7 +55,7 @@ private:
|
||||||
enum Attr a;
|
enum Attr a;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CardFilter(QString &term, Type type, Attr attr) : trm(term), t(type), a(attr)
|
CardFilter(QString const &term, Type type, Attr attr) : trm(term), t(type), a(attr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -227,27 +227,26 @@ bool FilterItem::acceptSubType(const CardInfoPtr info) const
|
||||||
return typeParts.size() > 1 && typeParts[1].contains(term, Qt::CaseInsensitive);
|
return typeParts.size() > 1 && typeParts[1].contains(term, Qt::CaseInsensitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FilterItem::acceptColor(const CardInfoPtr info) const
|
static bool matchesColor(QString const &term, QString const &colors) {
|
||||||
{
|
QString converted_term = term.trimmed().toLower();
|
||||||
QString converted_term = term.trimmed();
|
|
||||||
|
|
||||||
converted_term.replace("green", "g", Qt::CaseInsensitive);
|
converted_term.replace("green", "g");
|
||||||
converted_term.replace("grn", "g", Qt::CaseInsensitive);
|
converted_term.replace("grn", "g");
|
||||||
converted_term.replace("blue", "u", Qt::CaseInsensitive);
|
converted_term.replace("blue", "u");
|
||||||
converted_term.replace("blu", "u", Qt::CaseInsensitive);
|
converted_term.replace("blu", "u");
|
||||||
converted_term.replace("black", "b", Qt::CaseInsensitive);
|
converted_term.replace("black", "b");
|
||||||
converted_term.replace("blk", "b", Qt::CaseInsensitive);
|
converted_term.replace("blk", "b");
|
||||||
converted_term.replace("red", "r", Qt::CaseInsensitive);
|
converted_term.replace("red", "r");
|
||||||
converted_term.replace("white", "w", Qt::CaseInsensitive);
|
converted_term.replace("white", "w");
|
||||||
converted_term.replace("wht", "w", Qt::CaseInsensitive);
|
converted_term.replace("wht", "w");
|
||||||
converted_term.replace("colorless", "c", Qt::CaseInsensitive);
|
converted_term.replace("colorless", "c");
|
||||||
converted_term.replace("colourless", "c", Qt::CaseInsensitive);
|
converted_term.replace("colourless", "c");
|
||||||
converted_term.replace("none", "c", Qt::CaseInsensitive);
|
converted_term.replace("none", "c");
|
||||||
|
|
||||||
converted_term.replace(QString(" "), QString(""), Qt::CaseInsensitive);
|
converted_term.replace(QString(" "), QString(""));
|
||||||
|
|
||||||
// Colorless card filter
|
// Colorless card filter
|
||||||
if (converted_term.toLower() == "c" && info->getColors().length() < 1) {
|
if (converted_term == "c" && colors.length() < 1) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -257,7 +256,7 @@ bool FilterItem::acceptColor(const CardInfoPtr info) const
|
||||||
*/
|
*/
|
||||||
int match_count = 0;
|
int match_count = 0;
|
||||||
for (auto &it : converted_term) {
|
for (auto &it : converted_term) {
|
||||||
if (info->getColors().contains(it, Qt::CaseInsensitive)) {
|
if (colors.contains(it, Qt::CaseInsensitive)) {
|
||||||
match_count++;
|
match_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -265,6 +264,16 @@ bool FilterItem::acceptColor(const CardInfoPtr info) const
|
||||||
return match_count == converted_term.length();
|
return match_count == converted_term.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FilterItem::acceptColor(const CardInfoPtr info) const
|
||||||
|
{
|
||||||
|
return matchesColor(term, info->getColors());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FilterItem::acceptColorIdentity(const CardInfoPtr info) const
|
||||||
|
{
|
||||||
|
return matchesColor(term, info->getColorIdentity());
|
||||||
|
}
|
||||||
|
|
||||||
bool FilterItem::acceptText(const CardInfoPtr info, const CardSearchLanguage &searchLanguage) const
|
bool FilterItem::acceptText(const CardInfoPtr info, const CardSearchLanguage &searchLanguage) const
|
||||||
{
|
{
|
||||||
const QString &englishText = info->getText();
|
const QString &englishText = info->getText();
|
||||||
|
|
@ -485,6 +494,8 @@ bool FilterItem::acceptCardAttr(const CardInfoPtr info,
|
||||||
return acceptType(info);
|
return acceptType(info);
|
||||||
case CardFilter::AttrColor:
|
case CardFilter::AttrColor:
|
||||||
return acceptColor(info);
|
return acceptColor(info);
|
||||||
|
case CardFilter::AttrColorIdentity:
|
||||||
|
return acceptColorIdentity(info);
|
||||||
case CardFilter::AttrText:
|
case CardFilter::AttrText:
|
||||||
return acceptText(info, searchLanguage);
|
return acceptText(info, searchLanguage);
|
||||||
case CardFilter::AttrSet:
|
case CardFilter::AttrSet:
|
||||||
|
|
|
||||||
|
|
@ -223,6 +223,7 @@ public:
|
||||||
[[nodiscard]] bool acceptMainType(CardInfoPtr info) const;
|
[[nodiscard]] bool acceptMainType(CardInfoPtr info) const;
|
||||||
[[nodiscard]] bool acceptSubType(CardInfoPtr info) const;
|
[[nodiscard]] bool acceptSubType(CardInfoPtr info) const;
|
||||||
[[nodiscard]] bool acceptColor(CardInfoPtr info) const;
|
[[nodiscard]] bool acceptColor(CardInfoPtr info) const;
|
||||||
|
[[nodiscard]] bool acceptColorIdentity(CardInfoPtr info) const;
|
||||||
[[nodiscard]] bool acceptText(CardInfoPtr info, const CardSearchLanguage &searchLanguage) const;
|
[[nodiscard]] bool acceptText(CardInfoPtr info, const CardSearchLanguage &searchLanguage) const;
|
||||||
[[nodiscard]] bool acceptSet(CardInfoPtr info) const;
|
[[nodiscard]] bool acceptSet(CardInfoPtr info) const;
|
||||||
[[nodiscard]] bool acceptManaCost(CardInfoPtr info) const;
|
[[nodiscard]] bool acceptManaCost(CardInfoPtr info) const;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue