mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-07-15 06:52:15 -07:00
Allow filters to be saved and restored.
This commit is contained in:
parent
000f0c4b49
commit
1b65818cab
10 changed files with 247 additions and 7 deletions
|
|
@ -368,6 +368,14 @@ void TabDeckEditorVisual::actLoadDeck()
|
|||
deckDockWidget->updateBannerCardComboBox();
|
||||
}
|
||||
|
||||
void TabDeckEditorVisual::actLoadDeckFromClipboard()
|
||||
{
|
||||
TabGenericDeckEditor::actLoadDeckFromClipboard();
|
||||
tabContainer->visualDeckView->updateDisplay();
|
||||
tabContainer->deckAnalytics->refreshDisplays(deckDockWidget->deckModel);
|
||||
tabContainer->sampleHandWidget->setDeckModel(deckDockWidget->deckModel);
|
||||
}
|
||||
|
||||
void TabDeckEditorVisual::openDeckFromFile(const QString &fileName, DeckOpenLocation deckOpenLocation)
|
||||
{
|
||||
DeckLoader::FileFormat fmt = DeckLoader::getFormatFromName(fileName);
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ class TabDeckEditorVisual : public TabGenericDeckEditor
|
|||
protected slots:
|
||||
void actNewDeck() override;
|
||||
void actLoadDeck() override;
|
||||
void actLoadDeckFromClipboard() override;
|
||||
|
||||
void loadLayout() override;
|
||||
void restartLayout() override;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,8 @@ TabDeckEditorVisualTabWidget::TabDeckEditorVisualTabWidget(QWidget *parent,
|
|||
connect(visualDeckView, SIGNAL(sideboardCardClicked(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)), this,
|
||||
SLOT(onSideboardCardClickedDeckEditor(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)));
|
||||
|
||||
visualDatabaseDisplay = new VisualDatabaseDisplayWidget(this, cardDatabaseModel, cardDatabaseDisplayModel);
|
||||
visualDatabaseDisplay =
|
||||
new VisualDatabaseDisplayWidget(this, deckEditor, cardDatabaseModel, cardDatabaseDisplayModel);
|
||||
visualDatabaseDisplay->setObjectName("visualDatabaseView");
|
||||
connect(visualDatabaseDisplay, SIGNAL(cardHoveredDatabaseDisplay(CardInfoPtr)), this,
|
||||
SLOT(onCardChangedDatabaseDisplay(CardInfoPtr)));
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "../../../../game/filters/filter_card.h"
|
||||
#include "../../../../game/filters/filter_tree_model.h"
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,124 @@
|
|||
#include "visual_database_display_filter_save_load_widget.h"
|
||||
|
||||
#include "../../../../game/filters/filter_tree.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
|
||||
VisualDatabaseDisplayFilterSaveLoadWidget::VisualDatabaseDisplayFilterSaveLoadWidget(QWidget *parent,
|
||||
FilterTreeModel *_filterModel,
|
||||
const QString &savePath)
|
||||
: QWidget(parent), filterModel(_filterModel), saveDirectory(savePath)
|
||||
{
|
||||
setMinimumWidth(300);
|
||||
setMaximumHeight(300);
|
||||
|
||||
layout = new QVBoxLayout(this);
|
||||
setLayout(layout);
|
||||
|
||||
// Input for filter filename
|
||||
filenameInput = new QLineEdit(this);
|
||||
filenameInput->setPlaceholderText(tr("Enter filename..."));
|
||||
layout->addWidget(filenameInput);
|
||||
|
||||
// Save button
|
||||
saveButton = new QPushButton(tr("Save Filter"), this);
|
||||
layout->addWidget(saveButton);
|
||||
connect(saveButton, &QPushButton::clicked, this, &VisualDatabaseDisplayFilterSaveLoadWidget::saveFilter);
|
||||
|
||||
// File list container
|
||||
fileListWidget = new FlowWidget(this, Qt::Vertical, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAsNeeded);
|
||||
layout->addWidget(fileListWidget);
|
||||
|
||||
refreshFilterList(); // Populate the file list on startup
|
||||
}
|
||||
|
||||
void VisualDatabaseDisplayFilterSaveLoadWidget::saveFilter()
|
||||
{
|
||||
QString filename = filenameInput->text().trimmed();
|
||||
if (filename.isEmpty())
|
||||
return;
|
||||
|
||||
QString filePath = saveDirectory + "/" + filename + ".json";
|
||||
|
||||
// Serialize the filter model to JSON
|
||||
QJsonArray filtersArray;
|
||||
QList<const CardFilter *> cardFilters = filterModel->allFilters();
|
||||
|
||||
for (const CardFilter *filter : cardFilters) {
|
||||
filtersArray.append(filter->toJson()); // Assuming toJson() returns a QJsonObject
|
||||
}
|
||||
|
||||
QJsonObject root;
|
||||
root["filters"] = filtersArray;
|
||||
|
||||
QFile file(filePath);
|
||||
if (file.open(QIODevice::WriteOnly)) {
|
||||
file.write(QJsonDocument(root).toJson(QJsonDocument::Indented));
|
||||
file.close();
|
||||
}
|
||||
|
||||
filenameInput->clear();
|
||||
refreshFilterList(); // Update the file list
|
||||
}
|
||||
|
||||
void VisualDatabaseDisplayFilterSaveLoadWidget::loadFilter(const QString &filename)
|
||||
{
|
||||
QString filePath = saveDirectory + "/" + filename;
|
||||
|
||||
QFile file(filePath);
|
||||
if (!file.open(QIODevice::ReadOnly))
|
||||
return;
|
||||
|
||||
QByteArray jsonData = file.readAll();
|
||||
file.close();
|
||||
|
||||
QJsonDocument doc = QJsonDocument::fromJson(jsonData);
|
||||
if (!doc.isObject())
|
||||
return;
|
||||
|
||||
QJsonObject root = doc.object();
|
||||
if (!root.contains("filters") || !root["filters"].isArray())
|
||||
return;
|
||||
|
||||
QJsonArray filtersArray = root["filters"].toArray();
|
||||
|
||||
filterModel->clear();
|
||||
|
||||
filterModel->blockSignals(true);
|
||||
filterModel->filterTree()->blockSignals(true);
|
||||
for (const QJsonValue &value : filtersArray) {
|
||||
if (value.isObject()) {
|
||||
QJsonObject filterObj = value.toObject();
|
||||
CardFilter *filter = CardFilter::fromJson(filterObj);
|
||||
if (filter)
|
||||
filterModel->addFilter(filter);
|
||||
}
|
||||
}
|
||||
filterModel->blockSignals(false);
|
||||
filterModel->filterTree()->blockSignals(false);
|
||||
|
||||
filterModel->filterTree()->nodeAt(0)->nodeChanged();
|
||||
emit filterModel->layoutChanged();
|
||||
}
|
||||
|
||||
void VisualDatabaseDisplayFilterSaveLoadWidget::refreshFilterList()
|
||||
{
|
||||
// Clear existing file buttons
|
||||
for (auto button : fileButtons) {
|
||||
delete button;
|
||||
}
|
||||
fileButtons.clear();
|
||||
|
||||
QDir dir(saveDirectory);
|
||||
QStringList filterFiles = dir.entryList(QStringList() << "*.json", QDir::Files, QDir::Time);
|
||||
|
||||
for (const QString &filename : filterFiles) {
|
||||
auto *button = new QPushButton(filename, fileListWidget);
|
||||
fileListWidget->addWidget(button);
|
||||
fileButtons[filename] = button;
|
||||
|
||||
connect(button, &QPushButton::clicked, this, [this, filename]() { loadFilter(filename); });
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
#ifndef VISUAL_DATABASE_DISPLAY_FILTER_SAVE_LOAD_WIDGET_H
|
||||
#define VISUAL_DATABASE_DISPLAY_FILTER_SAVE_LOAD_WIDGET_H
|
||||
|
||||
#include "../../../../game/filters/filter_tree_model.h"
|
||||
#include "../general/layout_containers/flow_widget.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileDialog>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QLineEdit>
|
||||
#include <QMap>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
|
||||
class VisualDatabaseDisplayFilterSaveLoadWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VisualDatabaseDisplayFilterSaveLoadWidget(QWidget *parent,
|
||||
FilterTreeModel *filterModel,
|
||||
const QString &savePath);
|
||||
|
||||
void saveFilter();
|
||||
void loadFilter(const QString &filename);
|
||||
void refreshFilterList();
|
||||
|
||||
private:
|
||||
FilterTreeModel *filterModel;
|
||||
QString saveDirectory;
|
||||
|
||||
QVBoxLayout *layout;
|
||||
QLineEdit *filenameInput;
|
||||
QPushButton *saveButton;
|
||||
FlowWidget *fileListWidget;
|
||||
|
||||
QMap<QString, QPushButton *> fileButtons;
|
||||
};
|
||||
|
||||
#endif // VISUAL_DATABASE_DISPLAY_FILTER_SAVE_LOAD_WIDGET_H
|
||||
|
|
@ -1,10 +1,13 @@
|
|||
#include "visual_database_display_name_filter_widget.h"
|
||||
|
||||
#include "../../../tabs/tab_generic_deck_editor.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
|
||||
VisualDatabaseDisplayNameFilterWidget::VisualDatabaseDisplayNameFilterWidget(QWidget *parent,
|
||||
TabGenericDeckEditor *_deckEditor,
|
||||
FilterTreeModel *_filterModel)
|
||||
: QWidget(parent), filterModel(_filterModel)
|
||||
: QWidget(parent), deckEditor(_deckEditor), filterModel(_filterModel)
|
||||
{
|
||||
setMinimumWidth(300);
|
||||
setMaximumHeight(300);
|
||||
|
|
@ -22,12 +25,46 @@ VisualDatabaseDisplayNameFilterWidget::VisualDatabaseDisplayNameFilterWidget(QWi
|
|||
if (!text.isEmpty() && !activeFilters.contains(text)) {
|
||||
createNameFilter(text);
|
||||
searchBox->clear();
|
||||
updateFilterModel();
|
||||
}
|
||||
});
|
||||
|
||||
// Create container for active filters
|
||||
flowWidget = new FlowWidget(this, Qt::Horizontal, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAsNeeded);
|
||||
layout->addWidget(flowWidget);
|
||||
|
||||
loadFromDeckButton = new QPushButton(this);
|
||||
loadFromDeckButton->setText(tr("Load from Deck"));
|
||||
layout->addWidget(loadFromDeckButton);
|
||||
|
||||
connect(loadFromDeckButton, &QPushButton::clicked, this, &VisualDatabaseDisplayNameFilterWidget::actLoadFromDeck);
|
||||
}
|
||||
|
||||
void VisualDatabaseDisplayNameFilterWidget::actLoadFromDeck()
|
||||
{
|
||||
DeckListModel *deck_list_model = deckEditor->deckDockWidget->deckModel;
|
||||
|
||||
if (!deck_list_model)
|
||||
return;
|
||||
DeckList *decklist = deck_list_model->getDeckList();
|
||||
if (!decklist)
|
||||
return;
|
||||
InnerDecklistNode *listRoot = decklist->getRoot();
|
||||
if (!listRoot)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < listRoot->size(); i++) {
|
||||
InnerDecklistNode *currentZone = dynamic_cast<InnerDecklistNode *>(listRoot->at(i));
|
||||
if (!currentZone)
|
||||
continue;
|
||||
for (int j = 0; j < currentZone->size(); j++) {
|
||||
DecklistCardNode *currentCard = dynamic_cast<DecklistCardNode *>(currentZone->at(j));
|
||||
if (!currentCard)
|
||||
continue;
|
||||
createNameFilter(currentCard->getName());
|
||||
}
|
||||
}
|
||||
updateFilterModel();
|
||||
}
|
||||
|
||||
void VisualDatabaseDisplayNameFilterWidget::createNameFilter(const QString &name)
|
||||
|
|
@ -44,8 +81,6 @@ void VisualDatabaseDisplayNameFilterWidget::createNameFilter(const QString &name
|
|||
|
||||
flowWidget->addWidget(button);
|
||||
activeFilters[name] = button;
|
||||
|
||||
updateFilterModel();
|
||||
}
|
||||
|
||||
void VisualDatabaseDisplayNameFilterWidget::removeNameFilter(const QString &name)
|
||||
|
|
@ -60,10 +95,20 @@ void VisualDatabaseDisplayNameFilterWidget::removeNameFilter(const QString &name
|
|||
void VisualDatabaseDisplayNameFilterWidget::updateFilterModel()
|
||||
{
|
||||
// Clear existing name filters
|
||||
emit filterModel->layoutAboutToBeChanged();
|
||||
filterModel->clearFiltersOfType(CardFilter::Attr::AttrName);
|
||||
|
||||
filterModel->blockSignals(true);
|
||||
filterModel->filterTree()->blockSignals(true);
|
||||
|
||||
for (const auto &name : activeFilters.keys()) {
|
||||
QString nameString = name;
|
||||
filterModel->addFilter(new CardFilter(nameString, CardFilter::Type::TypeOr, CardFilter::Attr::AttrName));
|
||||
}
|
||||
|
||||
filterModel->blockSignals(false);
|
||||
filterModel->filterTree()->blockSignals(false);
|
||||
|
||||
filterModel->filterTree()->nodeAt(0)->nodeChanged();
|
||||
emit filterModel->layoutChanged();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#define VISUAL_DATABASE_DISPLAY_NAME_FILTER_WIDGET_H
|
||||
|
||||
#include "../../../../game/filters/filter_tree_model.h"
|
||||
#include "../../../tabs/tab_generic_deck_editor.h"
|
||||
#include "../general/layout_containers/flow_widget.h"
|
||||
|
||||
#include <QLineEdit>
|
||||
|
|
@ -14,7 +15,9 @@ class VisualDatabaseDisplayNameFilterWidget : public QWidget
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit VisualDatabaseDisplayNameFilterWidget(QWidget *parent, FilterTreeModel *filterModel);
|
||||
explicit VisualDatabaseDisplayNameFilterWidget(QWidget *parent,
|
||||
TabGenericDeckEditor *deckEditor,
|
||||
FilterTreeModel *filterModel);
|
||||
|
||||
void createNameFilter(const QString &name);
|
||||
void removeNameFilter(const QString &name);
|
||||
|
|
@ -22,12 +25,17 @@ public:
|
|||
void updateFilterModel();
|
||||
|
||||
private:
|
||||
TabGenericDeckEditor *deckEditor;
|
||||
FilterTreeModel *filterModel;
|
||||
QVBoxLayout *layout;
|
||||
QLineEdit *searchBox;
|
||||
FlowWidget *flowWidget;
|
||||
QPushButton *loadFromDeckButton;
|
||||
|
||||
QMap<QString, QPushButton *> activeFilters; // Store active name filter buttons
|
||||
|
||||
private slots:
|
||||
void actLoadFromDeck();
|
||||
};
|
||||
|
||||
#endif // VISUAL_DATABASE_DISPLAY_NAME_FILTER_WIDGET_H
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include "../cards/card_info_picture_with_text_overlay_widget.h"
|
||||
#include "../quick_settings/settings_button_widget.h"
|
||||
#include "visual_database_display_color_filter_widget.h"
|
||||
#include "visual_database_display_filter_save_load_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"
|
||||
|
|
@ -19,9 +20,11 @@
|
|||
#include <qpropertyanimation.h>
|
||||
|
||||
VisualDatabaseDisplayWidget::VisualDatabaseDisplayWidget(QWidget *parent,
|
||||
TabGenericDeckEditor *_deckEditor,
|
||||
CardDatabaseModel *database_model,
|
||||
CardDatabaseDisplayModel *database_display_model)
|
||||
: QWidget(parent), databaseModel(database_model), databaseDisplayModel(database_display_model)
|
||||
: QWidget(parent), deckEditor(_deckEditor), databaseModel(database_model),
|
||||
databaseDisplayModel(database_display_model)
|
||||
{
|
||||
cards = new QList<CardInfoPtr>;
|
||||
connect(databaseDisplayModel, &CardDatabaseDisplayModel::modelDirty, this,
|
||||
|
|
@ -53,7 +56,11 @@ VisualDatabaseDisplayWidget::VisualDatabaseDisplayWidget(QWidget *parent,
|
|||
filterModel->setObjectName("filterModel");
|
||||
databaseDisplayModel->setFilterTree(filterModel->filterTree());
|
||||
|
||||
auto nameFilterWidget = new VisualDatabaseDisplayNameFilterWidget(this, filterModel);
|
||||
auto saveLoadWidget =
|
||||
new VisualDatabaseDisplayFilterSaveLoadWidget(this, filterModel, "/home/ascor/Cockatrice_presets/");
|
||||
quickFilterWidget->addSettingsWidget(saveLoadWidget);
|
||||
|
||||
auto nameFilterWidget = new VisualDatabaseDisplayNameFilterWidget(this, deckEditor, filterModel);
|
||||
quickFilterWidget->addSettingsWidget(nameFilterWidget);
|
||||
|
||||
auto mainTypeFilterWidget = new VisualDatabaseDisplayMainTypeFilterWidget(this, filterModel);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include "../../../../game/cards/card_database_model.h"
|
||||
#include "../../../../game/filters/filter_tree_model.h"
|
||||
#include "../../../game_logic/key_signals.h"
|
||||
#include "../../../tabs/tab_generic_deck_editor.h"
|
||||
#include "../../layouts/flow_layout.h"
|
||||
#include "../cards/card_info_picture_with_text_overlay_widget.h"
|
||||
#include "../cards/card_size_widget.h"
|
||||
|
|
@ -29,6 +30,7 @@ class VisualDatabaseDisplayWidget : public QWidget
|
|||
|
||||
public:
|
||||
explicit VisualDatabaseDisplayWidget(QWidget *parent,
|
||||
TabGenericDeckEditor *deckEditor,
|
||||
CardDatabaseModel *database_model,
|
||||
CardDatabaseDisplayModel *database_display_model);
|
||||
|
||||
|
|
@ -61,6 +63,7 @@ protected slots:
|
|||
|
||||
private:
|
||||
KeySignals searchKeySignals;
|
||||
TabGenericDeckEditor *deckEditor;
|
||||
CardDatabaseModel *databaseModel;
|
||||
CardDatabaseDisplayModel *databaseDisplayModel;
|
||||
QTreeView *databaseView;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue