[TabDeckEditor] Refactor card database view into own class (#6967)

* rename method

* [TabDeckEditor] Refactor card database view into own class

* fix include guard

* directly get key signals for eventFilter

* fix includes
This commit is contained in:
RickyRister 2026-06-05 10:20:46 -07:00 committed by GitHub
parent 0da2ac4087
commit c14a008080
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 392 additions and 252 deletions

View file

@ -181,6 +181,7 @@ set(cockatrice_SOURCES
src/interface/widgets/deck_analytics/analyzer_modules/mana_distribution/mana_distribution_single_display_widget.cpp
src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_total_widget.cpp
src/interface/widgets/deck_analytics/analyzer_modules/mana_curve/mana_curve_category_widget.cpp
src/interface/widgets/deck_editor/card_database_view.cpp
src/interface/widgets/deck_editor/deck_list_history_manager_widget.cpp
src/interface/widgets/deck_editor/deck_editor_card_database_dock_widget.cpp
src/interface/widgets/deck_editor/deck_editor_card_info_dock_widget.cpp

View file

@ -0,0 +1,167 @@
#include "card_database_view.h"
#include "../../../client/settings/cache_settings.h"
#include "card_database_display_model.h"
#include "card_database_model.h"
#include <QApplication>
#include <QClipboard>
#include <QHeaderView>
#include <QMenu>
#include <libcockatrice/card/database/card_database_manager.h>
#include <libcockatrice/card/relation/card_relation.h>
#include <libcockatrice/deck_list/tree/inner_deck_list_node.h>
static bool canBeCommander(const CardInfo &cardInfo)
{
return (cardInfo.getCardType().contains("Legendary", Qt::CaseInsensitive) &&
cardInfo.getCardType().contains("Creature", Qt::CaseInsensitive)) ||
cardInfo.getText().contains("can be your commander", Qt::CaseInsensitive);
}
CardDatabaseView::CardDatabaseView(QWidget *parent, CardDatabaseDisplayModel *model)
: QTreeView(parent), databaseDisplayModel(model)
{
// set up object
setUniformRowHeights(true);
setRootIsDecorated(false);
setAlternatingRowColors(true);
setSortingEnabled(true);
sortByColumn(0, Qt::AscendingOrder);
QTreeView::setModel(databaseDisplayModel);
setContextMenuPolicy(Qt::CustomContextMenu);
connect(databaseDisplayModel, &CardDatabaseDisplayModel::modelDirty, this,
&CardDatabaseView::resetSelectionIfEmpty);
connect(this, &QTreeView::customContextMenuRequested, this, &CardDatabaseView::openCustomMenu);
connect(selectionModel(), &QItemSelectionModel::currentRowChanged, this, &CardDatabaseView::updateCard);
connect(this, &QTreeView::doubleClicked, this, &CardDatabaseView::actDoubleClick);
// layout settings
QByteArray dbHeaderState = SettingsCache::instance().layouts().getDeckEditorDbHeaderState();
if (dbHeaderState.isNull()) {
// first run
setColumnWidth(0, 200);
} else {
header()->restoreState(dbHeaderState);
}
connect(header(), &QHeaderView::geometriesChanged, this, &CardDatabaseView::saveDbHeaderState);
// create key filters
searchKeySignals.setObjectName("searchKeySignals");
connect(&searchKeySignals, &KeySignals::onEnter, this, [this] { addCard(DECK_ZONE_MAIN); });
connect(&searchKeySignals, &KeySignals::onCtrlAltEqual, this, [this] { addCard(DECK_ZONE_MAIN); });
connect(&searchKeySignals, &KeySignals::onCtrlAltRBracket, this, [this] { addCard(DECK_ZONE_SIDE); });
connect(&searchKeySignals, &KeySignals::onCtrlAltMinus, this, [this] { decrementCard(DECK_ZONE_MAIN); });
connect(&searchKeySignals, &KeySignals::onCtrlAltLBracket, this, [this] { decrementCard(DECK_ZONE_SIDE); });
connect(&searchKeySignals, &KeySignals::onCtrlAltEnter, this, [this] { addCard(DECK_ZONE_SIDE); });
connect(&searchKeySignals, &KeySignals::onCtrlEnter, this, [this] { addCard(DECK_ZONE_SIDE); });
connect(&searchKeySignals, &KeySignals::onCtrlC, this, &CardDatabaseView::copyDatabaseCellContents);
}
QString CardDatabaseView::currentCardName() const
{
const QModelIndex currentIndex = selectionModel()->currentIndex();
if (!currentIndex.isValid()) {
return {};
}
return currentIndex.siblingAtColumn(CardDatabaseModel::NameColumn).data().toString();
}
void CardDatabaseView::actDoubleClick()
{
if (QApplication::keyboardModifiers() & Qt::ControlModifier) {
addCard(DECK_ZONE_SIDE);
} else {
addCard(DECK_ZONE_MAIN);
}
}
void CardDatabaseView::addCard(const QString &zoneName)
{
emit cardAdded(currentCardName(), zoneName);
}
void CardDatabaseView::decrementCard(const QString &zoneName)
{
emit cardDecremented(currentCardName(), zoneName);
}
void CardDatabaseView::updateCard(const QModelIndex &current, const QModelIndex & /*previous*/)
{
if (!current.isValid()) {
return;
}
const QString cardName = current.siblingAtColumn(CardDatabaseModel::NameColumn).data().toString();
if (!current.model()->hasChildren(current.siblingAtColumn(CardDatabaseModel::NameColumn))) {
emit cardChanged(cardName);
}
}
void CardDatabaseView::resetSelectionIfEmpty()
{
QModelIndexList sel = selectionModel()->selectedRows();
if (sel.isEmpty() && databaseDisplayModel->rowCount() > 0) {
selectionModel()->setCurrentIndex(databaseDisplayModel->index(0, 0),
QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
}
}
void CardDatabaseView::copyDatabaseCellContents() const
{
auto _data = selectionModel()->currentIndex().data();
QApplication::clipboard()->setText(_data.toString());
}
void CardDatabaseView::saveDbHeaderState()
{
SettingsCache::instance().layouts().setDeckEditorDbHeaderState(header()->saveState());
}
void CardDatabaseView::openCustomMenu(QPoint point)
{
CardInfoPtr card = CardDatabaseManager::query()->getCardInfo(currentCardName());
if (!card) {
return;
}
QMenu menu;
// add to deck and sideboard options
QAction *addToDeck = menu.addAction(tr("Add to Deck"));
QAction *addToSideboard = menu.addAction(tr("Add to Sideboard"));
QAction *selectPrinting = menu.addAction(tr("Select Printing"));
connect(addToDeck, &QAction::triggered, this, [this, card] { emit cardAdded(card->getName(), DECK_ZONE_MAIN); });
connect(addToSideboard, &QAction::triggered, this,
[this, card] { emit cardAdded(card->getName(), DECK_ZONE_SIDE); });
connect(selectPrinting, &QAction::triggered, this, &CardDatabaseView::selectPrintingClicked);
if (canBeCommander(*card)) {
QAction *edhRecCommander = menu.addAction(tr("Show on EDHRec (Commander)"));
connect(edhRecCommander, &QAction::triggered, this, [this, card] { emit edhrecClicked(card, true); });
}
QAction *edhRecCard = menu.addAction(tr("Show on EDHRec (Card)"));
connect(edhRecCard, &QAction::triggered, this, [this, card] { emit edhrecClicked(card, false); });
// filling out the related cards submenu
auto *relatedMenu = new QMenu(tr("Show Related cards"));
menu.addMenu(relatedMenu);
auto relatedCards = card->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, this,
[this, relatedCardName] { emit relatedCardClicked(relatedCardName); });
}
}
menu.exec(mapToGlobal(point));
}

View file

@ -0,0 +1,59 @@
#ifndef COCKATRICE_CARD_DATABASE_VIEW_H
#define COCKATRICE_CARD_DATABASE_VIEW_H
#include "../../key_signals.h"
#include <QTreeView>
#include <libcockatrice/card/card_info.h>
class CardDatabaseModel;
class CardDatabaseDisplayModel;
/**
* @brief The card database table.
*/
class CardDatabaseView : public QTreeView
{
Q_OBJECT
KeySignals searchKeySignals;
CardDatabaseDisplayModel *databaseDisplayModel;
public:
explicit CardDatabaseView(QWidget *parent, CardDatabaseDisplayModel *model);
QString currentCardName() const;
/**
* @brief Get the KeySignals that are connected to this view.
* You can install the KeySignals as an eventFilter to capture keyboard shortcuts for adding and decrementing cards.
*/
KeySignals *getKeySignals()
{
return &searchKeySignals;
}
signals:
void cardChanged(const QString &cardName);
void cardAdded(const QString &cardName, const QString &zoneName);
void cardDecremented(const QString &cardName, const QString &zoneName);
void edhrecClicked(const CardInfoPtr &cardInfo, bool isCommander);
void selectPrintingClicked();
void relatedCardClicked(const QString &relatedCard);
private slots:
void actDoubleClick();
void addCard(const QString &zoneName);
void decrementCard(const QString &zoneName);
void updateCard(const QModelIndex &current, const QModelIndex &);
void resetSelectionIfEmpty();
void copyDatabaseCellContents() const;
void saveDbHeaderState();
void openCustomMenu(QPoint point);
};
#endif // COCKATRICE_CARD_DATABASE_VIEW_H

View file

@ -41,11 +41,6 @@ void DeckEditorCardDatabaseDockWidget::createDatabaseDisplayDock(AbstractTabDeck
&AbstractTabDeckEditor::updateCardInfo);
}
CardDatabase *DeckEditorCardDatabaseDockWidget::getDatabase() const
{
return databaseDisplayWidget->databaseModel->getDatabase();
}
void DeckEditorCardDatabaseDockWidget::retranslateUi()
{
setWindowTitle(tr("Card Database"));

View file

@ -17,7 +17,6 @@ public:
DeckEditorDatabaseDisplayWidget *databaseDisplayWidget;
CardDatabase *getDatabase() const;
void setFilterTree(FilterTree *filterTree);
public slots:

View file

@ -5,24 +5,17 @@
#include "../../../interface/widgets/tabs/abstract_tab_deck_editor.h"
#include "../../../interface/widgets/tabs/tab_supervisor.h"
#include "../../pixel_map_generator.h"
#include "card_database_view.h"
#include <QClipboard>
#include <QHeaderView>
#include <QMenu>
#include <QToolButton>
#include <QTreeView>
#include <libcockatrice/card/database/card_database_manager.h>
#include <libcockatrice/card/relation/card_relation.h>
static bool canBeCommander(const CardInfo &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(QWidget *parent, CardDatabaseModel *databaseModel)
: QWidget(parent), databaseModel(databaseModel)
: QWidget(parent)
{
setObjectName("databaseDisplayWidget");
@ -36,26 +29,10 @@ DeckEditorDatabaseDisplayWidget::DeckEditorDatabaseDisplayWidget(QWidget *parent
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, &SearchLineEdit::textChanged, this, &DeckEditorDatabaseDisplayWidget::updateSearch);
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, [this] { createSearchSyntaxHelpWindow(searchEdit); });
databaseDisplayModel = new CardDatabaseDisplayModel(this);
@ -63,33 +40,23 @@ DeckEditorDatabaseDisplayWidget::DeckEditorDatabaseDisplayWidget(QWidget *parent
databaseDisplayModel->setSourceModel(databaseModel);
databaseDisplayModel->setFilterKeyColumn(0);
databaseView = new QTreeView(this);
databaseView = new CardDatabaseView(this, databaseDisplayModel);
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, &QTreeView::customContextMenuRequested, this,
&DeckEditorDatabaseDisplayWidget::databaseCustomMenu);
connect(databaseView->selectionModel(), &QItemSelectionModel::currentRowChanged, this,
&DeckEditorDatabaseDisplayWidget::updateCard);
connect(databaseView, &QTreeView::doubleClicked, this, &DeckEditorDatabaseDisplayWidget::actAddCard);
QByteArray dbHeaderState = SettingsCache::instance().layouts().getDeckEditorDbHeaderState();
if (dbHeaderState.isNull()) {
// first run
databaseView->setColumnWidth(0, 200);
} else {
databaseView->header()->restoreState(dbHeaderState);
}
connect(databaseView->header(), &QHeaderView::geometriesChanged, this,
&DeckEditorDatabaseDisplayWidget::saveDbHeaderState);
searchEdit->setTreeView(databaseView);
searchEdit->installEventFilter(databaseView->getKeySignals());
connect(searchEdit, &SearchLineEdit::textChanged, databaseDisplayModel, &CardDatabaseDisplayModel::setStringFilter);
connect(databaseView, &CardDatabaseView::cardAdded, this, &DeckEditorDatabaseDisplayWidget::addCard);
connect(databaseView, &CardDatabaseView::cardDecremented, this, &DeckEditorDatabaseDisplayWidget::decrementCard);
connect(databaseView, &CardDatabaseView::cardChanged, this, &DeckEditorDatabaseDisplayWidget::updateCard);
connect(databaseView, &CardDatabaseView::edhrecClicked, this, &DeckEditorDatabaseDisplayWidget::edhrecRequested);
connect(databaseView, &CardDatabaseView::selectPrintingClicked, this,
&DeckEditorDatabaseDisplayWidget::printingSelectorRequested);
connect(databaseView, &CardDatabaseView::relatedCardClicked, this,
&DeckEditorDatabaseDisplayWidget::onRelatedCardClicked);
aAddCard = new QAction(QString(), this);
aAddCard->setIcon(QPixmap("theme:icons/arrow_right_green"));
@ -115,131 +82,39 @@ DeckEditorDatabaseDisplayWidget::DeckEditorDatabaseDisplayWidget(QWidget *parent
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 &current, const QModelIndex & /*previous*/)
{
if (!current.isValid()) {
return;
}
const QString cardName = current.siblingAtColumn(CardDatabaseModel::NameColumn).data().toString();
if (!current.model()->hasChildren(current.siblingAtColumn(CardDatabaseModel::NameColumn))) {
emit cardChanged(CardDatabaseManager::query()->getPreferredCard(cardName));
}
}
void DeckEditorDatabaseDisplayWidget::actAddCard()
{
if (QApplication::keyboardModifiers() & Qt::ControlModifier) {
actAddCardToSideboard();
} else {
actAddCardToMainDeck();
}
}
void DeckEditorDatabaseDisplayWidget::actAddCardToMainDeck()
{
highlightAllSearchEdit();
emit cardAdded(currentCard(), DECK_ZONE_MAIN);
addCard(databaseView->currentCardName(), DECK_ZONE_MAIN);
}
void DeckEditorDatabaseDisplayWidget::actAddCardToSideboard()
{
addCard(databaseView->currentCardName(), DECK_ZONE_SIDE);
}
void DeckEditorDatabaseDisplayWidget::addCard(const QString &cardName, const QString &zoneName)
{
highlightAllSearchEdit();
emit cardAdded(currentCard(), DECK_ZONE_SIDE);
ExactCard exactCard = CardDatabaseManager::query()->getPreferredCard(cardName);
emit cardAdded(exactCard, zoneName);
}
void DeckEditorDatabaseDisplayWidget::actDecrementCardFromMainDeck()
void DeckEditorDatabaseDisplayWidget::decrementCard(const QString &cardName, const QString &zoneName)
{
emit cardDecremented(currentCard(), DECK_ZONE_MAIN);
ExactCard exactCard = CardDatabaseManager::query()->getPreferredCard(cardName);
emit cardDecremented(exactCard, zoneName);
}
void DeckEditorDatabaseDisplayWidget::actDecrementCardFromSideboard()
void DeckEditorDatabaseDisplayWidget::updateCard(const QString &cardName)
{
emit cardDecremented(currentCard(), DECK_ZONE_SIDE);
}
ExactCard DeckEditorDatabaseDisplayWidget::currentCard() const
{
const QModelIndex currentIndex = databaseView->selectionModel()->currentIndex();
if (!currentIndex.isValid()) {
return {};
}
const QString cardName = currentIndex.siblingAtColumn(CardDatabaseModel::NameColumn).data().toString();
return CardDatabaseManager::query()->getPreferredCard(cardName);
}
void DeckEditorDatabaseDisplayWidget::databaseCustomMenu(QPoint point)
{
QMenu menu;
ExactCard card = currentCard();
if (card) {
// 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"));
connect(selectPrinting, &QAction::triggered, this, &DeckEditorDatabaseDisplayWidget::printingSelectorRequested);
if (canBeCommander(card.getInfo())) {
edhRecCommander = menu.addAction(tr("Show on EDHRec (Commander)"));
connect(edhRecCommander, &QAction::triggered, this,
[this, card] { emit edhrecRequested(card.getCardPtr(), true); });
}
edhRecCard = menu.addAction(tr("Show on EDHRec (Card)"));
connect(addToDeck, &QAction::triggered, this, &DeckEditorDatabaseDisplayWidget::actAddCardToMainDeck);
connect(addToSideboard, &QAction::triggered, this, &DeckEditorDatabaseDisplayWidget::actAddCardToSideboard);
connect(edhRecCard, &QAction::triggered, this,
[this, card] { emit edhrecRequested(card.getCardPtr(), false); });
// filling out the related cards submenu
auto *relatedMenu = new QMenu(tr("Show Related cards"));
menu.addMenu(relatedMenu);
auto relatedCards = card.getInfo().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, this, [this, relatedCardName] {
ExactCard card = CardDatabaseManager::query()->guessCard({relatedCardName});
emit cardInfoRequested(card);
});
}
}
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());
ExactCard exactCard = CardDatabaseManager::query()->getPreferredCard(cardName);
emit cardChanged(exactCard);
}
void DeckEditorDatabaseDisplayWidget::setFilterTree(FilterTree *filterTree)
@ -256,4 +131,10 @@ void DeckEditorDatabaseDisplayWidget::retranslateUi()
void DeckEditorDatabaseDisplayWidget::highlightAllSearchEdit()
{
searchEdit->setSelection(0, searchEdit->text().length());
}
void DeckEditorDatabaseDisplayWidget::onRelatedCardClicked(const QString &relatedCard)
{
ExactCard exactCard = CardDatabaseManager::query()->guessCard({relatedCard});
emit cardInfoRequested(exactCard);
}

View file

@ -9,7 +9,6 @@
#define DECK_EDITOR_DATABASE_DISPLAY_WIDGET_H
#include "../../../interface/widgets/tabs/abstract_tab_deck_editor.h"
#include "../../key_signals.h"
#include "../utility/custom_line_edit.h"
#include <QHBoxLayout>
@ -17,34 +16,31 @@
#include <libcockatrice/models/database/card_database_display_model.h>
#include <libcockatrice/models/database/card_database_model.h>
class CardDatabaseView;
class AbstractTabDeckEditor;
class DeckEditorDatabaseDisplayWidget : public QWidget
{
Q_OBJECT
public:
explicit DeckEditorDatabaseDisplayWidget(QWidget *parent, CardDatabaseModel *databaseModel);
CardDatabaseModel *databaseModel;
CardDatabaseDisplayModel *databaseDisplayModel;
QTreeView *getDatabaseView()
CardDatabaseView *getDatabaseView() const
{
return databaseView;
}
public slots:
ExactCard currentCard() const;
void setFilterTree(FilterTree *filterTree);
void clearAllDatabaseFilters();
void updateSearch(const QString &search);
void updateCard(const QModelIndex &current, const QModelIndex &);
void actAddCard();
void actAddCardToMainDeck();
void actAddCardToSideboard();
void actDecrementCardFromMainDeck();
void actDecrementCardFromSideboard();
void databaseCustomMenu(QPoint point);
void copyDatabaseCellContents();
void addCard(const QString &cardName, const QString &zoneName);
void decrementCard(const QString &cardName, const QString &zoneName);
void updateCard(const QString &cardName);
signals:
void cardAdded(const ExactCard &card, const QString &zoneName);
@ -56,8 +52,8 @@ signals:
void cardInfoRequested(const ExactCard &card);
private:
KeySignals searchKeySignals;
QTreeView *databaseView;
CardDatabaseDisplayModel *databaseDisplayModel;
CardDatabaseView *databaseView;
QHBoxLayout *searchLayout;
SearchLineEdit *searchEdit;
QAction *aAddCard, *aAddCardToSideboard;
@ -68,7 +64,8 @@ private:
private slots:
void retranslateUi();
void saveDbHeaderState();
void onRelatedCardClicked(const QString &relatedCard);
};
#endif // DECK_EDITOR_DATABASE_DISPLAY_WIDGET_H

View file

@ -1,14 +1,19 @@
#include "tab_visual_database_display.h"
#include "tab_deck_editor.h"
#include "tab_supervisor.h"
#include <libcockatrice/card/database/card_database_manager.h>
TabVisualDatabaseDisplay::TabVisualDatabaseDisplay(TabSupervisor *_tabSupervisor) : Tab(_tabSupervisor)
{
deckEditor = new TabDeckEditor(_tabSupervisor);
deckEditor->setHidden(true);
visualDatabaseDisplayWidget = new VisualDatabaseDisplayWidget(
this, deckEditor, deckEditor->cardDatabaseDockWidget->databaseDisplayWidget->databaseModel,
deckEditor->cardDatabaseDockWidget->databaseDisplayWidget->databaseDisplayModel);
auto databaseModel = new CardDatabaseModel(CardDatabaseManager::getInstance(), true, this);
databaseModel->setObjectName("databaseModel");
visualDatabaseDisplayWidget = new VisualDatabaseDisplayWidget(this, databaseModel);
connect(visualDatabaseDisplayWidget, &VisualDatabaseDisplayWidget::edhrecRequested, this,
&TabVisualDatabaseDisplay::openEdhrecTab);
setCentralWidget(visualDatabaseDisplayWidget);
@ -18,3 +23,8 @@ TabVisualDatabaseDisplay::TabVisualDatabaseDisplay(TabSupervisor *_tabSupervisor
void TabVisualDatabaseDisplay::retranslateUi()
{
}
void TabVisualDatabaseDisplay::openEdhrecTab(const CardInfoPtr &info, bool isCommander) const
{
getTabSupervisor()->addEdhrecTab(info, isCommander);
}

View file

@ -15,9 +15,11 @@ class TabVisualDatabaseDisplay : public Tab
Q_OBJECT
private:
TabDeckEditor *deckEditor;
VisualDatabaseDisplayWidget *visualDatabaseDisplayWidget;
private slots:
void openEdhrecTab(const CardInfoPtr &info, bool isCommander) const;
public:
TabVisualDatabaseDisplay(TabSupervisor *_tabSupervisor);
void retranslateUi() override;

View file

@ -1,6 +1,7 @@
#include "tab_deck_editor_visual.h"
#include "../../../../client/settings/cache_settings.h"
#include "../../cards/card_info_display_widget.h"
#include "../../deck_editor/deck_state_manager.h"
#include "../../filters/filter_builder.h"
#include "../../interface/pixel_map_generator.h"
@ -25,6 +26,7 @@
#include <QTimer>
#include <QTreeView>
#include <QVBoxLayout>
#include <libcockatrice/card/database/card_database_manager.h>
#include <libcockatrice/models/deck_list/deck_list_model.h>
#include <libcockatrice/protocol/pb/command_deck_upload.pb.h>
#include <libcockatrice/protocol/pending_command.h>
@ -63,9 +65,10 @@ void TabDeckEditorVisual::createCentralFrame()
centralFrame = new QVBoxLayout;
centralWidget->setLayout(centralFrame);
tabContainer = new TabDeckEditorVisualTabWidget(
centralWidget, this, deckStateManager->getModel(), cardDatabaseDockWidget->databaseDisplayWidget->databaseModel,
cardDatabaseDockWidget->databaseDisplayWidget->databaseDisplayModel);
auto databaseModel = new CardDatabaseModel(CardDatabaseManager::getInstance(), true, this);
databaseModel->setObjectName("databaseModel");
tabContainer = new TabDeckEditorVisualTabWidget(centralWidget, this, deckStateManager->getModel(), databaseModel);
connect(tabContainer, &TabDeckEditorVisualTabWidget::cardChanged, this,
&TabDeckEditorVisual::changeModelIndexAndCardInfo);
@ -76,6 +79,13 @@ void TabDeckEditorVisual::createCentralFrame()
connect(tabContainer, &TabDeckEditorVisualTabWidget::cardClickedDatabaseDisplay, this,
&TabDeckEditorVisual::processDatabaseCardClick);
connect(tabContainer, &TabDeckEditorVisualTabWidget::cardAdded, this, &TabDeckEditorVisual::addCard);
connect(tabContainer, &TabDeckEditorVisualTabWidget::cardDecremented, this, &TabDeckEditorVisual::decrementCard);
connect(tabContainer, &TabDeckEditorVisualTabWidget::edhrecRequested, this, &TabDeckEditorVisual::openEdhrecTab);
connect(tabContainer, &TabDeckEditorVisualTabWidget::printingSelectorRequested, this,
&TabDeckEditorVisual::showPrintingSelector);
connect(tabContainer, &TabDeckEditorVisualTabWidget::cardInfoRequested, this, &TabDeckEditorVisual::updateCardInfo);
centralFrame->addWidget(tabContainer);
setCentralWidget(centralWidget);
setDockOptions(QMainWindow::AnimatedDocks | QMainWindow::AllowNestedDocks | QMainWindow::AllowTabbedDocks);

View file

@ -9,7 +9,6 @@
* @param _deckEditor Pointer to the associated deck editor.
* @param _deckModel Pointer to the deck list model.
* @param _cardDatabaseModel Pointer to the card database model.
* @param _cardDatabaseDisplayModel Pointer to the card database display model.
*
* Initializes all sub-widgets (visual deck view, database display, deck analytics,
* sample hand) and sets up the tab layout and signal connections.
@ -17,10 +16,8 @@
TabDeckEditorVisualTabWidget::TabDeckEditorVisualTabWidget(QWidget *parent,
AbstractTabDeckEditor *_deckEditor,
DeckListModel *_deckModel,
CardDatabaseModel *_cardDatabaseModel,
CardDatabaseDisplayModel *_cardDatabaseDisplayModel)
: QTabWidget(parent), deckEditor(_deckEditor), deckModel(_deckModel), cardDatabaseModel(_cardDatabaseModel),
cardDatabaseDisplayModel(_cardDatabaseDisplayModel)
CardDatabaseModel *_cardDatabaseModel)
: QTabWidget(parent), deckEditor(_deckEditor), deckModel(_deckModel), cardDatabaseModel(_cardDatabaseModel)
{
this->setTabsClosable(true); // Enable tab closing
connect(this, &QTabWidget::tabCloseRequested, this, &TabDeckEditorVisualTabWidget::handleTabClose);
@ -37,13 +34,22 @@ TabDeckEditorVisualTabWidget::TabDeckEditorVisualTabWidget(QWidget *parent,
connect(visualDeckView, &VisualDeckEditorWidget::cardAdditionRequested, this,
&TabDeckEditorVisualTabWidget::actAddCard);
visualDatabaseDisplay =
new VisualDatabaseDisplayWidget(this, deckEditor, _cardDatabaseModel, _cardDatabaseDisplayModel, deckModel);
visualDatabaseDisplay = new VisualDatabaseDisplayWidget(this, _cardDatabaseModel, deckModel);
visualDatabaseDisplay->setObjectName("visualDatabaseView");
connect(visualDatabaseDisplay, &VisualDatabaseDisplayWidget::cardHoveredDatabaseDisplay, this,
&TabDeckEditorVisualTabWidget::onCardChangedDatabaseDisplay);
connect(visualDatabaseDisplay, &VisualDatabaseDisplayWidget::cardClickedDatabaseDisplay, this,
&TabDeckEditorVisualTabWidget::onCardClickedDatabaseDisplay);
connect(visualDatabaseDisplay, &VisualDatabaseDisplayWidget::cardAdded, this,
&TabDeckEditorVisualTabWidget::cardAdded);
connect(visualDatabaseDisplay, &VisualDatabaseDisplayWidget::cardDecremented, this,
&TabDeckEditorVisualTabWidget::cardDecremented);
connect(visualDatabaseDisplay, &VisualDatabaseDisplayWidget::edhrecRequested, this,
&TabDeckEditorVisualTabWidget::edhrecRequested);
connect(visualDatabaseDisplay, &VisualDatabaseDisplayWidget::printingSelectorRequested, this,
&TabDeckEditorVisualTabWidget::printingSelectorRequested);
connect(visualDatabaseDisplay, &VisualDatabaseDisplayWidget::cardInfoRequested, this,
&TabDeckEditorVisualTabWidget::cardInfoRequested);
statsAnalyzer = new DeckListStatisticsAnalyzer(this, deckModel);
statsAnalyzer->analyze();

View file

@ -55,13 +55,11 @@ public:
* @param _deckEditor Pointer to the deck editor instance.
* @param _deckModel Deck list model.
* @param _cardDatabaseModel Card database model.
* @param _cardDatabaseDisplayModel Database display model.
*/
explicit TabDeckEditorVisualTabWidget(QWidget *parent,
AbstractTabDeckEditor *_deckEditor,
DeckListModel *_deckModel,
CardDatabaseModel *_cardDatabaseModel,
CardDatabaseDisplayModel *_cardDatabaseDisplayModel);
CardDatabaseModel *_cardDatabaseModel);
/** @brief Add a new tab with a widget and title. */
void addNewTab(QWidget *widget, const QString &title);
@ -119,12 +117,17 @@ signals:
void cardClicked(QMouseEvent *event, const ExactCard &card, const QString &zoneName);
void cardClickedDatabaseDisplay(QMouseEvent *event, const ExactCard &card);
void cardAdded(const ExactCard &card, const QString &zoneName);
void cardDecremented(const ExactCard &card, const QString &zoneName);
void edhrecRequested(const CardInfoPtr &cardInfo, bool isCommander);
void printingSelectorRequested();
void cardInfoRequested(const ExactCard &cardName);
private:
QVBoxLayout *layout; ///< Layout for tabs and controls.
AbstractTabDeckEditor *deckEditor; ///< Reference to the deck editor.
DeckListModel *deckModel; ///< Deck list model.
CardDatabaseModel *cardDatabaseModel; ///< Card database model.
CardDatabaseDisplayModel *cardDatabaseDisplayModel; ///< Card database display model.
QVBoxLayout *layout; ///< Layout for tabs and controls.
AbstractTabDeckEditor *deckEditor; ///< Reference to the deck editor.
DeckListModel *deckModel; ///< Deck list model.
CardDatabaseModel *cardDatabaseModel; ///< Card database model.
private slots:
/**

View file

@ -1,5 +1,6 @@
#include "visual_database_display_filter_toolbar_widget.h"
#include "../deck_editor/card_database_view.h"
#include "visual_database_display_widget.h"
#include <QGroupBox>

View file

@ -5,7 +5,7 @@
#include "../../../filters/syntax_help.h"
#include "../../pixel_map_generator.h"
#include "../cards/card_info_picture_with_text_overlay_widget.h"
#include "../quick_settings/settings_button_widget.h"
#include "../deck_editor/card_database_view.h"
#include "../utility/custom_line_edit.h"
#include "visual_database_display_color_filter_widget.h"
#include "visual_database_display_filter_save_load_widget.h"
@ -23,18 +23,21 @@
#include <utility>
VisualDatabaseDisplayWidget::VisualDatabaseDisplayWidget(QWidget *parent,
AbstractTabDeckEditor *_deckEditor,
CardDatabaseModel *database_model,
CardDatabaseDisplayModel *database_display_model,
DeckListModel *deckListModel)
: QWidget(parent), deckEditor(_deckEditor), databaseModel(database_model),
databaseDisplayModel(database_display_model)
: QWidget(parent)
{
debounceTimer = new QTimer(this);
debounceTimer->setSingleShot(true); // Ensure it only fires once after the timeout
connect(debounceTimer, &QTimer::timeout, this, &VisualDatabaseDisplayWidget::onSearchModelChanged);
// Create display model
databaseDisplayModel = new CardDatabaseDisplayModel(this);
databaseDisplayModel->setObjectName("databaseDisplayModel");
databaseDisplayModel->setSourceModel(database_model);
databaseDisplayModel->setFilterKeyColumn(0);
cards = new QList<ExactCard>;
connect(databaseDisplayModel, &CardDatabaseDisplayModel::modelDirty, this,
&VisualDatabaseDisplayWidget::modelDirty);
@ -61,7 +64,6 @@ VisualDatabaseDisplayWidget::VisualDatabaseDisplayWidget(QWidget *parent,
searchEdit->addAction(loadColorAdjustedPixmap("theme:icons/search"), QLineEdit::LeadingPosition);
auto help = searchEdit->addAction(QPixmap("theme:icons/info"), QLineEdit::TrailingPosition);
connect(help, &QAction::triggered, this, [this] { createSearchSyntaxHelpWindow(searchEdit); });
searchEdit->installEventFilter(&searchKeySignals);
setFocusProxy(searchEdit);
setFocusPolicy(Qt::ClickFocus);
@ -76,37 +78,25 @@ VisualDatabaseDisplayWidget::VisualDatabaseDisplayWidget(QWidget *parent,
filterModel = new FilterTreeModel();
filterModel->setObjectName("filterModel");
searchKeySignals.setObjectName("searchKeySignals");
connect(searchEdit, &SearchLineEdit::textChanged, this, &VisualDatabaseDisplayWidget::updateSearch);
connect(searchEdit, &SearchLineEdit::textChanged, databaseDisplayModel, &CardDatabaseDisplayModel::setStringFilter);
DeckEditorDatabaseDisplayWidget *databaseDisplayWidget = deckEditor->cardDatabaseDockWidget->databaseDisplayWidget;
connect(&searchKeySignals, &KeySignals::onEnter, databaseDisplayWidget,
&DeckEditorDatabaseDisplayWidget::actAddCardToMainDeck);
connect(&searchKeySignals, &KeySignals::onCtrlAltEqual, databaseDisplayWidget,
&DeckEditorDatabaseDisplayWidget::actAddCardToMainDeck);
connect(&searchKeySignals, &KeySignals::onCtrlAltRBracket, databaseDisplayWidget,
&DeckEditorDatabaseDisplayWidget::actAddCardToSideboard);
connect(&searchKeySignals, &KeySignals::onCtrlAltMinus, databaseDisplayWidget,
&DeckEditorDatabaseDisplayWidget::actDecrementCardFromMainDeck);
connect(&searchKeySignals, &KeySignals::onCtrlAltLBracket, databaseDisplayWidget,
&DeckEditorDatabaseDisplayWidget::actDecrementCardFromSideboard);
connect(&searchKeySignals, &KeySignals::onCtrlAltEnter, databaseDisplayWidget,
&DeckEditorDatabaseDisplayWidget::actAddCardToSideboard);
connect(&searchKeySignals, &KeySignals::onCtrlEnter, databaseDisplayWidget,
&DeckEditorDatabaseDisplayWidget::actAddCardToSideboard);
connect(&searchKeySignals, &KeySignals::onCtrlC, databaseDisplayWidget,
&DeckEditorDatabaseDisplayWidget::copyDatabaseCellContents);
connect(help, &QAction::triggered, this, [this] { createSearchSyntaxHelpWindow(searchEdit); });
connect(databaseDisplayWidget, &DeckEditorDatabaseDisplayWidget::cardAdded, this,
&VisualDatabaseDisplayWidget::highlightAllSearchEdit);
databaseView = databaseDisplayWidget->getDatabaseView();
databaseView = new CardDatabaseView(this, databaseDisplayModel);
databaseView->setObjectName("databaseView");
databaseView->setFocusProxy(searchEdit);
databaseView->setItemDelegate(nullptr);
databaseView->setVisible(false);
searchEdit->setTreeView(databaseView);
searchEdit->installEventFilter(databaseView->getKeySignals());
connect(databaseView, &CardDatabaseView::cardChanged, this, &VisualDatabaseDisplayWidget::onSelectedCardChanged);
connect(databaseView, &CardDatabaseView::cardAdded, this, &VisualDatabaseDisplayWidget::actAddCard);
connect(databaseView, &CardDatabaseView::cardDecremented, this, &VisualDatabaseDisplayWidget::actDecrementCard);
connect(databaseView, &CardDatabaseView::edhrecClicked, this, &VisualDatabaseDisplayWidget::edhrecRequested);
connect(databaseView, &CardDatabaseView::selectPrintingClicked, this,
&VisualDatabaseDisplayWidget::printingSelectorRequested);
connect(databaseView, &CardDatabaseView::relatedCardClicked, this,
&VisualDatabaseDisplayWidget::onRelatedCardClicked);
colorFilterWidget = new VisualDatabaseDisplayColorFilterWidget(this, filterModel);
@ -225,7 +215,7 @@ void VisualDatabaseDisplayWidget::onHover(const ExactCard &hoveredCard)
emit cardHoveredDatabaseDisplay(hoveredCard);
}
void VisualDatabaseDisplayWidget::addCard(const ExactCard &cardToAdd)
void VisualDatabaseDisplayWidget::addCardToDisplay(const ExactCard &cardToAdd)
{
cards->append(cardToAdd);
auto *display = new CardInfoPictureWithTextOverlayWidget(flowWidget, false);
@ -237,16 +227,6 @@ void VisualDatabaseDisplayWidget::addCard(const ExactCard &cardToAdd)
connect(cardSizeWidget->getSlider(), &QSlider::valueChanged, display, &CardInfoPictureWidget::setScaleFactor);
}
void VisualDatabaseDisplayWidget::updateSearch(const QString &search) const
{
databaseDisplayModel->setStringFilter(search);
QModelIndexList sel = databaseView->selectionModel()->selectedRows();
if (sel.isEmpty() && databaseDisplayModel->rowCount()) {
databaseView->selectionModel()->setCurrentIndex(databaseDisplayModel->index(0, 0),
QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
}
}
bool VisualDatabaseDisplayWidget::isVisualDisplayMode() const
{
return !displayModeButton->isChecked();
@ -268,6 +248,30 @@ void VisualDatabaseDisplayWidget::onSearchModelChanged()
}
}
void VisualDatabaseDisplayWidget::onSelectedCardChanged(const QString &cardName)
{
emit cardHoveredDatabaseDisplay(CardDatabaseManager::query()->getPreferredCard(cardName));
}
void VisualDatabaseDisplayWidget::actAddCard(const QString &cardName, const QString &zoneName)
{
highlightAllSearchEdit();
ExactCard exactCard = CardDatabaseManager::query()->getPreferredCard(cardName);
emit cardAdded(exactCard, zoneName);
}
void VisualDatabaseDisplayWidget::actDecrementCard(const QString &cardName, const QString &zoneName)
{
ExactCard exactCard = CardDatabaseManager::query()->getPreferredCard(cardName);
emit cardDecremented(exactCard, zoneName);
}
void VisualDatabaseDisplayWidget::onRelatedCardClicked(const QString &relatedCard)
{
ExactCard exactCard = CardDatabaseManager::query()->guessCard({relatedCard});
emit cardInfoRequested(exactCard);
}
bool VisualDatabaseDisplayWidget::nearEndOfPage() const
{
if (!flowWidget->isVisible()) {
@ -334,12 +338,12 @@ void VisualDatabaseDisplayWidget::loadPage(int start, int end)
for (const CardFilter *setFilter : setFilters) {
if (setMap.contains(setFilter->term())) {
for (PrintingInfo printing : setMap[setFilter->term()]) {
addCard(ExactCard(info, printing));
addCardToDisplay(ExactCard(info, printing));
}
}
}
} else {
addCard(CardDatabaseManager::query()->getPreferredCard(info));
addCardToDisplay(CardDatabaseManager::query()->getPreferredCard(info));
}
} else {
qCDebug(VisualDatabaseDisplayLog) << "Card not found in database!";

View file

@ -34,9 +34,7 @@ class VisualDatabaseDisplayWidget : public QWidget
public:
explicit VisualDatabaseDisplayWidget(QWidget *parent,
AbstractTabDeckEditor *deckEditor,
CardDatabaseModel *database_model,
CardDatabaseDisplayModel *database_display_model,
DeckListModel *deckListModel = nullptr);
void retranslateUi();
@ -53,7 +51,7 @@ public:
return databaseDisplayModel;
}
QTreeView *getDatabaseView()
CardDatabaseView *getDatabaseView()
{
return databaseView;
}
@ -75,16 +73,26 @@ signals:
void cardClickedDatabaseDisplay(QMouseEvent *event, const ExactCard &card);
void cardHoveredDatabaseDisplay(const ExactCard &hoveredCard);
void cardAdded(const ExactCard &card, const QString &zoneName);
void cardDecremented(const ExactCard &card, const QString &zoneName);
void edhrecRequested(const CardInfoPtr &cardInfo, bool isCommander);
void printingSelectorRequested();
void cardInfoRequested(const ExactCard &cardName);
protected slots:
void initialize();
void onClick(QMouseEvent *event, const ExactCard &card);
void onHover(const ExactCard &hoveredCard);
void addCard(const ExactCard &cardToAdd);
void addCardToDisplay(const ExactCard &cardToAdd);
void databaseDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
void modelDirty() const;
void updateSearch(const QString &search) const;
void onDisplayModeChanged(bool checked);
void onSelectedCardChanged(const QString &cardName);
void actAddCard(const QString &cardName, const QString &zoneName);
void actDecrementCard(const QString &cardName, const QString &zoneName);
void onRelatedCardClicked(const QString &relatedCard);
private:
FlowWidget *searchContainer;
SearchLineEdit *searchEdit;
@ -96,11 +104,8 @@ private:
QToolButton *clearFilterWidget;
VisualDatabaseDisplayFilterToolbarWidget *filterContainer;
KeySignals searchKeySignals;
AbstractTabDeckEditor *deckEditor;
CardDatabaseModel *databaseModel;
CardDatabaseDisplayModel *databaseDisplayModel;
QTreeView *databaseView;
CardDatabaseView *databaseView;
QList<ExactCard> *cards;
QVBoxLayout *mainLayout;
QScrollArea *scrollArea;