mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-04-27 07:48:01 -07:00
Deck format legality checker (#6166)
* Deck legality checker. Took 51 seconds Took 1 minute Took 1 minute Took 5 minutes Took 3 minutes * Adjust format parsing. Took 8 minutes Took 3 seconds * toString() the xmlName Took 4 minutes * more toStrings() Took 5 minutes * Comments Took 3 minutes * Layout Took 2 minutes * Layout part 2: Electric boogaloo Took 59 seconds * Update cockatrice/src/interface/widgets/visual_database_display/visual_database_display_format_legality_filter_widget.cpp Co-authored-by: RickyRister <42636155+RickyRister@users.noreply.github.com> * Move layout. Took 4 minutes Took 10 seconds * Emit deckModified Took 6 minutes * Fix qOverloads Took 4 minutes * Fix qOverloads Took 12 seconds * Consider text and name in a special way. Took 11 minutes * Adjust "Any number of" oracle text Took 5 minutes * Store allowedCounts by format Took 15 minutes Took 6 seconds * Only restrict vintage. Took 2 minutes * Adjust for DBConverter. Took 6 minutes --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de> Co-authored-by: RickyRister <42636155+RickyRister@users.noreply.github.com>
This commit is contained in:
parent
2e2682aad4
commit
ccdda39e78
37 changed files with 987 additions and 35 deletions
|
|
@ -0,0 +1,205 @@
|
|||
#include "visual_database_display_format_legality_filter_widget.h"
|
||||
|
||||
#include "../../../filters/filter_tree_model.h"
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QSpinBox>
|
||||
#include <QTimer>
|
||||
#include <libcockatrice/card/database/card_database_manager.h>
|
||||
#include <libcockatrice/filters/filter_tree.h>
|
||||
|
||||
VisualDatabaseDisplayFormatLegalityFilterWidget::VisualDatabaseDisplayFormatLegalityFilterWidget(
|
||||
QWidget *parent,
|
||||
FilterTreeModel *_filterModel)
|
||||
: QWidget(parent), filterModel(_filterModel)
|
||||
{
|
||||
allFormatsWithCount = CardDatabaseManager::query()->getAllFormatsWithCount();
|
||||
|
||||
setMaximumHeight(75);
|
||||
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum);
|
||||
|
||||
layout = new QHBoxLayout(this);
|
||||
setLayout(layout);
|
||||
layout->setContentsMargins(0, 1, 0, 1);
|
||||
layout->setSpacing(1);
|
||||
layout->setAlignment(Qt::AlignTop);
|
||||
|
||||
flowWidget = new FlowWidget(this, Qt::Horizontal, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAsNeeded);
|
||||
layout->addWidget(flowWidget);
|
||||
|
||||
// Create the spinbox
|
||||
spinBox = new QSpinBox(this);
|
||||
spinBox->setMinimum(1);
|
||||
spinBox->setMaximum(getMaxMainTypeCount()); // Set the max value dynamically
|
||||
spinBox->setValue(150);
|
||||
layout->addWidget(spinBox);
|
||||
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,
|
||||
&VisualDatabaseDisplayFormatLegalityFilterWidget::updateFilterMode);
|
||||
connect(filterModel, &FilterTreeModel::layoutChanged, this, [this]() {
|
||||
QTimer::singleShot(100, this, &VisualDatabaseDisplayFormatLegalityFilterWidget::syncWithFilterModel);
|
||||
});
|
||||
|
||||
createFormatButtons(); // Populate buttons initially
|
||||
updateFilterMode(false); // Initialize toggle button text
|
||||
|
||||
retranslateUi();
|
||||
}
|
||||
|
||||
void VisualDatabaseDisplayFormatLegalityFilterWidget::retranslateUi()
|
||||
{
|
||||
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)"));
|
||||
}
|
||||
|
||||
void VisualDatabaseDisplayFormatLegalityFilterWidget::createFormatButtons()
|
||||
{
|
||||
// Iterate through main types and create buttons
|
||||
for (auto it = allFormatsWithCount.begin(); it != allFormatsWithCount.end(); ++it) {
|
||||
auto *button = new QPushButton(it.key(), flowWidget);
|
||||
button->setCheckable(true);
|
||||
button->setStyleSheet("QPushButton { background-color: lightgray; border: 1px solid gray; padding: 5px; }"
|
||||
"QPushButton:checked { background-color: green; color: white; }");
|
||||
|
||||
flowWidget->addWidget(button);
|
||||
formatButtons[it.key()] = button;
|
||||
|
||||
// Connect toggle signal
|
||||
connect(button, &QPushButton::toggled, this,
|
||||
[this, mainType = it.key()](bool checked) { handleFormatToggled(mainType, checked); });
|
||||
}
|
||||
updateFormatButtonsVisibility(); // Ensure visibility is updated initially
|
||||
}
|
||||
|
||||
void VisualDatabaseDisplayFormatLegalityFilterWidget::updateFormatButtonsVisibility()
|
||||
{
|
||||
int threshold = spinBox->value(); // Get the current spinbox value
|
||||
|
||||
// Iterate through buttons and hide/disable those below the threshold
|
||||
for (auto it = formatButtons.begin(); it != formatButtons.end(); ++it) {
|
||||
bool visible = allFormatsWithCount[it.key()] >= threshold;
|
||||
it.value()->setVisible(visible);
|
||||
it.value()->setEnabled(visible);
|
||||
}
|
||||
}
|
||||
|
||||
int VisualDatabaseDisplayFormatLegalityFilterWidget::getMaxMainTypeCount() const
|
||||
{
|
||||
int maxCount = 1;
|
||||
for (auto it = allFormatsWithCount.begin(); it != allFormatsWithCount.end(); ++it) {
|
||||
maxCount = qMax(maxCount, it.value());
|
||||
}
|
||||
return maxCount;
|
||||
}
|
||||
|
||||
void VisualDatabaseDisplayFormatLegalityFilterWidget::handleFormatToggled(const QString &format, bool active)
|
||||
{
|
||||
activeFormats[format] = active;
|
||||
|
||||
if (formatButtons.contains(format)) {
|
||||
formatButtons[format]->setChecked(active);
|
||||
}
|
||||
|
||||
updateFormatFilter();
|
||||
}
|
||||
|
||||
void VisualDatabaseDisplayFormatLegalityFilterWidget::updateFormatFilter()
|
||||
{
|
||||
// Clear existing filters related to main type
|
||||
filterModel->blockSignals(true);
|
||||
filterModel->filterTree()->blockSignals(true);
|
||||
filterModel->clearFiltersOfType(CardFilter::Attr::AttrFormat);
|
||||
|
||||
if (exactMatchMode) {
|
||||
// Exact Match: Only selected main types are allowed
|
||||
QSet<QString> selectedTypes;
|
||||
for (const auto &type : activeFormats.keys()) {
|
||||
if (activeFormats[type]) {
|
||||
selectedTypes.insert(type);
|
||||
}
|
||||
}
|
||||
|
||||
if (!selectedTypes.isEmpty()) {
|
||||
// Require all selected types (TypeAnd)
|
||||
for (const auto &type : selectedTypes) {
|
||||
QString typeString = type;
|
||||
filterModel->addFilter(
|
||||
new CardFilter(typeString, CardFilter::Type::TypeAnd, CardFilter::Attr::AttrFormat));
|
||||
}
|
||||
|
||||
// Exclude any other types (TypeAndNot)
|
||||
for (const auto &type : formatButtons.keys()) {
|
||||
if (!selectedTypes.contains(type)) {
|
||||
QString typeString = type;
|
||||
filterModel->addFilter(
|
||||
new CardFilter(typeString, CardFilter::Type::TypeAndNot, CardFilter::Attr::AttrFormat));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Default Includes Mode (TypeOr) - match any selected main types
|
||||
for (const auto &type : activeFormats.keys()) {
|
||||
if (activeFormats[type]) {
|
||||
QString typeString = type;
|
||||
filterModel->addFilter(
|
||||
new CardFilter(typeString, CardFilter::Type::TypeAnd, CardFilter::Attr::AttrFormat));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
filterModel->blockSignals(false);
|
||||
filterModel->filterTree()->blockSignals(false);
|
||||
|
||||
emit filterModel->filterTree()->changed();
|
||||
emit filterModel->layoutChanged();
|
||||
}
|
||||
|
||||
void VisualDatabaseDisplayFormatLegalityFilterWidget::updateFilterMode(bool checked)
|
||||
{
|
||||
exactMatchMode = checked;
|
||||
toggleButton->setText(exactMatchMode ? tr("Mode: Exact Match") : tr("Mode: Includes"));
|
||||
updateFormatFilter();
|
||||
}
|
||||
|
||||
void VisualDatabaseDisplayFormatLegalityFilterWidget::syncWithFilterModel()
|
||||
{
|
||||
// Temporarily block signals for each button to prevent toggling while updating button states
|
||||
for (auto it = formatButtons.begin(); it != formatButtons.end(); ++it) {
|
||||
it.value()->blockSignals(true);
|
||||
}
|
||||
|
||||
// Uncheck all buttons
|
||||
for (auto it = formatButtons.begin(); it != formatButtons.end(); ++it) {
|
||||
it.value()->setChecked(false);
|
||||
}
|
||||
|
||||
// Get active filters for main types
|
||||
QSet<QString> activeTypes;
|
||||
for (const auto &filter : filterModel->getFiltersOfType(CardFilter::AttrFormat)) {
|
||||
if (filter->type() == CardFilter::Type::TypeAnd) {
|
||||
activeTypes.insert(filter->term());
|
||||
}
|
||||
}
|
||||
|
||||
// Check the buttons for active types
|
||||
for (const auto &type : activeTypes) {
|
||||
activeFormats[type] = true;
|
||||
if (formatButtons.contains(type)) {
|
||||
formatButtons[type]->setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Re-enable signal emissions for each button
|
||||
for (auto it = formatButtons.begin(); it != formatButtons.end(); ++it) {
|
||||
it.value()->blockSignals(false);
|
||||
}
|
||||
|
||||
// Update the visibility of buttons
|
||||
updateFormatButtonsVisibility();
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
#ifndef COCKATRICE_VISUAL_DATABASE_DISPLAY_FORMAT_LEGALITY_FILTER_WIDGET_H
|
||||
#define COCKATRICE_VISUAL_DATABASE_DISPLAY_FORMAT_LEGALITY_FILTER_WIDGET_H
|
||||
|
||||
#include "../../../filters/filter_tree_model.h"
|
||||
#include "../general/layout_containers/flow_widget.h"
|
||||
|
||||
#include <QMap>
|
||||
#include <QPushButton>
|
||||
#include <QSpinBox>
|
||||
#include <QToolButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
|
||||
class VisualDatabaseDisplayFormatLegalityFilterWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VisualDatabaseDisplayFormatLegalityFilterWidget(QWidget *parent, FilterTreeModel *filterModel);
|
||||
void retranslateUi();
|
||||
void createFormatButtons();
|
||||
void updateFormatButtonsVisibility();
|
||||
int getMaxMainTypeCount() const;
|
||||
|
||||
void handleFormatToggled(const QString &format, bool active);
|
||||
void updateFormatFilter();
|
||||
void updateFilterMode(bool checked);
|
||||
void syncWithFilterModel();
|
||||
|
||||
private:
|
||||
FilterTreeModel *filterModel;
|
||||
QMap<QString, int> allFormatsWithCount;
|
||||
QSpinBox *spinBox;
|
||||
QHBoxLayout *layout;
|
||||
FlowWidget *flowWidget;
|
||||
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"
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_VISUAL_DATABASE_DISPLAY_FORMAT_LEGALITY_FILTER_WIDGET_H
|
||||
|
|
@ -33,7 +33,7 @@ VisualDatabaseDisplayMainTypeFilterWidget::VisualDatabaseDisplayMainTypeFilterWi
|
|||
spinBox->setMaximum(getMaxMainTypeCount()); // Set the max value dynamically
|
||||
spinBox->setValue(150);
|
||||
layout->addWidget(spinBox);
|
||||
connect(spinBox, QOverload<int>::of(&QSpinBox::valueChanged), this,
|
||||
connect(spinBox, qOverload<int>(&QSpinBox::valueChanged), this,
|
||||
&VisualDatabaseDisplayMainTypeFilterWidget::updateMainTypeButtonsVisibility);
|
||||
|
||||
// Create the toggle button for Exact Match/Includes mode
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ VisualDatabaseDisplayRecentSetFilterSettingsWidget::VisualDatabaseDisplayRecentS
|
|||
filterToMostRecentSetsAmount->setMaximum(100);
|
||||
filterToMostRecentSetsAmount->setValue(
|
||||
SettingsCache::instance().getVisualDatabaseDisplayFilterToMostRecentSetsAmount());
|
||||
connect(filterToMostRecentSetsAmount, QOverload<int>::of(&QSpinBox::valueChanged), &SettingsCache::instance(),
|
||||
connect(filterToMostRecentSetsAmount, qOverload<int>(&QSpinBox::valueChanged), &SettingsCache::instance(),
|
||||
&SettingsCache::setVisualDatabaseDisplayFilterToMostRecentSetsAmount);
|
||||
|
||||
layout->addWidget(filterToMostRecentSetsCheckBox);
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ VisualDatabaseDisplaySubTypeFilterWidget::VisualDatabaseDisplaySubTypeFilterWidg
|
|||
spinBox->setMaximum(getMaxSubTypeCount());
|
||||
spinBox->setValue(150);
|
||||
layout->addWidget(spinBox);
|
||||
connect(spinBox, QOverload<int>::of(&QSpinBox::valueChanged), this,
|
||||
connect(spinBox, qOverload<int>(&QSpinBox::valueChanged), this,
|
||||
&VisualDatabaseDisplaySubTypeFilterWidget::updateSubTypeButtonsVisibility);
|
||||
|
||||
// Create search box
|
||||
|
|
|
|||
|
|
@ -206,6 +206,7 @@ void VisualDatabaseDisplayWidget::initialize()
|
|||
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);
|
||||
|
||||
|
|
@ -223,6 +224,7 @@ void VisualDatabaseDisplayWidget::initialize()
|
|||
filterContainerLayout->addWidget(quickFilterSubTypeWidget);
|
||||
filterContainerLayout->addWidget(quickFilterSetWidget);
|
||||
filterContainerLayout->addWidget(mainTypeFilterWidget);
|
||||
filterContainerLayout->addWidget(formatLegalityWidget);
|
||||
|
||||
searchLayout->addWidget(colorFilterWidget);
|
||||
searchLayout->addWidget(clearFilterWidget);
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#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"
|
||||
|
|
@ -91,6 +92,7 @@ private:
|
|||
SettingsButtonWidget *quickFilterNameWidget;
|
||||
VisualDatabaseDisplayNameFilterWidget *nameFilterWidget;
|
||||
VisualDatabaseDisplayMainTypeFilterWidget *mainTypeFilterWidget;
|
||||
VisualDatabaseDisplayFormatLegalityFilterWidget *formatLegalityWidget;
|
||||
SettingsButtonWidget *quickFilterSubTypeWidget;
|
||||
VisualDatabaseDisplaySubTypeFilterWidget *subTypeFilterWidget;
|
||||
SettingsButtonWidget *quickFilterSetWidget;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue