mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-07-02 19:43:55 -07:00
Abstract deck editor (#5646)
* Generify TabDeckEditor. * Connect dockTopLevelChanged signals. * Connect eventFilters. * Remove comments. * Fix ze build (accidentally deleted a line) * Fix some pointer chaining. * Be a lot saner about some signals/slots, as in, individual Deck Editor widgets now internally determine their CardInfo and then simply communicate this to the DeckEditor * Lint. * DeckDock can handle its own menu. * DeckDock can handle its own decrement. * DeckDock now notifies the deck editor on deck change, instead of individually modifying menu items and modification status. * Rename. * Include pixelmap generator for icon. * Directly use an AbstractTabDeckEditor as parent. * Move clearing database filter into signal/slot relation. --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
parent
6df97a156f
commit
93d28717e0
34 changed files with 2370 additions and 1810 deletions
|
|
@ -12,6 +12,7 @@ set(cockatrice_SOURCES
|
||||||
src/game/board/abstract_graphics_item.cpp
|
src/game/board/abstract_graphics_item.cpp
|
||||||
src/game/board/arrow_item.cpp
|
src/game/board/arrow_item.cpp
|
||||||
src/game/board/arrow_target.cpp
|
src/game/board/arrow_target.cpp
|
||||||
|
src/client/ui/widgets/general/display/banner_widget.cpp
|
||||||
src/game/cards/card_database.cpp
|
src/game/cards/card_database.cpp
|
||||||
src/game/cards/card_database_manager.cpp
|
src/game/cards/card_database_manager.cpp
|
||||||
src/game/cards/card_database_model.cpp
|
src/game/cards/card_database_model.cpp
|
||||||
|
|
@ -141,6 +142,7 @@ set(cockatrice_SOURCES
|
||||||
src/client/tabs/tab.cpp
|
src/client/tabs/tab.cpp
|
||||||
src/client/tabs/tab_account.cpp
|
src/client/tabs/tab_account.cpp
|
||||||
src/client/tabs/tab_admin.cpp
|
src/client/tabs/tab_admin.cpp
|
||||||
|
src/client/tabs/abstract_tab_deck_editor.cpp
|
||||||
src/client/tabs/tab_deck_editor.cpp
|
src/client/tabs/tab_deck_editor.cpp
|
||||||
src/client/tabs/tab_deck_storage.cpp
|
src/client/tabs/tab_deck_storage.cpp
|
||||||
src/client/tabs/tab_game.cpp
|
src/client/tabs/tab_game.cpp
|
||||||
|
|
@ -177,6 +179,7 @@ set(cockatrice_SOURCES
|
||||||
src/client/ui/window_main.cpp
|
src/client/ui/window_main.cpp
|
||||||
src/game/zones/view_zone_widget.cpp
|
src/game/zones/view_zone_widget.cpp
|
||||||
src/game/zones/view_zone.cpp
|
src/game/zones/view_zone.cpp
|
||||||
|
src/client/menus/deck_editor/deck_editor_menu.cpp
|
||||||
src/client/tabs/visual_deck_storage/tab_deck_storage_visual.cpp
|
src/client/tabs/visual_deck_storage/tab_deck_storage_visual.cpp
|
||||||
src/client/ui/widgets/cards/deck_preview_card_picture_widget.cpp
|
src/client/ui/widgets/cards/deck_preview_card_picture_widget.cpp
|
||||||
src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_color_identity_widget.cpp
|
src/client/ui/widgets/visual_deck_storage/deck_preview/deck_preview_color_identity_widget.cpp
|
||||||
|
|
@ -192,6 +195,11 @@ set(cockatrice_SOURCES
|
||||||
src/client/ui/widgets/visual_deck_storage/visual_deck_storage_search_widget.cpp
|
src/client/ui/widgets/visual_deck_storage/visual_deck_storage_search_widget.cpp
|
||||||
src/client/ui/widgets/visual_deck_storage/visual_deck_storage_sort_widget.cpp
|
src/client/ui/widgets/visual_deck_storage/visual_deck_storage_sort_widget.cpp
|
||||||
src/client/ui/widgets/visual_deck_storage/visual_deck_storage_tag_filter_widget.cpp
|
src/client/ui/widgets/visual_deck_storage/visual_deck_storage_tag_filter_widget.cpp
|
||||||
|
src/client/ui/widgets/deck_editor/deck_editor_card_info_dock_widget.cpp
|
||||||
|
src/client/ui/widgets/deck_editor/deck_editor_database_display_widget.cpp
|
||||||
|
src/client/ui/widgets/deck_editor/deck_editor_deck_dock_widget.cpp
|
||||||
|
src/client/ui/widgets/deck_editor/deck_editor_filter_dock_widget.cpp
|
||||||
|
src/client/ui/widgets/deck_editor/deck_editor_printing_selector_dock_widget.cpp
|
||||||
${VERSION_STRING_CPP}
|
${VERSION_STRING_CPP}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
171
cockatrice/src/client/menus/deck_editor/deck_editor_menu.cpp
Normal file
171
cockatrice/src/client/menus/deck_editor/deck_editor_menu.cpp
Normal file
|
|
@ -0,0 +1,171 @@
|
||||||
|
#include "deck_editor_menu.h"
|
||||||
|
|
||||||
|
#include "../../../settings/cache_settings.h"
|
||||||
|
#include "../../../settings/shortcuts_settings.h"
|
||||||
|
|
||||||
|
DeckEditorMenu::DeckEditorMenu(QWidget *parent, AbstractTabDeckEditor *_deckEditor)
|
||||||
|
: QMenu(parent), deckEditor(_deckEditor)
|
||||||
|
{
|
||||||
|
aNewDeck = new QAction(QString(), this);
|
||||||
|
connect(aNewDeck, SIGNAL(triggered()), deckEditor, SLOT(actNewDeck()));
|
||||||
|
|
||||||
|
aLoadDeck = new QAction(QString(), this);
|
||||||
|
connect(aLoadDeck, SIGNAL(triggered()), deckEditor, SLOT(actLoadDeck()));
|
||||||
|
|
||||||
|
loadRecentDeckMenu = new QMenu(this);
|
||||||
|
connect(&SettingsCache::instance().recents(), &RecentsSettings::recentlyOpenedDeckPathsChanged, this,
|
||||||
|
&DeckEditorMenu::updateRecentlyOpened);
|
||||||
|
|
||||||
|
aClearRecents = new QAction(QString(), this);
|
||||||
|
connect(aClearRecents, &QAction::triggered, this, &DeckEditorMenu::actClearRecents);
|
||||||
|
|
||||||
|
updateRecentlyOpened();
|
||||||
|
|
||||||
|
aSaveDeck = new QAction(QString(), this);
|
||||||
|
connect(aSaveDeck, SIGNAL(triggered()), deckEditor, SLOT(actSaveDeck()));
|
||||||
|
|
||||||
|
aSaveDeckAs = new QAction(QString(), this);
|
||||||
|
connect(aSaveDeckAs, SIGNAL(triggered()), deckEditor, SLOT(actSaveDeckAs()));
|
||||||
|
|
||||||
|
aLoadDeckFromClipboard = new QAction(QString(), this);
|
||||||
|
connect(aLoadDeckFromClipboard, SIGNAL(triggered()), deckEditor, SLOT(actLoadDeckFromClipboard()));
|
||||||
|
|
||||||
|
aSaveDeckToClipboard = new QAction(QString(), this);
|
||||||
|
connect(aSaveDeckToClipboard, SIGNAL(triggered()), deckEditor, SLOT(actSaveDeckToClipboard()));
|
||||||
|
|
||||||
|
aSaveDeckToClipboardNoSetNameAndNumber = new QAction(QString(), this);
|
||||||
|
connect(aSaveDeckToClipboardNoSetNameAndNumber, SIGNAL(triggered()), deckEditor,
|
||||||
|
SLOT(actSaveDeckToClipboardNoSetNameAndNumber()));
|
||||||
|
|
||||||
|
aSaveDeckToClipboardRaw = new QAction(QString(), this);
|
||||||
|
connect(aSaveDeckToClipboardRaw, SIGNAL(triggered()), deckEditor, SLOT(actSaveDeckToClipboardRaw()));
|
||||||
|
|
||||||
|
aSaveDeckToClipboardRawNoSetNameAndNumber = new QAction(QString(), this);
|
||||||
|
connect(aSaveDeckToClipboardRawNoSetNameAndNumber, SIGNAL(triggered()), deckEditor,
|
||||||
|
SLOT(actSaveDeckToClipboardRawNoSetNameAndNumber()));
|
||||||
|
|
||||||
|
aPrintDeck = new QAction(QString(), this);
|
||||||
|
connect(aPrintDeck, SIGNAL(triggered()), deckEditor, SLOT(actPrintDeck()));
|
||||||
|
|
||||||
|
aExportDeckDecklist = new QAction(QString(), this);
|
||||||
|
connect(aExportDeckDecklist, SIGNAL(triggered()), deckEditor, SLOT(actExportDeckDecklist()));
|
||||||
|
|
||||||
|
aAnalyzeDeckDeckstats = new QAction(QString(), this);
|
||||||
|
connect(aAnalyzeDeckDeckstats, SIGNAL(triggered()), deckEditor, SLOT(actAnalyzeDeckDeckstats()));
|
||||||
|
|
||||||
|
aAnalyzeDeckTappedout = new QAction(QString(), this);
|
||||||
|
connect(aAnalyzeDeckTappedout, SIGNAL(triggered()), deckEditor, SLOT(actAnalyzeDeckTappedout()));
|
||||||
|
|
||||||
|
analyzeDeckMenu = new QMenu(this);
|
||||||
|
analyzeDeckMenu->addAction(aExportDeckDecklist);
|
||||||
|
analyzeDeckMenu->addAction(aAnalyzeDeckDeckstats);
|
||||||
|
analyzeDeckMenu->addAction(aAnalyzeDeckTappedout);
|
||||||
|
|
||||||
|
aClose = new QAction(QString(), this);
|
||||||
|
connect(aClose, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::closeRequest);
|
||||||
|
|
||||||
|
saveDeckToClipboardMenu = new QMenu(this);
|
||||||
|
saveDeckToClipboardMenu->addAction(aSaveDeckToClipboard);
|
||||||
|
saveDeckToClipboardMenu->addAction(aSaveDeckToClipboardNoSetNameAndNumber);
|
||||||
|
saveDeckToClipboardMenu->addAction(aSaveDeckToClipboardRaw);
|
||||||
|
saveDeckToClipboardMenu->addAction(aSaveDeckToClipboardRawNoSetNameAndNumber);
|
||||||
|
|
||||||
|
addAction(aNewDeck);
|
||||||
|
addAction(aLoadDeck);
|
||||||
|
addMenu(loadRecentDeckMenu);
|
||||||
|
addAction(aSaveDeck);
|
||||||
|
addAction(aSaveDeckAs);
|
||||||
|
addSeparator();
|
||||||
|
addAction(aLoadDeckFromClipboard);
|
||||||
|
addMenu(saveDeckToClipboardMenu);
|
||||||
|
addSeparator();
|
||||||
|
addAction(aPrintDeck);
|
||||||
|
addMenu(analyzeDeckMenu);
|
||||||
|
addSeparator();
|
||||||
|
addAction(deckEditor->filterDockWidget->aClearFilterOne);
|
||||||
|
addAction(deckEditor->filterDockWidget->aClearFilterAll);
|
||||||
|
addSeparator();
|
||||||
|
addAction(aClose);
|
||||||
|
|
||||||
|
retranslateUi();
|
||||||
|
connect(&SettingsCache::instance().shortcuts(), SIGNAL(shortCutChanged()), this, SLOT(refreshShortcuts()));
|
||||||
|
refreshShortcuts();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorMenu::setSaveStatus(bool newStatus)
|
||||||
|
{
|
||||||
|
aSaveDeck->setEnabled(newStatus);
|
||||||
|
aSaveDeckAs->setEnabled(newStatus);
|
||||||
|
aSaveDeckToClipboard->setEnabled(newStatus);
|
||||||
|
aSaveDeckToClipboardNoSetNameAndNumber->setEnabled(newStatus);
|
||||||
|
aSaveDeckToClipboardRaw->setEnabled(newStatus);
|
||||||
|
aSaveDeckToClipboardRawNoSetNameAndNumber->setEnabled(newStatus);
|
||||||
|
saveDeckToClipboardMenu->setEnabled(newStatus);
|
||||||
|
aPrintDeck->setEnabled(newStatus);
|
||||||
|
analyzeDeckMenu->setEnabled(newStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorMenu::updateRecentlyOpened()
|
||||||
|
{
|
||||||
|
loadRecentDeckMenu->clear();
|
||||||
|
for (const auto &deckPath : SettingsCache::instance().recents().getRecentlyOpenedDeckPaths()) {
|
||||||
|
QAction *aRecentlyOpenedDeck = new QAction(deckPath, this);
|
||||||
|
loadRecentDeckMenu->addAction(aRecentlyOpenedDeck);
|
||||||
|
connect(aRecentlyOpenedDeck, &QAction::triggered, deckEditor,
|
||||||
|
[=, this] { deckEditor->actOpenRecent(aRecentlyOpenedDeck->text()); });
|
||||||
|
}
|
||||||
|
loadRecentDeckMenu->addSeparator();
|
||||||
|
loadRecentDeckMenu->addAction(aClearRecents);
|
||||||
|
aClearRecents->setEnabled(SettingsCache::instance().recents().getRecentlyOpenedDeckPaths().length() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorMenu::actClearRecents()
|
||||||
|
{
|
||||||
|
SettingsCache::instance().recents().clearRecentlyOpenedDeckPaths();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorMenu::retranslateUi()
|
||||||
|
{
|
||||||
|
setTitle(tr("&Deck Editor"));
|
||||||
|
aNewDeck->setText(tr("&New deck"));
|
||||||
|
aLoadDeck->setText(tr("&Load deck..."));
|
||||||
|
loadRecentDeckMenu->setTitle(tr("Load recent deck..."));
|
||||||
|
aClearRecents->setText(tr("Clear"));
|
||||||
|
aSaveDeck->setText(tr("&Save deck"));
|
||||||
|
aSaveDeckAs->setText(tr("Save deck &as..."));
|
||||||
|
aLoadDeckFromClipboard->setText(tr("Load deck from cl&ipboard..."));
|
||||||
|
|
||||||
|
saveDeckToClipboardMenu->setTitle(tr("Save deck to clipboard"));
|
||||||
|
aSaveDeckToClipboard->setText(tr("Annotated"));
|
||||||
|
aSaveDeckToClipboardNoSetNameAndNumber->setText(tr("Annotated (No set name or number)"));
|
||||||
|
aSaveDeckToClipboardRaw->setText(tr("Not Annotated"));
|
||||||
|
aSaveDeckToClipboardRawNoSetNameAndNumber->setText(tr("Not Annotated (No set name or number)"));
|
||||||
|
|
||||||
|
aPrintDeck->setText(tr("&Print deck..."));
|
||||||
|
|
||||||
|
analyzeDeckMenu->setTitle(tr("&Send deck to online service"));
|
||||||
|
aExportDeckDecklist->setText(tr("Create decklist (decklist.org)"));
|
||||||
|
aAnalyzeDeckDeckstats->setText(tr("Analyze deck (deckstats.net)"));
|
||||||
|
aAnalyzeDeckTappedout->setText(tr("Analyze deck (tappedout.net)"));
|
||||||
|
|
||||||
|
aClose->setText(tr("&Close"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorMenu::refreshShortcuts()
|
||||||
|
{
|
||||||
|
ShortcutsSettings &shortcuts = SettingsCache::instance().shortcuts();
|
||||||
|
aNewDeck->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aNewDeck"));
|
||||||
|
aLoadDeck->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aLoadDeck"));
|
||||||
|
aSaveDeck->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aSaveDeck"));
|
||||||
|
aExportDeckDecklist->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aExportDeckDecklist"));
|
||||||
|
aSaveDeckAs->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aSaveDeckAs"));
|
||||||
|
aLoadDeckFromClipboard->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aLoadDeckFromClipboard"));
|
||||||
|
aPrintDeck->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aPrintDeck"));
|
||||||
|
aAnalyzeDeckDeckstats->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aAnalyzeDeck"));
|
||||||
|
aClose->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aClose"));
|
||||||
|
|
||||||
|
aSaveDeckToClipboard->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aSaveDeckToClipboard"));
|
||||||
|
aSaveDeckToClipboardRaw->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aSaveDeckToClipboardRaw"));
|
||||||
|
|
||||||
|
aClose->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aClose"));
|
||||||
|
}
|
||||||
32
cockatrice/src/client/menus/deck_editor/deck_editor_menu.h
Normal file
32
cockatrice/src/client/menus/deck_editor/deck_editor_menu.h
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef DECK_EDITOR_MENU_H
|
||||||
|
#define DECK_EDITOR_MENU_H
|
||||||
|
|
||||||
|
#include "../../tabs/abstract_tab_deck_editor.h"
|
||||||
|
|
||||||
|
#include <QMenu>
|
||||||
|
|
||||||
|
class AbstractTabDeckEditor;
|
||||||
|
class DeckEditorMenu : public QMenu
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit DeckEditorMenu(QWidget *parent, AbstractTabDeckEditor *deckEditor);
|
||||||
|
|
||||||
|
AbstractTabDeckEditor *deckEditor;
|
||||||
|
|
||||||
|
QAction *aNewDeck, *aLoadDeck, *aClearRecents, *aSaveDeck, *aSaveDeckAs, *aLoadDeckFromClipboard,
|
||||||
|
*aSaveDeckToClipboard, *aSaveDeckToClipboardNoSetNameAndNumber, *aSaveDeckToClipboardRaw,
|
||||||
|
*aSaveDeckToClipboardRawNoSetNameAndNumber, *aPrintDeck, *aExportDeckDecklist, *aAnalyzeDeckDeckstats,
|
||||||
|
*aAnalyzeDeckTappedout, *aClose;
|
||||||
|
QMenu *loadRecentDeckMenu, *analyzeDeckMenu, *saveDeckToClipboardMenu;
|
||||||
|
|
||||||
|
void setSaveStatus(bool newStatus);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void updateRecentlyOpened();
|
||||||
|
void actClearRecents();
|
||||||
|
void retranslateUi();
|
||||||
|
void refreshShortcuts();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
534
cockatrice/src/client/tabs/abstract_tab_deck_editor.cpp
Normal file
534
cockatrice/src/client/tabs/abstract_tab_deck_editor.cpp
Normal file
|
|
@ -0,0 +1,534 @@
|
||||||
|
#include "abstract_tab_deck_editor.h"
|
||||||
|
|
||||||
|
#include "../../client/game_logic/abstract_client.h"
|
||||||
|
#include "../../client/tapped_out_interface.h"
|
||||||
|
#include "../../client/ui/widgets/cards/card_info_frame_widget.h"
|
||||||
|
#include "../../deck/deck_stats_interface.h"
|
||||||
|
#include "../../dialogs/dlg_load_deck.h"
|
||||||
|
#include "../../dialogs/dlg_load_deck_from_clipboard.h"
|
||||||
|
#include "../../game/cards/card_database_manager.h"
|
||||||
|
#include "../../game/cards/card_database_model.h"
|
||||||
|
#include "../../server/pending_command.h"
|
||||||
|
#include "../../settings/cache_settings.h"
|
||||||
|
#include "../ui/picture_loader/picture_loader.h"
|
||||||
|
#include "../ui/pixel_map_generator.h"
|
||||||
|
#include "pb/command_deck_upload.pb.h"
|
||||||
|
#include "pb/response.pb.h"
|
||||||
|
#include "tab_supervisor.h"
|
||||||
|
#include "trice_limits.h"
|
||||||
|
|
||||||
|
#include <QAction>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QClipboard>
|
||||||
|
#include <QCloseEvent>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QDesktopServices>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QHeaderView>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QMenuBar>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QPrintPreviewDialog>
|
||||||
|
#include <QProcessEnvironment>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QRegularExpression>
|
||||||
|
#include <QSplitter>
|
||||||
|
#include <QTextStream>
|
||||||
|
#include <QTreeView>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
|
AbstractTabDeckEditor::AbstractTabDeckEditor(TabSupervisor *_tabSupervisor) : Tab(_tabSupervisor)
|
||||||
|
{
|
||||||
|
setDockOptions(QMainWindow::AnimatedDocks | QMainWindow::AllowNestedDocks | QMainWindow::AllowTabbedDocks);
|
||||||
|
|
||||||
|
databaseDisplayDockWidget = new DeckEditorDatabaseDisplayWidget(this);
|
||||||
|
deckDockWidget = new DeckEditorDeckDockWidget(this);
|
||||||
|
cardInfoDockWidget = new DeckEditorCardInfoDockWidget(this);
|
||||||
|
filterDockWidget = new DeckEditorFilterDockWidget(this);
|
||||||
|
printingSelectorDockWidget = new DeckEditorPrintingSelectorDockWidget(this);
|
||||||
|
|
||||||
|
connect(deckDockWidget, &DeckEditorDeckDockWidget::deckChanged, this, &AbstractTabDeckEditor::onDeckChanged);
|
||||||
|
connect(deckDockWidget, &DeckEditorDeckDockWidget::cardChanged, this, &AbstractTabDeckEditor::updateCard);
|
||||||
|
connect(this, &AbstractTabDeckEditor::decrementCard, deckDockWidget, &DeckEditorDeckDockWidget::actDecrementCard);
|
||||||
|
connect(databaseDisplayDockWidget, &DeckEditorDatabaseDisplayWidget::cardChanged, this,
|
||||||
|
&AbstractTabDeckEditor::updateCard);
|
||||||
|
connect(databaseDisplayDockWidget, &DeckEditorDatabaseDisplayWidget::addCardToMainDeck, this,
|
||||||
|
&AbstractTabDeckEditor::actAddCard);
|
||||||
|
connect(databaseDisplayDockWidget, &DeckEditorDatabaseDisplayWidget::addCardToSideboard, this,
|
||||||
|
&AbstractTabDeckEditor::actAddCardToSideboard);
|
||||||
|
connect(databaseDisplayDockWidget, &DeckEditorDatabaseDisplayWidget::decrementCardFromMainDeck, this,
|
||||||
|
&AbstractTabDeckEditor::actDecrementCard);
|
||||||
|
connect(databaseDisplayDockWidget, &DeckEditorDatabaseDisplayWidget::decrementCardFromSideboard, this,
|
||||||
|
&AbstractTabDeckEditor::actDecrementCardFromSideboard);
|
||||||
|
|
||||||
|
connect(filterDockWidget, &DeckEditorFilterDockWidget::clearAllDatabaseFilters, databaseDisplayDockWidget,
|
||||||
|
&DeckEditorDatabaseDisplayWidget::clearAllDatabaseFilters);
|
||||||
|
|
||||||
|
connect(&SettingsCache::instance().shortcuts(), SIGNAL(shortCutChanged()), this, SLOT(refreshShortcuts()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTabDeckEditor::updateCard(CardInfoPtr _card)
|
||||||
|
{
|
||||||
|
cardInfoDockWidget->updateCard(_card);
|
||||||
|
printingSelectorDockWidget->printingSelector->setCard(_card, DECK_ZONE_MAIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTabDeckEditor::onDeckChanged()
|
||||||
|
{
|
||||||
|
setModified(true);
|
||||||
|
deckMenu->setSaveStatus(!getDeckList()->isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTabDeckEditor::addCardHelper(const CardInfoPtr info, QString zoneName)
|
||||||
|
{
|
||||||
|
if (!info)
|
||||||
|
return;
|
||||||
|
if (info->getIsToken())
|
||||||
|
zoneName = DECK_ZONE_TOKENS;
|
||||||
|
|
||||||
|
QModelIndex newCardIndex = deckDockWidget->deckModel->addPreferredPrintingCard(info->getName(), zoneName, false);
|
||||||
|
// recursiveExpand(newCardIndex);
|
||||||
|
deckDockWidget->deckView->clearSelection();
|
||||||
|
deckDockWidget->deckView->setCurrentIndex(newCardIndex);
|
||||||
|
setModified(true);
|
||||||
|
databaseDisplayDockWidget->searchEdit->setSelection(0, databaseDisplayDockWidget->searchEdit->text().length());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTabDeckEditor::actAddCard(CardInfoPtr info)
|
||||||
|
{
|
||||||
|
if (QApplication::keyboardModifiers() & Qt::ControlModifier)
|
||||||
|
actAddCardToSideboard(info);
|
||||||
|
else
|
||||||
|
addCardHelper(info, DECK_ZONE_MAIN);
|
||||||
|
deckMenu->setSaveStatus(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTabDeckEditor::actAddCardToSideboard(CardInfoPtr info)
|
||||||
|
{
|
||||||
|
addCardHelper(info, DECK_ZONE_SIDE);
|
||||||
|
deckMenu->setSaveStatus(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTabDeckEditor::actDecrementCard(CardInfoPtr info)
|
||||||
|
{
|
||||||
|
emit decrementCard(info, DECK_ZONE_MAIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTabDeckEditor::actDecrementCardFromSideboard(CardInfoPtr info)
|
||||||
|
{
|
||||||
|
emit decrementCard(info, DECK_ZONE_SIDE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTabDeckEditor::actSwapCard(CardInfoPtr info, QString zoneName)
|
||||||
|
{
|
||||||
|
QString providerId = CardDatabaseManager::getInstance()->getSetInfoForCard(info).getProperty("uuid");
|
||||||
|
QString collectorNumber = CardDatabaseManager::getInstance()->getSetInfoForCard(info).getProperty("num");
|
||||||
|
deckDockWidget->swapCard(
|
||||||
|
deckDockWidget->deckModel->findCard(info->getName(), zoneName, providerId, collectorNumber));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTabDeckEditor::setDeck(DeckLoader *_deck)
|
||||||
|
{
|
||||||
|
deckDockWidget->setDeck(_deck);
|
||||||
|
PictureLoader::cacheCardPixmaps(CardDatabaseManager::getInstance()->getCards(getDeckList()->getCardList()));
|
||||||
|
setModified(false);
|
||||||
|
|
||||||
|
// If they load a deck, make the deck list appear
|
||||||
|
aDeckDockVisible->setChecked(true);
|
||||||
|
deckDockWidget->setVisible(aDeckDockVisible->isChecked());
|
||||||
|
}
|
||||||
|
|
||||||
|
DeckLoader *AbstractTabDeckEditor::getDeckList() const
|
||||||
|
{
|
||||||
|
return deckDockWidget->getDeckList();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTabDeckEditor::setModified(bool _modified)
|
||||||
|
{
|
||||||
|
modified = _modified;
|
||||||
|
emit tabTextChanged(this, getTabText());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns true if this tab is a blank newly opened tab, as if it was just created with the `New Deck` action.
|
||||||
|
*/
|
||||||
|
bool AbstractTabDeckEditor::isBlankNewDeck() const
|
||||||
|
{
|
||||||
|
DeckLoader *deck = getDeckList();
|
||||||
|
return !modified && deck->hasNotBeenLoaded();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTabDeckEditor::actNewDeck()
|
||||||
|
{
|
||||||
|
auto deckOpenLocation = confirmOpen(false);
|
||||||
|
|
||||||
|
if (deckOpenLocation == CANCELLED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deckOpenLocation == NEW_TAB) {
|
||||||
|
emit openDeckEditor(nullptr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanDeckAndResetModified();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTabDeckEditor::cleanDeckAndResetModified()
|
||||||
|
{
|
||||||
|
deckMenu->setSaveStatus(false);
|
||||||
|
deckDockWidget->cleanDeck();
|
||||||
|
setModified(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Displays the save confirmation dialogue that is shown before loading a deck, if required. Takes into
|
||||||
|
* account the `openDeckInNewTab` settting.
|
||||||
|
*
|
||||||
|
* @param openInSameTabIfBlank Open the deck in the same tab instead of a new tab if the current tab is completely
|
||||||
|
* blank. Only relevant when the `openDeckInNewTab` setting is enabled.
|
||||||
|
*
|
||||||
|
* @returns An enum that indicates if and where to load the deck
|
||||||
|
*/
|
||||||
|
AbstractTabDeckEditor::DeckOpenLocation AbstractTabDeckEditor::confirmOpen(const bool openInSameTabIfBlank)
|
||||||
|
{
|
||||||
|
// handle `openDeckInNewTab` setting
|
||||||
|
if (SettingsCache::instance().getOpenDeckInNewTab()) {
|
||||||
|
if (openInSameTabIfBlank && isBlankNewDeck()) {
|
||||||
|
return SAME_TAB;
|
||||||
|
} else {
|
||||||
|
return NEW_TAB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// early return if deck is unmodified
|
||||||
|
if (!modified) {
|
||||||
|
return SAME_TAB;
|
||||||
|
}
|
||||||
|
|
||||||
|
// do the save confirmation dialogue
|
||||||
|
tabSupervisor->setCurrentWidget(this);
|
||||||
|
|
||||||
|
QMessageBox *msgBox = createSaveConfirmationWindow();
|
||||||
|
QPushButton *newTabButton = msgBox->addButton(tr("Open in new tab"), QMessageBox::ApplyRole);
|
||||||
|
|
||||||
|
int ret = msgBox->exec();
|
||||||
|
|
||||||
|
// `exec()` returns an opaque value if a non-standard button was clicked.
|
||||||
|
// Directly check if newTabButton was clicked before switching over the standard buttons.
|
||||||
|
if (msgBox->clickedButton() == newTabButton) {
|
||||||
|
return NEW_TAB;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ret) {
|
||||||
|
case QMessageBox::Save:
|
||||||
|
return actSaveDeck() ? SAME_TAB : CANCELLED;
|
||||||
|
case QMessageBox::Discard:
|
||||||
|
return SAME_TAB;
|
||||||
|
default:
|
||||||
|
return CANCELLED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Creates the base save confirmation dialogue box.
|
||||||
|
*
|
||||||
|
* @returns A QMessageBox that can be further modified
|
||||||
|
*/
|
||||||
|
QMessageBox *AbstractTabDeckEditor::createSaveConfirmationWindow()
|
||||||
|
{
|
||||||
|
QMessageBox *msgBox = new QMessageBox(this);
|
||||||
|
msgBox->setIcon(QMessageBox::Warning);
|
||||||
|
msgBox->setWindowTitle(tr("Are you sure?"));
|
||||||
|
msgBox->setText(tr("The decklist has been modified.\nDo you want to save the changes?"));
|
||||||
|
msgBox->setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
|
||||||
|
return msgBox;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTabDeckEditor::actLoadDeck()
|
||||||
|
{
|
||||||
|
auto deckOpenLocation = confirmOpen();
|
||||||
|
|
||||||
|
if (deckOpenLocation == CANCELLED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DlgLoadDeck dialog(this);
|
||||||
|
if (!dialog.exec())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QString fileName = dialog.selectedFiles().at(0);
|
||||||
|
openDeckFromFile(fileName, deckOpenLocation);
|
||||||
|
deckDockWidget->updateBannerCardComboBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTabDeckEditor::actOpenRecent(const QString &fileName)
|
||||||
|
{
|
||||||
|
auto deckOpenLocation = confirmOpen();
|
||||||
|
|
||||||
|
if (deckOpenLocation == CANCELLED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
openDeckFromFile(fileName, deckOpenLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actually opens the deck from file
|
||||||
|
* @param fileName The path of the deck to open
|
||||||
|
* @param deckOpenLocation Which tab to open the deck
|
||||||
|
*/
|
||||||
|
void AbstractTabDeckEditor::openDeckFromFile(const QString &fileName, DeckOpenLocation deckOpenLocation)
|
||||||
|
{
|
||||||
|
DeckLoader::FileFormat fmt = DeckLoader::getFormatFromName(fileName);
|
||||||
|
|
||||||
|
auto *l = new DeckLoader;
|
||||||
|
if (l->loadFromFile(fileName, fmt, true)) {
|
||||||
|
SettingsCache::instance().recents().updateRecentlyOpenedDeckPaths(fileName);
|
||||||
|
if (deckOpenLocation == NEW_TAB) {
|
||||||
|
emit openDeckEditor(l);
|
||||||
|
} else {
|
||||||
|
deckMenu->setSaveStatus(false);
|
||||||
|
setDeck(l);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
delete l;
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("Could not open deck at %1").arg(fileName));
|
||||||
|
}
|
||||||
|
deckMenu->setSaveStatus(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AbstractTabDeckEditor::actSaveDeck()
|
||||||
|
{
|
||||||
|
DeckLoader *const deck = getDeckList();
|
||||||
|
if (deck->getLastRemoteDeckId() != -1) {
|
||||||
|
QString deckString = deck->writeToString_Native();
|
||||||
|
if (deckString.length() > MAX_FILE_LENGTH) {
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("Could not save remote deck"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Command_DeckUpload cmd;
|
||||||
|
cmd.set_deck_id(static_cast<google::protobuf::uint32>(deck->getLastRemoteDeckId()));
|
||||||
|
cmd.set_deck_list(deckString.toStdString());
|
||||||
|
|
||||||
|
PendingCommand *pend = AbstractClient::prepareSessionCommand(cmd);
|
||||||
|
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
||||||
|
SLOT(saveDeckRemoteFinished(Response)));
|
||||||
|
tabSupervisor->getClient()->sendCommand(pend);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else if (deck->getLastFileName().isEmpty())
|
||||||
|
return actSaveDeckAs();
|
||||||
|
else if (deck->saveToFile(deck->getLastFileName(), deck->getLastFileFormat())) {
|
||||||
|
setModified(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
QMessageBox::critical(
|
||||||
|
this, tr("Error"),
|
||||||
|
tr("The deck could not be saved.\nPlease check that the directory is writable and try again."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AbstractTabDeckEditor::actSaveDeckAs()
|
||||||
|
{
|
||||||
|
QFileDialog dialog(this, tr("Save deck"));
|
||||||
|
dialog.setDirectory(SettingsCache::instance().getDeckPath());
|
||||||
|
dialog.setAcceptMode(QFileDialog::AcceptSave);
|
||||||
|
dialog.setDefaultSuffix("cod");
|
||||||
|
dialog.setNameFilters(DeckLoader::fileNameFilters);
|
||||||
|
dialog.selectFile(getDeckList()->getName().trimmed() + ".cod");
|
||||||
|
if (!dialog.exec())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QString fileName = dialog.selectedFiles().at(0);
|
||||||
|
DeckLoader::FileFormat fmt = DeckLoader::getFormatFromName(fileName);
|
||||||
|
|
||||||
|
if (!getDeckList()->saveToFile(fileName, fmt)) {
|
||||||
|
QMessageBox::critical(
|
||||||
|
this, tr("Error"),
|
||||||
|
tr("The deck could not be saved.\nPlease check that the directory is writable and try again."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
setModified(false);
|
||||||
|
|
||||||
|
SettingsCache::instance().recents().updateRecentlyOpenedDeckPaths(fileName);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTabDeckEditor::saveDeckRemoteFinished(const Response &response)
|
||||||
|
{
|
||||||
|
if (response.response_code() != Response::RespOk)
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("The deck could not be saved."));
|
||||||
|
else
|
||||||
|
setModified(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTabDeckEditor::actLoadDeckFromClipboard()
|
||||||
|
{
|
||||||
|
auto deckOpenLocation = confirmOpen();
|
||||||
|
|
||||||
|
if (deckOpenLocation == CANCELLED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DlgLoadDeckFromClipboard dlg(this);
|
||||||
|
if (!dlg.exec())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (deckOpenLocation == NEW_TAB) {
|
||||||
|
emit openDeckEditor(dlg.getDeckList());
|
||||||
|
} else {
|
||||||
|
setDeck(dlg.getDeckList());
|
||||||
|
setModified(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
deckMenu->setSaveStatus(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTabDeckEditor::actSaveDeckToClipboard()
|
||||||
|
{
|
||||||
|
QString buffer;
|
||||||
|
QTextStream stream(&buffer);
|
||||||
|
getDeckList()->saveToStream_Plain(stream);
|
||||||
|
QApplication::clipboard()->setText(buffer, QClipboard::Clipboard);
|
||||||
|
QApplication::clipboard()->setText(buffer, QClipboard::Selection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTabDeckEditor::actSaveDeckToClipboardNoSetNameAndNumber()
|
||||||
|
{
|
||||||
|
QString buffer;
|
||||||
|
QTextStream stream(&buffer);
|
||||||
|
getDeckList()->saveToStream_Plain(stream, true, false);
|
||||||
|
QApplication::clipboard()->setText(buffer, QClipboard::Clipboard);
|
||||||
|
QApplication::clipboard()->setText(buffer, QClipboard::Selection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTabDeckEditor::actSaveDeckToClipboardRaw()
|
||||||
|
{
|
||||||
|
QString buffer;
|
||||||
|
QTextStream stream(&buffer);
|
||||||
|
getDeckList()->saveToStream_Plain(stream, false);
|
||||||
|
QApplication::clipboard()->setText(buffer, QClipboard::Clipboard);
|
||||||
|
QApplication::clipboard()->setText(buffer, QClipboard::Selection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTabDeckEditor::actSaveDeckToClipboardRawNoSetNameAndNumber()
|
||||||
|
{
|
||||||
|
QString buffer;
|
||||||
|
QTextStream stream(&buffer);
|
||||||
|
getDeckList()->saveToStream_Plain(stream, false, false);
|
||||||
|
QApplication::clipboard()->setText(buffer, QClipboard::Clipboard);
|
||||||
|
QApplication::clipboard()->setText(buffer, QClipboard::Selection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTabDeckEditor::actPrintDeck()
|
||||||
|
{
|
||||||
|
auto *dlg = new QPrintPreviewDialog(this);
|
||||||
|
connect(dlg, SIGNAL(paintRequested(QPrinter *)), deckDockWidget->deckModel, SLOT(printDeckList(QPrinter *)));
|
||||||
|
dlg->exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Action called when export deck to decklist menu item is pressed.
|
||||||
|
void AbstractTabDeckEditor::actExportDeckDecklist()
|
||||||
|
{
|
||||||
|
// Get the decklist class for the deck.
|
||||||
|
DeckLoader *const deck = getDeckList();
|
||||||
|
// create a string to load the decklist url into.
|
||||||
|
QString decklistUrlString;
|
||||||
|
// check if deck is not null
|
||||||
|
if (deck) {
|
||||||
|
// Get the decklist url string from the deck loader class.
|
||||||
|
decklistUrlString = deck->exportDeckToDecklist();
|
||||||
|
// Check to make sure the string isn't empty.
|
||||||
|
if (QString::compare(decklistUrlString, "", Qt::CaseInsensitive) == 0) {
|
||||||
|
// Show an error if the deck is empty, and return.
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("There are no cards in your deck to be exported"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Encode the string recieved from the model to make sure all characters are encoded.
|
||||||
|
// first we put it into a qurl object
|
||||||
|
QUrl decklistUrl = QUrl(decklistUrlString);
|
||||||
|
// we get the correctly encoded url.
|
||||||
|
decklistUrlString = decklistUrl.toEncoded();
|
||||||
|
// We open the url in the user's default browser
|
||||||
|
QDesktopServices::openUrl(decklistUrlString);
|
||||||
|
} else {
|
||||||
|
// if there's no deck loader object, return an error
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("No deck was selected to be saved."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTabDeckEditor::actAnalyzeDeckDeckstats()
|
||||||
|
{
|
||||||
|
auto *interface = new DeckStatsInterface(*databaseDisplayDockWidget->databaseModel->getDatabase(),
|
||||||
|
this); // it deletes itself when done
|
||||||
|
interface->analyzeDeck(getDeckList());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTabDeckEditor::actAnalyzeDeckTappedout()
|
||||||
|
{
|
||||||
|
auto *interface = new TappedOutInterface(*databaseDisplayDockWidget->databaseModel->getDatabase(),
|
||||||
|
this); // it deletes itself when done
|
||||||
|
interface->analyzeDeck(getDeckList());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTabDeckEditor::filterTreeChanged(FilterTree *filterTree)
|
||||||
|
{
|
||||||
|
databaseDisplayDockWidget->setFilterTree(filterTree);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method uses to sync docks state with menu items state
|
||||||
|
bool AbstractTabDeckEditor::eventFilter(QObject *o, QEvent *e)
|
||||||
|
{
|
||||||
|
if (e->type() == QEvent::Close) {
|
||||||
|
if (o == cardInfoDockWidget) {
|
||||||
|
aCardInfoDockVisible->setChecked(false);
|
||||||
|
aCardInfoDockFloating->setEnabled(false);
|
||||||
|
} else if (o == deckDockWidget) {
|
||||||
|
aDeckDockVisible->setChecked(false);
|
||||||
|
aDeckDockFloating->setEnabled(false);
|
||||||
|
} else if (o == filterDockWidget) {
|
||||||
|
aFilterDockVisible->setChecked(false);
|
||||||
|
aFilterDockFloating->setEnabled(false);
|
||||||
|
} else if (o == printingSelectorDockWidget) {
|
||||||
|
aPrintingSelectorDockVisible->setChecked(false);
|
||||||
|
aPrintingSelectorDockFloating->setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (o == this && e->type() == QEvent::Hide) {
|
||||||
|
LayoutsSettings &layouts = SettingsCache::instance().layouts();
|
||||||
|
layouts.setDeckEditorLayoutState(saveState());
|
||||||
|
layouts.setDeckEditorGeometry(saveGeometry());
|
||||||
|
layouts.setDeckEditorCardSize(cardInfoDockWidget->size());
|
||||||
|
layouts.setDeckEditorFilterSize(filterDockWidget->size());
|
||||||
|
layouts.setDeckEditorDeckSize(deckDockWidget->size());
|
||||||
|
layouts.setDeckEditorPrintingSelectorSize(printingSelectorDockWidget->size());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AbstractTabDeckEditor::confirmClose()
|
||||||
|
{
|
||||||
|
if (modified) {
|
||||||
|
tabSupervisor->setCurrentWidget(this);
|
||||||
|
int ret = createSaveConfirmationWindow()->exec();
|
||||||
|
if (ret == QMessageBox::Save)
|
||||||
|
return actSaveDeck();
|
||||||
|
else if (ret == QMessageBox::Cancel)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTabDeckEditor::closeRequest(bool forced)
|
||||||
|
{
|
||||||
|
if (!forced && !confirmClose()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit deckEditorClosing(this);
|
||||||
|
close();
|
||||||
|
}
|
||||||
147
cockatrice/src/client/tabs/abstract_tab_deck_editor.h
Normal file
147
cockatrice/src/client/tabs/abstract_tab_deck_editor.h
Normal file
|
|
@ -0,0 +1,147 @@
|
||||||
|
#ifndef TAB_GENERIC_DECK_EDITOR_H
|
||||||
|
#define TAB_GENERIC_DECK_EDITOR_H
|
||||||
|
|
||||||
|
#include "../../game/cards/card_database.h"
|
||||||
|
#include "../menus/deck_editor/deck_editor_menu.h"
|
||||||
|
#include "../ui/widgets/deck_editor/deck_editor_card_info_dock_widget.h"
|
||||||
|
#include "../ui/widgets/deck_editor/deck_editor_database_display_widget.h"
|
||||||
|
#include "../ui/widgets/deck_editor/deck_editor_deck_dock_widget.h"
|
||||||
|
#include "../ui/widgets/deck_editor/deck_editor_filter_dock_widget.h"
|
||||||
|
#include "../ui/widgets/deck_editor/deck_editor_printing_selector_dock_widget.h"
|
||||||
|
#include "../ui/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.h"
|
||||||
|
#include "tab.h"
|
||||||
|
|
||||||
|
class CardDatabaseModel;
|
||||||
|
class CardDatabaseDisplayModel;
|
||||||
|
|
||||||
|
class CardInfoFrameWidget;
|
||||||
|
class DeckLoader;
|
||||||
|
class DeckEditorMenu;
|
||||||
|
class DeckEditorCardInfoDockWidget;
|
||||||
|
class DeckEditorDatabaseDisplayWidget;
|
||||||
|
class DeckEditorDeckDockWidget;
|
||||||
|
class DeckEditorFilterDockWidget;
|
||||||
|
class DeckEditorPrintingSelectorDockWidget;
|
||||||
|
class DeckPreviewDeckTagsDisplayWidget;
|
||||||
|
class Response;
|
||||||
|
class FilterTreeModel;
|
||||||
|
class FilterBuilder;
|
||||||
|
|
||||||
|
class QTreeView;
|
||||||
|
class QTextEdit;
|
||||||
|
class QLabel;
|
||||||
|
class QComboBox;
|
||||||
|
class QGroupBox;
|
||||||
|
class QMessageBox;
|
||||||
|
class QHBoxLayout;
|
||||||
|
class QVBoxLayout;
|
||||||
|
class QPushButton;
|
||||||
|
class QDockWidget;
|
||||||
|
class QMenu;
|
||||||
|
class QAction;
|
||||||
|
|
||||||
|
class AbstractTabDeckEditor : public Tab
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit AbstractTabDeckEditor(TabSupervisor *_tabSupervisor);
|
||||||
|
|
||||||
|
// UI and Navigation
|
||||||
|
virtual void createMenus() = 0;
|
||||||
|
[[nodiscard]] virtual QString getTabText() const override = 0;
|
||||||
|
bool confirmClose();
|
||||||
|
virtual void retranslateUi() override = 0;
|
||||||
|
|
||||||
|
// Deck Management
|
||||||
|
virtual void setDeck(DeckLoader *_deckLoader);
|
||||||
|
DeckLoader *getDeckList() const;
|
||||||
|
void setModified(bool _windowModified);
|
||||||
|
|
||||||
|
// UI Elements
|
||||||
|
DeckEditorMenu *deckMenu;
|
||||||
|
DeckEditorDatabaseDisplayWidget *databaseDisplayDockWidget;
|
||||||
|
DeckEditorCardInfoDockWidget *cardInfoDockWidget;
|
||||||
|
DeckEditorDeckDockWidget *deckDockWidget;
|
||||||
|
DeckEditorFilterDockWidget *filterDockWidget;
|
||||||
|
DeckEditorPrintingSelectorDockWidget *printingSelectorDockWidget;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void onDeckChanged();
|
||||||
|
void updateCard(CardInfoPtr _card);
|
||||||
|
void actAddCard(CardInfoPtr info);
|
||||||
|
void actAddCardToSideboard(CardInfoPtr info);
|
||||||
|
void actDecrementCard(CardInfoPtr info);
|
||||||
|
void actDecrementCardFromSideboard(CardInfoPtr info);
|
||||||
|
void actOpenRecent(const QString &fileName);
|
||||||
|
void filterTreeChanged(FilterTree *filterTree);
|
||||||
|
void closeRequest(bool forced = false) override;
|
||||||
|
virtual void showPrintingSelector() = 0;
|
||||||
|
virtual void dockTopLevelChanged(bool topLevel) = 0;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void openDeckEditor(const DeckLoader *deckLoader);
|
||||||
|
void deckEditorClosing(AbstractTabDeckEditor *tab);
|
||||||
|
void decrementCard(CardInfoPtr card, QString zoneName);
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
// Deck Operations
|
||||||
|
virtual void actNewDeck();
|
||||||
|
void cleanDeckAndResetModified();
|
||||||
|
virtual void actLoadDeck();
|
||||||
|
bool actSaveDeck();
|
||||||
|
bool actSaveDeckAs();
|
||||||
|
virtual void actLoadDeckFromClipboard();
|
||||||
|
void actSaveDeckToClipboard();
|
||||||
|
void actSaveDeckToClipboardNoSetNameAndNumber();
|
||||||
|
void actSaveDeckToClipboardRaw();
|
||||||
|
void actSaveDeckToClipboardRawNoSetNameAndNumber();
|
||||||
|
void actPrintDeck();
|
||||||
|
void actExportDeckDecklist();
|
||||||
|
void actAnalyzeDeckDeckstats();
|
||||||
|
void actAnalyzeDeckTappedout();
|
||||||
|
|
||||||
|
// Remote Save
|
||||||
|
void saveDeckRemoteFinished(const Response &r);
|
||||||
|
|
||||||
|
// UI Layout Management
|
||||||
|
virtual void loadLayout() = 0;
|
||||||
|
virtual void restartLayout() = 0;
|
||||||
|
virtual void freeDocksSize() = 0;
|
||||||
|
virtual void refreshShortcuts() = 0;
|
||||||
|
|
||||||
|
bool eventFilter(QObject *o, QEvent *e) override;
|
||||||
|
virtual void dockVisibleTriggered() = 0;
|
||||||
|
virtual void dockFloatingTriggered() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* @brief Enum for selecting deck open location
|
||||||
|
*/
|
||||||
|
enum DeckOpenLocation
|
||||||
|
{
|
||||||
|
CANCELLED,
|
||||||
|
SAME_TAB,
|
||||||
|
NEW_TAB
|
||||||
|
};
|
||||||
|
|
||||||
|
DeckOpenLocation confirmOpen(bool openInSameTabIfBlank = true);
|
||||||
|
QMessageBox *createSaveConfirmationWindow();
|
||||||
|
bool isBlankNewDeck() const;
|
||||||
|
|
||||||
|
// Helper functions for card actions
|
||||||
|
void addCardHelper(CardInfoPtr info, QString zoneName);
|
||||||
|
void actSwapCard(CardInfoPtr info, QString zoneName);
|
||||||
|
virtual void openDeckFromFile(const QString &fileName, DeckOpenLocation deckOpenLocation);
|
||||||
|
|
||||||
|
// UI Menu Elements
|
||||||
|
QMenu *viewMenu, *cardInfoDockMenu, *deckDockMenu, *filterDockMenu, *printingSelectorDockMenu;
|
||||||
|
|
||||||
|
QAction *aResetLayout;
|
||||||
|
QAction *aCardInfoDockVisible, *aCardInfoDockFloating, *aDeckDockVisible, *aDeckDockFloating;
|
||||||
|
QAction *aFilterDockVisible, *aFilterDockFloating, *aPrintingSelectorDockVisible, *aPrintingSelectorDockFloating;
|
||||||
|
|
||||||
|
bool modified;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TAB_GENERIC_DECK_EDITOR_H
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,194 +1,41 @@
|
||||||
#ifndef WINDOW_DECKEDITOR_H
|
#ifndef WINDOW_DECKEDITOR_H
|
||||||
#define WINDOW_DECKEDITOR_H
|
#define WINDOW_DECKEDITOR_H
|
||||||
|
|
||||||
#include "../../deck/custom_line_edit.h"
|
|
||||||
#include "../../game/cards/card_database.h"
|
#include "../../game/cards/card_database.h"
|
||||||
#include "../game_logic/key_signals.h"
|
#include "../game_logic/key_signals.h"
|
||||||
#include "../ui/widgets/printing_selector/printing_selector.h"
|
|
||||||
#include "../ui/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.h"
|
#include "../ui/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.h"
|
||||||
#include "tab.h"
|
#include "abstract_tab_deck_editor.h"
|
||||||
|
|
||||||
#include <QAbstractItemModel>
|
|
||||||
#include <QDir>
|
|
||||||
|
|
||||||
class CardDatabaseModel;
|
class CardDatabaseModel;
|
||||||
class CardDatabaseDisplayModel;
|
class CardDatabaseDisplayModel;
|
||||||
class DeckListModel;
|
class DeckListModel;
|
||||||
class QTreeView;
|
|
||||||
|
|
||||||
class CardInfoFrameWidget;
|
|
||||||
class QTextEdit;
|
|
||||||
class QLabel;
|
class QLabel;
|
||||||
class DeckLoader;
|
class DeckLoader;
|
||||||
class DeckPreviewDeckTagsDisplayWidget;
|
|
||||||
class Response;
|
|
||||||
class FilterTreeModel;
|
|
||||||
class FilterBuilder;
|
|
||||||
class QComboBox;
|
|
||||||
class QGroupBox;
|
|
||||||
class QMessageBox;
|
|
||||||
class QHBoxLayout;
|
|
||||||
class QVBoxLayout;
|
|
||||||
class QPushButton;
|
|
||||||
class QDockWidget;
|
|
||||||
|
|
||||||
class TabDeckEditor : public Tab
|
class TabDeckEditor : public AbstractTabDeckEditor
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private slots:
|
|
||||||
void updateName(const QString &name);
|
|
||||||
void updateComments();
|
|
||||||
void updateBannerCardComboBox();
|
|
||||||
void setBannerCard(int);
|
|
||||||
void updateHash();
|
|
||||||
void updateCardInfoLeft(const QModelIndex ¤t, const QModelIndex &previous);
|
|
||||||
void updateCardInfoRight(const QModelIndex ¤t, const QModelIndex &previous);
|
|
||||||
void updatePrintingSelectorDatabase(const QModelIndex ¤t, const QModelIndex &previous);
|
|
||||||
void updatePrintingSelectorDeckView(const QModelIndex ¤t, const QModelIndex &previous);
|
|
||||||
void updateSearch(const QString &search);
|
|
||||||
void databaseCustomMenu(QPoint point);
|
|
||||||
void decklistCustomMenu(QPoint point);
|
|
||||||
void updateRecentlyOpened();
|
|
||||||
|
|
||||||
void actNewDeck();
|
protected slots:
|
||||||
void actLoadDeck();
|
void loadLayout() override;
|
||||||
void actOpenRecent(const QString &fileName);
|
void restartLayout() override;
|
||||||
void actClearRecents();
|
void freeDocksSize() override;
|
||||||
bool actSaveDeck();
|
void refreshShortcuts() override;
|
||||||
bool actSaveDeckAs();
|
|
||||||
void actLoadDeckFromClipboard();
|
|
||||||
void actSaveDeckToClipboard();
|
|
||||||
void actSaveDeckToClipboardNoSetNameAndNumber();
|
|
||||||
void actSaveDeckToClipboardRaw();
|
|
||||||
void actSaveDeckToClipboardRawNoSetNameAndNumber();
|
|
||||||
void actPrintDeck();
|
|
||||||
void actExportDeckDecklist();
|
|
||||||
void actAnalyzeDeckDeckstats();
|
|
||||||
void actAnalyzeDeckTappedout();
|
|
||||||
|
|
||||||
void actClearFilterAll();
|
|
||||||
void actClearFilterOne();
|
|
||||||
|
|
||||||
void actSwapCard();
|
|
||||||
void actAddCard();
|
|
||||||
void actAddCardToSideboard();
|
|
||||||
void actRemoveCard();
|
|
||||||
void actIncrement();
|
|
||||||
void actDecrement();
|
|
||||||
void actDecrementCard();
|
|
||||||
void actDecrementCardFromSideboard();
|
|
||||||
void copyDatabaseCellContents();
|
|
||||||
|
|
||||||
void saveDeckRemoteFinished(const Response &r);
|
|
||||||
void filterViewCustomContextMenu(const QPoint &point);
|
|
||||||
void filterRemove(QAction *action);
|
|
||||||
|
|
||||||
void loadLayout();
|
|
||||||
void restartLayout();
|
|
||||||
void freeDocksSize();
|
|
||||||
void refreshShortcuts();
|
|
||||||
|
|
||||||
bool eventFilter(QObject *o, QEvent *e) override;
|
bool eventFilter(QObject *o, QEvent *e) override;
|
||||||
void dockVisibleTriggered();
|
void dockVisibleTriggered() override;
|
||||||
void dockFloatingTriggered();
|
void dockFloatingTriggered() override;
|
||||||
void dockTopLevelChanged(bool topLevel);
|
void dockTopLevelChanged(bool topLevel) override;
|
||||||
void saveDbHeaderState();
|
|
||||||
void setSaveStatus(bool newStatus);
|
|
||||||
void showSearchSyntaxHelp();
|
|
||||||
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* @brief Which tab to open the new deck in
|
|
||||||
*/
|
|
||||||
enum DeckOpenLocation
|
|
||||||
{
|
|
||||||
CANCELLED,
|
|
||||||
SAME_TAB,
|
|
||||||
NEW_TAB
|
|
||||||
};
|
|
||||||
|
|
||||||
DeckOpenLocation confirmOpen(const bool openInSameTabIfBlank = true);
|
|
||||||
QMessageBox *createSaveConfirmationWindow();
|
|
||||||
|
|
||||||
bool isBlankNewDeck() const;
|
|
||||||
CardInfoPtr currentCardInfo() const;
|
|
||||||
void offsetCountAtIndex(const QModelIndex &idx, int offset);
|
|
||||||
void decrementCardHelper(QString zoneName);
|
|
||||||
bool swapCard(const QModelIndex &idx);
|
|
||||||
void recursiveExpand(const QModelIndex &index);
|
|
||||||
void openDeckFromFile(const QString &fileName, DeckOpenLocation deckOpenLocation);
|
|
||||||
|
|
||||||
QModelIndexList getSelectedCardNodes() const;
|
|
||||||
|
|
||||||
CardDatabaseModel *databaseModel;
|
|
||||||
CardDatabaseDisplayModel *databaseDisplayModel;
|
|
||||||
DeckListModel *deckModel;
|
|
||||||
QTreeView *databaseView;
|
|
||||||
|
|
||||||
QTreeView *deckView;
|
|
||||||
KeySignals deckViewKeySignals;
|
|
||||||
CardInfoFrameWidget *cardInfo;
|
|
||||||
PrintingSelector *printingSelector;
|
|
||||||
SearchLineEdit *searchEdit;
|
|
||||||
KeySignals searchKeySignals;
|
|
||||||
|
|
||||||
QLabel *nameLabel;
|
|
||||||
LineEditUnfocusable *nameEdit;
|
|
||||||
QLabel *commentsLabel;
|
|
||||||
QTextEdit *commentsEdit;
|
|
||||||
QLabel *bannerCardLabel;
|
|
||||||
QComboBox *bannerCardComboBox;
|
|
||||||
DeckPreviewDeckTagsDisplayWidget *deckTagsDisplayWidget;
|
|
||||||
QLabel *hashLabel1;
|
|
||||||
LineEditUnfocusable *hashLabel;
|
|
||||||
FilterTreeModel *filterModel;
|
|
||||||
QTreeView *filterView;
|
|
||||||
KeySignals filterViewKeySignals;
|
|
||||||
QWidget *filterBox;
|
|
||||||
|
|
||||||
QMenu *deckMenu, *viewMenu, *cardInfoDockMenu, *deckDockMenu, *filterDockMenu, *printingSelectorDockMenu,
|
|
||||||
*analyzeDeckMenu, *saveDeckToClipboardMenu, *loadRecentDeckMenu;
|
|
||||||
QAction *aNewDeck, *aLoadDeck, *aClearRecents, *aSaveDeck, *aSaveDeckAs, *aLoadDeckFromClipboard,
|
|
||||||
*aSaveDeckToClipboard, *aSaveDeckToClipboardNoSetNameAndNumber, *aSaveDeckToClipboardRaw,
|
|
||||||
*aSaveDeckToClipboardRawNoSetNameAndNumber, *aPrintDeck, *aExportDeckDecklist, *aAnalyzeDeckDeckstats,
|
|
||||||
*aAnalyzeDeckTappedout, *aClose;
|
|
||||||
QAction *aClearFilterAll, *aClearFilterOne;
|
|
||||||
QAction *aAddCard, *aAddCardToSideboard, *aRemoveCard, *aIncrement, *aDecrement, *aSwapCard;
|
|
||||||
QAction *aResetLayout;
|
|
||||||
QAction *aCardInfoDockVisible, *aCardInfoDockFloating, *aDeckDockVisible, *aDeckDockFloating, *aFilterDockVisible,
|
|
||||||
*aFilterDockFloating, *aPrintingSelectorDockVisible, *aPrintingSelectorDockFloating;
|
|
||||||
|
|
||||||
bool modified;
|
|
||||||
QVBoxLayout *centralFrame;
|
|
||||||
QHBoxLayout *searchLayout;
|
|
||||||
QDockWidget *cardInfoDock;
|
|
||||||
QDockWidget *deckDock;
|
|
||||||
QDockWidget *filterDock;
|
|
||||||
QDockWidget *printingSelectorDock;
|
|
||||||
QWidget *centralWidget;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit TabDeckEditor(TabSupervisor *_tabSupervisor);
|
explicit TabDeckEditor(TabSupervisor *_tabSupervisor);
|
||||||
void retranslateUi() override;
|
void retranslateUi() override;
|
||||||
QString getTabText() const override;
|
QString getTabText() const override;
|
||||||
void setDeck(DeckLoader *_deckLoader);
|
void createMenus() override;
|
||||||
void setModified(bool _windowModified);
|
|
||||||
bool confirmClose();
|
|
||||||
void createDeckDock();
|
|
||||||
void createCardInfoDock();
|
|
||||||
void createFiltersDock();
|
|
||||||
void createPrintingSelectorDock();
|
|
||||||
void createMenus();
|
|
||||||
void createCentralFrame();
|
|
||||||
void updateCardInfo(CardInfoPtr _card);
|
|
||||||
void addCardHelper(CardInfoPtr info, QString zoneName);
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void closeRequest(bool forced = false) override;
|
void showPrintingSelector() override;
|
||||||
void showPrintingSelector();
|
|
||||||
signals:
|
|
||||||
void openDeckEditor(const DeckLoader *deckLoader);
|
|
||||||
void deckEditorClosing(TabDeckEditor *tab);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -201,7 +201,7 @@ void TabSupervisor::retranslateUi()
|
||||||
QListIterator<TabGame *> replayIterator(replayTabs);
|
QListIterator<TabGame *> replayIterator(replayTabs);
|
||||||
while (replayIterator.hasNext())
|
while (replayIterator.hasNext())
|
||||||
tabs.append(replayIterator.next());
|
tabs.append(replayIterator.next());
|
||||||
QListIterator<TabDeckEditor *> deckEditorIterator(deckEditorTabs);
|
QListIterator<AbstractTabDeckEditor *> deckEditorIterator(deckEditorTabs);
|
||||||
while (deckEditorIterator.hasNext())
|
while (deckEditorIterator.hasNext())
|
||||||
tabs.append(deckEditorIterator.next());
|
tabs.append(deckEditorIterator.next());
|
||||||
QMapIterator<QString, TabMessage *> messageIterator(messageTabs);
|
QMapIterator<QString, TabMessage *> messageIterator(messageTabs);
|
||||||
|
|
@ -242,7 +242,7 @@ bool TabSupervisor::closeRequest()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (TabDeckEditor *tab : deckEditorTabs) {
|
for (AbstractTabDeckEditor *tab : deckEditorTabs) {
|
||||||
if (!tab->confirmClose())
|
if (!tab->confirmClose())
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -706,8 +706,8 @@ TabDeckEditor *TabSupervisor::addDeckEditorTab(const DeckLoader *deckToOpen)
|
||||||
auto *tab = new TabDeckEditor(this);
|
auto *tab = new TabDeckEditor(this);
|
||||||
if (deckToOpen)
|
if (deckToOpen)
|
||||||
tab->setDeck(new DeckLoader(*deckToOpen));
|
tab->setDeck(new DeckLoader(*deckToOpen));
|
||||||
connect(tab, &TabDeckEditor::deckEditorClosing, this, &TabSupervisor::deckEditorClosed);
|
connect(tab, &AbstractTabDeckEditor::deckEditorClosing, this, &TabSupervisor::deckEditorClosed);
|
||||||
connect(tab, &TabDeckEditor::openDeckEditor, this, &TabSupervisor::addDeckEditorTab);
|
connect(tab, &AbstractTabDeckEditor::openDeckEditor, this, &TabSupervisor::addDeckEditorTab);
|
||||||
myAddTab(tab);
|
myAddTab(tab);
|
||||||
deckEditorTabs.append(tab);
|
deckEditorTabs.append(tab);
|
||||||
setCurrentWidget(tab);
|
setCurrentWidget(tab);
|
||||||
|
|
@ -726,7 +726,7 @@ TabEdhRec *TabSupervisor::addEdhrecTab(const CardInfoPtr &cardToQuery, bool isCo
|
||||||
return tab;
|
return tab;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabSupervisor::deckEditorClosed(TabDeckEditor *tab)
|
void TabSupervisor::deckEditorClosed(AbstractTabDeckEditor *tab)
|
||||||
{
|
{
|
||||||
if (tab == currentWidget())
|
if (tab == currentWidget())
|
||||||
emit setMenu();
|
emit setMenu();
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "../../deck/deck_loader.h"
|
#include "../../deck/deck_loader.h"
|
||||||
#include "../../server/user/user_list_proxy.h"
|
#include "../../server/user/user_list_proxy.h"
|
||||||
|
#include "abstract_tab_deck_editor.h"
|
||||||
#include "api/edhrec/tab_edhrec.h"
|
#include "api/edhrec/tab_edhrec.h"
|
||||||
#include "visual_deck_storage/tab_deck_storage_visual.h"
|
#include "visual_deck_storage/tab_deck_storage_visual.h"
|
||||||
|
|
||||||
|
|
@ -87,7 +88,7 @@ private:
|
||||||
QMap<int, TabGame *> gameTabs;
|
QMap<int, TabGame *> gameTabs;
|
||||||
QList<TabGame *> replayTabs;
|
QList<TabGame *> replayTabs;
|
||||||
QMap<QString, TabMessage *> messageTabs;
|
QMap<QString, TabMessage *> messageTabs;
|
||||||
QList<TabDeckEditor *> deckEditorTabs;
|
QList<AbstractTabDeckEditor *> deckEditorTabs;
|
||||||
bool isLocalGame;
|
bool isLocalGame;
|
||||||
|
|
||||||
QAction *aTabDeckEditor, *aTabVisualDeckStorage, *aTabServer, *aTabAccount, *aTabDeckStorage, *aTabReplays,
|
QAction *aTabDeckEditor, *aTabVisualDeckStorage, *aTabServer, *aTabAccount, *aTabDeckStorage, *aTabReplays,
|
||||||
|
|
@ -132,7 +133,7 @@ public:
|
||||||
{
|
{
|
||||||
return roomTabs;
|
return roomTabs;
|
||||||
}
|
}
|
||||||
QList<TabDeckEditor *> getDeckEditorTabs() const
|
QList<AbstractTabDeckEditor *> getDeckEditorTabs() const
|
||||||
{
|
{
|
||||||
return deckEditorTabs;
|
return deckEditorTabs;
|
||||||
}
|
}
|
||||||
|
|
@ -174,7 +175,7 @@ private slots:
|
||||||
void processUserLeft(const QString &userName);
|
void processUserLeft(const QString &userName);
|
||||||
void processUserJoined(const ServerInfo_User &userInfo);
|
void processUserJoined(const ServerInfo_User &userInfo);
|
||||||
void talkLeft(TabMessage *tab);
|
void talkLeft(TabMessage *tab);
|
||||||
void deckEditorClosed(TabDeckEditor *tab);
|
void deckEditorClosed(AbstractTabDeckEditor *tab);
|
||||||
void tabUserEvent(bool globalEvent);
|
void tabUserEvent(bool globalEvent);
|
||||||
void updateTabText(Tab *tab, const QString &newTabText);
|
void updateTabText(Tab *tab, const QString &newTabText);
|
||||||
void processRoomEvent(const RoomEvent &event);
|
void processRoomEvent(const RoomEvent &event);
|
||||||
|
|
|
||||||
|
|
@ -296,7 +296,7 @@ QMenu *CardInfoPictureWidget::createAddToOpenDeckMenu()
|
||||||
auto addToOpenDeckMenu = new QMenu(tr("Add card to deck"));
|
auto addToOpenDeckMenu = new QMenu(tr("Add card to deck"));
|
||||||
|
|
||||||
auto *mainWindow = qobject_cast<MainWindow *>(window());
|
auto *mainWindow = qobject_cast<MainWindow *>(window());
|
||||||
QList<TabDeckEditor *> deckEditorTabs = mainWindow->getTabSupervisor()->getDeckEditorTabs();
|
QList<AbstractTabDeckEditor *> deckEditorTabs = mainWindow->getTabSupervisor()->getDeckEditorTabs();
|
||||||
|
|
||||||
if (deckEditorTabs.isEmpty()) {
|
if (deckEditorTabs.isEmpty()) {
|
||||||
addToOpenDeckMenu->setEnabled(false);
|
addToOpenDeckMenu->setEnabled(false);
|
||||||
|
|
@ -308,14 +308,14 @@ QMenu *CardInfoPictureWidget::createAddToOpenDeckMenu()
|
||||||
|
|
||||||
QAction *addCard = addCardMenu->addAction(tr("Mainboard"));
|
QAction *addCard = addCardMenu->addAction(tr("Mainboard"));
|
||||||
connect(addCard, &QAction::triggered, this, [this, deckEditorTab] {
|
connect(addCard, &QAction::triggered, this, [this, deckEditorTab] {
|
||||||
deckEditorTab->updateCardInfo(info);
|
deckEditorTab->updateCard(info);
|
||||||
deckEditorTab->addCardHelper(info, DECK_ZONE_MAIN);
|
deckEditorTab->actAddCard(info);
|
||||||
});
|
});
|
||||||
|
|
||||||
QAction *addCardSideboard = addCardMenu->addAction(tr("Sideboard"));
|
QAction *addCardSideboard = addCardMenu->addAction(tr("Sideboard"));
|
||||||
connect(addCardSideboard, &QAction::triggered, this, [this, deckEditorTab] {
|
connect(addCardSideboard, &QAction::triggered, this, [this, deckEditorTab] {
|
||||||
deckEditorTab->updateCardInfo(info);
|
deckEditorTab->updateCard(info);
|
||||||
deckEditorTab->addCardHelper(info, DECK_ZONE_SIDE);
|
deckEditorTab->actAddCardToSideboard(info);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
#include "deck_editor_card_info_dock_widget.h"
|
||||||
|
|
||||||
|
#include "../cards/card_info_frame_widget.h"
|
||||||
|
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
DeckEditorCardInfoDockWidget::DeckEditorCardInfoDockWidget(AbstractTabDeckEditor *parent)
|
||||||
|
: QDockWidget(parent), deckEditor(parent)
|
||||||
|
{
|
||||||
|
setObjectName("cardInfoDock");
|
||||||
|
|
||||||
|
setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
|
||||||
|
setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable);
|
||||||
|
|
||||||
|
createCardInfoDock();
|
||||||
|
|
||||||
|
retranslateUi();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorCardInfoDockWidget::createCardInfoDock()
|
||||||
|
{
|
||||||
|
cardInfo = new CardInfoFrameWidget();
|
||||||
|
cardInfo->setObjectName("cardInfo");
|
||||||
|
auto *cardInfoFrame = new QVBoxLayout;
|
||||||
|
cardInfoFrame->setObjectName("cardInfoFrame");
|
||||||
|
cardInfoFrame->addWidget(cardInfo);
|
||||||
|
|
||||||
|
auto *cardInfoDockContents = new QWidget();
|
||||||
|
cardInfoDockContents->setObjectName("cardInfoDockContents");
|
||||||
|
cardInfoDockContents->setLayout(cardInfoFrame);
|
||||||
|
setWidget(cardInfoDockContents);
|
||||||
|
|
||||||
|
installEventFilter(deckEditor);
|
||||||
|
connect(this, &QDockWidget::topLevelChanged, deckEditor, &AbstractTabDeckEditor::dockTopLevelChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorCardInfoDockWidget::updateCard(CardInfoPtr _card)
|
||||||
|
{
|
||||||
|
cardInfo->setCard(_card);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorCardInfoDockWidget::retranslateUi()
|
||||||
|
{
|
||||||
|
setWindowTitle(tr("Card Info"));
|
||||||
|
cardInfo->retranslateUi();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef DECK_EDITOR_CARD_INFO_DOCK_WIDGET_H
|
||||||
|
#define DECK_EDITOR_CARD_INFO_DOCK_WIDGET_H
|
||||||
|
|
||||||
|
#include "../../../tabs/abstract_tab_deck_editor.h"
|
||||||
|
#include "../cards/card_info_frame_widget.h"
|
||||||
|
|
||||||
|
#include <QDockWidget>
|
||||||
|
|
||||||
|
class AbstractTabDeckEditor;
|
||||||
|
class DeckEditorCardInfoDockWidget : public QDockWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit DeckEditorCardInfoDockWidget(AbstractTabDeckEditor *parent);
|
||||||
|
void createCardInfoDock();
|
||||||
|
void retranslateUi();
|
||||||
|
|
||||||
|
AbstractTabDeckEditor *deckEditor;
|
||||||
|
CardInfoFrameWidget *cardInfo;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void updateCard(CardInfoPtr _card);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DECK_EDITOR_CARD_INFO_DOCK_WIDGET_H
|
||||||
|
|
@ -0,0 +1,279 @@
|
||||||
|
#include "deck_editor_database_display_widget.h"
|
||||||
|
|
||||||
|
#include "../../../../game/cards/card_database_manager.h"
|
||||||
|
#include "../../../../settings/cache_settings.h"
|
||||||
|
#include "../../../tabs/abstract_tab_deck_editor.h"
|
||||||
|
#include "../../../tabs/tab_supervisor.h"
|
||||||
|
#include "../../../ui/pixel_map_generator.h"
|
||||||
|
|
||||||
|
#include <QClipboard>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QHeaderView>
|
||||||
|
#include <QMenu>
|
||||||
|
#include <QTextBrowser>
|
||||||
|
#include <QToolButton>
|
||||||
|
#include <QTreeView>
|
||||||
|
|
||||||
|
static bool canBeCommander(const CardInfoPtr &cardInfo)
|
||||||
|
{
|
||||||
|
return ((cardInfo->getCardType().contains("Legendary", Qt::CaseInsensitive) &&
|
||||||
|
cardInfo->getCardType().contains("Creature", Qt::CaseInsensitive))) ||
|
||||||
|
cardInfo->getText().contains("can be your commander", Qt::CaseInsensitive);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeckEditorDatabaseDisplayWidget::DeckEditorDatabaseDisplayWidget(AbstractTabDeckEditor *parent)
|
||||||
|
: QWidget(parent), deckEditor(parent)
|
||||||
|
{
|
||||||
|
setObjectName("centralWidget");
|
||||||
|
|
||||||
|
centralFrame = new QVBoxLayout(this);
|
||||||
|
centralFrame->setObjectName("centralFrame");
|
||||||
|
setLayout(centralFrame);
|
||||||
|
|
||||||
|
searchEdit = new SearchLineEdit();
|
||||||
|
searchEdit->setObjectName("searchEdit");
|
||||||
|
searchEdit->setPlaceholderText(tr("Search by card name (or search expressions)"));
|
||||||
|
searchEdit->setClearButtonEnabled(true);
|
||||||
|
searchEdit->addAction(loadColorAdjustedPixmap("theme:icons/search"), QLineEdit::LeadingPosition);
|
||||||
|
auto help = searchEdit->addAction(QPixmap("theme:icons/info"), QLineEdit::TrailingPosition);
|
||||||
|
searchEdit->installEventFilter(&searchKeySignals);
|
||||||
|
|
||||||
|
setFocusProxy(searchEdit);
|
||||||
|
setFocusPolicy(Qt::ClickFocus);
|
||||||
|
|
||||||
|
searchKeySignals.setObjectName("searchKeySignals");
|
||||||
|
connect(searchEdit, SIGNAL(textChanged(const QString &)), this, SLOT(updateSearch(const QString &)));
|
||||||
|
connect(&searchKeySignals, &KeySignals::onEnter, this, &DeckEditorDatabaseDisplayWidget::actAddCardToMainDeck);
|
||||||
|
connect(&searchKeySignals, &KeySignals::onCtrlAltEqual, this,
|
||||||
|
&DeckEditorDatabaseDisplayWidget::actAddCardToMainDeck);
|
||||||
|
connect(&searchKeySignals, &KeySignals::onCtrlAltRBracket, this,
|
||||||
|
&DeckEditorDatabaseDisplayWidget::actAddCardToSideboard);
|
||||||
|
connect(&searchKeySignals, &KeySignals::onCtrlAltMinus, this,
|
||||||
|
&DeckEditorDatabaseDisplayWidget::actDecrementCardFromMainDeck);
|
||||||
|
connect(&searchKeySignals, &KeySignals::onCtrlAltLBracket, this,
|
||||||
|
&DeckEditorDatabaseDisplayWidget::actDecrementCardFromSideboard);
|
||||||
|
connect(&searchKeySignals, &KeySignals::onCtrlAltEnter, this,
|
||||||
|
&DeckEditorDatabaseDisplayWidget::actAddCardToSideboard);
|
||||||
|
connect(&searchKeySignals, &KeySignals::onCtrlEnter, this, &DeckEditorDatabaseDisplayWidget::actAddCardToSideboard);
|
||||||
|
connect(&searchKeySignals, &KeySignals::onCtrlC, this, &DeckEditorDatabaseDisplayWidget::copyDatabaseCellContents);
|
||||||
|
connect(help, &QAction::triggered, this, &DeckEditorDatabaseDisplayWidget::showSearchSyntaxHelp);
|
||||||
|
|
||||||
|
databaseModel = new CardDatabaseModel(CardDatabaseManager::getInstance(), true, this);
|
||||||
|
databaseModel->setObjectName("databaseModel");
|
||||||
|
databaseDisplayModel = new CardDatabaseDisplayModel(this);
|
||||||
|
databaseDisplayModel->setObjectName("databaseDisplayModel");
|
||||||
|
databaseDisplayModel->setSourceModel(databaseModel);
|
||||||
|
databaseDisplayModel->setFilterKeyColumn(0);
|
||||||
|
|
||||||
|
databaseView = new QTreeView(this);
|
||||||
|
databaseView->setObjectName("databaseView");
|
||||||
|
databaseView->setFocusProxy(searchEdit);
|
||||||
|
databaseView->setUniformRowHeights(true);
|
||||||
|
databaseView->setRootIsDecorated(false);
|
||||||
|
databaseView->setAlternatingRowColors(true);
|
||||||
|
databaseView->setSortingEnabled(true);
|
||||||
|
databaseView->sortByColumn(0, Qt::AscendingOrder);
|
||||||
|
databaseView->setModel(databaseDisplayModel);
|
||||||
|
databaseView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
connect(databaseView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(databaseCustomMenu(QPoint)));
|
||||||
|
connect(databaseView->selectionModel(), &QItemSelectionModel::currentRowChanged, this,
|
||||||
|
&DeckEditorDatabaseDisplayWidget::updateCard);
|
||||||
|
connect(databaseView, &QTreeView::doubleClicked, this, &DeckEditorDatabaseDisplayWidget::actAddCardToMainDeck);
|
||||||
|
|
||||||
|
QByteArray dbHeaderState = SettingsCache::instance().layouts().getDeckEditorDbHeaderState();
|
||||||
|
if (dbHeaderState.isNull()) {
|
||||||
|
// first run
|
||||||
|
databaseView->setColumnWidth(0, 200);
|
||||||
|
} else {
|
||||||
|
databaseView->header()->restoreState(dbHeaderState);
|
||||||
|
}
|
||||||
|
connect(databaseView->header(), SIGNAL(geometriesChanged()), this, SLOT(saveDbHeaderState()));
|
||||||
|
|
||||||
|
searchEdit->setTreeView(databaseView);
|
||||||
|
|
||||||
|
aAddCard = new QAction(QString(), this);
|
||||||
|
aAddCard->setIcon(QPixmap("theme:icons/arrow_right_green"));
|
||||||
|
connect(aAddCard, &QAction::triggered, this, &DeckEditorDatabaseDisplayWidget::actAddCardToMainDeck);
|
||||||
|
auto *tbAddCard = new QToolButton(this);
|
||||||
|
tbAddCard->setDefaultAction(aAddCard);
|
||||||
|
|
||||||
|
aAddCardToSideboard = new QAction(QString(), this);
|
||||||
|
aAddCardToSideboard->setIcon(QPixmap("theme:icons/arrow_right_blue"));
|
||||||
|
connect(aAddCardToSideboard, &QAction::triggered, this, &DeckEditorDatabaseDisplayWidget::actAddCardToSideboard);
|
||||||
|
auto *tbAddCardToSideboard = new QToolButton(this);
|
||||||
|
tbAddCardToSideboard->setDefaultAction(aAddCardToSideboard);
|
||||||
|
|
||||||
|
searchLayout = new QHBoxLayout;
|
||||||
|
searchLayout->setObjectName("searchLayout");
|
||||||
|
searchLayout->addWidget(searchEdit);
|
||||||
|
searchLayout->addWidget(tbAddCard);
|
||||||
|
searchLayout->addWidget(tbAddCardToSideboard);
|
||||||
|
|
||||||
|
centralFrame->addLayout(searchLayout);
|
||||||
|
centralFrame->addWidget(databaseView);
|
||||||
|
|
||||||
|
retranslateUi();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDatabaseDisplayWidget::updateSearch(const QString &search)
|
||||||
|
{
|
||||||
|
databaseDisplayModel->setStringFilter(search);
|
||||||
|
QModelIndexList sel = databaseView->selectionModel()->selectedRows();
|
||||||
|
if (sel.isEmpty() && databaseDisplayModel->rowCount())
|
||||||
|
databaseView->selectionModel()->setCurrentIndex(databaseDisplayModel->index(0, 0),
|
||||||
|
QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDatabaseDisplayWidget::clearAllDatabaseFilters()
|
||||||
|
{
|
||||||
|
databaseDisplayModel->clearFilterAll();
|
||||||
|
searchEdit->setText("");
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDatabaseDisplayWidget::updateCard(const QModelIndex ¤t, const QModelIndex & /*previous*/)
|
||||||
|
{
|
||||||
|
const QString cardName = current.sibling(current.row(), 0).data().toString();
|
||||||
|
const QString cardProviderID = CardDatabaseManager::getInstance()->getPreferredPrintingProviderIdForCard(cardName);
|
||||||
|
|
||||||
|
if (!current.isValid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!current.model()->hasChildren(current.sibling(current.row(), 0))) {
|
||||||
|
CardInfoPtr card = CardDatabaseManager::getInstance()->getCardByNameAndProviderId(cardName, cardProviderID);
|
||||||
|
emit cardChanged(card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDatabaseDisplayWidget::actAddCardToMainDeck()
|
||||||
|
{
|
||||||
|
emit addCardToMainDeck(currentCardInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDatabaseDisplayWidget::actAddCardToSideboard()
|
||||||
|
{
|
||||||
|
emit addCardToSideboard(currentCardInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDatabaseDisplayWidget::actDecrementCardFromMainDeck()
|
||||||
|
{
|
||||||
|
emit decrementCardFromMainDeck(currentCardInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDatabaseDisplayWidget::actDecrementCardFromSideboard()
|
||||||
|
{
|
||||||
|
emit decrementCardFromSideboard(currentCardInfo());
|
||||||
|
}
|
||||||
|
|
||||||
|
CardInfoPtr DeckEditorDatabaseDisplayWidget::currentCardInfo() const
|
||||||
|
{
|
||||||
|
const QModelIndex currentIndex = databaseView->selectionModel()->currentIndex();
|
||||||
|
if (!currentIndex.isValid()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString cardName = currentIndex.sibling(currentIndex.row(), 0).data().toString();
|
||||||
|
|
||||||
|
return CardDatabaseManager::getInstance()->getCard(cardName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDatabaseDisplayWidget::databaseCustomMenu(QPoint point)
|
||||||
|
{
|
||||||
|
QMenu menu;
|
||||||
|
const CardInfoPtr info = currentCardInfo();
|
||||||
|
|
||||||
|
if (info) {
|
||||||
|
// add to deck and sideboard options
|
||||||
|
QAction *addToDeck, *addToSideboard, *selectPrinting, *edhRecCommander, *edhRecCard;
|
||||||
|
addToDeck = menu.addAction(tr("Add to Deck"));
|
||||||
|
addToSideboard = menu.addAction(tr("Add to Sideboard"));
|
||||||
|
selectPrinting = menu.addAction(tr("Select Printing"));
|
||||||
|
if (canBeCommander(info)) {
|
||||||
|
edhRecCommander = menu.addAction(tr("Show on EDHREC (Commander)"));
|
||||||
|
connect(edhRecCommander, &QAction::triggered, this,
|
||||||
|
[this, info] { deckEditor->getTabSupervisor()->addEdhrecTab(info, true); });
|
||||||
|
}
|
||||||
|
edhRecCard = menu.addAction(tr("Show on EDHREC (Card)"));
|
||||||
|
|
||||||
|
connect(addToDeck, &QAction::triggered, this, &DeckEditorDatabaseDisplayWidget::actAddCardToMainDeck);
|
||||||
|
connect(addToSideboard, &QAction::triggered, this, &DeckEditorDatabaseDisplayWidget::actAddCardToSideboard);
|
||||||
|
connect(selectPrinting, &QAction::triggered, this, [this, info] { deckEditor->showPrintingSelector(); });
|
||||||
|
connect(edhRecCard, &QAction::triggered, this,
|
||||||
|
[this, info] { deckEditor->getTabSupervisor()->addEdhrecTab(info); });
|
||||||
|
|
||||||
|
// filling out the related cards submenu
|
||||||
|
auto *relatedMenu = new QMenu(tr("Show Related cards"));
|
||||||
|
menu.addMenu(relatedMenu);
|
||||||
|
auto relatedCards = info->getAllRelatedCards();
|
||||||
|
if (relatedCards.isEmpty()) {
|
||||||
|
relatedMenu->setDisabled(true);
|
||||||
|
} else {
|
||||||
|
for (const CardRelation *rel : relatedCards) {
|
||||||
|
const QString &relatedCardName = rel->getName();
|
||||||
|
QAction *relatedCard = relatedMenu->addAction(relatedCardName);
|
||||||
|
connect(
|
||||||
|
relatedCard, &QAction::triggered, deckEditor->cardInfoDockWidget->cardInfo,
|
||||||
|
[this, relatedCardName] { deckEditor->cardInfoDockWidget->cardInfo->setCard(relatedCardName); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
menu.exec(databaseView->mapToGlobal(point));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDatabaseDisplayWidget::copyDatabaseCellContents()
|
||||||
|
{
|
||||||
|
auto _data = databaseView->selectionModel()->currentIndex().data();
|
||||||
|
QApplication::clipboard()->setText(_data.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDatabaseDisplayWidget::saveDbHeaderState()
|
||||||
|
{
|
||||||
|
SettingsCache::instance().layouts().setDeckEditorDbHeaderState(databaseView->header()->saveState());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDatabaseDisplayWidget::showSearchSyntaxHelp()
|
||||||
|
{
|
||||||
|
|
||||||
|
QFile file("theme:help/search.md");
|
||||||
|
|
||||||
|
if (!file.open(QFile::ReadOnly | QFile::Text)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextStream in(&file);
|
||||||
|
QString text = in.readAll();
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
// Poor Markdown Converter
|
||||||
|
auto opts = QRegularExpression::MultilineOption;
|
||||||
|
text = text.replace(QRegularExpression("^(###)(.*)", opts), "<h3>\\2</h3>")
|
||||||
|
.replace(QRegularExpression("^(##)(.*)", opts), "<h2>\\2</h2>")
|
||||||
|
.replace(QRegularExpression("^(#)(.*)", opts), "<h1>\\2</h1>")
|
||||||
|
.replace(QRegularExpression("^------*", opts), "<hr />")
|
||||||
|
.replace(QRegularExpression(R"(\[([^[]+)\]\(([^\)]+)\))", opts), R"(<a href='\2'>\1</a>)");
|
||||||
|
|
||||||
|
auto browser = new QTextBrowser;
|
||||||
|
browser->setParent(this, Qt::Window | Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint |
|
||||||
|
Qt::WindowCloseButtonHint | Qt::WindowFullscreenButtonHint);
|
||||||
|
browser->setWindowTitle("Search Help");
|
||||||
|
browser->setReadOnly(true);
|
||||||
|
browser->setMinimumSize({500, 600});
|
||||||
|
|
||||||
|
QString sheet = QString("a { text-decoration: underline; color: rgb(71,158,252) };");
|
||||||
|
browser->document()->setDefaultStyleSheet(sheet);
|
||||||
|
|
||||||
|
browser->setHtml(text);
|
||||||
|
connect(browser, &QTextBrowser::anchorClicked, [this](const QUrl &link) { searchEdit->setText(link.fragment()); });
|
||||||
|
browser->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDatabaseDisplayWidget::setFilterTree(FilterTree *filterTree)
|
||||||
|
{
|
||||||
|
databaseDisplayModel->setFilterTree(filterTree);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDatabaseDisplayWidget::retranslateUi()
|
||||||
|
{
|
||||||
|
aAddCard->setText(tr("Add card to &maindeck"));
|
||||||
|
aAddCardToSideboard->setText(tr("Add card to &sideboard"));
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
#ifndef DECK_EDITOR_DATABASE_DISPLAY_WIDGET_H
|
||||||
|
#define DECK_EDITOR_DATABASE_DISPLAY_WIDGET_H
|
||||||
|
|
||||||
|
#include "../../../../deck/custom_line_edit.h"
|
||||||
|
#include "../../../../game/cards/card_database_model.h"
|
||||||
|
#include "../../../game_logic/key_signals.h"
|
||||||
|
#include "../../../tabs/abstract_tab_deck_editor.h"
|
||||||
|
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class AbstractTabDeckEditor;
|
||||||
|
class DeckEditorDatabaseDisplayWidget : public QWidget
|
||||||
|
{
|
||||||
|
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit DeckEditorDatabaseDisplayWidget(AbstractTabDeckEditor *parent);
|
||||||
|
AbstractTabDeckEditor *deckEditor;
|
||||||
|
SearchLineEdit *searchEdit;
|
||||||
|
CardDatabaseModel *databaseModel;
|
||||||
|
CardDatabaseDisplayModel *databaseDisplayModel;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
CardInfoPtr currentCardInfo() const;
|
||||||
|
void setFilterTree(FilterTree *filterTree);
|
||||||
|
void clearAllDatabaseFilters();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void addCardToMainDeck(CardInfoPtr card);
|
||||||
|
void addCardToSideboard(CardInfoPtr card);
|
||||||
|
void decrementCardFromMainDeck(CardInfoPtr card);
|
||||||
|
void decrementCardFromSideboard(CardInfoPtr card);
|
||||||
|
void cardChanged(CardInfoPtr _card);
|
||||||
|
|
||||||
|
private:
|
||||||
|
KeySignals searchKeySignals;
|
||||||
|
QTreeView *databaseView;
|
||||||
|
QHBoxLayout *searchLayout;
|
||||||
|
QAction *aAddCard, *aAddCardToSideboard;
|
||||||
|
QVBoxLayout *centralFrame;
|
||||||
|
QWidget *centralWidget;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void showSearchSyntaxHelp();
|
||||||
|
void retranslateUi();
|
||||||
|
void updateSearch(const QString &search);
|
||||||
|
void updateCard(const QModelIndex ¤t, const QModelIndex &);
|
||||||
|
void actAddCardToMainDeck();
|
||||||
|
void actAddCardToSideboard();
|
||||||
|
void actDecrementCardFromMainDeck();
|
||||||
|
void actDecrementCardFromSideboard();
|
||||||
|
void databaseCustomMenu(QPoint point);
|
||||||
|
void copyDatabaseCellContents();
|
||||||
|
void saveDbHeaderState();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DECK_EDITOR_DATABASE_DISPLAY_WIDGET_H
|
||||||
|
|
@ -0,0 +1,522 @@
|
||||||
|
#include "deck_editor_deck_dock_widget.h"
|
||||||
|
|
||||||
|
#include "../../../../game/cards/card_database_manager.h"
|
||||||
|
#include "../../../../settings/cache_settings.h"
|
||||||
|
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QDockWidget>
|
||||||
|
#include <QHeaderView>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QSplitter>
|
||||||
|
#include <QTextEdit>
|
||||||
|
#include <trice_limits.h>
|
||||||
|
|
||||||
|
DeckEditorDeckDockWidget::DeckEditorDeckDockWidget(AbstractTabDeckEditor *parent)
|
||||||
|
: QDockWidget(parent), deckEditor(parent)
|
||||||
|
{
|
||||||
|
setObjectName("deckDock");
|
||||||
|
|
||||||
|
setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
|
||||||
|
setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable);
|
||||||
|
|
||||||
|
installEventFilter(deckEditor);
|
||||||
|
connect(this, SIGNAL(topLevelChanged(bool)), deckEditor, SLOT(dockTopLevelChanged(bool)));
|
||||||
|
createDeckDock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDeckDockWidget::createDeckDock()
|
||||||
|
{
|
||||||
|
deckModel = new DeckListModel(this);
|
||||||
|
deckModel->setObjectName("deckModel");
|
||||||
|
connect(deckModel, SIGNAL(deckHashChanged()), this, SLOT(updateHash()));
|
||||||
|
deckView = new QTreeView();
|
||||||
|
deckView->setObjectName("deckView");
|
||||||
|
deckView->setModel(deckModel);
|
||||||
|
deckView->setUniformRowHeights(true);
|
||||||
|
deckView->setSortingEnabled(true);
|
||||||
|
deckView->sortByColumn(1, Qt::AscendingOrder);
|
||||||
|
deckView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||||
|
deckView->installEventFilter(&deckViewKeySignals);
|
||||||
|
deckView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
deckView->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||||
|
connect(deckView->selectionModel(), &QItemSelectionModel::currentRowChanged, this,
|
||||||
|
&DeckEditorDeckDockWidget::updateCard);
|
||||||
|
connect(deckView, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(actSwapCard()));
|
||||||
|
connect(deckView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(decklistCustomMenu(QPoint)));
|
||||||
|
connect(&deckViewKeySignals, SIGNAL(onShiftS()), this, SLOT(actSwapCard()));
|
||||||
|
connect(&deckViewKeySignals, SIGNAL(onEnter()), this, SLOT(actIncrement()));
|
||||||
|
connect(&deckViewKeySignals, SIGNAL(onCtrlAltEqual()), this, SLOT(actIncrement()));
|
||||||
|
connect(&deckViewKeySignals, SIGNAL(onCtrlAltMinus()), this, SLOT(actDecrementSelection()));
|
||||||
|
connect(&deckViewKeySignals, SIGNAL(onShiftRight()), this, SLOT(actIncrement()));
|
||||||
|
connect(&deckViewKeySignals, SIGNAL(onShiftLeft()), this, SLOT(actDecrementSelection()));
|
||||||
|
connect(&deckViewKeySignals, SIGNAL(onDelete()), this, SLOT(actRemoveCard()));
|
||||||
|
|
||||||
|
nameLabel = new QLabel();
|
||||||
|
nameLabel->setObjectName("nameLabel");
|
||||||
|
nameEdit = new LineEditUnfocusable;
|
||||||
|
nameEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||||
|
nameEdit->setObjectName("nameEdit");
|
||||||
|
nameLabel->setBuddy(nameEdit);
|
||||||
|
connect(nameEdit, SIGNAL(textChanged(const QString &)), this, SLOT(updateName(const QString &)));
|
||||||
|
commentsLabel = new QLabel();
|
||||||
|
commentsLabel->setObjectName("commentsLabel");
|
||||||
|
commentsEdit = new QTextEdit;
|
||||||
|
commentsEdit->setAcceptRichText(false);
|
||||||
|
commentsEdit->setMinimumHeight(nameEdit->minimumSizeHint().height());
|
||||||
|
commentsEdit->setObjectName("commentsEdit");
|
||||||
|
commentsLabel->setBuddy(commentsEdit);
|
||||||
|
connect(commentsEdit, SIGNAL(textChanged()), this, SLOT(updateComments()));
|
||||||
|
bannerCardLabel = new QLabel();
|
||||||
|
bannerCardLabel->setObjectName("bannerCardLabel");
|
||||||
|
bannerCardLabel->setText(tr("Banner Card"));
|
||||||
|
bannerCardComboBox = new QComboBox(this);
|
||||||
|
connect(deckModel, &DeckListModel::dataChanged, this, [this]() {
|
||||||
|
// Delay the update to avoid race conditions
|
||||||
|
QTimer::singleShot(100, this, &DeckEditorDeckDockWidget::updateBannerCardComboBox);
|
||||||
|
});
|
||||||
|
connect(bannerCardComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||||
|
&DeckEditorDeckDockWidget::setBannerCard);
|
||||||
|
|
||||||
|
deckTagsDisplayWidget = new DeckPreviewDeckTagsDisplayWidget(this, deckModel->getDeckList());
|
||||||
|
|
||||||
|
aIncrement = new QAction(QString(), this);
|
||||||
|
aIncrement->setIcon(QPixmap("theme:icons/increment"));
|
||||||
|
connect(aIncrement, SIGNAL(triggered()), this, SLOT(actIncrement()));
|
||||||
|
auto *tbIncrement = new QToolButton(this);
|
||||||
|
tbIncrement->setDefaultAction(aIncrement);
|
||||||
|
|
||||||
|
aDecrement = new QAction(QString(), this);
|
||||||
|
aDecrement->setIcon(QPixmap("theme:icons/decrement"));
|
||||||
|
connect(aDecrement, SIGNAL(triggered()), this, SLOT(actDecrementSelection()));
|
||||||
|
auto *tbDecrement = new QToolButton(this);
|
||||||
|
tbDecrement->setDefaultAction(aDecrement);
|
||||||
|
|
||||||
|
aRemoveCard = new QAction(QString(), this);
|
||||||
|
aRemoveCard->setIcon(QPixmap("theme:icons/remove_row"));
|
||||||
|
connect(aRemoveCard, SIGNAL(triggered()), this, SLOT(actRemoveCard()));
|
||||||
|
auto *tbRemoveCard = new QToolButton(this);
|
||||||
|
tbRemoveCard->setDefaultAction(aRemoveCard);
|
||||||
|
|
||||||
|
aSwapCard = new QAction(QString(), this);
|
||||||
|
aSwapCard->setIcon(QPixmap("theme:icons/swap"));
|
||||||
|
connect(aSwapCard, SIGNAL(triggered()), this, SLOT(actSwapCard()));
|
||||||
|
auto *tbSwapCard = new QToolButton(this);
|
||||||
|
tbSwapCard->setDefaultAction(aSwapCard);
|
||||||
|
|
||||||
|
auto *upperLayout = new QGridLayout;
|
||||||
|
upperLayout->setObjectName("upperLayout");
|
||||||
|
upperLayout->addWidget(nameLabel, 0, 0);
|
||||||
|
upperLayout->addWidget(nameEdit, 0, 1);
|
||||||
|
|
||||||
|
upperLayout->addWidget(commentsLabel, 1, 0);
|
||||||
|
upperLayout->addWidget(commentsEdit, 1, 1);
|
||||||
|
|
||||||
|
upperLayout->addWidget(bannerCardLabel, 2, 0);
|
||||||
|
upperLayout->addWidget(bannerCardComboBox, 2, 1);
|
||||||
|
|
||||||
|
upperLayout->addWidget(deckTagsDisplayWidget, 3, 1);
|
||||||
|
|
||||||
|
hashLabel1 = new QLabel();
|
||||||
|
hashLabel1->setObjectName("hashLabel1");
|
||||||
|
auto *hashSizePolicy = new QSizePolicy();
|
||||||
|
hashSizePolicy->setHorizontalPolicy(QSizePolicy::Fixed);
|
||||||
|
hashLabel1->setSizePolicy(*hashSizePolicy);
|
||||||
|
hashLabel = new LineEditUnfocusable;
|
||||||
|
hashLabel->setObjectName("hashLabel");
|
||||||
|
hashLabel->setReadOnly(true);
|
||||||
|
hashLabel->setFrame(false);
|
||||||
|
|
||||||
|
auto *lowerLayout = new QGridLayout;
|
||||||
|
lowerLayout->setObjectName("lowerLayout");
|
||||||
|
lowerLayout->addWidget(hashLabel1, 0, 0);
|
||||||
|
lowerLayout->addWidget(hashLabel, 0, 1);
|
||||||
|
lowerLayout->addWidget(tbIncrement, 0, 2);
|
||||||
|
lowerLayout->addWidget(tbDecrement, 0, 3);
|
||||||
|
lowerLayout->addWidget(tbRemoveCard, 0, 4);
|
||||||
|
lowerLayout->addWidget(tbSwapCard, 0, 5);
|
||||||
|
lowerLayout->addWidget(deckView, 1, 0, 1, 6);
|
||||||
|
|
||||||
|
// Create widgets for both layouts to make splitter work correctly
|
||||||
|
auto *topWidget = new QWidget;
|
||||||
|
topWidget->setLayout(upperLayout);
|
||||||
|
auto *bottomWidget = new QWidget;
|
||||||
|
bottomWidget->setLayout(lowerLayout);
|
||||||
|
|
||||||
|
auto *split = new QSplitter;
|
||||||
|
split->setObjectName("deckSplitter");
|
||||||
|
split->setOrientation(Qt::Vertical);
|
||||||
|
split->setChildrenCollapsible(true);
|
||||||
|
split->addWidget(topWidget);
|
||||||
|
split->addWidget(bottomWidget);
|
||||||
|
split->setStretchFactor(0, 1);
|
||||||
|
split->setStretchFactor(1, 4);
|
||||||
|
|
||||||
|
auto *rightFrame = new QVBoxLayout;
|
||||||
|
rightFrame->setObjectName("rightFrame");
|
||||||
|
rightFrame->addWidget(split);
|
||||||
|
|
||||||
|
auto *deckDockContents = new QWidget();
|
||||||
|
deckDockContents->setObjectName("deckDockContents");
|
||||||
|
deckDockContents->setLayout(rightFrame);
|
||||||
|
setWidget(deckDockContents);
|
||||||
|
|
||||||
|
refreshShortcuts();
|
||||||
|
retranslateUi();
|
||||||
|
}
|
||||||
|
|
||||||
|
CardInfoPtr DeckEditorDeckDockWidget::getCurrentCard()
|
||||||
|
{
|
||||||
|
QModelIndex current = deckView->selectionModel()->currentIndex();
|
||||||
|
if (!current.isValid())
|
||||||
|
return {};
|
||||||
|
const QString cardName = current.sibling(current.row(), 1).data().toString();
|
||||||
|
const QString cardProviderID = current.sibling(current.row(), 4).data().toString();
|
||||||
|
const QModelIndex gparent = current.parent().parent();
|
||||||
|
|
||||||
|
if (!gparent.isValid()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString zoneName = gparent.sibling(gparent.row(), 1).data(Qt::EditRole).toString();
|
||||||
|
|
||||||
|
if (!current.model()->hasChildren(current.sibling(current.row(), 0))) {
|
||||||
|
QString cardName = current.sibling(current.row(), 1).data().toString();
|
||||||
|
QString providerId = current.sibling(current.row(), 4).data().toString();
|
||||||
|
if (CardInfoPtr selectedCard =
|
||||||
|
CardDatabaseManager::getInstance()->getCardByNameAndProviderId(cardName, providerId)) {
|
||||||
|
return selectedCard;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDeckDockWidget::updateCard(const QModelIndex /*¤t*/, const QModelIndex & /*previous*/)
|
||||||
|
{
|
||||||
|
if (CardInfoPtr card = getCurrentCard()) {
|
||||||
|
emit cardChanged(card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDeckDockWidget::updateName(const QString &name)
|
||||||
|
{
|
||||||
|
deckModel->getDeckList()->setName(name);
|
||||||
|
deckEditor->setModified(true);
|
||||||
|
deckEditor->deckMenu->setSaveStatus(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDeckDockWidget::updateComments()
|
||||||
|
{
|
||||||
|
deckModel->getDeckList()->setComments(commentsEdit->toPlainText());
|
||||||
|
deckEditor->setModified(true);
|
||||||
|
deckEditor->deckMenu->setSaveStatus(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDeckDockWidget::updateHash()
|
||||||
|
{
|
||||||
|
hashLabel->setText(deckModel->getDeckList()->getDeckHash());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDeckDockWidget::updateBannerCardComboBox()
|
||||||
|
{
|
||||||
|
// Store the current text of the combo box
|
||||||
|
QString currentText = bannerCardComboBox->currentText();
|
||||||
|
|
||||||
|
// Block signals temporarily
|
||||||
|
bool wasBlocked = bannerCardComboBox->blockSignals(true);
|
||||||
|
|
||||||
|
// Clear the existing items in the combo box
|
||||||
|
bannerCardComboBox->clear();
|
||||||
|
|
||||||
|
// Prepare the new items with deduplication
|
||||||
|
QSet<QPair<QString, QString>> bannerCardSet;
|
||||||
|
InnerDecklistNode *listRoot = deckModel->getDeckList()->getRoot();
|
||||||
|
for (int i = 0; i < listRoot->size(); i++) {
|
||||||
|
InnerDecklistNode *currentZone = dynamic_cast<InnerDecklistNode *>(listRoot->at(i));
|
||||||
|
for (int j = 0; j < currentZone->size(); j++) {
|
||||||
|
DecklistCardNode *currentCard = dynamic_cast<DecklistCardNode *>(currentZone->at(j));
|
||||||
|
if (!currentCard)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (int k = 0; k < currentCard->getNumber(); ++k) {
|
||||||
|
CardInfoPtr info = CardDatabaseManager::getInstance()->getCardByNameAndProviderId(
|
||||||
|
currentCard->getName(), currentCard->getCardProviderId());
|
||||||
|
if (info) {
|
||||||
|
bannerCardSet.insert(
|
||||||
|
QPair<QString, QString>(currentCard->getName(), currentCard->getCardProviderId()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QPair<QString, QString>> pairList = bannerCardSet.values();
|
||||||
|
|
||||||
|
// Sort QList by the first() element of the QPair
|
||||||
|
std::sort(pairList.begin(), pairList.end(), [](const QPair<QString, QString> &a, const QPair<QString, QString> &b) {
|
||||||
|
return a.first.toLower() < b.first.toLower();
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const auto &pair : pairList) {
|
||||||
|
QVariantMap dataMap;
|
||||||
|
dataMap["name"] = pair.first;
|
||||||
|
dataMap["uuid"] = pair.second;
|
||||||
|
|
||||||
|
bannerCardComboBox->addItem(pair.first, dataMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to restore the previous selection by finding the currentText
|
||||||
|
int restoredIndex = bannerCardComboBox->findText(currentText);
|
||||||
|
if (restoredIndex != -1) {
|
||||||
|
bannerCardComboBox->setCurrentIndex(restoredIndex);
|
||||||
|
} else {
|
||||||
|
// Add a placeholder "-" and set it as the current selection
|
||||||
|
int bannerIndex = bannerCardComboBox->findText(deckModel->getDeckList()->getBannerCard().first);
|
||||||
|
if (bannerIndex != -1) {
|
||||||
|
bannerCardComboBox->setCurrentIndex(bannerIndex);
|
||||||
|
} else {
|
||||||
|
bannerCardComboBox->insertItem(0, "-");
|
||||||
|
bannerCardComboBox->setCurrentIndex(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore the previous signal blocking state
|
||||||
|
bannerCardComboBox->blockSignals(wasBlocked);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDeckDockWidget::setBannerCard(int /* changedIndex */)
|
||||||
|
{
|
||||||
|
QVariantMap itemData = bannerCardComboBox->itemData(bannerCardComboBox->currentIndex()).toMap();
|
||||||
|
deckModel->getDeckList()->setBannerCard(
|
||||||
|
QPair<QString, QString>(itemData["name"].toString(), itemData["uuid"].toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDeckDockWidget::setDeck(DeckLoader *_deck)
|
||||||
|
{
|
||||||
|
deckModel->setDeckList(_deck);
|
||||||
|
|
||||||
|
nameEdit->setText(deckModel->getDeckList()->getName());
|
||||||
|
commentsEdit->setText(deckModel->getDeckList()->getComments());
|
||||||
|
bannerCardComboBox->setCurrentText(deckModel->getDeckList()->getBannerCard().first);
|
||||||
|
updateBannerCardComboBox();
|
||||||
|
updateHash();
|
||||||
|
deckModel->sort(deckView->header()->sortIndicatorSection(), deckView->header()->sortIndicatorOrder());
|
||||||
|
deckView->expandAll();
|
||||||
|
deckView->expandAll();
|
||||||
|
|
||||||
|
deckTagsDisplayWidget->connectDeckList(deckModel->getDeckList());
|
||||||
|
}
|
||||||
|
|
||||||
|
DeckLoader *DeckEditorDeckDockWidget::getDeckList()
|
||||||
|
{
|
||||||
|
return deckModel->getDeckList();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDeckDockWidget::cleanDeck()
|
||||||
|
{
|
||||||
|
deckModel->cleanList();
|
||||||
|
nameEdit->setText(QString());
|
||||||
|
commentsEdit->setText(QString());
|
||||||
|
hashLabel->setText(QString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDeckDockWidget::recursiveExpand(const QModelIndex &index)
|
||||||
|
{
|
||||||
|
if (index.parent().isValid())
|
||||||
|
recursiveExpand(index.parent());
|
||||||
|
deckView->expand(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the index of all the currently selected card nodes in the decklist table.
|
||||||
|
* The list is in reverse order of the visual selection, so that rows can be deleted while iterating over them.
|
||||||
|
*
|
||||||
|
* @return A model index list containing all selected card nodes
|
||||||
|
*/
|
||||||
|
QModelIndexList DeckEditorDeckDockWidget::getSelectedCardNodes() const
|
||||||
|
{
|
||||||
|
auto selectedRows = deckView->selectionModel()->selectedRows();
|
||||||
|
|
||||||
|
const auto notLeafNode = [this](const auto &index) { return deckModel->hasChildren(index); };
|
||||||
|
selectedRows.erase(std::remove_if(selectedRows.begin(), selectedRows.end(), notLeafNode), selectedRows.end());
|
||||||
|
|
||||||
|
std::reverse(selectedRows.begin(), selectedRows.end());
|
||||||
|
return selectedRows;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDeckDockWidget::actIncrement()
|
||||||
|
{
|
||||||
|
auto selectedRows = getSelectedCardNodes();
|
||||||
|
|
||||||
|
for (const auto &index : selectedRows) {
|
||||||
|
offsetCountAtIndex(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDeckDockWidget::actSwapCard()
|
||||||
|
{
|
||||||
|
auto selectedRows = getSelectedCardNodes();
|
||||||
|
|
||||||
|
// hack to maintain the old reselection behavior when currently selected row of a single-selection gets deleted
|
||||||
|
// TODO: remove the hack and also handle reselection when all rows of a multi-selection gets deleted
|
||||||
|
if (selectedRows.length() == 1) {
|
||||||
|
deckView->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isModified = false;
|
||||||
|
for (const auto ¤tIndex : selectedRows) {
|
||||||
|
if (swapCard(currentIndex)) {
|
||||||
|
isModified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deckView->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||||
|
|
||||||
|
if (isModified) {
|
||||||
|
emit deckChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Swaps the card at the index between the maindeck and sideboard
|
||||||
|
*
|
||||||
|
* @param currentIndex The index to swap.
|
||||||
|
* @return True if the swap was successful
|
||||||
|
*/
|
||||||
|
bool DeckEditorDeckDockWidget::swapCard(const QModelIndex ¤tIndex)
|
||||||
|
{
|
||||||
|
if (!currentIndex.isValid())
|
||||||
|
return false;
|
||||||
|
const QString cardName = currentIndex.sibling(currentIndex.row(), 1).data().toString();
|
||||||
|
const QString cardProviderID = currentIndex.sibling(currentIndex.row(), 4).data().toString();
|
||||||
|
const QModelIndex gparent = currentIndex.parent().parent();
|
||||||
|
|
||||||
|
if (!gparent.isValid())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const QString zoneName = gparent.sibling(gparent.row(), 1).data(Qt::EditRole).toString();
|
||||||
|
offsetCountAtIndex(currentIndex, -1);
|
||||||
|
const QString otherZoneName = zoneName == DECK_ZONE_MAIN ? DECK_ZONE_SIDE : DECK_ZONE_MAIN;
|
||||||
|
|
||||||
|
// Third argument (true) says create the card no matter what, even if not in DB
|
||||||
|
QModelIndex newCardIndex = deckModel->addCard(
|
||||||
|
cardName, CardDatabaseManager::getInstance()->getSpecificSetForCard(cardName, cardProviderID), otherZoneName,
|
||||||
|
true);
|
||||||
|
recursiveExpand(newCardIndex);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDeckDockWidget::actDecrementCard(CardInfoPtr info, QString zoneName)
|
||||||
|
{
|
||||||
|
if (!info)
|
||||||
|
return;
|
||||||
|
if (info->getIsToken())
|
||||||
|
zoneName = DECK_ZONE_TOKENS;
|
||||||
|
|
||||||
|
QString providerId = CardDatabaseManager::getInstance()->getSetInfoForCard(info).getProperty("uuid");
|
||||||
|
QString collectorNumber = CardDatabaseManager::getInstance()->getSetInfoForCard(info).getProperty("num");
|
||||||
|
|
||||||
|
QModelIndex idx = deckModel->findCard(info->getName(), zoneName, providerId, collectorNumber);
|
||||||
|
if (!idx.isValid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
deckView->clearSelection();
|
||||||
|
deckView->setCurrentIndex(idx);
|
||||||
|
offsetCountAtIndex(idx, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDeckDockWidget::actDecrementSelection()
|
||||||
|
{
|
||||||
|
auto selectedRows = getSelectedCardNodes();
|
||||||
|
|
||||||
|
// hack to maintain the old reselection behavior when currently selected row of a single-selection gets deleted
|
||||||
|
// TODO: remove the hack and also handle reselection when all rows of a multi-selection gets deleted
|
||||||
|
if (selectedRows.length() == 1) {
|
||||||
|
deckView->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto &index : selectedRows) {
|
||||||
|
offsetCountAtIndex(index, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
deckView->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDeckDockWidget::actRemoveCard()
|
||||||
|
{
|
||||||
|
auto selectedRows = getSelectedCardNodes();
|
||||||
|
|
||||||
|
// hack to maintain the old reselection behavior when currently selected row of a single-selection gets deleted
|
||||||
|
// TODO: remove the hack and also handle reselection when all rows of a multi-selection gets deleted
|
||||||
|
if (selectedRows.length() == 1) {
|
||||||
|
deckView->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isModified = false;
|
||||||
|
for (const auto &index : selectedRows) {
|
||||||
|
if (!index.isValid() || deckModel->hasChildren(index)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
deckModel->removeRow(index.row(), index.parent());
|
||||||
|
isModified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
deckView->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||||
|
|
||||||
|
if (isModified) {
|
||||||
|
emit deckChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDeckDockWidget::offsetCountAtIndex(const QModelIndex &idx, int offset)
|
||||||
|
{
|
||||||
|
if (!idx.isValid() || deckModel->hasChildren(idx)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QModelIndex numberIndex = idx.sibling(idx.row(), 0);
|
||||||
|
const int count = deckModel->data(numberIndex, Qt::EditRole).toInt();
|
||||||
|
const int new_count = count + offset;
|
||||||
|
if (new_count <= 0)
|
||||||
|
deckModel->removeRow(idx.row(), idx.parent());
|
||||||
|
else
|
||||||
|
deckModel->setData(numberIndex, new_count, Qt::EditRole);
|
||||||
|
|
||||||
|
emit deckChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDeckDockWidget::decklistCustomMenu(QPoint point)
|
||||||
|
{
|
||||||
|
QMenu menu;
|
||||||
|
const CardInfoPtr info = getCurrentCard();
|
||||||
|
|
||||||
|
QAction *selectPrinting = menu.addAction(tr("Select Printing"));
|
||||||
|
|
||||||
|
connect(selectPrinting, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::showPrintingSelector);
|
||||||
|
|
||||||
|
menu.exec(deckView->mapToGlobal(point));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDeckDockWidget::refreshShortcuts()
|
||||||
|
{
|
||||||
|
ShortcutsSettings &shortcuts = SettingsCache::instance().shortcuts();
|
||||||
|
aRemoveCard->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aRemoveCard"));
|
||||||
|
aIncrement->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aIncrement"));
|
||||||
|
aDecrement->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aDecrement"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorDeckDockWidget::retranslateUi()
|
||||||
|
{
|
||||||
|
setWindowTitle(tr("Deck"));
|
||||||
|
|
||||||
|
nameLabel->setText(tr("Deck &name:"));
|
||||||
|
commentsLabel->setText(tr("&Comments:"));
|
||||||
|
hashLabel1->setText(tr("Hash:"));
|
||||||
|
|
||||||
|
aIncrement->setText(tr("&Increment number"));
|
||||||
|
aDecrement->setText(tr("&Decrement number"));
|
||||||
|
aRemoveCard->setText(tr("&Remove row"));
|
||||||
|
aSwapCard->setText(tr("Swap card to/from sideboard"));
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
#ifndef DECK_EDITOR_DECK_DOCK_WIDGET_H
|
||||||
|
#define DECK_EDITOR_DECK_DOCK_WIDGET_H
|
||||||
|
|
||||||
|
#include "../../../../deck/custom_line_edit.h"
|
||||||
|
#include "../../../../game/cards/card_database.h"
|
||||||
|
#include "../../../game_logic/key_signals.h"
|
||||||
|
#include "../../../tabs/abstract_tab_deck_editor.h"
|
||||||
|
#include "../visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.h"
|
||||||
|
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QDockWidget>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QTextEdit>
|
||||||
|
#include <QTreeView>
|
||||||
|
|
||||||
|
class DeckListModel;
|
||||||
|
class AbstractTabDeckEditor;
|
||||||
|
class DeckEditorDeckDockWidget : public QDockWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit DeckEditorDeckDockWidget(AbstractTabDeckEditor *parent);
|
||||||
|
DeckListModel *deckModel;
|
||||||
|
QTreeView *deckView;
|
||||||
|
QComboBox *bannerCardComboBox;
|
||||||
|
void createDeckDock();
|
||||||
|
CardInfoPtr getCurrentCard();
|
||||||
|
void retranslateUi();
|
||||||
|
QString getDeckName()
|
||||||
|
{
|
||||||
|
return nameEdit->text();
|
||||||
|
}
|
||||||
|
QString getSimpleDeckName()
|
||||||
|
{
|
||||||
|
return nameEdit->text().simplified();
|
||||||
|
}
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void cleanDeck();
|
||||||
|
void updateBannerCardComboBox();
|
||||||
|
void setDeck(DeckLoader *_deck);
|
||||||
|
DeckLoader *getDeckList();
|
||||||
|
void actIncrement();
|
||||||
|
bool swapCard(const QModelIndex &idx);
|
||||||
|
void actDecrementCard(CardInfoPtr info, QString zoneName);
|
||||||
|
void actDecrementSelection();
|
||||||
|
void actSwapCard();
|
||||||
|
void actRemoveCard();
|
||||||
|
void offsetCountAtIndex(const QModelIndex &idx, int offset);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void deckChanged();
|
||||||
|
void cardChanged(CardInfoPtr _card);
|
||||||
|
|
||||||
|
private:
|
||||||
|
AbstractTabDeckEditor *deckEditor;
|
||||||
|
KeySignals deckViewKeySignals;
|
||||||
|
QLabel *nameLabel;
|
||||||
|
LineEditUnfocusable *nameEdit;
|
||||||
|
QLabel *commentsLabel;
|
||||||
|
QTextEdit *commentsEdit;
|
||||||
|
QLabel *bannerCardLabel;
|
||||||
|
DeckPreviewDeckTagsDisplayWidget *deckTagsDisplayWidget;
|
||||||
|
QLabel *hashLabel1;
|
||||||
|
LineEditUnfocusable *hashLabel;
|
||||||
|
|
||||||
|
QAction *aRemoveCard, *aIncrement, *aDecrement, *aSwapCard;
|
||||||
|
|
||||||
|
void recursiveExpand(const QModelIndex &index);
|
||||||
|
QModelIndexList getSelectedCardNodes() const;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void decklistCustomMenu(QPoint point);
|
||||||
|
void updateCard(QModelIndex, const QModelIndex ¤t);
|
||||||
|
void updateName(const QString &name);
|
||||||
|
void updateComments();
|
||||||
|
void setBannerCard(int);
|
||||||
|
void updateHash();
|
||||||
|
void refreshShortcuts();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DECK_EDITOR_DECK_DOCK_WIDGET_H
|
||||||
|
|
@ -0,0 +1,143 @@
|
||||||
|
#include "deck_editor_filter_dock_widget.h"
|
||||||
|
|
||||||
|
#include "../../../../game/cards/card_database_model.h"
|
||||||
|
#include "../../../../game/filters/filter_builder.h"
|
||||||
|
#include "../../../../game/filters/filter_tree_model.h"
|
||||||
|
#include "../../../../settings/cache_settings.h"
|
||||||
|
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <QMenu>
|
||||||
|
#include <QToolButton>
|
||||||
|
|
||||||
|
DeckEditorFilterDockWidget::DeckEditorFilterDockWidget(AbstractTabDeckEditor *parent)
|
||||||
|
: QDockWidget(parent), deckEditor(parent)
|
||||||
|
{
|
||||||
|
setObjectName("filterDock");
|
||||||
|
|
||||||
|
setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable);
|
||||||
|
|
||||||
|
createFiltersDock();
|
||||||
|
retranslateUi();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorFilterDockWidget::createFiltersDock()
|
||||||
|
{
|
||||||
|
filterModel = new FilterTreeModel();
|
||||||
|
filterModel->setObjectName("filterModel");
|
||||||
|
deckEditor->filterTreeChanged(filterModel->filterTree());
|
||||||
|
filterView = new QTreeView;
|
||||||
|
filterView->setObjectName("filterView");
|
||||||
|
filterView->setModel(filterModel);
|
||||||
|
filterView->setUniformRowHeights(true);
|
||||||
|
filterView->setHeaderHidden(true);
|
||||||
|
filterView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
|
filterView->installEventFilter(&filterViewKeySignals);
|
||||||
|
connect(filterModel, SIGNAL(layoutChanged()), filterView, SLOT(expandAll()));
|
||||||
|
connect(filterView, SIGNAL(customContextMenuRequested(const QPoint &)), this,
|
||||||
|
SLOT(filterViewCustomContextMenu(const QPoint &)));
|
||||||
|
connect(&filterViewKeySignals, SIGNAL(onDelete()), this, SLOT(actClearFilterOne()));
|
||||||
|
|
||||||
|
auto *filterBuilder = new FilterBuilder;
|
||||||
|
filterBuilder->setObjectName("filterBuilder");
|
||||||
|
connect(filterBuilder, SIGNAL(add(const CardFilter *)), filterModel, SLOT(addFilter(const CardFilter *)));
|
||||||
|
|
||||||
|
aClearFilterOne = new QAction(QString(), this);
|
||||||
|
aClearFilterOne->setIcon(QPixmap("theme:icons/decrement"));
|
||||||
|
connect(aClearFilterOne, SIGNAL(triggered()), this, SLOT(actClearFilterOne()));
|
||||||
|
|
||||||
|
aClearFilterAll = new QAction(QString(), this);
|
||||||
|
aClearFilterAll->setIcon(QPixmap("theme:icons/clearsearch"));
|
||||||
|
connect(aClearFilterAll, SIGNAL(triggered()), this, SLOT(actClearFilterAll()));
|
||||||
|
|
||||||
|
auto *filterDelOne = new QToolButton();
|
||||||
|
filterDelOne->setObjectName("filterDelOne");
|
||||||
|
filterDelOne->setDefaultAction(aClearFilterOne);
|
||||||
|
filterDelOne->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||||
|
|
||||||
|
auto *filterDelAll = new QToolButton();
|
||||||
|
filterDelAll->setObjectName("filterDelAll");
|
||||||
|
filterDelAll->setDefaultAction(aClearFilterAll);
|
||||||
|
filterDelAll->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||||
|
|
||||||
|
auto *filterLayout = new QGridLayout;
|
||||||
|
filterLayout->setObjectName("filterLayout");
|
||||||
|
filterLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
filterLayout->addWidget(filterBuilder, 0, 0, 1, 3);
|
||||||
|
filterLayout->addWidget(filterView, 1, 0, 1, 3);
|
||||||
|
filterLayout->addWidget(filterDelOne, 2, 0, 1, 1);
|
||||||
|
filterLayout->addWidget(filterDelAll, 2, 2, 1, 1);
|
||||||
|
|
||||||
|
filterBox = new QWidget();
|
||||||
|
filterBox->setObjectName("filterBox");
|
||||||
|
filterBox->setLayout(filterLayout);
|
||||||
|
|
||||||
|
auto *filterFrame = new QVBoxLayout;
|
||||||
|
filterFrame->setObjectName("filterFrame");
|
||||||
|
filterFrame->addWidget(filterBox);
|
||||||
|
|
||||||
|
auto *filterDockContents = new QWidget(this);
|
||||||
|
filterDockContents->setObjectName("filterDockContents");
|
||||||
|
filterDockContents->setLayout(filterFrame);
|
||||||
|
setWidget(filterDockContents);
|
||||||
|
|
||||||
|
installEventFilter(deckEditor);
|
||||||
|
connect(this, &QDockWidget::topLevelChanged, deckEditor, &AbstractTabDeckEditor::dockTopLevelChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorFilterDockWidget::filterViewCustomContextMenu(const QPoint &point)
|
||||||
|
{
|
||||||
|
QMenu menu;
|
||||||
|
QAction *action;
|
||||||
|
QModelIndex idx;
|
||||||
|
|
||||||
|
idx = filterView->indexAt(point);
|
||||||
|
if (!idx.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
action = menu.addAction(QString("delete"));
|
||||||
|
action->setData(point);
|
||||||
|
connect(&menu, SIGNAL(triggered(QAction *)), this, SLOT(filterRemove(QAction *)));
|
||||||
|
menu.exec(filterView->mapToGlobal(point));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorFilterDockWidget::filterRemove(QAction *action)
|
||||||
|
{
|
||||||
|
QPoint point;
|
||||||
|
QModelIndex idx;
|
||||||
|
|
||||||
|
point = action->data().toPoint();
|
||||||
|
idx = filterView->indexAt(point);
|
||||||
|
if (!idx.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
filterModel->removeRow(idx.row(), idx.parent());
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorFilterDockWidget::actClearFilterAll()
|
||||||
|
{
|
||||||
|
emit clearAllDatabaseFilters();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorFilterDockWidget::actClearFilterOne()
|
||||||
|
{
|
||||||
|
QModelIndexList selIndexes = filterView->selectionModel()->selectedIndexes();
|
||||||
|
for (QModelIndex idx : selIndexes) {
|
||||||
|
filterModel->removeRow(idx.row(), idx.parent());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorFilterDockWidget::refreshShortcuts()
|
||||||
|
{
|
||||||
|
ShortcutsSettings &shortcuts = SettingsCache::instance().shortcuts();
|
||||||
|
|
||||||
|
aClearFilterAll->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aClearFilterAll"));
|
||||||
|
aClearFilterOne->setShortcuts(shortcuts.getShortcut("TabDeckEditor/aClearFilterOne"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorFilterDockWidget::retranslateUi()
|
||||||
|
{
|
||||||
|
setWindowTitle(tr("Filters"));
|
||||||
|
|
||||||
|
aClearFilterAll->setText(tr("&Clear all filters"));
|
||||||
|
aClearFilterOne->setText(tr("Delete selected"));
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
#ifndef DECK_EDITOR_FILTER_DOCK_WIDGET_H
|
||||||
|
#define DECK_EDITOR_FILTER_DOCK_WIDGET_H
|
||||||
|
|
||||||
|
#include "../../../game_logic/key_signals.h"
|
||||||
|
#include "../../../tabs/abstract_tab_deck_editor.h"
|
||||||
|
|
||||||
|
#include <QDockWidget>
|
||||||
|
#include <QTreeView>
|
||||||
|
|
||||||
|
class FilterTreeModel;
|
||||||
|
class AbstractTabDeckEditor;
|
||||||
|
class DeckEditorFilterDockWidget : public QDockWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit DeckEditorFilterDockWidget(AbstractTabDeckEditor *parent);
|
||||||
|
void createFiltersDock();
|
||||||
|
void retranslateUi();
|
||||||
|
QAction *aClearFilterAll, *aClearFilterOne;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void clearAllDatabaseFilters();
|
||||||
|
|
||||||
|
private:
|
||||||
|
AbstractTabDeckEditor *deckEditor;
|
||||||
|
FilterTreeModel *filterModel;
|
||||||
|
QTreeView *filterView;
|
||||||
|
KeySignals filterViewKeySignals;
|
||||||
|
QWidget *filterBox;
|
||||||
|
|
||||||
|
void filterRemove(QAction *action);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void filterViewCustomContextMenu(const QPoint &point);
|
||||||
|
void actClearFilterAll();
|
||||||
|
void actClearFilterOne();
|
||||||
|
void refreshShortcuts();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DECK_EDITOR_FILTER_DOCK_WIDGET_H
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
#include "deck_editor_printing_selector_dock_widget.h"
|
||||||
|
|
||||||
|
#include "../../../tabs/abstract_tab_deck_editor.h"
|
||||||
|
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
DeckEditorPrintingSelectorDockWidget::DeckEditorPrintingSelectorDockWidget(AbstractTabDeckEditor *parent)
|
||||||
|
: QDockWidget(parent), deckEditor(parent)
|
||||||
|
{
|
||||||
|
setObjectName("printingSelectorDock");
|
||||||
|
|
||||||
|
setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
|
||||||
|
setFeatures(QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable);
|
||||||
|
setFloating(false);
|
||||||
|
|
||||||
|
createPrintingSelectorDock();
|
||||||
|
|
||||||
|
retranslateUi();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorPrintingSelectorDockWidget::createPrintingSelectorDock()
|
||||||
|
{
|
||||||
|
printingSelector = new PrintingSelector(this, deckEditor);
|
||||||
|
printingSelector->setObjectName("printingSelector");
|
||||||
|
auto *printingSelectorFrame = new QVBoxLayout;
|
||||||
|
printingSelectorFrame->setObjectName("printingSelectorFrame");
|
||||||
|
printingSelectorFrame->addWidget(printingSelector);
|
||||||
|
|
||||||
|
auto *printingSelectorDockContents = new QWidget();
|
||||||
|
printingSelectorDockContents->setObjectName("printingSelectorDockContents");
|
||||||
|
printingSelectorDockContents->setLayout(printingSelectorFrame);
|
||||||
|
setWidget(printingSelectorDockContents);
|
||||||
|
|
||||||
|
installEventFilter(deckEditor);
|
||||||
|
connect(this, &QDockWidget::topLevelChanged, deckEditor, &AbstractTabDeckEditor::dockTopLevelChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeckEditorPrintingSelectorDockWidget::retranslateUi()
|
||||||
|
{
|
||||||
|
setWindowTitle(tr("Printing Selector"));
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef DECK_EDITOR_PRINTING_SELECTOR_DOCK_WIDGET_H
|
||||||
|
#define DECK_EDITOR_PRINTING_SELECTOR_DOCK_WIDGET_H
|
||||||
|
|
||||||
|
#include "../../../tabs/abstract_tab_deck_editor.h"
|
||||||
|
#include "../printing_selector/printing_selector.h"
|
||||||
|
|
||||||
|
#include <QDockWidget>
|
||||||
|
|
||||||
|
class TabDeckEditor;
|
||||||
|
class DeckEditorPrintingSelectorDockWidget : public QDockWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit DeckEditorPrintingSelectorDockWidget(AbstractTabDeckEditor *parent);
|
||||||
|
void createPrintingSelectorDock();
|
||||||
|
void retranslateUi();
|
||||||
|
PrintingSelector *printingSelector;
|
||||||
|
|
||||||
|
private:
|
||||||
|
AbstractTabDeckEditor *deckEditor;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DECK_EDITOR_PRINTING_SELECTOR_DOCK_WIDGET_H
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
* @param setInfoForCard The set information for the card.
|
* @param setInfoForCard The set information for the card.
|
||||||
*/
|
*/
|
||||||
AllZonesCardAmountWidget::AllZonesCardAmountWidget(QWidget *parent,
|
AllZonesCardAmountWidget::AllZonesCardAmountWidget(QWidget *parent,
|
||||||
TabDeckEditor *deckEditor,
|
AbstractTabDeckEditor *deckEditor,
|
||||||
DeckListModel *deckModel,
|
DeckListModel *deckModel,
|
||||||
QTreeView *deckView,
|
QTreeView *deckView,
|
||||||
QSlider *cardSizeSlider,
|
QSlider *cardSizeSlider,
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ class AllZonesCardAmountWidget : public QWidget
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit AllZonesCardAmountWidget(QWidget *parent,
|
explicit AllZonesCardAmountWidget(QWidget *parent,
|
||||||
TabDeckEditor *deckEditor,
|
AbstractTabDeckEditor *deckEditor,
|
||||||
DeckListModel *deckModel,
|
DeckListModel *deckModel,
|
||||||
QTreeView *deckView,
|
QTreeView *deckView,
|
||||||
QSlider *cardSizeSlider,
|
QSlider *cardSizeSlider,
|
||||||
|
|
@ -31,7 +31,7 @@ public slots:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QVBoxLayout *layout;
|
QVBoxLayout *layout;
|
||||||
TabDeckEditor *deckEditor;
|
AbstractTabDeckEditor *deckEditor;
|
||||||
DeckListModel *deckModel;
|
DeckListModel *deckModel;
|
||||||
QTreeView *deckView;
|
QTreeView *deckView;
|
||||||
QSlider *cardSizeSlider;
|
QSlider *cardSizeSlider;
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* @param zoneName The zone name (e.g., DECK_ZONE_MAIN or DECK_ZONE_SIDE).
|
* @param zoneName The zone name (e.g., DECK_ZONE_MAIN or DECK_ZONE_SIDE).
|
||||||
*/
|
*/
|
||||||
CardAmountWidget::CardAmountWidget(QWidget *parent,
|
CardAmountWidget::CardAmountWidget(QWidget *parent,
|
||||||
TabDeckEditor *deckEditor,
|
AbstractTabDeckEditor *deckEditor,
|
||||||
DeckListModel *deckModel,
|
DeckListModel *deckModel,
|
||||||
QTreeView *deckView,
|
QTreeView *deckView,
|
||||||
QSlider *cardSizeSlider,
|
QSlider *cardSizeSlider,
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
#include "../../../../deck/deck_list_model.h"
|
#include "../../../../deck/deck_list_model.h"
|
||||||
#include "../../../../deck/deck_loader.h"
|
#include "../../../../deck/deck_loader.h"
|
||||||
#include "../../../../game/cards/card_database.h"
|
#include "../../../../game/cards/card_database.h"
|
||||||
#include "../../../tabs/tab_deck_editor.h"
|
#include "../../../tabs/abstract_tab_deck_editor.h"
|
||||||
#include "../general/display/dynamic_font_size_push_button.h"
|
#include "../general/display/dynamic_font_size_push_button.h"
|
||||||
|
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
|
|
@ -18,7 +18,7 @@ class CardAmountWidget : public QWidget
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit CardAmountWidget(QWidget *parent,
|
explicit CardAmountWidget(QWidget *parent,
|
||||||
TabDeckEditor *deckEditor,
|
AbstractTabDeckEditor *deckEditor,
|
||||||
DeckListModel *deckModel,
|
DeckListModel *deckModel,
|
||||||
QTreeView *deckView,
|
QTreeView *deckView,
|
||||||
QSlider *cardSizeSlider,
|
QSlider *cardSizeSlider,
|
||||||
|
|
@ -36,7 +36,7 @@ protected:
|
||||||
void showEvent(QShowEvent *event) override;
|
void showEvent(QShowEvent *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TabDeckEditor *deckEditor;
|
AbstractTabDeckEditor *deckEditor;
|
||||||
DeckListModel *deckModel;
|
DeckListModel *deckModel;
|
||||||
QTreeView *deckView;
|
QTreeView *deckView;
|
||||||
QSlider *cardSizeSlider;
|
QSlider *cardSizeSlider;
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,9 @@
|
||||||
* @param deckModel The DeckListModel instance that provides data for the deck's contents.
|
* @param deckModel The DeckListModel instance that provides data for the deck's contents.
|
||||||
* @param deckView The QTreeView instance used to display the deck and its contents.
|
* @param deckView The QTreeView instance used to display the deck and its contents.
|
||||||
*/
|
*/
|
||||||
PrintingSelector::PrintingSelector(QWidget *parent,
|
PrintingSelector::PrintingSelector(QWidget *parent, AbstractTabDeckEditor *_deckEditor)
|
||||||
TabDeckEditor *deckEditor,
|
: QWidget(parent), deckEditor(_deckEditor), deckModel(deckEditor->deckDockWidget->deckModel),
|
||||||
DeckListModel *deckModel,
|
deckView(deckEditor->deckDockWidget->deckView)
|
||||||
QTreeView *deckView)
|
|
||||||
: QWidget(parent), deckEditor(deckEditor), deckModel(deckModel), deckView(deckView)
|
|
||||||
{
|
{
|
||||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
layout = new QVBoxLayout(this);
|
layout = new QVBoxLayout(this);
|
||||||
|
|
|
||||||
|
|
@ -19,13 +19,13 @@ class PrintingSelectorCardSearchWidget;
|
||||||
class PrintingSelectorCardSelectionWidget;
|
class PrintingSelectorCardSelectionWidget;
|
||||||
class PrintingSelectorCardSortingWidget;
|
class PrintingSelectorCardSortingWidget;
|
||||||
class PrintingSelectorViewOptionsWidget;
|
class PrintingSelectorViewOptionsWidget;
|
||||||
class TabDeckEditor;
|
class AbstractTabDeckEditor;
|
||||||
class PrintingSelector : public QWidget
|
class PrintingSelector : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PrintingSelector(QWidget *parent, TabDeckEditor *deckEditor, DeckListModel *deckModel, QTreeView *deckView);
|
PrintingSelector(QWidget *parent, AbstractTabDeckEditor *deckEditor);
|
||||||
|
|
||||||
void setCard(const CardInfoPtr &newCard, const QString &_currentZone);
|
void setCard(const CardInfoPtr &newCard, const QString &_currentZone);
|
||||||
void getAllSetsForCurrentCard();
|
void getAllSetsForCurrentCard();
|
||||||
|
|
@ -51,7 +51,7 @@ private:
|
||||||
FlowWidget *flowWidget;
|
FlowWidget *flowWidget;
|
||||||
CardSizeWidget *cardSizeWidget;
|
CardSizeWidget *cardSizeWidget;
|
||||||
PrintingSelectorCardSelectionWidget *cardSelectionBar;
|
PrintingSelectorCardSelectionWidget *cardSelectionBar;
|
||||||
TabDeckEditor *deckEditor;
|
AbstractTabDeckEditor *deckEditor;
|
||||||
DeckListModel *deckModel;
|
DeckListModel *deckModel;
|
||||||
QTreeView *deckView;
|
QTreeView *deckView;
|
||||||
CardInfoPtr selectedCard;
|
CardInfoPtr selectedCard;
|
||||||
|
|
|
||||||
|
|
@ -19,16 +19,16 @@
|
||||||
* display.
|
* display.
|
||||||
*
|
*
|
||||||
* @param parent The parent widget for this display.
|
* @param parent The parent widget for this display.
|
||||||
* @param deckEditor The TabDeckEditor instance for deck management.
|
* @param _deckEditor The TabDeckEditor instance for deck management.
|
||||||
* @param deckModel The DeckListModel instance providing deck data.
|
* @param _deckModel The DeckListModel instance providing deck data.
|
||||||
* @param deckView The QTreeView instance displaying the deck.
|
* @param _deckView The QTreeView instance displaying the deck.
|
||||||
* @param cardSizeSlider The slider controlling the size of the displayed card.
|
* @param _cardSizeSlider The slider controlling the size of the displayed card.
|
||||||
* @param rootCard The root card object, representing the card to be displayed.
|
* @param _rootCard The root card object, representing the card to be displayed.
|
||||||
* @param setInfoForCard The set-specific information for the card being displayed.
|
* @param _setInfoForCard The set-specific information for the card being displayed.
|
||||||
* @param currentZone The current zone in which the card is located.
|
* @param _currentZone The current zone in which the card is located.
|
||||||
*/
|
*/
|
||||||
PrintingSelectorCardDisplayWidget::PrintingSelectorCardDisplayWidget(QWidget *parent,
|
PrintingSelectorCardDisplayWidget::PrintingSelectorCardDisplayWidget(QWidget *parent,
|
||||||
TabDeckEditor *_deckEditor,
|
AbstractTabDeckEditor *_deckEditor,
|
||||||
DeckListModel *_deckModel,
|
DeckListModel *_deckModel,
|
||||||
QTreeView *_deckView,
|
QTreeView *_deckView,
|
||||||
QSlider *_cardSizeSlider,
|
QSlider *_cardSizeSlider,
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,13 @@
|
||||||
#ifndef PRINTING_SELECTOR_CARD_DISPLAY_WIDGET_H
|
#ifndef PRINTING_SELECTOR_CARD_DISPLAY_WIDGET_H
|
||||||
#define PRINTING_SELECTOR_CARD_DISPLAY_WIDGET_H
|
#define PRINTING_SELECTOR_CARD_DISPLAY_WIDGET_H
|
||||||
|
|
||||||
#include "../../../../client/ui/widgets/cards/card_info_picture_widget.h"
|
|
||||||
#include "../../../../deck/deck_list_model.h"
|
#include "../../../../deck/deck_list_model.h"
|
||||||
#include "../../../../game/cards/card_database.h"
|
#include "../../../../game/cards/card_database.h"
|
||||||
#include "../../../tabs/tab_deck_editor.h"
|
#include "../../../tabs/abstract_tab_deck_editor.h"
|
||||||
#include "printing_selector_card_overlay_widget.h"
|
#include "printing_selector_card_overlay_widget.h"
|
||||||
#include "set_name_and_collectors_number_display_widget.h"
|
#include "set_name_and_collectors_number_display_widget.h"
|
||||||
|
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QTreeView>
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
class PrintingSelectorCardDisplayWidget : public QWidget
|
class PrintingSelectorCardDisplayWidget : public QWidget
|
||||||
|
|
@ -19,7 +16,7 @@ class PrintingSelectorCardDisplayWidget : public QWidget
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PrintingSelectorCardDisplayWidget(QWidget *parent,
|
PrintingSelectorCardDisplayWidget(QWidget *parent,
|
||||||
TabDeckEditor *_deckEditor,
|
AbstractTabDeckEditor *_deckEditor,
|
||||||
DeckListModel *_deckModel,
|
DeckListModel *_deckModel,
|
||||||
QTreeView *_deckView,
|
QTreeView *_deckView,
|
||||||
QSlider *_cardSizeSlider,
|
QSlider *_cardSizeSlider,
|
||||||
|
|
@ -36,7 +33,7 @@ signals:
|
||||||
private:
|
private:
|
||||||
QVBoxLayout *layout;
|
QVBoxLayout *layout;
|
||||||
SetNameAndCollectorsNumberDisplayWidget *setNameAndCollectorsNumberDisplayWidget;
|
SetNameAndCollectorsNumberDisplayWidget *setNameAndCollectorsNumberDisplayWidget;
|
||||||
TabDeckEditor *deckEditor;
|
AbstractTabDeckEditor *deckEditor;
|
||||||
DeckListModel *deckModel;
|
DeckListModel *deckModel;
|
||||||
QTreeView *deckView;
|
QTreeView *deckView;
|
||||||
QSlider *cardSizeSlider;
|
QSlider *cardSizeSlider;
|
||||||
|
|
|
||||||
|
|
@ -17,15 +17,15 @@
|
||||||
* as a widget that displays the card amounts in different zones (mainboard, sideboard, etc.).
|
* as a widget that displays the card amounts in different zones (mainboard, sideboard, etc.).
|
||||||
*
|
*
|
||||||
* @param parent The parent widget for this overlay.
|
* @param parent The parent widget for this overlay.
|
||||||
* @param deckEditor The TabDeckEditor instance for deck management.
|
* @param _deckEditor The TabDeckEditor instance for deck management.
|
||||||
* @param deckModel The DeckListModel instance providing deck data.
|
* @param _deckModel The DeckListModel instance providing deck data.
|
||||||
* @param deckView The QTreeView instance displaying the deck.
|
* @param _deckView The QTreeView instance displaying the deck.
|
||||||
* @param cardSizeSlider The slider controlling the size of the card.
|
* @param _cardSizeSlider The slider controlling the size of the card.
|
||||||
* @param rootCard The root card object that contains information about the card.
|
* @param _rootCard The root card object that contains information about the card.
|
||||||
* @param setInfoForCard The set-specific information for the card being displayed.
|
* @param _setInfoForCard The set-specific information for the card being displayed.
|
||||||
*/
|
*/
|
||||||
PrintingSelectorCardOverlayWidget::PrintingSelectorCardOverlayWidget(QWidget *parent,
|
PrintingSelectorCardOverlayWidget::PrintingSelectorCardOverlayWidget(QWidget *parent,
|
||||||
TabDeckEditor *_deckEditor,
|
AbstractTabDeckEditor *_deckEditor,
|
||||||
DeckListModel *_deckModel,
|
DeckListModel *_deckModel,
|
||||||
QTreeView *_deckView,
|
QTreeView *_deckView,
|
||||||
QSlider *_cardSizeSlider,
|
QSlider *_cardSizeSlider,
|
||||||
|
|
@ -120,7 +120,7 @@ void PrintingSelectorCardOverlayWidget::enterEvent(QEvent *event)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
QWidget::enterEvent(event);
|
QWidget::enterEvent(event);
|
||||||
deckEditor->updateCardInfo(setCard);
|
deckEditor->updateCard(setCard);
|
||||||
|
|
||||||
// Check if either mainboard or sideboard amount is greater than 0
|
// Check if either mainboard or sideboard amount is greater than 0
|
||||||
if (allZonesCardAmountWidget->getMainboardAmount() > 0 || allZonesCardAmountWidget->getSideboardAmount() > 0) {
|
if (allZonesCardAmountWidget->getMainboardAmount() > 0 || allZonesCardAmountWidget->getSideboardAmount() > 0) {
|
||||||
|
|
@ -199,7 +199,7 @@ void PrintingSelectorCardOverlayWidget::customMenu(QPoint point)
|
||||||
const QString &relatedCardName = rel->getName();
|
const QString &relatedCardName = rel->getName();
|
||||||
QAction *relatedCard = relatedMenu->addAction(relatedCardName);
|
QAction *relatedCard = relatedMenu->addAction(relatedCardName);
|
||||||
connect(relatedCard, &QAction::triggered, deckEditor, [this, relatedCardName] {
|
connect(relatedCard, &QAction::triggered, deckEditor, [this, relatedCardName] {
|
||||||
deckEditor->updateCardInfo(CardDatabaseManager::getInstance()->getCard(relatedCardName));
|
deckEditor->updateCard(CardDatabaseManager::getInstance()->getCard(relatedCardName));
|
||||||
deckEditor->showPrintingSelector();
|
deckEditor->showPrintingSelector();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
#include "../../../../client/ui/widgets/cards/card_info_picture_widget.h"
|
#include "../../../../client/ui/widgets/cards/card_info_picture_widget.h"
|
||||||
#include "../../../../deck/deck_list_model.h"
|
#include "../../../../deck/deck_list_model.h"
|
||||||
#include "../../../../game/cards/card_database.h"
|
#include "../../../../game/cards/card_database.h"
|
||||||
#include "../../../tabs/tab_deck_editor.h"
|
#include "../../../tabs/abstract_tab_deck_editor.h"
|
||||||
#include "all_zones_card_amount_widget.h"
|
#include "all_zones_card_amount_widget.h"
|
||||||
#include "card_amount_widget.h"
|
#include "card_amount_widget.h"
|
||||||
#include "set_name_and_collectors_number_display_widget.h"
|
#include "set_name_and_collectors_number_display_widget.h"
|
||||||
|
|
@ -15,7 +15,7 @@ class PrintingSelectorCardOverlayWidget : public QWidget
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PrintingSelectorCardOverlayWidget(QWidget *parent,
|
explicit PrintingSelectorCardOverlayWidget(QWidget *parent,
|
||||||
TabDeckEditor *_deckEditor,
|
AbstractTabDeckEditor *_deckEditor,
|
||||||
DeckListModel *_deckModel,
|
DeckListModel *_deckModel,
|
||||||
QTreeView *_deckView,
|
QTreeView *_deckView,
|
||||||
QSlider *_cardSizeSlider,
|
QSlider *_cardSizeSlider,
|
||||||
|
|
@ -39,7 +39,7 @@ signals:
|
||||||
private:
|
private:
|
||||||
CardInfoPictureWidget *cardInfoPicture;
|
CardInfoPictureWidget *cardInfoPicture;
|
||||||
AllZonesCardAmountWidget *allZonesCardAmountWidget;
|
AllZonesCardAmountWidget *allZonesCardAmountWidget;
|
||||||
TabDeckEditor *deckEditor;
|
AbstractTabDeckEditor *deckEditor;
|
||||||
DeckListModel *deckModel;
|
DeckListModel *deckModel;
|
||||||
QTreeView *deckView;
|
QTreeView *deckView;
|
||||||
QSlider *cardSizeSlider;
|
QSlider *cardSizeSlider;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef DECK_PREVIEW_DECK_TAGS_DISPLAY_WIDGET_H
|
#ifndef DECK_PREVIEW_DECK_TAGS_DISPLAY_WIDGET_H
|
||||||
#define DECK_PREVIEW_DECK_TAGS_DISPLAY_WIDGET_H
|
#define DECK_PREVIEW_DECK_TAGS_DISPLAY_WIDGET_H
|
||||||
|
|
||||||
#include "../../../../tabs/tab_deck_editor.h"
|
#include "../../../../../deck/deck_loader.h"
|
||||||
#include "deck_preview_widget.h"
|
#include "deck_preview_widget.h"
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include "deck_preview_tag_addition_widget.h"
|
#include "deck_preview_tag_addition_widget.h"
|
||||||
|
|
||||||
#include "../../../../../settings/cache_settings.h"
|
#include "../../../../../settings/cache_settings.h"
|
||||||
|
#include "../../../../tabs/abstract_tab_deck_editor.h"
|
||||||
#include "deck_preview_tag_dialog.h"
|
#include "deck_preview_tag_dialog.h"
|
||||||
|
|
||||||
#include <QFontMetrics>
|
#include <QFontMetrics>
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@
|
||||||
#include "deck_preview_color_identity_widget.h"
|
#include "deck_preview_color_identity_widget.h"
|
||||||
#include "deck_preview_deck_tags_display_widget.h"
|
#include "deck_preview_deck_tags_display_widget.h"
|
||||||
|
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QEvent>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,11 @@ public:
|
||||||
return lastRemoteDeckId;
|
return lastRemoteDeckId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool hasNotBeenLoaded() const
|
||||||
|
{
|
||||||
|
return getLastFileName().isEmpty() && getLastRemoteDeckId() == -1;
|
||||||
|
}
|
||||||
|
|
||||||
void clearSetNamesAndNumbers();
|
void clearSetNamesAndNumbers();
|
||||||
static FileFormat getFormatFromName(const QString &fileName);
|
static FileFormat getFormatFromName(const QString &fileName);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue