Update color filter logic to be proper and implement include/exclude mode.

This commit is contained in:
Lukas Brübach 2025-04-07 03:52:59 +02:00
parent 3323508722
commit 2b24b52cfc
2 changed files with 138 additions and 47 deletions

View file

@ -41,8 +41,12 @@ VisualDatabaseDisplayColorFilterWidget::VisualDatabaseDisplayColorFilterWidget(Q
&VisualDatabaseDisplayColorFilterWidget::updateColorFilter); &VisualDatabaseDisplayColorFilterWidget::updateColorFilter);
connect(this, &VisualDatabaseDisplayColorFilterWidget::filterModeChanged, this, connect(this, &VisualDatabaseDisplayColorFilterWidget::filterModeChanged, this,
&VisualDatabaseDisplayColorFilterWidget::updateColorFilter); &VisualDatabaseDisplayColorFilterWidget::updateColorFilter);
connect(filterModel, &FilterTreeModel::layoutChanged, this, connect(filterModel, &FilterTreeModel::layoutChanged, this, [this]() {
[this]() { QTimer::singleShot(100, this, &VisualDatabaseDisplayColorFilterWidget::syncWithFilterModel); }); if (blockSync) {
return; // Skip sync if we're blocking it
}
QTimer::singleShot(100, this, &VisualDatabaseDisplayColorFilterWidget::syncWithFilterModel);
});
// Call retranslateUi to set the initial text // Call retranslateUi to set the initial text
retranslateUi(); retranslateUi();
@ -50,74 +54,152 @@ VisualDatabaseDisplayColorFilterWidget::VisualDatabaseDisplayColorFilterWidget(Q
void VisualDatabaseDisplayColorFilterWidget::retranslateUi() void VisualDatabaseDisplayColorFilterWidget::retranslateUi()
{ {
// Set the toggle button text based on the current mode switch (currentMode) {
toggleButton->setText(exactMatchMode ? tr("Mode: Exact Match") : tr("Mode: Includes")); case FilterMode::ExactMatch:
toggleButton->setText(tr("Mode: Exact Match"));
break;
case FilterMode::Includes:
toggleButton->setText(tr("Mode: Includes"));
break;
case FilterMode::IncludeExclude:
toggleButton->setText(tr("Mode: Include/Exclude"));
break;
}
} }
void VisualDatabaseDisplayColorFilterWidget::handleColorToggled(QChar color, bool active) void VisualDatabaseDisplayColorFilterWidget::handleColorToggled(QChar color, bool active)
{ {
activeColors[color] = active; switch (currentMode) {
emit activeColorsChanged(); case FilterMode::ExactMatch:
// In Exact Match Mode, only allow the selected colors
if (active) {
activeColors[color] = true; // Add color to the selected list
} else {
activeColors[color] = false; // Remove color from the selected list
}
break;
case FilterMode::Includes:
// In Includes Mode, toggle the color freely (include selected colors)
activeColors[color] = active;
break;
case FilterMode::IncludeExclude:
// In Include/Exclude Mode, toggle the color freely (include selected, exclude unselected)
if (active) {
activeColors[color] = true; // Include the color
} else {
activeColors[color] = false; // Exclude the color
}
break;
}
emit activeColorsChanged(); // Notify listeners that the active colors have changed
} }
void VisualDatabaseDisplayColorFilterWidget::updateColorFilter() void VisualDatabaseDisplayColorFilterWidget::updateColorFilter()
{ {
// Clear existing filters related to color blockSync = true;
// Clear previous filters
filterModel->clearFiltersOfType(CardFilter::Attr::AttrColor); filterModel->clearFiltersOfType(CardFilter::Attr::AttrColor);
if (exactMatchMode) { QSet<QString> selectedColors;
// Exact match: card must have ONLY the selected colors QSet<QString> excludedColors;
QSet<QString> selectedColors;
for (const auto &color : activeColors.keys()) {
if (activeColors[color]) {
selectedColors.insert(color);
}
}
if (!selectedColors.isEmpty()) { // Collect active colors in the selected and excluded sets
// Require all selected colors (TypeAnd) for (const auto &color : activeColors.keys()) {
for (const auto &color : selectedColors) { if (activeColors[color]) {
QString colorString = color; selectedColors.insert(color); // Include this color
filterModel->addFilter( } else {
new CardFilter(colorString, CardFilter::Type::TypeAnd, CardFilter::Attr::AttrColor)); excludedColors.insert(color); // Exclude this color
}
// Exclude any other colors (TypeAndNot)
QStringList allPossibleColors = {"W", "U", "B", "R", "G"};
for (const auto &color : allPossibleColors) {
if (!selectedColors.contains(color)) {
QString colorString = color;
filterModel->addFilter(
new CardFilter(colorString, CardFilter::Type::TypeAndNot, CardFilter::Attr::AttrColor));
}
}
}
} else {
// Default includes mode (TypeAnd) - match any selected colors
for (const auto &color : activeColors.keys()) {
if (activeColors[color]) { // If the color is active
QString colorString = color;
filterModel->addFilter(
new CardFilter(colorString, CardFilter::Type::TypeAnd, CardFilter::Attr::AttrColor));
}
} }
} }
switch (currentMode) {
case FilterMode::ExactMatch:
// Exact Match Mode: Only selected colors are allowed
if (!selectedColors.isEmpty()) {
// Require all selected colors (TypeAnd)
for (const auto &color : selectedColors) {
QString colorString = color;
filterModel->addFilter(
new CardFilter(colorString, CardFilter::Type::TypeAnd, CardFilter::Attr::AttrColor));
}
// Exclude all other colors
QStringList allPossibleColors = {"W", "U", "B", "R", "G"};
for (const auto &color : allPossibleColors) {
if (!selectedColors.contains(color)) {
QString colorString = color;
filterModel->addFilter(
new CardFilter(colorString, CardFilter::Type::TypeAndNot, CardFilter::Attr::AttrColor));
}
}
}
break;
case FilterMode::Includes:
// Includes Mode: Just include selected colors without restrictions
for (const auto &color : selectedColors) {
QString colorString = color;
filterModel->addFilter(new CardFilter(colorString, CardFilter::Type::TypeOr,
CardFilter::Attr::AttrColor)); // OR for selected colors
}
break;
case FilterMode::IncludeExclude:
// Include/Exclude Mode: Include selected colors and exclude unselected colors
for (const auto &color : selectedColors) {
QString colorString = color;
filterModel->addFilter(new CardFilter(colorString, CardFilter::Type::TypeOr,
CardFilter::Attr::AttrColor)); // OR for selected colors
}
for (const auto &color : excludedColors) {
QString colorString = color;
filterModel->addFilter(new CardFilter(colorString, CardFilter::Type::TypeAndNot,
CardFilter::Attr::AttrColor)); // AND NOT for excluded colors
}
break;
}
blockSync = false;
} }
void VisualDatabaseDisplayColorFilterWidget::updateFilterMode(bool checked) void VisualDatabaseDisplayColorFilterWidget::updateFilterMode(bool checked)
{ {
exactMatchMode = checked; // Toggle between modes blockSync = true;
retranslateUi(); // Update the button text
emit filterModeChanged(exactMatchMode); if (checked) {
// Cycle through the modes in a clear manner
switch (currentMode) {
case FilterMode::ExactMatch:
currentMode = FilterMode::Includes; // Switch to Includes
break;
case FilterMode::Includes:
currentMode = FilterMode::IncludeExclude; // Switch to Include/Exclude
break;
case FilterMode::IncludeExclude:
currentMode = FilterMode::ExactMatch; // Switch to Exact Match
break;
}
}
retranslateUi(); // Update button text based on the mode
emit filterModeChanged(currentMode); // Signal mode change
updateColorFilter(); // Reapply the filter based on the new mode
blockSync = false;
} }
void VisualDatabaseDisplayColorFilterWidget::syncWithFilterModel() void VisualDatabaseDisplayColorFilterWidget::syncWithFilterModel()
{ {
blockSync = true;
QSet<QString> currentFilters; QSet<QString> currentFilters;
// Get current filters of type color // Get current filters of type color
for (const auto &filter : filterModel->getFiltersOfType(CardFilter::Attr::AttrColor)) { for (const auto &filter : filterModel->getFiltersOfType(CardFilter::Attr::AttrColor)) {
if (filter->type() == CardFilter::Type::TypeAnd || filter->type() == CardFilter::Type::TypeAndNot) { if (filter->type() == CardFilter::Type::TypeAnd || filter->type() == CardFilter::Type::TypeOr) {
currentFilters.insert(filter->term()); currentFilters.insert(filter->term());
} }
} }
@ -157,4 +239,5 @@ void VisualDatabaseDisplayColorFilterWidget::syncWithFilterModel()
} }
updateColorFilter(); updateColorFilter();
blockSync = false;
} }

View file

@ -26,6 +26,13 @@ private:
int circleDiameter; int circleDiameter;
}; };
enum class FilterMode
{
ExactMatch, // Only selected colors are included, all others are excluded.
Includes, // Include selected colors (OR condition).
IncludeExclude // Include selected colors (OR) and exclude unselected colors (AND NOT).
};
class VisualDatabaseDisplayColorFilterWidget : public QWidget class VisualDatabaseDisplayColorFilterWidget : public QWidget
{ {
Q_OBJECT Q_OBJECT
@ -35,7 +42,7 @@ public:
void retranslateUi(); void retranslateUi();
signals: signals:
void filterModeChanged(bool exactMatchMode); void filterModeChanged(FilterMode filterMode);
void activeColorsChanged(); void activeColorsChanged();
private slots: private slots:
@ -49,7 +56,8 @@ private:
QHBoxLayout *layout; QHBoxLayout *layout;
QPushButton *toggleButton; QPushButton *toggleButton;
QMap<QChar, bool> activeColors; QMap<QChar, bool> activeColors;
bool exactMatchMode = false; // Default to "includes" mode FilterMode currentMode = FilterMode::Includes; // Default mode
bool blockSync = false;
}; };
#endif // VISUAL_DATABASE_DISPLAY_COLOR_FILTER_WIDGET_H #endif // VISUAL_DATABASE_DISPLAY_COLOR_FILTER_WIDGET_H