Compare commits

..

2 Commits

Author SHA1 Message Date
tooomm
b413e2bfc6 further references as list 2025-12-21 12:22:13 +01:00
tooomm
aa3e801045 Add xsd scheme information 2025-12-21 12:12:09 +01:00
19 changed files with 154 additions and 167 deletions

View File

@@ -43,23 +43,23 @@ void DeckStatsInterface::queryFinished(QNetworkReply *reply)
deleteLater(); deleteLater();
} }
void DeckStatsInterface::getAnalyzeRequestData(const DeckList &deck, QByteArray &data) void DeckStatsInterface::getAnalyzeRequestData(DeckList *deck, QByteArray *data)
{ {
DeckList deckWithoutTokens; DeckList deckWithoutTokens;
copyDeckWithoutTokens(deck, deckWithoutTokens); copyDeckWithoutTokens(*deck, deckWithoutTokens);
QUrl params; QUrl params;
QUrlQuery urlQuery; QUrlQuery urlQuery;
urlQuery.addQueryItem("deck", deckWithoutTokens.writeToString_Plain()); urlQuery.addQueryItem("deck", deckWithoutTokens.writeToString_Plain());
urlQuery.addQueryItem("decktitle", deck.getName()); urlQuery.addQueryItem("decktitle", deck->getName());
params.setQuery(urlQuery); params.setQuery(urlQuery);
data.append(params.query(QUrl::EncodeReserved).toUtf8()); data->append(params.query(QUrl::EncodeReserved).toUtf8());
} }
void DeckStatsInterface::analyzeDeck(const DeckList &deck) void DeckStatsInterface::analyzeDeck(DeckList *deck)
{ {
QByteArray data; QByteArray data;
getAnalyzeRequestData(deck, data); getAnalyzeRequestData(deck, &data);
QNetworkRequest request(QUrl("https://deckstats.net/index.php")); QNetworkRequest request(QUrl("https://deckstats.net/index.php"));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
@@ -68,7 +68,7 @@ void DeckStatsInterface::analyzeDeck(const DeckList &deck)
manager->post(request, data); manager->post(request, data);
} }
void DeckStatsInterface::copyDeckWithoutTokens(const DeckList &source, DeckList &destination) void DeckStatsInterface::copyDeckWithoutTokens(DeckList &source, DeckList &destination)
{ {
auto copyIfNotAToken = [this, &destination](const auto node, const auto card) { auto copyIfNotAToken = [this, &destination](const auto node, const auto card) {
CardInfoPtr dbCard = cardDatabase.query()->getCardInfo(card->getName()); CardInfoPtr dbCard = cardDatabase.query()->getCardInfo(card->getName());

View File

@@ -28,15 +28,15 @@ private:
* closest non-token card instead. So we construct a new deck which has no * closest non-token card instead. So we construct a new deck which has no
* tokens. * tokens.
*/ */
void copyDeckWithoutTokens(const DeckList &source, DeckList &destination); void copyDeckWithoutTokens(DeckList &source, DeckList &destination);
private slots: private slots:
void queryFinished(QNetworkReply *reply); void queryFinished(QNetworkReply *reply);
void getAnalyzeRequestData(const DeckList &deck, QByteArray &data); void getAnalyzeRequestData(DeckList *deck, QByteArray *data);
public: public:
explicit DeckStatsInterface(CardDatabase &_cardDatabase, QObject *parent = nullptr); explicit DeckStatsInterface(CardDatabase &_cardDatabase, QObject *parent = nullptr);
void analyzeDeck(const DeckList &deck); void analyzeDeck(DeckList *deck);
}; };
#endif #endif

View File

@@ -67,24 +67,24 @@ void TappedOutInterface::queryFinished(QNetworkReply *reply)
deleteLater(); deleteLater();
} }
void TappedOutInterface::getAnalyzeRequestData(const DeckList &deck, QByteArray &data) void TappedOutInterface::getAnalyzeRequestData(DeckList *deck, QByteArray *data)
{ {
DeckList mainboard, sideboard; DeckList mainboard, sideboard;
copyDeckSplitMainAndSide(deck, mainboard, sideboard); copyDeckSplitMainAndSide(*deck, mainboard, sideboard);
QUrl params; QUrl params;
QUrlQuery urlQuery; QUrlQuery urlQuery;
urlQuery.addQueryItem("name", deck.getName()); urlQuery.addQueryItem("name", deck->getName());
urlQuery.addQueryItem("mainboard", mainboard.writeToString_Plain(false, true)); urlQuery.addQueryItem("mainboard", mainboard.writeToString_Plain(false, true));
urlQuery.addQueryItem("sideboard", sideboard.writeToString_Plain(false, true)); urlQuery.addQueryItem("sideboard", sideboard.writeToString_Plain(false, true));
params.setQuery(urlQuery); params.setQuery(urlQuery);
data.append(params.query(QUrl::EncodeReserved).toUtf8()); data->append(params.query(QUrl::EncodeReserved).toUtf8());
} }
void TappedOutInterface::analyzeDeck(const DeckList &deck) void TappedOutInterface::analyzeDeck(DeckList *deck)
{ {
QByteArray data; QByteArray data;
getAnalyzeRequestData(deck, data); getAnalyzeRequestData(deck, &data);
QNetworkRequest request(QUrl("https://tappedout.net/mtg-decks/paste/")); QNetworkRequest request(QUrl("https://tappedout.net/mtg-decks/paste/"));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
@@ -93,7 +93,7 @@ void TappedOutInterface::analyzeDeck(const DeckList &deck)
manager->post(request, data); manager->post(request, data);
} }
void TappedOutInterface::copyDeckSplitMainAndSide(const DeckList &source, DeckList &mainboard, DeckList &sideboard) void TappedOutInterface::copyDeckSplitMainAndSide(DeckList &source, DeckList &mainboard, DeckList &sideboard)
{ {
auto copyMainOrSide = [this, &mainboard, &sideboard](const auto node, const auto card) { auto copyMainOrSide = [this, &mainboard, &sideboard](const auto node, const auto card) {
CardInfoPtr dbCard = cardDatabase.query()->getCardInfo(card->getName()); CardInfoPtr dbCard = cardDatabase.query()->getCardInfo(card->getName());

View File

@@ -30,14 +30,14 @@ private:
QNetworkAccessManager *manager; QNetworkAccessManager *manager;
CardDatabase &cardDatabase; CardDatabase &cardDatabase;
void copyDeckSplitMainAndSide(const DeckList &source, DeckList &mainboard, DeckList &sideboard); void copyDeckSplitMainAndSide(DeckList &source, DeckList &mainboard, DeckList &sideboard);
private slots: private slots:
void queryFinished(QNetworkReply *reply); void queryFinished(QNetworkReply *reply);
void getAnalyzeRequestData(const DeckList &deck, QByteArray &data); void getAnalyzeRequestData(DeckList *deck, QByteArray *data);
public: public:
explicit TappedOutInterface(CardDatabase &_cardDatabase, QObject *parent = nullptr); explicit TappedOutInterface(CardDatabase &_cardDatabase, QObject *parent = nullptr);
void analyzeDeck(const DeckList &deck); void analyzeDeck(DeckList *deck);
}; };
#endif #endif

View File

@@ -287,14 +287,14 @@ static QString toDecklistExportString(const QList<const DecklistCardNode *> &car
* @param deckList The decklist to export * @param deckList The decklist to export
* @param website The website we're sending the deck to * @param website The website we're sending the deck to
*/ */
QString DeckLoader::exportDeckToDecklist(const DeckList &deckList, DecklistWebsite website) QString DeckLoader::exportDeckToDecklist(const DeckList *deckList, DecklistWebsite website)
{ {
// Add the base url // Add the base url
QString deckString = "https://" + getDomainForWebsite(website) + "/?"; QString deckString = "https://" + getDomainForWebsite(website) + "/?";
// export all cards in zone // export all cards in zone
QString mainBoardCards = toDecklistExportString(deckList.getCardNodes({DECK_ZONE_MAIN})); QString mainBoardCards = toDecklistExportString(deckList->getCardNodes({DECK_ZONE_MAIN}));
QString sideBoardCards = toDecklistExportString(deckList.getCardNodes({DECK_ZONE_SIDE})); QString sideBoardCards = toDecklistExportString(deckList->getCardNodes({DECK_ZONE_SIDE}));
// Remove the extra return at the end of the last cards // Remove the extra return at the end of the last cards
mainBoardCards.chop(3); mainBoardCards.chop(3);
@@ -310,7 +310,7 @@ QString DeckLoader::exportDeckToDecklist(const DeckList &deckList, DecklistWebsi
return deckString; return deckString;
} }
void DeckLoader::saveToClipboard(const DeckList &deckList, bool addComments, bool addSetNameAndNumber) void DeckLoader::saveToClipboard(const DeckList *deckList, bool addComments, bool addSetNameAndNumber)
{ {
QString buffer; QString buffer;
QTextStream stream(&buffer); QTextStream stream(&buffer);
@@ -320,7 +320,7 @@ void DeckLoader::saveToClipboard(const DeckList &deckList, bool addComments, boo
} }
bool DeckLoader::saveToStream_Plain(QTextStream &out, bool DeckLoader::saveToStream_Plain(QTextStream &out,
const DeckList &deckList, const DeckList *deckList,
bool addComments, bool addComments,
bool addSetNameAndNumber) bool addSetNameAndNumber)
{ {
@@ -329,7 +329,7 @@ bool DeckLoader::saveToStream_Plain(QTextStream &out,
} }
// loop zones // loop zones
for (auto zoneNode : deckList.getZoneNodes()) { for (auto zoneNode : deckList->getZoneNodes()) {
saveToStream_DeckZone(out, zoneNode, addComments, addSetNameAndNumber); saveToStream_DeckZone(out, zoneNode, addComments, addSetNameAndNumber);
// end of zone // end of zone
@@ -339,14 +339,14 @@ bool DeckLoader::saveToStream_Plain(QTextStream &out,
return true; return true;
} }
void DeckLoader::saveToStream_DeckHeader(QTextStream &out, const DeckList &deckList) void DeckLoader::saveToStream_DeckHeader(QTextStream &out, const DeckList *deckList)
{ {
if (!deckList.getName().isEmpty()) { if (!deckList->getName().isEmpty()) {
out << "// " << deckList.getName() << "\n\n"; out << "// " << deckList->getName() << "\n\n";
} }
if (!deckList.getComments().isEmpty()) { if (!deckList->getComments().isEmpty()) {
QStringList commentRows = deckList.getComments().split(QRegularExpression("\n|\r\n|\r")); QStringList commentRows = deckList->getComments().split(QRegularExpression("\n|\r\n|\r"));
for (const QString &row : commentRows) { for (const QString &row : commentRows) {
out << "// " << row << "\n"; out << "// " << row << "\n";
} }
@@ -434,7 +434,7 @@ void DeckLoader::saveToStream_DeckZoneCards(QTextStream &out,
} }
} }
bool DeckLoader::convertToCockatriceFormat(const QString &fileName) bool DeckLoader::convertToCockatriceFormat(QString fileName)
{ {
// Change the file extension to .cod // Change the file extension to .cod
QFileInfo fileInfo(fileName); QFileInfo fileInfo(fileName);
@@ -543,7 +543,7 @@ void DeckLoader::printDeckListNode(QTextCursor *cursor, const InnerDecklistNode
cursor->movePosition(QTextCursor::End); cursor->movePosition(QTextCursor::End);
} }
void DeckLoader::printDeckList(QPrinter *printer, const DeckList &deckList) void DeckLoader::printDeckList(QPrinter *printer, const DeckList *deckList)
{ {
QTextDocument doc; QTextDocument doc;
@@ -559,14 +559,14 @@ void DeckLoader::printDeckList(QPrinter *printer, const DeckList &deckList)
headerCharFormat.setFontWeight(QFont::Bold); headerCharFormat.setFontWeight(QFont::Bold);
cursor.insertBlock(headerBlockFormat, headerCharFormat); cursor.insertBlock(headerBlockFormat, headerCharFormat);
cursor.insertText(deckList.getName()); cursor.insertText(deckList->getName());
headerCharFormat.setFontPointSize(12); headerCharFormat.setFontPointSize(12);
cursor.insertBlock(headerBlockFormat, headerCharFormat); cursor.insertBlock(headerBlockFormat, headerCharFormat);
cursor.insertText(deckList.getComments()); cursor.insertText(deckList->getComments());
cursor.insertBlock(headerBlockFormat, headerCharFormat); cursor.insertBlock(headerBlockFormat, headerCharFormat);
for (auto zoneNode : deckList.getZoneNodes()) { for (auto zoneNode : deckList->getZoneNodes()) {
cursor.insertHtml("<br><img src=theme:hr.jpg>"); cursor.insertHtml("<br><img src=theme:hr.jpg>");
cursor.insertBlock(headerBlockFormat, headerCharFormat); cursor.insertBlock(headerBlockFormat, headerCharFormat);

View File

@@ -59,11 +59,11 @@ public:
bool saveToFile(const QString &fileName, DeckFileFormat::Format fmt); bool saveToFile(const QString &fileName, DeckFileFormat::Format fmt);
bool updateLastLoadedTimestamp(const QString &fileName, DeckFileFormat::Format fmt); bool updateLastLoadedTimestamp(const QString &fileName, DeckFileFormat::Format fmt);
static QString exportDeckToDecklist(const DeckList &deckList, DecklistWebsite website); static QString exportDeckToDecklist(const DeckList *deckList, DecklistWebsite website);
static void saveToClipboard(const DeckList &deckList, bool addComments = true, bool addSetNameAndNumber = true); static void saveToClipboard(const DeckList *deckList, bool addComments = true, bool addSetNameAndNumber = true);
static bool saveToStream_Plain(QTextStream &out, static bool saveToStream_Plain(QTextStream &out,
const DeckList &deckList, const DeckList *deckList,
bool addComments = true, bool addComments = true,
bool addSetNameAndNumber = true); bool addSetNameAndNumber = true);
@@ -72,9 +72,9 @@ public:
* @param printer The printer to render the decklist to. * @param printer The printer to render the decklist to.
* @param deckList * @param deckList
*/ */
static void printDeckList(QPrinter *printer, const DeckList &deckList); static void printDeckList(QPrinter *printer, const DeckList *deckList);
bool convertToCockatriceFormat(const QString &fileName); bool convertToCockatriceFormat(QString fileName);
LoadedDeck &getDeck() LoadedDeck &getDeck()
{ {
@@ -91,7 +91,7 @@ public:
private: private:
static void printDeckListNode(QTextCursor *cursor, const InnerDecklistNode *node); static void printDeckListNode(QTextCursor *cursor, const InnerDecklistNode *node);
static void saveToStream_DeckHeader(QTextStream &out, const DeckList &deckList); static void saveToStream_DeckHeader(QTextStream &out, const DeckList *deckList);
static void saveToStream_DeckZone(QTextStream &out, static void saveToStream_DeckZone(QTextStream &out,
const InnerDecklistNode *zoneNode, const InnerDecklistNode *zoneNode,

View File

@@ -76,14 +76,14 @@ void DeckEditorDeckDockWidget::createDeckDock()
deckView->setSelectionMode(QAbstractItemView::ExtendedSelection); deckView->setSelectionMode(QAbstractItemView::ExtendedSelection);
connect(deckView->selectionModel(), &QItemSelectionModel::currentRowChanged, this, connect(deckView->selectionModel(), &QItemSelectionModel::currentRowChanged, this,
&DeckEditorDeckDockWidget::updateCard); &DeckEditorDeckDockWidget::updateCard);
connect(deckView, &QTreeView::doubleClicked, this, &DeckEditorDeckDockWidget::actSwapSelection); connect(deckView, &QTreeView::doubleClicked, this, &DeckEditorDeckDockWidget::actSwapCard);
deckView->setContextMenuPolicy(Qt::CustomContextMenu); deckView->setContextMenuPolicy(Qt::CustomContextMenu);
connect(deckView, &QTreeView::customContextMenuRequested, this, &DeckEditorDeckDockWidget::decklistCustomMenu); connect(deckView, &QTreeView::customContextMenuRequested, this, &DeckEditorDeckDockWidget::decklistCustomMenu);
connect(&deckViewKeySignals, &KeySignals::onShiftS, this, &DeckEditorDeckDockWidget::actSwapSelection); connect(&deckViewKeySignals, &KeySignals::onShiftS, this, &DeckEditorDeckDockWidget::actSwapCard);
connect(&deckViewKeySignals, &KeySignals::onEnter, this, &DeckEditorDeckDockWidget::actIncrementSelection); connect(&deckViewKeySignals, &KeySignals::onEnter, this, &DeckEditorDeckDockWidget::actIncrement);
connect(&deckViewKeySignals, &KeySignals::onCtrlAltEqual, this, &DeckEditorDeckDockWidget::actIncrementSelection); connect(&deckViewKeySignals, &KeySignals::onCtrlAltEqual, this, &DeckEditorDeckDockWidget::actIncrement);
connect(&deckViewKeySignals, &KeySignals::onCtrlAltMinus, this, &DeckEditorDeckDockWidget::actDecrementSelection); connect(&deckViewKeySignals, &KeySignals::onCtrlAltMinus, this, &DeckEditorDeckDockWidget::actDecrementSelection);
connect(&deckViewKeySignals, &KeySignals::onShiftRight, this, &DeckEditorDeckDockWidget::actIncrementSelection); connect(&deckViewKeySignals, &KeySignals::onShiftRight, this, &DeckEditorDeckDockWidget::actIncrement);
connect(&deckViewKeySignals, &KeySignals::onShiftLeft, this, &DeckEditorDeckDockWidget::actDecrementSelection); connect(&deckViewKeySignals, &KeySignals::onShiftLeft, this, &DeckEditorDeckDockWidget::actDecrementSelection);
connect(&deckViewKeySignals, &KeySignals::onDelete, this, &DeckEditorDeckDockWidget::actRemoveCard); connect(&deckViewKeySignals, &KeySignals::onDelete, this, &DeckEditorDeckDockWidget::actRemoveCard);
@@ -181,7 +181,7 @@ void DeckEditorDeckDockWidget::createDeckDock()
aIncrement = new QAction(QString(), this); aIncrement = new QAction(QString(), this);
aIncrement->setIcon(QPixmap("theme:icons/increment")); aIncrement->setIcon(QPixmap("theme:icons/increment"));
connect(aIncrement, &QAction::triggered, this, &DeckEditorDeckDockWidget::actIncrementSelection); connect(aIncrement, &QAction::triggered, this, &DeckEditorDeckDockWidget::actIncrement);
auto *tbIncrement = new QToolButton(this); auto *tbIncrement = new QToolButton(this);
tbIncrement->setDefaultAction(aIncrement); tbIncrement->setDefaultAction(aIncrement);
@@ -199,7 +199,7 @@ void DeckEditorDeckDockWidget::createDeckDock()
aSwapCard = new QAction(QString(), this); aSwapCard = new QAction(QString(), this);
aSwapCard->setIcon(QPixmap("theme:icons/swap")); aSwapCard->setIcon(QPixmap("theme:icons/swap"));
connect(aSwapCard, &QAction::triggered, this, &DeckEditorDeckDockWidget::actSwapSelection); connect(aSwapCard, &QAction::triggered, this, &DeckEditorDeckDockWidget::actSwapCard);
auto *tbSwapCard = new QToolButton(this); auto *tbSwapCard = new QToolButton(this);
tbSwapCard->setDefaultAction(aSwapCard); tbSwapCard->setDefaultAction(aSwapCard);
@@ -386,15 +386,15 @@ void DeckEditorDeckDockWidget::updateBannerCardComboBox()
// Collect unique (name, providerId) pairs // Collect unique (name, providerId) pairs
QSet<QPair<QString, QString>> bannerCardSet; QSet<QPair<QString, QString>> bannerCardSet;
QList<CardRef> cardsInDeck = deckModel->getCardRefs(); QList<const DecklistCardNode *> cardsInDeck = deckModel->getDeckList()->getCardNodes();
for (auto cardRef : cardsInDeck) { for (auto currentCard : cardsInDeck) {
if (!CardDatabaseManager::query()->getCard(cardRef)) { if (!CardDatabaseManager::query()->getCard(currentCard->toCardRef())) {
continue; continue;
} }
// Insert one entry per distinct card, ignore copies // Insert one entry per distinct card, ignore copies
bannerCardSet.insert({cardRef.name, cardRef.providerId}); bannerCardSet.insert({currentCard->getName(), currentCard->getCardProviderId()});
} }
// Convert to sorted list // Convert to sorted list
@@ -527,9 +527,9 @@ DeckLoader *DeckEditorDeckDockWidget::getDeckLoader()
return deckLoader; return deckLoader;
} }
const DeckList &DeckEditorDeckDockWidget::getDeckList() const DeckList *DeckEditorDeckDockWidget::getDeckList()
{ {
return *deckModel->getDeckList(); return deckModel->getDeckList();
} }
/** /**
@@ -582,32 +582,7 @@ QModelIndexList DeckEditorDeckDockWidget::getSelectedCardNodes() const
return selectedRows; return selectedRows;
} }
void DeckEditorDeckDockWidget::actAddCard(const ExactCard &card, const QString &_zoneName) void DeckEditorDeckDockWidget::actIncrement()
{
if (!card) {
return;
}
QString zoneName = card.getInfo().getIsToken() ? DECK_ZONE_TOKENS : _zoneName;
emit requestDeckHistorySave(tr("Added (%1): %2 (%3) %4")
.arg(zoneName, card.getName(), card.getPrinting().getSet()->getCorrectedShortName(),
card.getPrinting().getProperty("num")));
QModelIndex newCardIndex = deckModel->addCard(card, zoneName);
if (!newCardIndex.isValid()) {
return;
}
expandAll();
deckView->clearSelection();
deckView->setCurrentIndex(newCardIndex);
emit deckModified();
}
void DeckEditorDeckDockWidget::actIncrementSelection()
{ {
auto selectedRows = getSelectedCardNodes(); auto selectedRows = getSelectedCardNodes();
@@ -616,20 +591,7 @@ void DeckEditorDeckDockWidget::actIncrementSelection()
} }
} }
void DeckEditorDeckDockWidget::actSwapCard(const ExactCard &card, const QString &zoneName) void DeckEditorDeckDockWidget::actSwapCard()
{
QString providerId = card.getPrinting().getUuid();
QString collectorNumber = card.getPrinting().getProperty("num");
QModelIndex foundCard = deckModel->findCard(card.getName(), zoneName, providerId, collectorNumber);
if (!foundCard.isValid()) {
foundCard = deckModel->findCard(card.getName(), zoneName);
}
swapCard(foundCard);
}
void DeckEditorDeckDockWidget::actSwapSelection()
{ {
auto selectedRows = getSelectedCardNodes(); auto selectedRows = getSelectedCardNodes();

View File

@@ -61,14 +61,14 @@ public slots:
void syncDisplayWidgetsToModel(); void syncDisplayWidgetsToModel();
void sortDeckModelToDeckView(); void sortDeckModelToDeckView();
DeckLoader *getDeckLoader(); DeckLoader *getDeckLoader();
const DeckList &getDeckList() const; DeckList *getDeckList();
void actAddCard(const ExactCard &card, const QString &zoneName); void actIncrement();
void actIncrementSelection(); bool swapCard(const QModelIndex &idx);
void actDecrementCard(const ExactCard &card, QString zoneName); void actDecrementCard(const ExactCard &card, QString zoneName);
void actDecrementSelection(); void actDecrementSelection();
void actSwapCard(const ExactCard &card, const QString &zoneName); void actSwapCard();
void actSwapSelection();
void actRemoveCard(); void actRemoveCard();
void offsetCountAtIndex(const QModelIndex &idx, int offset);
void initializeFormats(); void initializeFormats();
void expandAll(); void expandAll();
@@ -108,11 +108,9 @@ private:
void recursiveExpand(const QModelIndex &index); void recursiveExpand(const QModelIndex &index);
[[nodiscard]] QModelIndexList getSelectedCardNodes() const; [[nodiscard]] QModelIndexList getSelectedCardNodes() const;
void offsetCountAtIndex(const QModelIndex &idx, int offset);
private slots: private slots:
void decklistCustomMenu(QPoint point); void decklistCustomMenu(QPoint point);
bool swapCard(const QModelIndex &currentIndex);
void updateCard(QModelIndex, const QModelIndex &current); void updateCard(QModelIndex, const QModelIndex &current);
void updateName(const QString &name); void updateName(const QString &name);
void updateComments(); void updateComments();

View File

@@ -150,7 +150,7 @@ DlgEditDeckInClipboard::DlgEditDeckInClipboard(const DeckList &_deckList, bool _
* @param addComments Whether to add annotations * @param addComments Whether to add annotations
* @return A QString * @return A QString
*/ */
static QString deckListToString(const DeckList &deckList, bool addComments) static QString deckListToString(const DeckList *deckList, bool addComments)
{ {
QString buffer; QString buffer;
QTextStream stream(&buffer); QTextStream stream(&buffer);
@@ -160,7 +160,7 @@ static QString deckListToString(const DeckList &deckList, bool addComments)
void DlgEditDeckInClipboard::actRefresh() void DlgEditDeckInClipboard::actRefresh()
{ {
setText(deckListToString(deckList, annotated)); setText(deckListToString(&deckList, annotated));
} }
void DlgEditDeckInClipboard::actOK() void DlgEditDeckInClipboard::actOK()

View File

@@ -178,7 +178,7 @@ void DlgSelectSetForCards::actOK()
void DlgSelectSetForCards::actClear() void DlgSelectSetForCards::actClear()
{ {
emit deckAboutToBeModified(tr("Cleared all printing information.")); emit deckAboutToBeModified(tr("Cleared all printing information."));
model->forEachCard(CardNodeFunction::ClearPrintingData()); model->getDeckList()->forEachCard(CardNodeFunction::ClearPrintingData());
emit deckModified(); emit deckModified();
accept(); accept();
} }
@@ -186,8 +186,8 @@ void DlgSelectSetForCards::actClear()
void DlgSelectSetForCards::actSetAllToPreferred() void DlgSelectSetForCards::actSetAllToPreferred()
{ {
emit deckAboutToBeModified(tr("Set all printings to preferred.")); emit deckAboutToBeModified(tr("Set all printings to preferred."));
model->forEachCard(CardNodeFunction::ClearPrintingData()); model->getDeckList()->forEachCard(CardNodeFunction::ClearPrintingData());
model->forEachCard(CardNodeFunction::SetProviderIdToPreferred()); model->getDeckList()->forEachCard(CardNodeFunction::SetProviderIdToPreferred());
emit deckModified(); emit deckModified();
accept(); accept();
} }

View File

@@ -124,7 +124,7 @@ void AbstractTabDeckEditor::onDeckModified()
*/ */
void AbstractTabDeckEditor::onDeckHistorySaveRequested(const QString &modificationReason) void AbstractTabDeckEditor::onDeckHistorySaveRequested(const QString &modificationReason)
{ {
historyManager->save(deckDockWidget->getDeckList().createMemento(modificationReason)); historyManager->save(deckDockWidget->getDeckList()->createMemento(modificationReason));
} }
/** /**
@@ -140,9 +140,23 @@ void AbstractTabDeckEditor::onDeckHistoryClearRequested()
* @param card Card to add. * @param card Card to add.
* @param zoneName Zone to add the card to. * @param zoneName Zone to add the card to.
*/ */
void AbstractTabDeckEditor::addCardHelper(const ExactCard &card, const QString &zoneName) void AbstractTabDeckEditor::addCardHelper(const ExactCard &card, QString zoneName)
{ {
deckDockWidget->actAddCard(card, zoneName); if (!card)
return;
if (card.getInfo().getIsToken())
zoneName = DECK_ZONE_TOKENS;
onDeckHistorySaveRequested(QString(tr("Added (%1): %2 (%3) %4"))
.arg(zoneName, card.getName(), card.getPrinting().getSet()->getCorrectedShortName(),
card.getPrinting().getProperty("num")));
QModelIndex newCardIndex = deckDockWidget->deckModel->addCard(card, zoneName);
deckDockWidget->expandAll();
deckDockWidget->deckView->clearSelection();
deckDockWidget->deckView->setCurrentIndex(newCardIndex);
setModified(true);
databaseDisplayDockWidget->searchEdit->setSelection(0, databaseDisplayDockWidget->searchEdit->text().length()); databaseDisplayDockWidget->searchEdit->setSelection(0, databaseDisplayDockWidget->searchEdit->text().length());
} }
@@ -179,6 +193,24 @@ void AbstractTabDeckEditor::actDecrementCardFromSideboard(const ExactCard &card)
emit decrementCard(card, DECK_ZONE_SIDE); emit decrementCard(card, DECK_ZONE_SIDE);
} }
/**
* @brief Swaps a card in a deck zone.
* @param card Card to swap.
* @param zoneName Zone to swap in.
*/
void AbstractTabDeckEditor::actSwapCard(const ExactCard &card, const QString &zoneName)
{
QString providerId = card.getPrinting().getUuid();
QString collectorNumber = card.getPrinting().getProperty("num");
QModelIndex foundCard = deckDockWidget->deckModel->findCard(card.getName(), zoneName, providerId, collectorNumber);
if (!foundCard.isValid()) {
foundCard = deckDockWidget->deckModel->findCard(card.getName(), zoneName);
}
deckDockWidget->swapCard(foundCard);
}
/** /**
* @brief Opens a deck in this tab. * @brief Opens a deck in this tab.
* @param deck The deck * @param deck The deck
@@ -199,7 +231,7 @@ void AbstractTabDeckEditor::openDeck(const LoadedDeck &deck)
void AbstractTabDeckEditor::setDeck(const LoadedDeck &_deck) void AbstractTabDeckEditor::setDeck(const LoadedDeck &_deck)
{ {
deckDockWidget->setDeck(_deck); deckDockWidget->setDeck(_deck);
CardPictureLoader::cacheCardPixmaps(CardDatabaseManager::query()->getCards(getDeckList().getCardRefList())); CardPictureLoader::cacheCardPixmaps(CardDatabaseManager::query()->getCards(getDeckList()->getCardRefList()));
setModified(false); setModified(false);
aDeckDockVisible->setChecked(true); aDeckDockVisible->setChecked(true);
@@ -213,7 +245,7 @@ DeckLoader *AbstractTabDeckEditor::getDeckLoader() const
} }
/** @brief Returns the currently loaded deck list. */ /** @brief Returns the currently loaded deck list. */
const DeckList &AbstractTabDeckEditor::getDeckList() const DeckList *AbstractTabDeckEditor::getDeckList() const
{ {
return deckDockWidget->getDeckList(); return deckDockWidget->getDeckList();
} }
@@ -414,7 +446,7 @@ bool AbstractTabDeckEditor::actSaveDeckAs()
dialog.setAcceptMode(QFileDialog::AcceptSave); dialog.setAcceptMode(QFileDialog::AcceptSave);
dialog.setDefaultSuffix("cod"); dialog.setDefaultSuffix("cod");
dialog.setNameFilters(DeckLoader::FILE_NAME_FILTERS); dialog.setNameFilters(DeckLoader::FILE_NAME_FILTERS);
dialog.selectFile(getDeckList().getName().trimmed()); dialog.selectFile(getDeckList()->getName().trimmed());
if (!dialog.exec()) if (!dialog.exec())
return false; return false;
@@ -559,21 +591,26 @@ void AbstractTabDeckEditor::actLoadDeckFromWebsite()
*/ */
void AbstractTabDeckEditor::exportToDecklistWebsite(DeckLoader::DecklistWebsite website) void AbstractTabDeckEditor::exportToDecklistWebsite(DeckLoader::DecklistWebsite website)
{ {
QString decklistUrlString = DeckLoader::exportDeckToDecklist(getDeckList(), website); if (DeckList *deckList = getDeckList()) {
// Check to make sure the string isn't empty. QString decklistUrlString = DeckLoader::exportDeckToDecklist(deckList, website);
if (decklistUrlString.isEmpty()) { // Check to make sure the string isn't empty.
// Show an error if the deck is empty, and return. if (decklistUrlString.isEmpty()) {
QMessageBox::critical(this, tr("Error"), tr("There are no cards in your deck to be exported")); // Show an error if the deck is empty, and return.
return; QMessageBox::critical(this, tr("Error"), tr("There are no cards in your deck to be exported"));
} return;
}
// Encode the string recieved from the model to make sure all characters are encoded. // Encode the string recieved from the model to make sure all characters are encoded.
// first we put it into a qurl object // first we put it into a qurl object
QUrl decklistUrl = QUrl(decklistUrlString); QUrl decklistUrl = QUrl(decklistUrlString);
// we get the correctly encoded url. // we get the correctly encoded url.
decklistUrlString = decklistUrl.toEncoded(); decklistUrlString = decklistUrl.toEncoded();
// We open the url in the user's default browser // We open the url in the user's default browser
QDesktopServices::openUrl(decklistUrlString); QDesktopServices::openUrl(decklistUrlString);
} else {
// if there's no deck loader object, return an error
QMessageBox::critical(this, tr("Error"), tr("No deck was selected to be exported."));
}
} }
/** @brief Exports deck to www.decklist.org. */ /** @brief Exports deck to www.decklist.org. */

View File

@@ -77,6 +77,7 @@ class QAction;
* *
* - actAddCard(const ExactCard &card) — Adds a card to the deck. * - actAddCard(const ExactCard &card) — Adds a card to the deck.
* - actDecrementCard(const ExactCard &card) — Removes a single instance of a card from the deck. * - actDecrementCard(const ExactCard &card) — Removes a single instance of a card from the deck.
* - actSwapCard(const ExactCard &card, const QString &zone) — Swaps a card between zones.
* - actRemoveCard() — Removes the currently selected card from the deck. * - actRemoveCard() — Removes the currently selected card from the deck.
* - actSaveDeckAs() — Performs a "Save As" action for the deck. * - actSaveDeckAs() — Performs a "Save As" action for the deck.
* - updateCard(const ExactCard &card) — Updates the currently displayed card info in the dock. * - updateCard(const ExactCard &card) — Updates the currently displayed card info in the dock.
@@ -121,7 +122,7 @@ public:
DeckLoader *getDeckLoader() const; DeckLoader *getDeckLoader() const;
/** @brief Returns the currently active deck list. */ /** @brief Returns the currently active deck list. */
const DeckList &getDeckList() const; DeckList *getDeckList() const;
/** @brief Sets the modified state of the tab. /** @brief Sets the modified state of the tab.
* @param _windowModified Whether the tab is modified. * @param _windowModified Whether the tab is modified.
@@ -319,7 +320,10 @@ protected:
bool isBlankNewDeck() const; bool isBlankNewDeck() const;
/** @brief Helper function to add a card to a specific deck zone. */ /** @brief Helper function to add a card to a specific deck zone. */
void addCardHelper(const ExactCard &card, const QString &zoneName); void addCardHelper(const ExactCard &card, QString zoneName);
/** @brief Swaps a card in the deck view. */
void actSwapCard(const ExactCard &card, const QString &zoneName);
/** @brief Opens a deck from a file. */ /** @brief Opens a deck from a file. */
virtual void openDeckFromFile(const QString &fileName, DeckOpenLocation deckOpenLocation); virtual void openDeckFromFile(const QString &fileName, DeckOpenLocation deckOpenLocation);

View File

@@ -70,7 +70,9 @@ ArchidektApiResponseDeckDisplayWidget::ArchidektApiResponseDeckDisplayWidget(QWi
connect(model, &DeckListModel::modelReset, this, &ArchidektApiResponseDeckDisplayWidget::decklistModelReset); connect(model, &DeckListModel::modelReset, this, &ArchidektApiResponseDeckDisplayWidget::decklistModelReset);
model->getDeckList()->loadFromStream_Plain(deckStream, false); model->getDeckList()->loadFromStream_Plain(deckStream, false);
model->forEachCard(CardNodeFunction::ResolveProviderId()); model->getDeckList()->forEachCard(CardNodeFunction::ResolveProviderId());
model->rebuildTree();
retranslateUi(); retranslateUi();
} }

View File

@@ -191,7 +191,7 @@ void TabDeckEditorVisual::processMainboardCardClick(QMouseEvent *event,
// Double click = swap // Double click = swap
if (event->type() == QEvent::MouseButtonDblClick && event->button() == Qt::LeftButton) { if (event->type() == QEvent::MouseButtonDblClick && event->button() == Qt::LeftButton) {
deckDockWidget->actSwapCard(card, zoneName); actSwapCard(card, zoneName);
idx = deckDockWidget->deckModel->findCard(card.getName(), zoneName); idx = deckDockWidget->deckModel->findCard(card.getName(), zoneName);
sel->setCurrentIndex(idx, QItemSelectionModel::ClearAndSelect); sel->setCurrentIndex(idx, QItemSelectionModel::ClearAndSelect);
return; return;

View File

@@ -334,13 +334,13 @@ QMenu *DeckPreviewWidget::createRightClickMenu()
auto saveToClipboardMenu = menu->addMenu(tr("Save Deck to Clipboard")); auto saveToClipboardMenu = menu->addMenu(tr("Save Deck to Clipboard"));
connect(saveToClipboardMenu->addAction(tr("Annotated")), &QAction::triggered, this, connect(saveToClipboardMenu->addAction(tr("Annotated")), &QAction::triggered, this,
[this] { DeckLoader::saveToClipboard(deckLoader->getDeck().deckList, true, true); }); [this] { DeckLoader::saveToClipboard(&deckLoader->getDeck().deckList, true, true); });
connect(saveToClipboardMenu->addAction(tr("Annotated (No set info)")), &QAction::triggered, this, connect(saveToClipboardMenu->addAction(tr("Annotated (No set info)")), &QAction::triggered, this,
[this] { DeckLoader::saveToClipboard(deckLoader->getDeck().deckList, true, false); }); [this] { DeckLoader::saveToClipboard(&deckLoader->getDeck().deckList, true, false); });
connect(saveToClipboardMenu->addAction(tr("Not Annotated")), &QAction::triggered, this, connect(saveToClipboardMenu->addAction(tr("Not Annotated")), &QAction::triggered, this,
[this] { DeckLoader::saveToClipboard(deckLoader->getDeck().deckList, false, true); }); [this] { DeckLoader::saveToClipboard(&deckLoader->getDeck().deckList, false, true); });
connect(saveToClipboardMenu->addAction(tr("Not Annotated (No set info)")), &QAction::triggered, this, connect(saveToClipboardMenu->addAction(tr("Not Annotated (No set info)")), &QAction::triggered, this,
[this] { DeckLoader::saveToClipboard(deckLoader->getDeck().deckList, false, false); }); [this] { DeckLoader::saveToClipboard(&deckLoader->getDeck().deckList, false, false); });
menu->addSeparator(); menu->addSeparator();

View File

@@ -1,3 +1,16 @@
@page card_database_schema_and_parsing Card Database Schema and Parsing @page card_database_schema_and_parsing Card Database Schema and Parsing
# Card Database Schemas
Cockatrice uses `XML files` to store information of available cards to be used in the app (`cards.xml`).
The token file follows the schema of the card database (`tokens.xml`), too.
Saved decks (`<deckname>.xml`) use a different schema.
- [XSD Schema for `Card Databases`](https://github.com/Cockatrice/Cockatrice/blob/master/doc/carddatabase_v4/cards.xsd) <kbd>v4</kbd>
- [XSD Schema for `Decks`](https://github.com/Cockatrice/Cockatrice/blob/master/doc/deck.xsd) <kbd>v1</kbd>
# Card Database Parsing
TODO TODO

View File

@@ -8,10 +8,8 @@ by selecting "Deck Editor" or "Visual Deck Editor" under the "Tabs" application
# Further References # Further References
See @ref editing_decks for information on how to modify the attributes and contents of a deck in the Deck Editor - See @ref editing_decks for information on how to modify the attributes and contents of a deck in the Deck Editor
widgets. widgets.
- See @ref exporting_decks for information on how to store and persist your deck either in-client or to external
See @ref exporting_decks for information on how to store and persist your deck either in-client or to external
services. services.
- See @ref importing_decks for information on how to import existing decks either in-client or from external services
See @ref importing_decks for information on how to import existing decks either in-client or from external services

View File

@@ -561,11 +561,6 @@ void DeckListModel::setDeckList(DeckList *_deck)
rebuildTree(); rebuildTree();
} }
void DeckListModel::forEachCard(const std::function<void(InnerDecklistNode *, DecklistCardNode *)> &func)
{
deckList->forEachCard(func);
}
static QList<ExactCard> cardNodesToExactCards(QList<const DecklistCardNode *> nodes) static QList<ExactCard> cardNodesToExactCards(QList<const DecklistCardNode *> nodes)
{ {
QList<ExactCard> cards; QList<ExactCard> cards;
@@ -605,17 +600,6 @@ QList<QString> DeckListModel::getCardNames() const
return names; return names;
} }
QList<CardRef> DeckListModel::getCardRefs() const
{
auto nodes = deckList->getCardNodes();
QList<CardRef> cardRefs;
std::transform(nodes.cbegin(), nodes.cend(), std::back_inserter(cardRefs),
[](auto node) { return node->toCardRef(); });
return cardRefs;
}
QList<QString> DeckListModel::getZones() const QList<QString> DeckListModel::getZones() const
{ {
auto zoneNodes = deckList->getZoneNodes(); auto zoneNodes = deckList->getZoneNodes();

View File

@@ -309,13 +309,6 @@ public:
} }
void setDeckList(DeckList *_deck); void setDeckList(DeckList *_deck);
/**
* @brief Apply a function to every card in the deck tree.
*
* @param func Function taking (zone node, card node).
*/
void forEachCard(const std::function<void(InnerDecklistNode *, DecklistCardNode *)> &func);
/** /**
* @brief Creates a list consisting of the entries of the model mapped into ExactCards (with each entry looked up * @brief Creates a list consisting of the entries of the model mapped into ExactCards (with each entry looked up
* in the card database). * in the card database).
@@ -330,10 +323,6 @@ public:
* @brief Gets a deduplicated list of all card names that appear in the model * @brief Gets a deduplicated list of all card names that appear in the model
*/ */
[[nodiscard]] QList<QString> getCardNames() const; [[nodiscard]] QList<QString> getCardNames() const;
/**
* @brief Gets a deduplicated list of all CardRefs that appear in the model
*/
[[nodiscard]] QList<CardRef> getCardRefs() const;
/** /**
* @brief Gets a list of all zone names that appear in the model * @brief Gets a list of all zone names that appear in the model
*/ */