[VDD] Move main type and format filter to quick settings (#6511)

* [VDD] Reorder quick filters

Took 1 hour 10 minutes

Took 5 seconds


Took 49 seconds

* [VDD] Use Font Awesome Icons

Took 49 minutes

Took 5 seconds

* [VDD] Shuffle some widgets around, label things.

Took 31 minutes

Took 5 seconds

* Change buttons to be push rather than toggle.

Took 17 minutes

Took 9 seconds

* Reduce margins, retranslate button texts.

Took 15 minutes

Took 9 seconds

* Actually do it, don't commit the commented out testing version lol

Took 3 minutes

* Start sets in include, correct subtype include/exact match logic.

Took 12 minutes

* Block sync.

Took 16 minutes

Took 8 seconds

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
BruebachL 2026-01-14 11:56:09 +01:00 committed by GitHub
parent 47720ff286
commit a4eef648bc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 392 additions and 224 deletions

View file

@ -31,12 +31,12 @@ VisualDatabaseDisplayColorFilterWidget::VisualDatabaseDisplayColorFilterWidget(Q
&VisualDatabaseDisplayColorFilterWidget::handleColorToggled);
}
toggleButton = new QPushButton(this);
toggleButton->setCheckable(true);
layout->addWidget(toggleButton);
modeComboBox = new QComboBox(this);
layout->addWidget(modeComboBox);
connect(modeComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&VisualDatabaseDisplayColorFilterWidget::updateFilterMode);
// Connect the button's toggled signal
connect(toggleButton, &QPushButton::toggled, this, &VisualDatabaseDisplayColorFilterWidget::updateFilterMode);
connect(filterModel, &FilterTreeModel::layoutChanged, this,
[this]() { QTimer::singleShot(100, this, &VisualDatabaseDisplayColorFilterWidget::syncWithFilterModel); });
@ -46,19 +46,22 @@ VisualDatabaseDisplayColorFilterWidget::VisualDatabaseDisplayColorFilterWidget(Q
void VisualDatabaseDisplayColorFilterWidget::retranslateUi()
{
switch (currentMode) {
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;
modeComboBox->blockSignals(true);
modeComboBox->clear();
modeComboBox->addItem(tr("Exact match"), QVariant::fromValue(FilterMode::ExactMatch));
modeComboBox->addItem(tr("Includes"), QVariant::fromValue(FilterMode::Includes));
modeComboBox->addItem(tr("Include / Exclude"), QVariant::fromValue(FilterMode::IncludeExclude));
modeComboBox->setToolTip(tr("How selected and unselected colors are combined in the filter"));
// Restore current mode
const int index = modeComboBox->findData(QVariant::fromValue(currentMode));
if (index >= 0) {
modeComboBox->setCurrentIndex(index);
}
toggleButton->setToolTip(tr("Filter mode (AND/OR/NOT conjunctions of filters)"));
modeComboBox->blockSignals(false);
}
void VisualDatabaseDisplayColorFilterWidget::handleColorToggled(QChar color, bool active)
@ -145,24 +148,19 @@ void VisualDatabaseDisplayColorFilterWidget::removeFilter(QChar color)
void VisualDatabaseDisplayColorFilterWidget::updateFilterMode()
{
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;
const QVariant data = modeComboBox->currentData();
if (!data.isValid()) {
return;
}
currentMode = data.value<FilterMode>();
filterModel->blockSignals(true);
filterModel->filterTree()->blockSignals(true);
filterModel->clearFiltersOfType(CardFilter::Attr::AttrColor);
QList<ManaSymbolWidget *> manaSymbolWidgets = findChildren<ManaSymbolWidget *>();
const QList<ManaSymbolWidget *> manaSymbolWidgets = findChildren<ManaSymbolWidget *>();
for (ManaSymbolWidget *manaSymbolWidget : manaSymbolWidgets) {
handleColorToggled(manaSymbolWidget->getSymbolChar(), manaSymbolWidget->isColorActive());
@ -173,9 +171,7 @@ void VisualDatabaseDisplayColorFilterWidget::updateFilterMode()
emit filterModel->filterTree()->changed();
emit filterModel->layoutChanged();
retranslateUi(); // Update button text based on the mode
emit filterModeChanged(currentMode); // Signal mode change
emit filterModeChanged(currentMode);
}
void VisualDatabaseDisplayColorFilterWidget::setManaSymbolActive(QChar color, bool active)

View file

@ -9,8 +9,8 @@
#include "../../../filters/filter_tree_model.h"
#include <QComboBox>
#include <QHBoxLayout>
#include <QPushButton>
#include <QWidget>
class VisualDatabaseDisplayColorFilterCircleWidget : public QWidget
@ -39,6 +39,8 @@ enum class FilterMode
IncludeExclude // Include selected colors (OR) and exclude unselected colors (AND NOT).
};
Q_DECLARE_METATYPE(FilterMode)
class VisualDatabaseDisplayColorFilterWidget : public QWidget
{
Q_OBJECT
@ -62,7 +64,7 @@ private slots:
private:
FilterTreeModel *filterModel;
QHBoxLayout *layout;
QPushButton *toggleButton;
QComboBox *modeComboBox;
FilterMode currentMode = FilterMode::Includes; // Default mode
};

View file

@ -0,0 +1,135 @@
#include "visual_database_display_filter_toolbar_widget.h"
#include "visual_database_display_widget.h"
VisualDatabaseDisplayFilterToolbarWidget::VisualDatabaseDisplayFilterToolbarWidget(VisualDatabaseDisplayWidget *_parent)
: QWidget(_parent), visualDatabaseDisplay(_parent)
{
filterContainerLayout = new QHBoxLayout(this);
filterContainerLayout->setContentsMargins(11, 0, 11, 0);
setLayout(filterContainerLayout);
filterContainerLayout->setAlignment(Qt::AlignLeft);
setMaximumHeight(80);
connect(this, &VisualDatabaseDisplayFilterToolbarWidget::searchModelChanged, visualDatabaseDisplay,
&VisualDatabaseDisplayWidget::onSearchModelChanged);
filterByLabel = new QLabel(this);
sortByLabel = new QLabel(this);
sortColumnCombo = new QComboBox(this);
sortColumnCombo->setSizeAdjustPolicy(QComboBox::SizeAdjustPolicy::AdjustToContents);
sortOrderCombo = new QComboBox(this);
sortOrderCombo->setSizeAdjustPolicy(QComboBox::SizeAdjustPolicy::AdjustToContents);
sortOrderCombo->addItem("Ascending", Qt::AscendingOrder);
sortOrderCombo->addItem("Descending", Qt::DescendingOrder);
sortOrderCombo->view()->setMinimumWidth(sortOrderCombo->view()->sizeHintForColumn(0));
sortOrderCombo->adjustSize();
// Populate columns dynamically from the model
for (int i = 0; i < visualDatabaseDisplay->getDatabaseDisplayModel()->columnCount(); ++i) {
QString header = visualDatabaseDisplay->getDatabaseDisplayModel()->headerData(i, Qt::Horizontal).toString();
sortColumnCombo->addItem(header, i);
}
sortColumnCombo->view()->setMinimumWidth(sortColumnCombo->view()->sizeHintForColumn(0));
sortColumnCombo->adjustSize();
connect(sortColumnCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [this]() {
int column = sortColumnCombo->currentData().toInt();
Qt::SortOrder order = static_cast<Qt::SortOrder>(sortOrderCombo->currentData().toInt());
visualDatabaseDisplay->getDatabaseView()->sortByColumn(column, order);
emit searchModelChanged();
});
connect(sortOrderCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [this]() {
int column = sortColumnCombo->currentData().toInt();
Qt::SortOrder order = static_cast<Qt::SortOrder>(sortOrderCombo->currentData().toInt());
visualDatabaseDisplay->getDatabaseView()->sortByColumn(column, order);
emit searchModelChanged();
});
quickFilterSaveLoadWidget = new SettingsButtonWidget(this);
quickFilterSaveLoadWidget->setButtonIcon(QPixmap("theme:icons/floppy_disk"));
quickFilterNameWidget = new SettingsButtonWidget(this);
quickFilterNameWidget->setButtonIcon(QPixmap("theme:icons/pen_to_square"));
quickFilterMainTypeWidget = new SettingsButtonWidget(this);
quickFilterMainTypeWidget->setButtonIcon(QPixmap("theme:icons/circle_half_stroke"));
quickFilterSubTypeWidget = new SettingsButtonWidget(this);
quickFilterSubTypeWidget->setButtonIcon(QPixmap("theme:icons/dragon"));
quickFilterSetWidget = new SettingsButtonWidget(this);
quickFilterSetWidget->setButtonIcon(QPixmap("theme:icons/scroll"));
quickFilterFormatLegalityWidget = new SettingsButtonWidget(this);
quickFilterFormatLegalityWidget->setButtonIcon(QPixmap("theme:icons/scale_balanced"));
retranslateUi();
}
void VisualDatabaseDisplayFilterToolbarWidget::initialize()
{
sortByLabel->setVisible(true);
filterByLabel->setVisible(true);
quickFilterSaveLoadWidget->setVisible(true);
quickFilterNameWidget->setVisible(true);
quickFilterSubTypeWidget->setVisible(true);
quickFilterSetWidget->setVisible(true);
auto filterModel = visualDatabaseDisplay->filterModel;
saveLoadWidget = new VisualDatabaseDisplayFilterSaveLoadWidget(this, filterModel);
nameFilterWidget =
new VisualDatabaseDisplayNameFilterWidget(this, visualDatabaseDisplay->getDeckEditor(), filterModel);
mainTypeFilterWidget = new VisualDatabaseDisplayMainTypeFilterWidget(this, filterModel);
formatLegalityWidget = new VisualDatabaseDisplayFormatLegalityFilterWidget(this, filterModel);
subTypeFilterWidget = new VisualDatabaseDisplaySubTypeFilterWidget(this, filterModel);
setFilterWidget = new VisualDatabaseDisplaySetFilterWidget(this, filterModel);
quickFilterSaveLoadWidget->addSettingsWidget(saveLoadWidget);
quickFilterNameWidget->addSettingsWidget(nameFilterWidget);
quickFilterMainTypeWidget->addSettingsWidget(mainTypeFilterWidget);
quickFilterSubTypeWidget->addSettingsWidget(subTypeFilterWidget);
quickFilterSetWidget->addSettingsWidget(setFilterWidget);
quickFilterFormatLegalityWidget->addSettingsWidget(formatLegalityWidget);
filterContainerLayout->addWidget(sortByLabel);
filterContainerLayout->addWidget(sortColumnCombo);
filterContainerLayout->addWidget(sortOrderCombo);
filterContainerLayout->addWidget(filterByLabel);
filterContainerLayout->addWidget(quickFilterNameWidget);
filterContainerLayout->addWidget(quickFilterMainTypeWidget);
filterContainerLayout->addWidget(quickFilterSubTypeWidget);
filterContainerLayout->addWidget(quickFilterSetWidget);
filterContainerLayout->addWidget(quickFilterFormatLegalityWidget);
filterContainerLayout->addStretch();
filterContainerLayout->addWidget(quickFilterSaveLoadWidget);
}
void VisualDatabaseDisplayFilterToolbarWidget::retranslateUi()
{
sortByLabel->setText(tr("Sort by:"));
filterByLabel->setText(tr("Filter by:"));
quickFilterSaveLoadWidget->setToolTip(tr("Save and load filters"));
quickFilterNameWidget->setToolTip(tr("Filter by exact card name"));
quickFilterMainTypeWidget->setToolTip(tr("Filter by card main-type"));
quickFilterSubTypeWidget->setToolTip(tr("Filter by card sub-type"));
quickFilterSetWidget->setToolTip(tr("Filter by set"));
quickFilterFormatLegalityWidget->setToolTip(tr("Filter by format legality"));
quickFilterSaveLoadWidget->setButtonText(tr("Save/Load"));
quickFilterNameWidget->setButtonText(tr("Name"));
quickFilterMainTypeWidget->setButtonText(tr("Main Type"));
quickFilterSubTypeWidget->setButtonText(tr("Sub Type"));
quickFilterSetWidget->setButtonText(tr("Sets"));
quickFilterFormatLegalityWidget->setButtonText(tr("Formats"));
}

View file

@ -0,0 +1,48 @@
#ifndef COCKATRICE_VISUAL_DATABASE_DISPLAY_FILTER_TOOLBAR_WIDGET_H
#define COCKATRICE_VISUAL_DATABASE_DISPLAY_FILTER_TOOLBAR_WIDGET_H
#include "visual_database_display_filter_save_load_widget.h"
#include "visual_database_display_format_legality_filter_widget.h"
#include "visual_database_display_main_type_filter_widget.h"
#include "visual_database_display_name_filter_widget.h"
#include "visual_database_display_set_filter_widget.h"
#include "visual_database_display_sub_type_filter_widget.h"
class VisualDatabaseDisplayWidget;
class VisualDatabaseDisplayFilterToolbarWidget : public QWidget
{
Q_OBJECT
signals:
void searchModelChanged();
public:
explicit VisualDatabaseDisplayFilterToolbarWidget(VisualDatabaseDisplayWidget *parent);
void initialize();
void retranslateUi();
private:
VisualDatabaseDisplayWidget *visualDatabaseDisplay;
QLabel *sortByLabel;
QComboBox *sortColumnCombo, *sortOrderCombo;
QLabel *filterByLabel;
QHBoxLayout *filterContainerLayout;
SettingsButtonWidget *quickFilterSaveLoadWidget;
VisualDatabaseDisplayFilterSaveLoadWidget *saveLoadWidget;
SettingsButtonWidget *quickFilterNameWidget;
VisualDatabaseDisplayNameFilterWidget *nameFilterWidget;
SettingsButtonWidget *quickFilterMainTypeWidget;
VisualDatabaseDisplayMainTypeFilterWidget *mainTypeFilterWidget;
SettingsButtonWidget *quickFilterSubTypeWidget;
VisualDatabaseDisplaySubTypeFilterWidget *subTypeFilterWidget;
SettingsButtonWidget *quickFilterSetWidget;
VisualDatabaseDisplaySetFilterWidget *setFilterWidget;
SettingsButtonWidget *quickFilterFormatLegalityWidget;
VisualDatabaseDisplayFormatLegalityFilterWidget *formatLegalityWidget;
};
#endif // COCKATRICE_VISUAL_DATABASE_DISPLAY_FILTER_TOOLBAR_WIDGET_H

View file

@ -2,6 +2,7 @@
#include "../../../filters/filter_tree_model.h"
#include <QLabel>
#include <QPushButton>
#include <QSpinBox>
#include <QTimer>
@ -14,11 +15,14 @@ VisualDatabaseDisplayFormatLegalityFilterWidget::VisualDatabaseDisplayFormatLega
: QWidget(parent), filterModel(_filterModel)
{
allFormatsWithCount = CardDatabaseManager::query()->getAllFormatsWithCount();
int maxValue = std::numeric_limits<int>::min();
for (int value : allFormatsWithCount) {
maxValue = std::max(maxValue, value);
}
setMinimumWidth(300);
setMaximumHeight(300);
setMaximumHeight(75);
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
layout = new QHBoxLayout(this);
layout = new QVBoxLayout(this);
setLayout(layout);
layout->setContentsMargins(0, 1, 0, 1);
layout->setSpacing(1);
@ -27,33 +31,45 @@ VisualDatabaseDisplayFormatLegalityFilterWidget::VisualDatabaseDisplayFormatLega
flowWidget = new FlowWidget(this, Qt::Horizontal, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAsNeeded);
layout->addWidget(flowWidget);
// Create a container for the threshold control
auto *thresholdLayout = new QHBoxLayout();
thresholdLayout->setContentsMargins(0, 0, 0, 0);
thresholdLabel = new QLabel(this);
thresholdLayout->addWidget(thresholdLabel);
// Create the spinbox
spinBox = new QSpinBox(this);
spinBox->setMinimum(1);
spinBox->setMaximum(getMaxMainTypeCount()); // Set the max value dynamically
spinBox->setMaximum(maxValue); // Set the max value dynamically
spinBox->setValue(150);
layout->addWidget(spinBox);
thresholdLayout->addWidget(spinBox);
thresholdLayout->addStretch();
layout->addLayout(thresholdLayout);
connect(spinBox, qOverload<int>(&QSpinBox::valueChanged), this,
&VisualDatabaseDisplayFormatLegalityFilterWidget::updateFormatButtonsVisibility);
// Create the toggle button for Exact Match/Includes mode
toggleButton = new QPushButton(this);
toggleButton->setCheckable(true);
layout->addWidget(toggleButton);
connect(toggleButton, &QPushButton::toggled, this,
connect(toggleButton, &QPushButton::clicked, this,
&VisualDatabaseDisplayFormatLegalityFilterWidget::updateFilterMode);
connect(filterModel, &FilterTreeModel::layoutChanged, this, [this]() {
QTimer::singleShot(100, this, &VisualDatabaseDisplayFormatLegalityFilterWidget::syncWithFilterModel);
});
createFormatButtons(); // Populate buttons initially
updateFilterMode(false); // Initialize toggle button text
createFormatButtons(); // Populate buttons initially
updateFilterMode(); // Initialize toggle button text
retranslateUi();
}
void VisualDatabaseDisplayFormatLegalityFilterWidget::retranslateUi()
{
thresholdLabel->setText(tr("Show formats with at least:"));
spinBox->setSuffix(tr(" cards"));
spinBox->setToolTip(tr("Do not display formats with less than this amount of cards in the database"));
toggleButton->setToolTip(tr("Filter mode (AND/OR/NOT conjunctions of filters)"));
}
@ -160,9 +176,9 @@ void VisualDatabaseDisplayFormatLegalityFilterWidget::updateFormatFilter()
emit filterModel->layoutChanged();
}
void VisualDatabaseDisplayFormatLegalityFilterWidget::updateFilterMode(bool checked)
void VisualDatabaseDisplayFormatLegalityFilterWidget::updateFilterMode()
{
exactMatchMode = checked;
exactMatchMode = !exactMatchMode;
toggleButton->setText(exactMatchMode ? tr("Mode: Exact Match") : tr("Mode: Includes"));
updateFormatFilter();
}

View file

@ -4,6 +4,7 @@
#include "../../../filters/filter_tree_model.h"
#include "../general/layout_containers/flow_widget.h"
#include <QLabel>
#include <QMap>
#include <QPushButton>
#include <QSpinBox>
@ -23,21 +24,23 @@ public:
void handleFormatToggled(const QString &format, bool active);
void updateFormatFilter();
void updateFilterMode(bool checked);
void updateFilterMode();
void syncWithFilterModel();
private:
FilterTreeModel *filterModel;
QMap<QString, int> allFormatsWithCount;
QSpinBox *spinBox;
QHBoxLayout *layout;
QVBoxLayout *layout;
FlowWidget *flowWidget;
QLabel *thresholdLabel;
QSpinBox *spinBox;
QPushButton *toggleButton; // Mode switch button
QMap<QString, bool> activeFormats; // Track active filters
QMap<QString, QPushButton *> formatButtons; // Store toggle buttons
bool exactMatchMode = false; // Toggle between "Exact Match" and "Includes"
bool exactMatchMode = true; // Toggle between "Exact Match" and "Includes"
};
#endif // COCKATRICE_VISUAL_DATABASE_DISPLAY_FORMAT_LEGALITY_FILTER_WIDGET_H

View file

@ -2,6 +2,7 @@
#include "../../../filters/filter_tree_model.h"
#include <QLabel>
#include <QPushButton>
#include <QSpinBox>
#include <QTimer>
@ -12,13 +13,12 @@ VisualDatabaseDisplayMainTypeFilterWidget::VisualDatabaseDisplayMainTypeFilterWi
FilterTreeModel *_filterModel)
: QWidget(parent), filterModel(_filterModel)
{
allMainCardTypesWithCount = CardDatabaseManager::query()->getAllMainCardTypesWithCount();
// Get all main card types with their count
allMainCardTypesWithCount = CardDatabaseManager::query()->getAllMainCardTypesWithCount();
setMinimumWidth(300);
setMaximumHeight(200);
setMaximumHeight(75);
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
layout = new QHBoxLayout(this);
layout = new QVBoxLayout(this);
setLayout(layout);
layout->setContentsMargins(0, 1, 0, 1);
layout->setSpacing(1);
@ -27,32 +27,44 @@ VisualDatabaseDisplayMainTypeFilterWidget::VisualDatabaseDisplayMainTypeFilterWi
flowWidget = new FlowWidget(this, Qt::Horizontal, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAsNeeded);
layout->addWidget(flowWidget);
// Create a container for the threshold control
auto *thresholdLayout = new QHBoxLayout();
thresholdLayout->setContentsMargins(0, 0, 0, 0);
thresholdLabel = new QLabel(this);
thresholdLayout->addWidget(thresholdLabel);
// Create the spinbox
spinBox = new QSpinBox(this);
spinBox->setMinimum(1);
spinBox->setMaximum(getMaxMainTypeCount()); // Set the max value dynamically
spinBox->setMaximum(getMaxMainTypeCount());
spinBox->setValue(150);
layout->addWidget(spinBox);
thresholdLayout->addWidget(spinBox);
thresholdLayout->addStretch();
layout->addLayout(thresholdLayout);
connect(spinBox, qOverload<int>(&QSpinBox::valueChanged), this,
&VisualDatabaseDisplayMainTypeFilterWidget::updateMainTypeButtonsVisibility);
// Create the toggle button for Exact Match/Includes mode
toggleButton = new QPushButton(this);
toggleButton->setCheckable(true);
layout->addWidget(toggleButton);
connect(toggleButton, &QPushButton::toggled, this, &VisualDatabaseDisplayMainTypeFilterWidget::updateFilterMode);
connect(toggleButton, &QPushButton::clicked, this, &VisualDatabaseDisplayMainTypeFilterWidget::updateFilterMode);
connect(filterModel, &FilterTreeModel::layoutChanged, this, [this]() {
QTimer::singleShot(100, this, &VisualDatabaseDisplayMainTypeFilterWidget::syncWithFilterModel);
});
createMainTypeButtons(); // Populate buttons initially
updateFilterMode(false); // Initialize toggle button text
updateFilterMode(); // Initialize toggle button text
retranslateUi();
}
void VisualDatabaseDisplayMainTypeFilterWidget::retranslateUi()
{
thresholdLabel->setText(tr("Show main types with at least:"));
spinBox->setSuffix(tr(" cards"));
spinBox->setToolTip(tr("Do not display card main-types with less than this amount of cards in the database"));
toggleButton->setToolTip(tr("Filter mode (AND/OR/NOT conjunctions of filters)"));
}
@ -159,9 +171,9 @@ void VisualDatabaseDisplayMainTypeFilterWidget::updateMainTypeFilter()
emit filterModel->layoutChanged();
}
void VisualDatabaseDisplayMainTypeFilterWidget::updateFilterMode(bool checked)
void VisualDatabaseDisplayMainTypeFilterWidget::updateFilterMode()
{
exactMatchMode = checked;
exactMatchMode = !exactMatchMode;
toggleButton->setText(exactMatchMode ? tr("Mode: Exact Match") : tr("Mode: Includes"));
updateMainTypeFilter();
}

View file

@ -10,6 +10,7 @@
#include "../../../filters/filter_tree_model.h"
#include "../general/layout_containers/flow_widget.h"
#include <QLabel>
#include <QMap>
#include <QPushButton>
#include <QSpinBox>
@ -28,21 +29,23 @@ public:
void handleMainTypeToggled(const QString &mainType, bool active);
void updateMainTypeFilter();
void updateFilterMode(bool checked);
void updateFilterMode();
void syncWithFilterModel();
private:
FilterTreeModel *filterModel;
QMap<QString, int> allMainCardTypesWithCount;
QSpinBox *spinBox;
QHBoxLayout *layout;
QVBoxLayout *layout;
FlowWidget *flowWidget;
QLabel *thresholdLabel;
QSpinBox *spinBox;
QPushButton *toggleButton; // Mode switch button
QMap<QString, bool> activeMainTypes; // Track active filters
QMap<QString, QPushButton *> typeButtons; // Store toggle buttons
bool exactMatchMode = false; // Toggle between "Exact Match" and "Includes"
bool exactMatchMode = true; // Toggle between "Exact Match" and "Includes"
};
#endif // VISUAL_DATABASE_DISPLAY_MAIN_TYPE_FILTER_WIDGET_H

View file

@ -53,14 +53,6 @@ VisualDatabaseDisplaySetFilterWidget::VisualDatabaseDisplaySetFilterWidget(QWidg
layout = new QVBoxLayout(this);
setLayout(layout);
recentSetsSettingsWidget = new VisualDatabaseDisplayRecentSetFilterSettingsWidget(this);
layout->addWidget(recentSetsSettingsWidget);
connect(&SettingsCache::instance(), &SettingsCache::visualDatabaseDisplayFilterToMostRecentSetsEnabledChanged, this,
&VisualDatabaseDisplaySetFilterWidget::filterToRecentSets);
connect(&SettingsCache::instance(), &SettingsCache::visualDatabaseDisplayFilterToMostRecentSetsAmountChanged, this,
&VisualDatabaseDisplaySetFilterWidget::filterToRecentSets);
searchBox = new QLineEdit(this);
searchBox->setPlaceholderText(tr("Search sets..."));
layout->addWidget(searchBox);
@ -70,15 +62,23 @@ VisualDatabaseDisplaySetFilterWidget::VisualDatabaseDisplaySetFilterWidget(QWidg
flowWidget = new FlowWidget(this, Qt::Horizontal, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAsNeeded);
layout->addWidget(flowWidget);
recentSetsSettingsWidget = new VisualDatabaseDisplayRecentSetFilterSettingsWidget(this);
layout->addWidget(recentSetsSettingsWidget);
connect(&SettingsCache::instance(), &SettingsCache::visualDatabaseDisplayFilterToMostRecentSetsEnabledChanged, this,
&VisualDatabaseDisplaySetFilterWidget::filterToRecentSets);
connect(&SettingsCache::instance(), &SettingsCache::visualDatabaseDisplayFilterToMostRecentSetsAmountChanged, this,
&VisualDatabaseDisplaySetFilterWidget::filterToRecentSets);
// Create the toggle button for Exact Match/Includes mode
toggleButton = new QPushButton(this);
toggleButton->setCheckable(true);
layout->addWidget(toggleButton);
connect(toggleButton, &QPushButton::toggled, this, &VisualDatabaseDisplaySetFilterWidget::updateFilterMode);
connect(toggleButton, &QPushButton::clicked, this, &VisualDatabaseDisplaySetFilterWidget::updateFilterMode);
connect(filterModel, &FilterTreeModel::layoutChanged, this,
[this]() { QTimer::singleShot(100, this, &VisualDatabaseDisplaySetFilterWidget::syncWithFilterModel); });
createSetButtons(); // Populate buttons initially
updateFilterMode();
retranslateUi();
}
@ -266,9 +266,16 @@ void VisualDatabaseDisplaySetFilterWidget::syncWithFilterModel()
}
}
void VisualDatabaseDisplaySetFilterWidget::updateFilterMode(bool checked)
void VisualDatabaseDisplaySetFilterWidget::updateFilterMode()
{
exactMatchMode = checked;
// Disconnect the layoutChanged -> sync lambda temporarily
disconnect(filterModel, &FilterTreeModel::layoutChanged, this, nullptr);
exactMatchMode = !exactMatchMode;
updateSetFilter();
retranslateUi();
// Reconnect the layoutChanged -> sync lambda
connect(filterModel, &FilterTreeModel::layoutChanged, this,
[this]() { QTimer::singleShot(100, this, &VisualDatabaseDisplaySetFilterWidget::syncWithFilterModel); });
}

View file

@ -44,7 +44,7 @@ public:
void updateSetFilter();
void syncWithFilterModel();
void updateFilterMode(bool checked);
void updateFilterMode();
private:
FilterTreeModel *filterModel;
@ -60,7 +60,7 @@ private:
QMap<QString, QPushButton *> setButtons; // Store set filter buttons
QMap<QString, bool> activeSets; // Track active set filters
bool exactMatchMode = false; // Toggle between "Exact Match" and "Includes"
bool exactMatchMode = true; // Toggle between "Exact Match" and "Includes"
};
#endif // VISUAL_DATABASE_DISPLAY_SET_FILTER_WIDGET_H

View file

@ -2,6 +2,7 @@
#include "../../../filters/filter_tree_model.h"
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QSpinBox>
@ -20,15 +21,6 @@ VisualDatabaseDisplaySubTypeFilterWidget::VisualDatabaseDisplaySubTypeFilterWidg
layout = new QVBoxLayout(this);
setLayout(layout);
// Create and setup the spinbox
spinBox = new QSpinBox(this);
spinBox->setMinimum(1);
spinBox->setMaximum(getMaxSubTypeCount());
spinBox->setValue(150);
layout->addWidget(spinBox);
connect(spinBox, qOverload<int>(&QSpinBox::valueChanged), this,
&VisualDatabaseDisplaySubTypeFilterWidget::updateSubTypeButtonsVisibility);
// Create search box
searchBox = new QLineEdit(this);
searchBox->setPlaceholderText(tr("Search subtypes..."));
@ -40,23 +32,44 @@ VisualDatabaseDisplaySubTypeFilterWidget::VisualDatabaseDisplaySubTypeFilterWidg
flowWidget->setMaximumHeight(300);
layout->addWidget(flowWidget);
// Create a container for the threshold control
auto *thresholdLayout = new QHBoxLayout();
thresholdLayout->setContentsMargins(0, 0, 0, 0);
thresholdLabel = new QLabel(this);
thresholdLayout->addWidget(thresholdLabel);
// Create the spinbox
spinBox = new QSpinBox(this);
spinBox->setMinimum(1);
spinBox->setMaximum(getMaxSubTypeCount());
spinBox->setValue(150);
thresholdLayout->addWidget(spinBox);
thresholdLayout->addStretch();
layout->addLayout(thresholdLayout);
connect(spinBox, qOverload<int>(&QSpinBox::valueChanged), this,
&VisualDatabaseDisplaySubTypeFilterWidget::updateSubTypeButtonsVisibility);
// Toggle button setup (Exact Match / Includes mode)
toggleButton = new QPushButton(this);
toggleButton->setCheckable(true);
layout->addWidget(toggleButton);
connect(toggleButton, &QPushButton::toggled, this, &VisualDatabaseDisplaySubTypeFilterWidget::updateFilterMode);
connect(toggleButton, &QPushButton::clicked, this, &VisualDatabaseDisplaySubTypeFilterWidget::updateFilterMode);
connect(filterModel, &FilterTreeModel::layoutChanged, this, [this]() {
QTimer::singleShot(100, this, &VisualDatabaseDisplaySubTypeFilterWidget::syncWithFilterModel);
});
createSubTypeButtons(); // Populate buttons initially
updateFilterMode(false); // Initialize the toggle button text
createSubTypeButtons(); // Populate buttons initially
updateFilterMode(); // Initialize the toggle button text
retranslateUi();
}
void VisualDatabaseDisplaySubTypeFilterWidget::retranslateUi()
{
thresholdLabel->setText(tr("Show sub types with at least:"));
spinBox->setSuffix(tr(" cards"));
spinBox->setToolTip(tr("Do not display card sub-types with less than this amount of cards in the database"));
toggleButton->setToolTip(tr("Filter mode (AND/OR/NOT conjunctions of filters)"));
}
@ -155,7 +168,7 @@ void VisualDatabaseDisplaySubTypeFilterWidget::updateSubTypeFilter()
if (activeSubTypes[type]) {
QString typeString = type;
filterModel->addFilter(
new CardFilter(typeString, CardFilter::Type::TypeAnd, CardFilter::Attr::AttrSubType));
new CardFilter(typeString, CardFilter::Type::TypeOr, CardFilter::Attr::AttrSubType));
}
}
}
@ -166,9 +179,9 @@ void VisualDatabaseDisplaySubTypeFilterWidget::updateSubTypeFilter()
emit filterModel->layoutChanged();
}
void VisualDatabaseDisplaySubTypeFilterWidget::updateFilterMode(bool checked)
void VisualDatabaseDisplaySubTypeFilterWidget::updateFilterMode()
{
exactMatchMode = checked;
exactMatchMode = !exactMatchMode;
toggleButton->setText(exactMatchMode ? tr("Mode: Exact Match") : tr("Mode: Includes"));
updateSubTypeFilter();
}
@ -188,7 +201,7 @@ void VisualDatabaseDisplaySubTypeFilterWidget::syncWithFilterModel()
// Get active filters for sub types
QSet<QString> activeTypes;
for (const auto &filter : filterModel->getFiltersOfType(CardFilter::AttrSubType)) {
if (filter->type() == CardFilter::Type::TypeAnd) {
if (filter->type() == CardFilter::Type::TypeAnd || filter->type() == CardFilter::Type::TypeOr) {
activeTypes.insert(filter->term());
}
}

View file

@ -10,6 +10,7 @@
#include "../../../filters/filter_tree_model.h"
#include "../general/layout_containers/flow_widget.h"
#include <QLabel>
#include <QMap>
#include <QPushButton>
#include <QSpinBox>
@ -27,22 +28,24 @@ public:
void handleSubTypeToggled(const QString &mainType, bool active);
void updateSubTypeFilter();
void updateFilterMode(bool checked);
void updateFilterMode();
void syncWithFilterModel();
private:
FilterTreeModel *filterModel;
QMap<QString, int> allSubCardTypesWithCount;
QSpinBox *spinBox;
QVBoxLayout *layout;
QLineEdit *searchBox;
FlowWidget *flowWidget;
QLabel *thresholdLabel;
QSpinBox *spinBox;
QPushButton *toggleButton; // Mode switch button
QMap<QString, bool> activeSubTypes; // Track active filters
QMap<QString, QPushButton *> typeButtons; // Store toggle buttons
bool exactMatchMode = false; // Toggle between "Exact Match" and "Includes"
bool exactMatchMode = true; // Toggle between "Exact Match" and "Includes"
};
#endif // VISUAL_DATABASE_DISPLAY_SUB_TYPE_FILTER_WIDGET_H

View file

@ -101,49 +101,9 @@ VisualDatabaseDisplayWidget::VisualDatabaseDisplayWidget(QWidget *parent,
searchEdit->setTreeView(databaseView);
sortByLabel = new QLabel(this);
sortColumnCombo = new QComboBox(this);
sortColumnCombo->setSizeAdjustPolicy(QComboBox::SizeAdjustPolicy::AdjustToContents);
sortOrderCombo = new QComboBox(this);
sortOrderCombo->setSizeAdjustPolicy(QComboBox::SizeAdjustPolicy::AdjustToContents);
sortOrderCombo->addItem("Ascending", Qt::AscendingOrder);
sortOrderCombo->addItem("Descending", Qt::DescendingOrder);
sortOrderCombo->view()->setMinimumWidth(sortOrderCombo->view()->sizeHintForColumn(0));
sortOrderCombo->adjustSize();
// Populate columns dynamically from the model
for (int i = 0; i < databaseDisplayModel->columnCount(); ++i) {
QString header = databaseDisplayModel->headerData(i, Qt::Horizontal).toString();
sortColumnCombo->addItem(header, i);
}
sortColumnCombo->view()->setMinimumWidth(sortColumnCombo->view()->sizeHintForColumn(0));
sortColumnCombo->adjustSize();
connect(sortColumnCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [this]() {
int column = sortColumnCombo->currentData().toInt();
Qt::SortOrder order = static_cast<Qt::SortOrder>(sortOrderCombo->currentData().toInt());
databaseView->sortByColumn(column, order);
searchModelChanged();
});
connect(sortOrderCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [this]() {
int column = sortColumnCombo->currentData().toInt();
Qt::SortOrder order = static_cast<Qt::SortOrder>(sortOrderCombo->currentData().toInt());
databaseView->sortByColumn(column, order);
searchModelChanged();
});
colorFilterWidget = new VisualDatabaseDisplayColorFilterWidget(this, filterModel);
filterContainer = new QWidget(this);
filterContainerLayout = new QHBoxLayout(filterContainer);
filterContainer->setLayout(filterContainerLayout);
filterByLabel = new QLabel(this);
filterContainer = new VisualDatabaseDisplayFilterToolbarWidget(this);
clearFilterWidget = new QToolButton();
clearFilterWidget->setFixedSize(32, 32);
@ -158,20 +118,6 @@ VisualDatabaseDisplayWidget::VisualDatabaseDisplayWidget(QWidget *parent,
emit filterModel->layoutChanged();
});
quickFilterSaveLoadWidget = new SettingsButtonWidget(this);
quickFilterSaveLoadWidget->setButtonIcon(QPixmap("theme:icons/lock"));
quickFilterNameWidget = new SettingsButtonWidget(this);
quickFilterNameWidget->setButtonIcon(QPixmap("theme:icons/rename"));
quickFilterSubTypeWidget = new SettingsButtonWidget(this);
quickFilterSubTypeWidget->setButtonIcon(QPixmap("theme:icons/player"));
quickFilterSetWidget = new SettingsButtonWidget(this);
quickFilterSetWidget->setButtonIcon(QPixmap("theme:icons/scales"));
filterContainer->setMaximumHeight(80);
databaseLoadIndicator = new QLabel(this);
databaseLoadIndicator->setAlignment(Qt::AlignCenter);
@ -180,12 +126,7 @@ VisualDatabaseDisplayWidget::VisualDatabaseDisplayWidget(QWidget *parent,
if (CardDatabaseManager::getInstance()->getLoadStatus() != LoadStatus::Ok) {
connect(CardDatabaseManager::getInstance(), &CardDatabase::cardDatabaseLoadingFinished, this,
&VisualDatabaseDisplayWidget::initialize);
sortByLabel->setVisible(false);
filterByLabel->setVisible(false);
quickFilterSaveLoadWidget->setVisible(false);
quickFilterNameWidget->setVisible(false);
quickFilterSubTypeWidget->setVisible(false);
quickFilterSetWidget->setVisible(false);
filterContainer->setVisible(false);
} else {
initialize();
databaseLoadIndicator->setVisible(false);
@ -198,35 +139,7 @@ void VisualDatabaseDisplayWidget::initialize()
{
databaseLoadIndicator->setVisible(false);
sortByLabel->setVisible(true);
filterByLabel->setVisible(true);
quickFilterSaveLoadWidget->setVisible(true);
quickFilterNameWidget->setVisible(true);
quickFilterSubTypeWidget->setVisible(true);
quickFilterSetWidget->setVisible(true);
saveLoadWidget = new VisualDatabaseDisplayFilterSaveLoadWidget(this, filterModel);
nameFilterWidget = new VisualDatabaseDisplayNameFilterWidget(this, deckEditor, filterModel);
mainTypeFilterWidget = new VisualDatabaseDisplayMainTypeFilterWidget(this, filterModel);
formatLegalityWidget = new VisualDatabaseDisplayFormatLegalityFilterWidget(this, filterModel);
subTypeFilterWidget = new VisualDatabaseDisplaySubTypeFilterWidget(this, filterModel);
setFilterWidget = new VisualDatabaseDisplaySetFilterWidget(this, filterModel);
quickFilterSaveLoadWidget->addSettingsWidget(saveLoadWidget);
quickFilterNameWidget->addSettingsWidget(nameFilterWidget);
quickFilterSubTypeWidget->addSettingsWidget(subTypeFilterWidget);
quickFilterSetWidget->addSettingsWidget(setFilterWidget);
filterContainerLayout->addWidget(sortByLabel);
filterContainerLayout->addWidget(sortColumnCombo);
filterContainerLayout->addWidget(sortOrderCombo);
filterContainerLayout->addWidget(filterByLabel);
filterContainerLayout->addWidget(quickFilterSaveLoadWidget);
filterContainerLayout->addWidget(quickFilterNameWidget);
filterContainerLayout->addWidget(quickFilterSubTypeWidget);
filterContainerLayout->addWidget(quickFilterSetWidget);
filterContainerLayout->addWidget(mainTypeFilterWidget);
filterContainerLayout->addWidget(formatLegalityWidget);
filterContainer->initialize();
searchLayout->addWidget(colorFilterWidget);
searchLayout->addWidget(clearFilterWidget);
@ -246,11 +159,11 @@ void VisualDatabaseDisplayWidget::initialize()
debounceTimer = new QTimer(this);
debounceTimer->setSingleShot(true); // Ensure it only fires once after the timeout
connect(debounceTimer, &QTimer::timeout, this, &VisualDatabaseDisplayWidget::searchModelChanged);
connect(debounceTimer, &QTimer::timeout, this, &VisualDatabaseDisplayWidget::onSearchModelChanged);
databaseDisplayModel->setFilterTree(filterModel->filterTree());
connect(filterModel, &FilterTreeModel::layoutChanged, this, &VisualDatabaseDisplayWidget::searchModelChanged);
connect(filterModel, &FilterTreeModel::layoutChanged, this, &VisualDatabaseDisplayWidget::onSearchModelChanged);
loadCardsTimer = new QTimer(this);
loadCardsTimer->setSingleShot(true); // Ensure it only fires once after the timeout
@ -264,16 +177,7 @@ void VisualDatabaseDisplayWidget::initialize()
void VisualDatabaseDisplayWidget::retranslateUi()
{
databaseLoadIndicator->setText(tr("Loading database ..."));
clearFilterWidget->setToolTip(tr("Clear all filters"));
sortByLabel->setText(tr("Sort by:"));
filterByLabel->setText(tr("Filter by:"));
quickFilterSaveLoadWidget->setToolTip(tr("Save and load filters"));
quickFilterNameWidget->setToolTip(tr("Filter by exact card name"));
quickFilterSubTypeWidget->setToolTip(tr("Filter by card sub-type"));
quickFilterSetWidget->setToolTip(tr("Filter by set"));
}
void VisualDatabaseDisplayWidget::resizeEvent(QResizeEvent *event)
@ -332,7 +236,7 @@ void VisualDatabaseDisplayWidget::updateSearch(const QString &search) const
QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
}
void VisualDatabaseDisplayWidget::searchModelChanged()
void VisualDatabaseDisplayWidget::onSearchModelChanged()
{
if (flowWidget->isVisible()) {
// Clear the current page and prepare for new data

View file

@ -16,12 +16,7 @@
#include "../general/layout_containers/overlap_control_widget.h"
#include "../utility/custom_line_edit.h"
#include "visual_database_display_color_filter_widget.h"
#include "visual_database_display_filter_save_load_widget.h"
#include "visual_database_display_format_legality_filter_widget.h"
#include "visual_database_display_main_type_filter_widget.h"
#include "visual_database_display_name_filter_widget.h"
#include "visual_database_display_set_filter_widget.h"
#include "visual_database_display_sub_type_filter_widget.h"
#include "visual_database_display_filter_toolbar_widget.h"
#include <QLoggingCategory>
#include <QVBoxLayout>
@ -52,6 +47,21 @@ public:
void sortCardList(const QStringList &properties, Qt::SortOrder order) const;
void setDeckList(const DeckList &new_deck_list_model);
AbstractTabDeckEditor *getDeckEditor()
{
return deckEditor;
}
CardDatabaseDisplayModel *getDatabaseDisplayModel()
{
return databaseDisplayModel;
}
QTreeView *getDatabaseView()
{
return databaseView;
}
QWidget *searchContainer;
QHBoxLayout *searchLayout;
SearchLineEdit *searchEdit;
@ -60,7 +70,7 @@ public:
VisualDatabaseDisplayColorFilterWidget *colorFilterWidget;
public slots:
void searchModelChanged();
void onSearchModelChanged();
signals:
void cardClickedDatabaseDisplay(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance);
@ -80,23 +90,8 @@ protected slots:
private:
QLabel *databaseLoadIndicator;
QLabel *sortByLabel;
QComboBox *sortColumnCombo, *sortOrderCombo;
QLabel *filterByLabel;
QToolButton *clearFilterWidget;
QWidget *filterContainer;
QHBoxLayout *filterContainerLayout;
SettingsButtonWidget *quickFilterSaveLoadWidget;
VisualDatabaseDisplayFilterSaveLoadWidget *saveLoadWidget;
SettingsButtonWidget *quickFilterNameWidget;
VisualDatabaseDisplayNameFilterWidget *nameFilterWidget;
VisualDatabaseDisplayMainTypeFilterWidget *mainTypeFilterWidget;
VisualDatabaseDisplayFormatLegalityFilterWidget *formatLegalityWidget;
SettingsButtonWidget *quickFilterSubTypeWidget;
VisualDatabaseDisplaySubTypeFilterWidget *subTypeFilterWidget;
SettingsButtonWidget *quickFilterSetWidget;
VisualDatabaseDisplaySetFilterWidget *setFilterWidget;
VisualDatabaseDisplayFilterToolbarWidget *filterContainer;
KeySignals searchKeySignals;
AbstractTabDeckEditor *deckEditor;
CardDatabaseModel *databaseModel;