mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-06-10 16:24:45 -07:00
* move message_log_widget to game * move files * update headers * fix cmakelists * oracle fixes * split implementation out to cpp * fix recursive import * fix main file * format
This commit is contained in:
parent
f484c98152
commit
17dcaf9afa
337 changed files with 728 additions and 721 deletions
|
|
@ -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(const ExactCard &_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(const ExactCard &_card);
|
||||
};
|
||||
|
||||
#endif // DECK_EDITOR_CARD_INFO_DOCK_WIDGET_H
|
||||
|
|
@ -0,0 +1,258 @@
|
|||
#include "deck_editor_database_display_widget.h"
|
||||
|
||||
#include "../../../database/card_database_manager.h"
|
||||
#include "../../../filters/syntax_help.h"
|
||||
#include "../../../settings/cache_settings.h"
|
||||
#include "../../../tabs/abstract_tab_deck_editor.h"
|
||||
#include "../../../tabs/tab_supervisor.h"
|
||||
#include "../../pixel_map_generator.h"
|
||||
|
||||
#include <QClipboard>
|
||||
#include <QFile>
|
||||
#include <QHeaderView>
|
||||
#include <QMenu>
|
||||
#include <QTextBrowser>
|
||||
#include <QToolButton>
|
||||
#include <QTreeView>
|
||||
|
||||
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(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, &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); });
|
||||
|
||||
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, &QTreeView::customContextMenuRequested, this,
|
||||
&DeckEditorDatabaseDisplayWidget::databaseCustomMenu);
|
||||
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(), &QHeaderView::geometriesChanged, this,
|
||||
&DeckEditorDatabaseDisplayWidget::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();
|
||||
|
||||
if (!current.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!current.model()->hasChildren(current.sibling(current.row(), 0))) {
|
||||
emit cardChanged(getCardOrPinnedPrinting(cardName));
|
||||
}
|
||||
}
|
||||
|
||||
void DeckEditorDatabaseDisplayWidget::actAddCardToMainDeck()
|
||||
{
|
||||
emit addCardToMainDeck(currentCard());
|
||||
}
|
||||
|
||||
void DeckEditorDatabaseDisplayWidget::actAddCardToSideboard()
|
||||
{
|
||||
emit addCardToSideboard(currentCard());
|
||||
}
|
||||
|
||||
void DeckEditorDatabaseDisplayWidget::actDecrementCardFromMainDeck()
|
||||
{
|
||||
emit decrementCardFromMainDeck(currentCard());
|
||||
}
|
||||
|
||||
void DeckEditorDatabaseDisplayWidget::actDecrementCardFromSideboard()
|
||||
{
|
||||
emit decrementCardFromSideboard(currentCard());
|
||||
}
|
||||
|
||||
ExactCard DeckEditorDatabaseDisplayWidget::currentCard() const
|
||||
{
|
||||
const QModelIndex currentIndex = databaseView->selectionModel()->currentIndex();
|
||||
if (!currentIndex.isValid()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const QString cardName = currentIndex.sibling(currentIndex.row(), 0).data().toString();
|
||||
|
||||
return getCardOrPinnedPrinting(cardName);
|
||||
}
|
||||
|
||||
ExactCard DeckEditorDatabaseDisplayWidget::getCardOrPinnedPrinting(QString cardName) const
|
||||
{
|
||||
const auto &cardProviderId = SettingsCache::instance().cardOverrides().getCardPreferenceOverride(cardName);
|
||||
|
||||
ExactCard card = CardDatabaseManager::getInstance()->getCard({cardName});
|
||||
|
||||
if (cardProviderId != "") {
|
||||
return ExactCard(card.getCardPtr(),
|
||||
CardDatabaseManager::getInstance()->getSpecificPrinting({cardName, cardProviderId}));
|
||||
}
|
||||
|
||||
return card;
|
||||
}
|
||||
|
||||
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"));
|
||||
if (canBeCommander(card.getInfo())) {
|
||||
edhRecCommander = menu.addAction(tr("Show on EDHRec (Commander)"));
|
||||
connect(edhRecCommander, &QAction::triggered, this,
|
||||
[this, card] { deckEditor->getTabSupervisor()->addEdhrecTab(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(selectPrinting, &QAction::triggered, this, [this, card] { deckEditor->showPrintingSelector(); });
|
||||
connect(edhRecCard, &QAction::triggered, this,
|
||||
[this, card] { deckEditor->getTabSupervisor()->addEdhrecTab(card.getCardPtr()); });
|
||||
|
||||
// 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, 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::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 "../../../database/card_database_model.h"
|
||||
#include "../../../deck/custom_line_edit.h"
|
||||
#include "../../../tabs/abstract_tab_deck_editor.h"
|
||||
#include "../../../utility/key_signals.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:
|
||||
ExactCard currentCard() const;
|
||||
ExactCard getCardOrPinnedPrinting(QString cardName) const;
|
||||
void setFilterTree(FilterTree *filterTree);
|
||||
void clearAllDatabaseFilters();
|
||||
|
||||
signals:
|
||||
void addCardToMainDeck(const ExactCard &card);
|
||||
void addCardToSideboard(const ExactCard &card);
|
||||
void decrementCardFromMainDeck(const ExactCard &card);
|
||||
void decrementCardFromSideboard(const ExactCard &card);
|
||||
void cardChanged(const ExactCard &_card);
|
||||
|
||||
private:
|
||||
KeySignals searchKeySignals;
|
||||
QTreeView *databaseView;
|
||||
QHBoxLayout *searchLayout;
|
||||
QAction *aAddCard, *aAddCardToSideboard;
|
||||
QVBoxLayout *centralFrame;
|
||||
QWidget *centralWidget;
|
||||
|
||||
private slots:
|
||||
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,613 @@
|
|||
#include "deck_editor_deck_dock_widget.h"
|
||||
|
||||
#include "../../../database/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, &DeckEditorDeckDockWidget::topLevelChanged, deckEditor, &AbstractTabDeckEditor::dockTopLevelChanged);
|
||||
createDeckDock();
|
||||
}
|
||||
|
||||
void DeckEditorDeckDockWidget::createDeckDock()
|
||||
{
|
||||
deckModel = new DeckListModel(this);
|
||||
deckModel->setObjectName("deckModel");
|
||||
connect(deckModel, &DeckListModel::deckHashChanged, this, &DeckEditorDeckDockWidget::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, &QTreeView::doubleClicked, this, &DeckEditorDeckDockWidget::actSwapCard);
|
||||
connect(deckView, &QTreeView::customContextMenuRequested, this, &DeckEditorDeckDockWidget::decklistCustomMenu);
|
||||
connect(&deckViewKeySignals, &KeySignals::onShiftS, this, &DeckEditorDeckDockWidget::actSwapCard);
|
||||
connect(&deckViewKeySignals, &KeySignals::onEnter, this, &DeckEditorDeckDockWidget::actIncrement);
|
||||
connect(&deckViewKeySignals, &KeySignals::onCtrlAltEqual, this, &DeckEditorDeckDockWidget::actIncrement);
|
||||
connect(&deckViewKeySignals, &KeySignals::onCtrlAltMinus, this, &DeckEditorDeckDockWidget::actDecrementSelection);
|
||||
connect(&deckViewKeySignals, &KeySignals::onShiftRight, this, &DeckEditorDeckDockWidget::actIncrement);
|
||||
connect(&deckViewKeySignals, &KeySignals::onShiftLeft, this, &DeckEditorDeckDockWidget::actDecrementSelection);
|
||||
connect(&deckViewKeySignals, &KeySignals::onDelete, this, &DeckEditorDeckDockWidget::actRemoveCard);
|
||||
|
||||
nameLabel = new QLabel();
|
||||
nameLabel->setObjectName("nameLabel");
|
||||
nameEdit = new LineEditUnfocusable;
|
||||
nameEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
nameEdit->setObjectName("nameEdit");
|
||||
nameLabel->setBuddy(nameEdit);
|
||||
connect(nameEdit, &LineEditUnfocusable::textChanged, this, &DeckEditorDeckDockWidget::updateName);
|
||||
|
||||
quickSettingsWidget = new SettingsButtonWidget(this);
|
||||
|
||||
showBannerCardCheckBox = new QCheckBox();
|
||||
showBannerCardCheckBox->setObjectName("showBannerCardCheckBox");
|
||||
showBannerCardCheckBox->setChecked(SettingsCache::instance().getDeckEditorBannerCardComboBoxVisible());
|
||||
connect(showBannerCardCheckBox, &QCheckBox::QT_STATE_CHANGED, &SettingsCache::instance(),
|
||||
&SettingsCache::setDeckEditorBannerCardComboBoxVisible);
|
||||
connect(&SettingsCache::instance(), &SettingsCache::deckEditorBannerCardComboBoxVisibleChanged, this,
|
||||
&DeckEditorDeckDockWidget::updateShowBannerCardComboBox);
|
||||
|
||||
showTagsWidgetCheckBox = new QCheckBox();
|
||||
showTagsWidgetCheckBox->setObjectName("showTagsWidgetCheckBox");
|
||||
showTagsWidgetCheckBox->setChecked(SettingsCache::instance().getDeckEditorTagsWidgetVisible());
|
||||
connect(showTagsWidgetCheckBox, &QCheckBox::QT_STATE_CHANGED, &SettingsCache::instance(),
|
||||
&SettingsCache::setDeckEditorTagsWidgetVisible);
|
||||
connect(&SettingsCache::instance(), &SettingsCache::deckEditorTagsWidgetVisibleChanged, this,
|
||||
&DeckEditorDeckDockWidget::updateShowTagsWidget);
|
||||
|
||||
quickSettingsWidget->addSettingsWidget(showBannerCardCheckBox);
|
||||
quickSettingsWidget->addSettingsWidget(showTagsWidgetCheckBox);
|
||||
|
||||
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, &QTextEdit::textChanged, this, &DeckEditorDeckDockWidget::updateComments);
|
||||
bannerCardLabel = new QLabel();
|
||||
bannerCardLabel->setObjectName("bannerCardLabel");
|
||||
bannerCardLabel->setText(tr("Banner Card"));
|
||||
bannerCardLabel->setHidden(!SettingsCache::instance().getDeckEditorBannerCardComboBoxVisible());
|
||||
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);
|
||||
bannerCardComboBox->setHidden(!SettingsCache::instance().getDeckEditorBannerCardComboBoxVisible());
|
||||
|
||||
deckTagsDisplayWidget = new DeckPreviewDeckTagsDisplayWidget(this, deckModel->getDeckList());
|
||||
deckTagsDisplayWidget->setHidden(!SettingsCache::instance().getDeckEditorTagsWidgetVisible());
|
||||
|
||||
activeGroupCriteriaLabel = new QLabel(this);
|
||||
|
||||
activeGroupCriteriaComboBox = new QComboBox(this);
|
||||
activeGroupCriteriaComboBox->addItem(tr("Main Type"), DeckListModelGroupCriteria::MAIN_TYPE);
|
||||
activeGroupCriteriaComboBox->addItem(tr("Mana Cost"), DeckListModelGroupCriteria::MANA_COST);
|
||||
activeGroupCriteriaComboBox->addItem(tr("Colors"), DeckListModelGroupCriteria::COLOR);
|
||||
connect(activeGroupCriteriaComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), [this]() {
|
||||
deckModel->setActiveGroupCriteria(
|
||||
static_cast<DeckListModelGroupCriteria>(activeGroupCriteriaComboBox->currentData(Qt::UserRole).toInt()));
|
||||
deckModel->sort(deckView->header()->sortIndicatorSection(), deckView->header()->sortIndicatorOrder());
|
||||
deckView->expandAll();
|
||||
deckView->expandAll();
|
||||
});
|
||||
|
||||
aIncrement = new QAction(QString(), this);
|
||||
aIncrement->setIcon(QPixmap("theme:icons/increment"));
|
||||
connect(aIncrement, &QAction::triggered, this, &DeckEditorDeckDockWidget::actIncrement);
|
||||
auto *tbIncrement = new QToolButton(this);
|
||||
tbIncrement->setDefaultAction(aIncrement);
|
||||
|
||||
aDecrement = new QAction(QString(), this);
|
||||
aDecrement->setIcon(QPixmap("theme:icons/decrement"));
|
||||
connect(aDecrement, &QAction::triggered, this, &DeckEditorDeckDockWidget::actDecrementSelection);
|
||||
auto *tbDecrement = new QToolButton(this);
|
||||
tbDecrement->setDefaultAction(aDecrement);
|
||||
|
||||
aRemoveCard = new QAction(QString(), this);
|
||||
aRemoveCard->setIcon(QPixmap("theme:icons/remove_row"));
|
||||
connect(aRemoveCard, &QAction::triggered, this, &DeckEditorDeckDockWidget::actRemoveCard);
|
||||
auto *tbRemoveCard = new QToolButton(this);
|
||||
tbRemoveCard->setDefaultAction(aRemoveCard);
|
||||
|
||||
aSwapCard = new QAction(QString(), this);
|
||||
aSwapCard->setIcon(QPixmap("theme:icons/swap"));
|
||||
connect(aSwapCard, &QAction::triggered, this, &DeckEditorDeckDockWidget::actSwapCard);
|
||||
auto *tbSwapCard = new QToolButton(this);
|
||||
tbSwapCard->setDefaultAction(aSwapCard);
|
||||
|
||||
auto *upperLayout = new QGridLayout;
|
||||
upperLayout->setObjectName("upperLayout");
|
||||
upperLayout->setContentsMargins(11, 11, 11, 0);
|
||||
|
||||
upperLayout->addWidget(nameLabel, 0, 0);
|
||||
upperLayout->addWidget(nameEdit, 0, 1);
|
||||
upperLayout->addWidget(quickSettingsWidget, 0, 2);
|
||||
|
||||
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);
|
||||
|
||||
upperLayout->addWidget(activeGroupCriteriaLabel, 4, 0);
|
||||
upperLayout->addWidget(activeGroupCriteriaComboBox, 4, 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();
|
||||
}
|
||||
|
||||
ExactCard 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 (ExactCard selectedCard = CardDatabaseManager::getInstance()->getCard({cardName, providerId})) {
|
||||
return selectedCard;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void DeckEditorDeckDockWidget::updateCard(const QModelIndex /*¤t*/, const QModelIndex & /*previous*/)
|
||||
{
|
||||
if (ExactCard card = getCurrentCard()) {
|
||||
emit cardChanged(card);
|
||||
}
|
||||
}
|
||||
|
||||
void DeckEditorDeckDockWidget::updateName(const QString &name)
|
||||
{
|
||||
deckModel->getDeckList()->setName(name);
|
||||
deckEditor->setModified(name.isEmpty());
|
||||
emit nameChanged();
|
||||
emit deckModified();
|
||||
}
|
||||
|
||||
void DeckEditorDeckDockWidget::updateComments()
|
||||
{
|
||||
deckModel->getDeckList()->setComments(commentsEdit->toPlainText());
|
||||
deckEditor->setModified(commentsEdit->toPlainText().isEmpty());
|
||||
emit commentsChanged();
|
||||
emit deckModified();
|
||||
}
|
||||
|
||||
void DeckEditorDeckDockWidget::updateHash()
|
||||
{
|
||||
hashLabel->setText(deckModel->getDeckList()->getDeckHash());
|
||||
emit hashChanged();
|
||||
emit deckModified();
|
||||
}
|
||||
|
||||
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) {
|
||||
if (CardDatabaseManager::getInstance()->getCard(currentCard->toCardRef())) {
|
||||
bannerCardSet.insert({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) {
|
||||
bannerCardComboBox->addItem(pair.first, QVariant::fromValue(pair));
|
||||
}
|
||||
|
||||
// Try to restore the previous selection by finding the currentText
|
||||
int restoredIndex = bannerCardComboBox->findText(currentText);
|
||||
if (restoredIndex != -1) {
|
||||
bannerCardComboBox->setCurrentIndex(restoredIndex);
|
||||
if (deckModel->getDeckList()->getBannerCard().providerId !=
|
||||
bannerCardComboBox->currentData().value<QPair<QString, QString>>().second) {
|
||||
setBannerCard(restoredIndex);
|
||||
}
|
||||
} else {
|
||||
// Add a placeholder "-" and set it as the current selection
|
||||
int bannerIndex = bannerCardComboBox->findText(deckModel->getDeckList()->getBannerCard().name);
|
||||
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 */)
|
||||
{
|
||||
auto [name, id] = bannerCardComboBox->currentData().value<QPair<QString, QString>>();
|
||||
deckModel->getDeckList()->setBannerCard({name, id});
|
||||
deckEditor->setModified(true);
|
||||
emit deckModified();
|
||||
}
|
||||
|
||||
void DeckEditorDeckDockWidget::updateShowBannerCardComboBox(const bool visible)
|
||||
{
|
||||
bannerCardLabel->setHidden(!visible);
|
||||
bannerCardComboBox->setHidden(!visible);
|
||||
}
|
||||
|
||||
void DeckEditorDeckDockWidget::updateShowTagsWidget(const bool visible)
|
||||
{
|
||||
deckTagsDisplayWidget->setHidden(!visible);
|
||||
}
|
||||
|
||||
void DeckEditorDeckDockWidget::syncBannerCardComboBoxSelectionWithDeck()
|
||||
{
|
||||
if (deckModel->getDeckList()->getBannerCard().name == "") {
|
||||
if (bannerCardComboBox->findText("-") != -1) {
|
||||
bannerCardComboBox->setCurrentIndex(bannerCardComboBox->findText("-"));
|
||||
} else {
|
||||
bannerCardComboBox->insertItem(0, "-");
|
||||
bannerCardComboBox->setCurrentIndex(0);
|
||||
}
|
||||
} else {
|
||||
bannerCardComboBox->setCurrentText(deckModel->getDeckList()->getBannerCard().name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the currently active deck for this tab
|
||||
* @param _deck The deck. Takes ownership of the object
|
||||
*/
|
||||
void DeckEditorDeckDockWidget::setDeck(DeckLoader *_deck)
|
||||
{
|
||||
deckModel->setDeckList(_deck);
|
||||
|
||||
nameEdit->setText(deckModel->getDeckList()->getName());
|
||||
commentsEdit->setText(deckModel->getDeckList()->getComments());
|
||||
|
||||
syncBannerCardComboBoxSelectionWithDeck();
|
||||
updateBannerCardComboBox();
|
||||
updateHash();
|
||||
deckModel->sort(deckView->header()->sortIndicatorSection(), deckView->header()->sortIndicatorOrder());
|
||||
deckView->expandAll();
|
||||
deckView->expandAll();
|
||||
|
||||
deckTagsDisplayWidget->connectDeckList(deckModel->getDeckList());
|
||||
|
||||
emit deckChanged();
|
||||
}
|
||||
|
||||
DeckLoader *DeckEditorDeckDockWidget::getDeckList()
|
||||
{
|
||||
return deckModel->getDeckList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the tab to the state for a blank new tab.
|
||||
*/
|
||||
void DeckEditorDeckDockWidget::cleanDeck()
|
||||
{
|
||||
deckModel->cleanList();
|
||||
nameEdit->setText(QString());
|
||||
emit nameChanged();
|
||||
commentsEdit->setText(QString());
|
||||
emit commentsChanged();
|
||||
hashLabel->setText(QString());
|
||||
emit hashChanged();
|
||||
emit deckModified();
|
||||
emit deckChanged();
|
||||
updateBannerCardComboBox();
|
||||
deckTagsDisplayWidget->connectDeckList(deckModel->getDeckList());
|
||||
}
|
||||
|
||||
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 deckModified();
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
ExactCard card = CardDatabaseManager::getInstance()->getCard({cardName, cardProviderID});
|
||||
QModelIndex newCardIndex = card ? deckModel->addCard(card, otherZoneName)
|
||||
// Third argument (true) says create the card no matter what, even if not in DB
|
||||
: deckModel->addPreferredPrintingCard(cardName, otherZoneName, true);
|
||||
recursiveExpand(newCardIndex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DeckEditorDeckDockWidget::actDecrementCard(const ExactCard &card, QString zoneName)
|
||||
{
|
||||
if (!card)
|
||||
return;
|
||||
if (card.getInfo().getIsToken())
|
||||
zoneName = DECK_ZONE_TOKENS;
|
||||
|
||||
QString providerId = card.getPrinting().getUuid();
|
||||
QString collectorNumber = card.getPrinting().getProperty("num");
|
||||
|
||||
QModelIndex idx = deckModel->findCard(card.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 deckModified();
|
||||
}
|
||||
}
|
||||
|
||||
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 deckModified();
|
||||
}
|
||||
|
||||
void DeckEditorDeckDockWidget::decklistCustomMenu(QPoint point)
|
||||
{
|
||||
QMenu menu;
|
||||
|
||||
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:"));
|
||||
quickSettingsWidget->setToolTip(tr("Banner Card/Tags Visibility Settings"));
|
||||
showBannerCardCheckBox->setText(tr("Show banner card selection menu"));
|
||||
showTagsWidgetCheckBox->setText(tr("Show tags selection menu"));
|
||||
commentsLabel->setText(tr("&Comments:"));
|
||||
activeGroupCriteriaLabel->setText(tr("Group by:"));
|
||||
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,94 @@
|
|||
#ifndef DECK_EDITOR_DECK_DOCK_WIDGET_H
|
||||
#define DECK_EDITOR_DECK_DOCK_WIDGET_H
|
||||
|
||||
#include "../../../card/card_info.h"
|
||||
#include "../../../deck/custom_line_edit.h"
|
||||
#include "../../../tabs/abstract_tab_deck_editor.h"
|
||||
#include "../../../utility/key_signals.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();
|
||||
ExactCard 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(const ExactCard &card, QString zoneName);
|
||||
void actDecrementSelection();
|
||||
void actSwapCard();
|
||||
void actRemoveCard();
|
||||
void offsetCountAtIndex(const QModelIndex &idx, int offset);
|
||||
|
||||
signals:
|
||||
void nameChanged();
|
||||
void commentsChanged();
|
||||
void hashChanged();
|
||||
void deckChanged();
|
||||
void deckModified();
|
||||
void cardChanged(const ExactCard &_card);
|
||||
|
||||
private:
|
||||
AbstractTabDeckEditor *deckEditor;
|
||||
KeySignals deckViewKeySignals;
|
||||
QLabel *nameLabel;
|
||||
LineEditUnfocusable *nameEdit;
|
||||
SettingsButtonWidget *quickSettingsWidget;
|
||||
QCheckBox *showBannerCardCheckBox;
|
||||
QCheckBox *showTagsWidgetCheckBox;
|
||||
QLabel *commentsLabel;
|
||||
QTextEdit *commentsEdit;
|
||||
QLabel *bannerCardLabel;
|
||||
DeckPreviewDeckTagsDisplayWidget *deckTagsDisplayWidget;
|
||||
QLabel *hashLabel1;
|
||||
LineEditUnfocusable *hashLabel;
|
||||
QLabel *activeGroupCriteriaLabel;
|
||||
QComboBox *activeGroupCriteriaComboBox;
|
||||
|
||||
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();
|
||||
void updateShowBannerCardComboBox(bool visible);
|
||||
void updateShowTagsWidget(bool visible);
|
||||
void syncBannerCardComboBoxSelectionWithDeck();
|
||||
};
|
||||
|
||||
#endif // DECK_EDITOR_DECK_DOCK_WIDGET_H
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
#include "deck_editor_filter_dock_widget.h"
|
||||
|
||||
#include "../../../database/card_database_model.h"
|
||||
#include "../../../filters/filter_builder.h"
|
||||
#include "../../../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, &FilterTreeModel::layoutChanged, filterView, &QTreeView::expandAll);
|
||||
connect(filterView, &QTreeView::customContextMenuRequested, this,
|
||||
&DeckEditorFilterDockWidget::filterViewCustomContextMenu);
|
||||
connect(&filterViewKeySignals, &KeySignals::onDelete, this, &DeckEditorFilterDockWidget::actClearFilterOne);
|
||||
|
||||
auto *filterBuilder = new FilterBuilder;
|
||||
filterBuilder->setObjectName("filterBuilder");
|
||||
connect(filterBuilder, &FilterBuilder::add, filterModel, &FilterTreeModel::addFilter);
|
||||
|
||||
aClearFilterOne = new QAction(QString(), this);
|
||||
aClearFilterOne->setIcon(QPixmap("theme:icons/decrement"));
|
||||
connect(aClearFilterOne, &QAction::triggered, this, &DeckEditorFilterDockWidget::actClearFilterOne);
|
||||
|
||||
aClearFilterAll = new QAction(QString(), this);
|
||||
aClearFilterAll->setIcon(QPixmap("theme:icons/clearsearch"));
|
||||
connect(aClearFilterAll, &QAction::triggered, this, &DeckEditorFilterDockWidget::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, &QMenu::triggered, this, &DeckEditorFilterDockWidget::filterRemove);
|
||||
menu.exec(filterView->mapToGlobal(point));
|
||||
}
|
||||
|
||||
void DeckEditorFilterDockWidget::filterRemove(const 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,39 @@
|
|||
#ifndef DECK_EDITOR_FILTER_DOCK_WIDGET_H
|
||||
#define DECK_EDITOR_FILTER_DOCK_WIDGET_H
|
||||
|
||||
#include "../../../tabs/abstract_tab_deck_editor.h"
|
||||
#include "../../../utility/key_signals.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;
|
||||
|
||||
private slots:
|
||||
void filterViewCustomContextMenu(const QPoint &point);
|
||||
void filterRemove(const QAction *action);
|
||||
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
|
||||
Loading…
Add table
Add a link
Reference in a new issue