New visual deck storage (#5290)

* Add TabDeckStorageVisual

* Visual Deck Storage

* Add BannerCard to .cod format, use it in the visual deck storage widget.

* Show filename instead of deckname if deck name is empty.

* Lint.

* Don't delint cmake list through hooks.

* Add deck loading functionality.

* Open Decks on double click, not single click.

* Void event for now.

* Fix build issue with overload?

* Fix build issue with overload?

* Include QDebug.

* Turn the tab into a widget.

* Move the signals down to the widget, move the connections and slots up to the parent widgets.

* No banner card equals an empty CardInfoPtr.

* Add an option to sort by filename or last modified.

* Flip last modified comparison.

* Lint.

* Don't open decks twice in the storage tab.

* Fix unload deck not working by showing/hiding widgets instead of adding/removing to layout.

* Add a search bar.

* Add a card size slider.

* Lint.

* Lint.

* Lint.

* Fix settings mocks.

* No need to QDebug.

* No need to QDebug.

* Member variable.

* Member variable.

* Non-lambda.

* Change set to list conversion.

* Specify overload.

* Include MouseEvent

* Adjust font size dynamically.

* Add an option to show the visual deck storage on database load.

* Fix the close button not working on the tab, add an option to launch the visual deck storage tab to Cockatrice menu.

* Override virtual functions.

* Correct tab text.

* Add a setting to remember last used sorting order for visual deck storage widget.

* Update banner card combo box correctly.

* Fix mocks.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
Co-authored-by: Zach H <zahalpern+github@gmail.com>
This commit is contained in:
BruebachL 2025-01-06 00:12:20 +01:00 committed by GitHub
parent 7496e79e8c
commit 62f7c7f9ce
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 834 additions and 31 deletions

View file

@ -0,0 +1,104 @@
#include "tab_deck_storage_visual.h"
#include "../../../game/cards/card_database_model.h"
#include "../tab_supervisor.h"
#include "pb/command_deck_del.pb.h"
#include <QAction>
#include <QDebug>
#include <QDirIterator>
#include <QFileSystemModel>
#include <QHBoxLayout>
#include <QInputDialog>
#include <QMessageBox>
#include <QMouseEvent>
#include <QScreen>
#include <QToolBar>
#include <QTreeView>
class FlowLayout;
TabDeckStorageVisual::TabDeckStorageVisual(TabSupervisor *_tabSupervisor, AbstractClient *_client)
: Tab(_tabSupervisor), client(_client)
{
deck_list_model = new DeckListModel(this);
deck_list_model->setObjectName("visualDeckModel");
QWidget *container = new QWidget(this);
QVBoxLayout *layout = new QVBoxLayout(container);
container->setLayout(layout);
this->setCentralWidget(container);
leftToolBar = new QToolBar;
leftToolBar->setOrientation(Qt::Horizontal);
leftToolBar->setIconSize(QSize(32, 32));
QHBoxLayout *leftToolBarLayout = new QHBoxLayout(this);
leftToolBarLayout->addStretch();
leftToolBarLayout->addWidget(leftToolBar);
leftToolBarLayout->addStretch();
aOpenLocalDeck = new QAction(this);
aOpenLocalDeck->setIcon(QPixmap("theme:icons/pencil"));
connect(aOpenLocalDeck, SIGNAL(triggered()), this, SLOT(actOpenLocalDeck()));
aDeleteLocalDeck = new QAction(this);
aDeleteLocalDeck->setIcon(QPixmap("theme:icons/remove_row"));
connect(aDeleteLocalDeck, SIGNAL(triggered()), this, SLOT(actDeleteLocalDeck()));
connect(this, &TabDeckStorageVisual::openDeckEditor, tabSupervisor, &TabSupervisor::addDeckEditorTab);
leftToolBar->addAction(aOpenLocalDeck);
leftToolBar->addAction(aDeleteLocalDeck);
visualDeckStorageWidget = new VisualDeckStorageWidget(this);
connect(visualDeckStorageWidget, &VisualDeckStorageWidget::imageDoubleClicked, this,
&TabDeckStorageVisual::actOpenLocalDeck);
// layout->addWidget(leftToolBar);
layout->addWidget(visualDeckStorageWidget);
retranslateUi();
}
void TabDeckStorageVisual::closeRequest()
{
this->close();
}
void TabDeckStorageVisual::retranslateUi()
{
aOpenLocalDeck->setText(tr("Open in deck editor"));
aDeleteLocalDeck->setText(tr("Delete"));
}
QString TabDeckStorageVisual::getTargetPath() const
{
return {};
}
void TabDeckStorageVisual::actOpenLocalDeck(QMouseEvent *event, DeckPreviewCardPictureWidget *instance)
{
(void)event;
DeckLoader deckLoader;
if (!deckLoader.loadFromFile(instance->filePath, DeckLoader::CockatriceFormat))
return;
emit openDeckEditor(&deckLoader);
}
void TabDeckStorageVisual::actDeleteLocalDeck()
{
QModelIndex curLeft = localDirView->selectionModel()->currentIndex();
if (localDirModel->isDir(curLeft))
return;
if (QMessageBox::warning(this, tr("Delete local file"),
tr("Are you sure you want to delete \"%1\"?").arg(localDirModel->fileName(curLeft)),
QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes)
return;
localDirModel->remove(curLeft);
}
void TabDeckStorageVisual::cardUpdateFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
qDebug() << "Card update process finished with exit code:" << exitCode << "and exit status:" << exitStatus;
}

View file

@ -0,0 +1,56 @@
#ifndef TAB_DECK_STORAGE_VISUAL_H
#define TAB_DECK_STORAGE_VISUAL_H
#include "../../../deck/deck_list_model.h"
#include "../../../deck/deck_view.h"
#include "../../ui/widgets/cards/deck_preview_card_picture_widget.h"
#include "../../ui/widgets/visual_deck_storage/visual_deck_storage_widget.h"
#include "../tab.h"
#include <QProcess>
class AbstractClient;
class QTreeView;
class QFileSystemModel;
class QToolBar;
class QTreeWidget;
class QTreeWidgetItem;
class QGroupBox;
class CommandContainer;
class Response;
class DeckLoader;
class TabDeckStorageVisual final : public Tab
{
Q_OBJECT
public:
TabDeckStorageVisual(TabSupervisor *_tabSupervisor, AbstractClient *_client);
void retranslateUi() override;
QString getTabText() const override
{
return tr("Visual Deck storage");
}
public slots:
void cardUpdateFinished(int exitCode, QProcess::ExitStatus exitStatus);
void closeRequest() override;
void actOpenLocalDeck(QMouseEvent *event, DeckPreviewCardPictureWidget *instance);
void actDeleteLocalDeck();
signals:
void openDeckEditor(const DeckLoader *deckLoader);
private:
QWidget *container;
QHBoxLayout *layout;
AbstractClient *client;
QTreeView *localDirView;
QFileSystemModel *localDirModel;
QToolBar *leftToolBar;
QGroupBox *leftGroupBox;
VisualDeckStorageWidget *visualDeckStorageWidget;
DeckListModel *deck_list_model;
QAction *aOpenLocalDeck, *aDeleteLocalDeck;
QString getTargetPath() const;
};
#endif