mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-06-12 09:04:53 -07:00
Deck loader is a gui class. (#6294)
* Deck loader is a gui class. Took 31 minutes Took 3 minutes * Deck Loader is responsible for printing. Took 8 minutes Took 2 seconds * Style proxy. Took 14 minutes Took 6 minutes Took 1 minute * Don't need to include QBrush anymore. Took 3 minutes Took 7 seconds * Includes for printer. Took 5 minutes * Nuke getDeckList() Took 9 minutes * Adjust to rebase. Took 35 seconds * Lint. Took 3 minutes * Braces for one line return statements. Took 13 minutes Took 50 seconds * Enum for model columns. Took 9 minutes * One more single line if. Took 1 minute * Another style lint on a sunday night Took 5 minutes * Move enum to namespace. Took 3 minutes * Fix a critical blocker. Took 5 minutes * Update docs. Took 3 minutes * Doxygen and namespace enums. Took 2 minutes Took 15 seconds * Adjust to namespace. Took 4 minutes Took 1 minute --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
parent
c16267e60f
commit
bfedc12fa8
33 changed files with 384 additions and 255 deletions
704
cockatrice/src/interface/deck_loader/deck_loader.cpp
Normal file
704
cockatrice/src/interface/deck_loader/deck_loader.cpp
Normal file
|
|
@ -0,0 +1,704 @@
|
|||
#include "deck_loader.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QFutureWatcher>
|
||||
#include <QPrinter>
|
||||
#include <QRegularExpression>
|
||||
#include <QStringList>
|
||||
#include <QTextCursor>
|
||||
#include <QTextDocument>
|
||||
#include <QTextStream>
|
||||
#include <QTextTable>
|
||||
#include <QtConcurrentRun>
|
||||
#include <libcockatrice/card/database/card_database.h>
|
||||
#include <libcockatrice/card/database/card_database_manager.h>
|
||||
#include <libcockatrice/deck_list/deck_list.h>
|
||||
#include <libcockatrice/deck_list/deck_list_card_node.h>
|
||||
|
||||
const QStringList DeckLoader::ACCEPTED_FILE_EXTENSIONS = {"*.cod", "*.dec", "*.dek", "*.txt", "*.mwDeck"};
|
||||
|
||||
const QStringList DeckLoader::FILE_NAME_FILTERS = {
|
||||
tr("Common deck formats (%1)").arg(ACCEPTED_FILE_EXTENSIONS.join(" ")), tr("All files (*.*)")};
|
||||
|
||||
DeckLoader::DeckLoader() : DeckList(), lastFileName(QString()), lastFileFormat(CockatriceFormat), lastRemoteDeckId(-1)
|
||||
{
|
||||
}
|
||||
|
||||
DeckLoader::DeckLoader(const QString &nativeString)
|
||||
: DeckList(nativeString), lastFileName(QString()), lastFileFormat(CockatriceFormat), lastRemoteDeckId(-1)
|
||||
{
|
||||
}
|
||||
|
||||
DeckLoader::DeckLoader(const DeckList &other)
|
||||
: DeckList(other), lastFileName(QString()), lastFileFormat(CockatriceFormat), lastRemoteDeckId(-1)
|
||||
{
|
||||
}
|
||||
|
||||
DeckLoader::DeckLoader(const DeckLoader &other)
|
||||
: DeckList(other), lastFileName(other.lastFileName), lastFileFormat(other.lastFileFormat),
|
||||
lastRemoteDeckId(other.lastRemoteDeckId)
|
||||
{
|
||||
}
|
||||
|
||||
bool DeckLoader::loadFromFile(const QString &fileName, FileFormat fmt, bool userRequest)
|
||||
{
|
||||
QFile file(fileName);
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
switch (fmt) {
|
||||
case PlainTextFormat:
|
||||
result = loadFromFile_Plain(&file);
|
||||
break;
|
||||
case CockatriceFormat: {
|
||||
result = loadFromFile_Native(&file);
|
||||
qCInfo(DeckLoaderLog) << "Loaded from" << fileName << "-" << result;
|
||||
if (!result) {
|
||||
qCInfo(DeckLoaderLog) << "Retrying as plain format";
|
||||
file.seek(0);
|
||||
result = loadFromFile_Plain(&file);
|
||||
fmt = PlainTextFormat;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
lastFileName = fileName;
|
||||
lastFileFormat = fmt;
|
||||
if (userRequest) {
|
||||
updateLastLoadedTimestamp(fileName, fmt);
|
||||
}
|
||||
|
||||
emit deckLoaded();
|
||||
}
|
||||
|
||||
qCInfo(DeckLoaderLog) << "Deck was loaded -" << result;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DeckLoader::loadFromFileAsync(const QString &fileName, FileFormat fmt, bool userRequest)
|
||||
{
|
||||
auto *watcher = new QFutureWatcher<bool>(this);
|
||||
|
||||
connect(watcher, &QFutureWatcher<bool>::finished, this, [this, watcher, fileName, fmt, userRequest]() {
|
||||
const bool result = watcher->result();
|
||||
watcher->deleteLater();
|
||||
|
||||
if (result) {
|
||||
lastFileName = fileName;
|
||||
lastFileFormat = fmt;
|
||||
if (userRequest) {
|
||||
updateLastLoadedTimestamp(fileName, fmt);
|
||||
}
|
||||
emit deckLoaded();
|
||||
}
|
||||
|
||||
emit loadFinished(result);
|
||||
});
|
||||
|
||||
QFuture<bool> future = QtConcurrent::run([=, this]() {
|
||||
QFile file(fileName);
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (fmt) {
|
||||
case PlainTextFormat:
|
||||
return loadFromFile_Plain(&file);
|
||||
case CockatriceFormat: {
|
||||
bool result = false;
|
||||
result = loadFromFile_Native(&file);
|
||||
if (!result) {
|
||||
file.seek(0);
|
||||
return loadFromFile_Plain(&file);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
watcher->setFuture(future);
|
||||
return true; // Return immediately to indicate the async task was started
|
||||
}
|
||||
|
||||
bool DeckLoader::loadFromRemote(const QString &nativeString, int remoteDeckId)
|
||||
{
|
||||
bool result = loadFromString_Native(nativeString);
|
||||
if (result) {
|
||||
lastFileName = QString();
|
||||
lastFileFormat = CockatriceFormat;
|
||||
lastRemoteDeckId = remoteDeckId;
|
||||
|
||||
emit deckLoaded();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DeckLoader::saveToFile(const QString &fileName, FileFormat fmt)
|
||||
{
|
||||
QFile file(fileName);
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
switch (fmt) {
|
||||
case PlainTextFormat:
|
||||
result = saveToFile_Plain(&file);
|
||||
break;
|
||||
case CockatriceFormat:
|
||||
result = saveToFile_Native(&file);
|
||||
break;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
lastFileName = fileName;
|
||||
lastFileFormat = fmt;
|
||||
}
|
||||
|
||||
file.flush();
|
||||
file.close();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DeckLoader::updateLastLoadedTimestamp(const QString &fileName, FileFormat fmt)
|
||||
{
|
||||
QFileInfo fileInfo(fileName);
|
||||
if (!fileInfo.exists()) {
|
||||
qCWarning(DeckLoaderLog) << "File does not exist:" << fileName;
|
||||
return false;
|
||||
}
|
||||
|
||||
QDateTime originalTimestamp = fileInfo.lastModified();
|
||||
|
||||
// Open the file for writing
|
||||
QFile file(fileName);
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
qCWarning(DeckLoaderLog) << "Failed to open file for writing:" << fileName;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
|
||||
// Perform file modifications
|
||||
switch (fmt) {
|
||||
case PlainTextFormat:
|
||||
result = saveToFile_Plain(&file);
|
||||
break;
|
||||
case CockatriceFormat:
|
||||
setLastLoadedTimestamp(QDateTime::currentDateTime().toString());
|
||||
result = saveToFile_Native(&file);
|
||||
break;
|
||||
}
|
||||
|
||||
file.close(); // Close the file to ensure changes are flushed
|
||||
|
||||
if (result) {
|
||||
lastFileName = fileName;
|
||||
lastFileFormat = fmt;
|
||||
|
||||
// Re-open the file and set the original timestamp
|
||||
if (!file.open(QIODevice::ReadWrite)) {
|
||||
qCWarning(DeckLoaderLog) << "Failed to re-open file to set timestamp:" << fileName;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!file.setFileTime(originalTimestamp, QFileDevice::FileModificationTime)) {
|
||||
qCWarning(DeckLoaderLog) << "Failed to set modification time for file:" << fileName;
|
||||
file.close();
|
||||
return false;
|
||||
}
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static QString getDomainForWebsite(DeckLoader::DecklistWebsite website)
|
||||
{
|
||||
switch (website) {
|
||||
case DeckLoader::DecklistOrg:
|
||||
return "www.decklist.org";
|
||||
case DeckLoader::DecklistXyz:
|
||||
return "www.decklist.xyz";
|
||||
default:
|
||||
qCWarning(DeckLoaderLog) << "Invalid decklist website enum:" << website;
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the card to the String that represents it in the decklist export
|
||||
*/
|
||||
static QString toDecklistExportString(const DecklistCardNode *card)
|
||||
{
|
||||
QString cardString;
|
||||
// Get the number of cards and add the card name
|
||||
cardString += QString::number(card->getNumber());
|
||||
// Add a space between card num and name
|
||||
cardString += "%20";
|
||||
// Add card name
|
||||
cardString += card->getName();
|
||||
|
||||
if (!card->getCardSetShortName().isNull()) {
|
||||
cardString += "%20";
|
||||
cardString += "(" + card->getCardSetShortName() + ")";
|
||||
}
|
||||
if (!card->getCardCollectorNumber().isNull()) {
|
||||
cardString += "%20";
|
||||
cardString += card->getCardCollectorNumber();
|
||||
}
|
||||
|
||||
// Add a return at the end of the card
|
||||
cardString += "%0A";
|
||||
|
||||
return cardString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Export deck to decklist function, called to format the deck in a way to be sent to a server
|
||||
* @param website The website we're sending the deck to
|
||||
*/
|
||||
QString DeckLoader::exportDeckToDecklist(DecklistWebsite website)
|
||||
{
|
||||
// Add the base url
|
||||
QString deckString = "https://" + getDomainForWebsite(website) + "/?";
|
||||
// Create two strings to pass to function
|
||||
QString mainBoardCards, sideBoardCards;
|
||||
|
||||
// Set up the function to call
|
||||
auto formatDeckListForExport = [&mainBoardCards, &sideBoardCards](const auto *node, const auto *card) {
|
||||
// Get the card name
|
||||
CardInfoPtr dbCard = CardDatabaseManager::query()->getCardInfo(card->getName());
|
||||
if (!dbCard || dbCard->getIsToken()) {
|
||||
// If it's a token, we don't care about the card.
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if it's a sideboard card.
|
||||
if (node->getName() == DECK_ZONE_SIDE) {
|
||||
sideBoardCards += toDecklistExportString(card);
|
||||
} else {
|
||||
// If it's a mainboard card, do the same thing, but for the mainboard card string
|
||||
mainBoardCards += toDecklistExportString(card);
|
||||
}
|
||||
};
|
||||
|
||||
// call our struct function for each card in the deck
|
||||
forEachCard(formatDeckListForExport);
|
||||
// Remove the extra return at the end of the last cards
|
||||
mainBoardCards.chop(3);
|
||||
sideBoardCards.chop(3);
|
||||
// if after we've called it for each card, and the strings are empty, we know that
|
||||
// there were no non-token cards in the deck, so show an error message.
|
||||
if ((QString::compare(mainBoardCards, "", Qt::CaseInsensitive) == 0) &&
|
||||
(QString::compare(sideBoardCards, "", Qt::CaseInsensitive) == 0)) {
|
||||
return "";
|
||||
}
|
||||
// return a string with the url for decklist export
|
||||
deckString += "deckmain=" + mainBoardCards + "&deckside=" + sideBoardCards;
|
||||
return deckString;
|
||||
}
|
||||
|
||||
// This struct is here to support the forEachCard function call, defined in decklist.
|
||||
// It requires a function to be called for each card, and it will set the providerId to the preferred printing.
|
||||
struct SetProviderIdToPreferred
|
||||
{
|
||||
// Main operator for struct, allowing the foreachcard to work.
|
||||
SetProviderIdToPreferred()
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(const InnerDecklistNode *node, DecklistCardNode *card) const
|
||||
{
|
||||
Q_UNUSED(node);
|
||||
PrintingInfo preferredPrinting = CardDatabaseManager::query()->getPreferredPrinting(card->getName());
|
||||
QString providerId = preferredPrinting.getUuid();
|
||||
QString setShortName = preferredPrinting.getSet()->getShortName();
|
||||
QString collectorNumber = preferredPrinting.getProperty("num");
|
||||
|
||||
card->setCardProviderId(providerId);
|
||||
card->setCardCollectorNumber(collectorNumber);
|
||||
card->setCardSetShortName(setShortName);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This function iterates through each card in the decklist and sets the providerId
|
||||
* on each card based on its set name and collector number.
|
||||
*/
|
||||
void DeckLoader::setProviderIdToPreferredPrinting()
|
||||
{
|
||||
// Set up the struct to call.
|
||||
SetProviderIdToPreferred setProviderIdToPreferred;
|
||||
|
||||
// Call the forEachCard method for each card in the deck
|
||||
forEachCard(setProviderIdToPreferred);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the providerId on each card in the decklist based on its set name and collector number.
|
||||
*/
|
||||
void DeckLoader::resolveSetNameAndNumberToProviderID()
|
||||
{
|
||||
auto setProviderId = [](const auto node, const auto card) {
|
||||
Q_UNUSED(node);
|
||||
// Retrieve the providerId based on setName and collectorNumber
|
||||
QString providerId =
|
||||
CardDatabaseManager::getInstance()
|
||||
->query()
|
||||
->getSpecificPrinting(card->getName(), card->getCardSetShortName(), card->getCardCollectorNumber())
|
||||
.getUuid();
|
||||
|
||||
// Set the providerId on the card
|
||||
card->setCardProviderId(providerId);
|
||||
};
|
||||
|
||||
forEachCard(setProviderId);
|
||||
}
|
||||
|
||||
// This struct is here to support the forEachCard function call, defined in decklist.
|
||||
// It requires a function to be called for each card, and it will set the providerId.
|
||||
struct ClearSetNameNumberAndProviderId
|
||||
{
|
||||
// Main operator for struct, allowing the foreachcard to work.
|
||||
ClearSetNameNumberAndProviderId()
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(const InnerDecklistNode *node, DecklistCardNode *card) const
|
||||
{
|
||||
Q_UNUSED(node);
|
||||
// Set the providerId on the card
|
||||
card->setCardSetShortName(nullptr);
|
||||
card->setCardCollectorNumber(nullptr);
|
||||
card->setCardProviderId(nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Clears the set name and numbers on each card in the decklist.
|
||||
*/
|
||||
void DeckLoader::clearSetNamesAndNumbers()
|
||||
{
|
||||
auto clearSetNameAndNumber = [](const auto node, auto card) {
|
||||
Q_UNUSED(node)
|
||||
// Set the providerId on the card
|
||||
card->setCardSetShortName(nullptr);
|
||||
card->setCardCollectorNumber(nullptr);
|
||||
card->setCardProviderId(nullptr);
|
||||
};
|
||||
|
||||
forEachCard(clearSetNameAndNumber);
|
||||
}
|
||||
|
||||
DeckLoader::FileFormat DeckLoader::getFormatFromName(const QString &fileName)
|
||||
{
|
||||
if (fileName.endsWith(".cod", Qt::CaseInsensitive)) {
|
||||
return CockatriceFormat;
|
||||
}
|
||||
return PlainTextFormat;
|
||||
}
|
||||
|
||||
void DeckLoader::saveToClipboard(bool addComments, bool addSetNameAndNumber) const
|
||||
{
|
||||
QString buffer;
|
||||
QTextStream stream(&buffer);
|
||||
saveToStream_Plain(stream, addComments, addSetNameAndNumber);
|
||||
QApplication::clipboard()->setText(buffer, QClipboard::Clipboard);
|
||||
QApplication::clipboard()->setText(buffer, QClipboard::Selection);
|
||||
}
|
||||
|
||||
bool DeckLoader::saveToStream_Plain(QTextStream &out, bool addComments, bool addSetNameAndNumber) const
|
||||
{
|
||||
if (addComments) {
|
||||
saveToStream_DeckHeader(out);
|
||||
}
|
||||
|
||||
// loop zones
|
||||
for (int i = 0; i < getRoot()->size(); i++) {
|
||||
const auto *zoneNode = dynamic_cast<InnerDecklistNode *>(getRoot()->at(i));
|
||||
|
||||
saveToStream_DeckZone(out, zoneNode, addComments, addSetNameAndNumber);
|
||||
|
||||
// end of zone
|
||||
out << "\n";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DeckLoader::saveToStream_DeckHeader(QTextStream &out) const
|
||||
{
|
||||
if (!getName().isEmpty()) {
|
||||
out << "// " << getName() << "\n\n";
|
||||
}
|
||||
|
||||
if (!getComments().isEmpty()) {
|
||||
QStringList commentRows = getComments().split(QRegularExpression("\n|\r\n|\r"));
|
||||
for (const QString &row : commentRows) {
|
||||
out << "// " << row << "\n";
|
||||
}
|
||||
out << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void DeckLoader::saveToStream_DeckZone(QTextStream &out,
|
||||
const InnerDecklistNode *zoneNode,
|
||||
bool addComments,
|
||||
bool addSetNameAndNumber) const
|
||||
{
|
||||
// group cards by card type and count the subtotals
|
||||
QMultiMap<QString, DecklistCardNode *> cardsByType;
|
||||
QMap<QString, int> cardTotalByType;
|
||||
int cardTotal = 0;
|
||||
|
||||
for (int j = 0; j < zoneNode->size(); j++) {
|
||||
auto *card = dynamic_cast<DecklistCardNode *>(zoneNode->at(j));
|
||||
|
||||
CardInfoPtr info = CardDatabaseManager::query()->getCardInfo(card->getName());
|
||||
QString cardType = info ? info->getMainCardType() : "unknown";
|
||||
|
||||
cardsByType.insert(cardType, card);
|
||||
|
||||
if (cardTotalByType.contains(cardType)) {
|
||||
cardTotalByType[cardType] += card->getNumber();
|
||||
} else {
|
||||
cardTotalByType[cardType] = card->getNumber();
|
||||
}
|
||||
|
||||
cardTotal += card->getNumber();
|
||||
}
|
||||
|
||||
if (addComments) {
|
||||
out << "// " << cardTotal << " " << zoneNode->getVisibleName() << "\n";
|
||||
}
|
||||
|
||||
// print cards to stream
|
||||
for (const QString &cardType : cardsByType.uniqueKeys()) {
|
||||
if (addComments) {
|
||||
out << "// " << cardTotalByType[cardType] << " " << cardType << "\n";
|
||||
}
|
||||
|
||||
QList<DecklistCardNode *> cards = cardsByType.values(cardType);
|
||||
|
||||
saveToStream_DeckZoneCards(out, zoneNode, cards, addComments, addSetNameAndNumber);
|
||||
|
||||
if (addComments) {
|
||||
out << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeckLoader::saveToStream_DeckZoneCards(QTextStream &out,
|
||||
const InnerDecklistNode *zoneNode,
|
||||
QList<DecklistCardNode *> cards,
|
||||
bool addComments,
|
||||
bool addSetNameAndNumber) const
|
||||
{
|
||||
// QMultiMap sorts values in reverse order
|
||||
for (int i = cards.size() - 1; i >= 0; --i) {
|
||||
DecklistCardNode *card = cards[i];
|
||||
|
||||
if (zoneNode->getName() == DECK_ZONE_SIDE && addComments) {
|
||||
out << "SB: ";
|
||||
}
|
||||
|
||||
if (card->getNumber()) {
|
||||
out << card->getNumber();
|
||||
}
|
||||
if (!card->getName().isNull() && !card->getName().isEmpty()) {
|
||||
out << " " << card->getName();
|
||||
}
|
||||
if (addSetNameAndNumber) {
|
||||
if (!card->getCardSetShortName().isNull() && !card->getCardSetShortName().isEmpty()) {
|
||||
out << " "
|
||||
<< "(" << card->getCardSetShortName() << ")";
|
||||
}
|
||||
if (!card->getCardCollectorNumber().isNull()) {
|
||||
out << " " << card->getCardCollectorNumber();
|
||||
}
|
||||
}
|
||||
out << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
bool DeckLoader::convertToCockatriceFormat(QString fileName)
|
||||
{
|
||||
// Change the file extension to .cod
|
||||
QFileInfo fileInfo(fileName);
|
||||
QString newFileName = QDir::toNativeSeparators(fileInfo.path() + "/" + fileInfo.completeBaseName() + ".cod");
|
||||
|
||||
// Open the new file for writing
|
||||
QFile file(newFileName);
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
qCWarning(DeckLoaderLog) << "Failed to open file for writing:" << newFileName;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
|
||||
// Perform file modifications based on the detected format
|
||||
switch (getFormatFromName(fileName)) {
|
||||
case PlainTextFormat:
|
||||
// Save in Cockatrice's native format
|
||||
result = saveToFile_Native(&file);
|
||||
break;
|
||||
case CockatriceFormat:
|
||||
qCInfo(DeckLoaderLog) << "File is already in Cockatrice format. No conversion needed.";
|
||||
result = true;
|
||||
break;
|
||||
default:
|
||||
qCWarning(DeckLoaderLog) << "Unsupported file format for conversion:" << fileName;
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
// Delete the old file if conversion was successful
|
||||
if (result) {
|
||||
if (!QFile::remove(fileName)) {
|
||||
qCWarning(DeckLoaderLog) << "Failed to delete original file:" << fileName;
|
||||
} else {
|
||||
qCInfo(DeckLoaderLog) << "Original file deleted successfully:" << fileName;
|
||||
}
|
||||
lastFileName = newFileName;
|
||||
lastFileFormat = CockatriceFormat;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
QString DeckLoader::getCardZoneFromName(QString cardName, QString currentZoneName)
|
||||
{
|
||||
CardInfoPtr card = CardDatabaseManager::query()->getCardInfo(cardName);
|
||||
|
||||
if (card && card->getIsToken()) {
|
||||
return DECK_ZONE_TOKENS;
|
||||
}
|
||||
|
||||
return currentZoneName;
|
||||
}
|
||||
|
||||
QString DeckLoader::getCompleteCardName(const QString &cardName) const
|
||||
{
|
||||
if (CardDatabaseManager::getInstance()) {
|
||||
ExactCard temp = CardDatabaseManager::query()->guessCard({cardName});
|
||||
if (temp) {
|
||||
return temp.getName();
|
||||
}
|
||||
}
|
||||
|
||||
return cardName;
|
||||
}
|
||||
|
||||
void DeckLoader::printDeckListNode(QTextCursor *cursor, InnerDecklistNode *node)
|
||||
{
|
||||
const int totalColumns = 2;
|
||||
|
||||
if (node->height() == 1) {
|
||||
QTextBlockFormat blockFormat;
|
||||
QTextCharFormat charFormat;
|
||||
charFormat.setFontPointSize(11);
|
||||
charFormat.setFontWeight(QFont::Bold);
|
||||
cursor->insertBlock(blockFormat, charFormat);
|
||||
|
||||
QTextTableFormat tableFormat;
|
||||
tableFormat.setCellPadding(0);
|
||||
tableFormat.setCellSpacing(0);
|
||||
tableFormat.setBorder(0);
|
||||
QTextTable *table = cursor->insertTable(node->size() + 1, totalColumns, tableFormat);
|
||||
for (int i = 0; i < node->size(); i++) {
|
||||
auto *card = dynamic_cast<AbstractDecklistCardNode *>(node->at(i));
|
||||
|
||||
QTextCharFormat cellCharFormat;
|
||||
cellCharFormat.setFontPointSize(9);
|
||||
|
||||
QTextTableCell cell = table->cellAt(i, 0);
|
||||
cell.setFormat(cellCharFormat);
|
||||
QTextCursor cellCursor = cell.firstCursorPosition();
|
||||
cellCursor.insertText(QString("%1 ").arg(card->getNumber()));
|
||||
|
||||
cell = table->cellAt(i, 1);
|
||||
cell.setFormat(cellCharFormat);
|
||||
cellCursor = cell.firstCursorPosition();
|
||||
cellCursor.insertText(card->getName());
|
||||
}
|
||||
} else if (node->height() == 2) {
|
||||
QTextBlockFormat blockFormat;
|
||||
QTextCharFormat charFormat;
|
||||
charFormat.setFontPointSize(14);
|
||||
charFormat.setFontWeight(QFont::Bold);
|
||||
|
||||
cursor->insertBlock(blockFormat, charFormat);
|
||||
|
||||
QTextTableFormat tableFormat;
|
||||
tableFormat.setCellPadding(10);
|
||||
tableFormat.setCellSpacing(0);
|
||||
tableFormat.setBorder(0);
|
||||
QVector<QTextLength> constraints;
|
||||
for (int i = 0; i < totalColumns; i++) {
|
||||
constraints << QTextLength(QTextLength::PercentageLength, 100.0 / totalColumns);
|
||||
}
|
||||
tableFormat.setColumnWidthConstraints(constraints);
|
||||
|
||||
QTextTable *table = cursor->insertTable(1, totalColumns, tableFormat);
|
||||
for (int i = 0; i < node->size(); i++) {
|
||||
QTextCursor cellCursor = table->cellAt(0, (i * totalColumns) / node->size()).lastCursorPosition();
|
||||
printDeckListNode(&cellCursor, dynamic_cast<InnerDecklistNode *>(node->at(i)));
|
||||
}
|
||||
}
|
||||
|
||||
cursor->movePosition(QTextCursor::End);
|
||||
}
|
||||
|
||||
void DeckLoader::printDeckList(QPrinter *printer)
|
||||
{
|
||||
QTextDocument doc;
|
||||
|
||||
QFont font("Serif");
|
||||
font.setStyleHint(QFont::Serif);
|
||||
doc.setDefaultFont(font);
|
||||
|
||||
QTextCursor cursor(&doc);
|
||||
|
||||
QTextBlockFormat headerBlockFormat;
|
||||
QTextCharFormat headerCharFormat;
|
||||
headerCharFormat.setFontPointSize(16);
|
||||
headerCharFormat.setFontWeight(QFont::Bold);
|
||||
|
||||
cursor.insertBlock(headerBlockFormat, headerCharFormat);
|
||||
cursor.insertText(getName());
|
||||
|
||||
headerCharFormat.setFontPointSize(12);
|
||||
cursor.insertBlock(headerBlockFormat, headerCharFormat);
|
||||
cursor.insertText(getComments());
|
||||
cursor.insertBlock(headerBlockFormat, headerCharFormat);
|
||||
|
||||
for (int i = 0; i < getRoot()->size(); i++) {
|
||||
cursor.insertHtml("<br><img src=theme:hr.jpg>");
|
||||
// cursor.insertHtml("<hr>");
|
||||
cursor.insertBlock(headerBlockFormat, headerCharFormat);
|
||||
|
||||
printDeckListNode(&cursor, dynamic_cast<InnerDecklistNode *>(getRoot()->at(i)));
|
||||
}
|
||||
|
||||
doc.print(printer);
|
||||
}
|
||||
123
cockatrice/src/interface/deck_loader/deck_loader.h
Normal file
123
cockatrice/src/interface/deck_loader/deck_loader.h
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
/**
|
||||
* @file deck_loader.h
|
||||
* @ingroup ImportExport
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef DECK_LOADER_H
|
||||
#define DECK_LOADER_H
|
||||
|
||||
#include <QLoggingCategory>
|
||||
#include <QPrinter>
|
||||
#include <QTextCursor>
|
||||
#include <libcockatrice/deck_list/deck_list.h>
|
||||
|
||||
inline Q_LOGGING_CATEGORY(DeckLoaderLog, "deck_loader")
|
||||
|
||||
class DeckLoader : public DeckList
|
||||
{
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void deckLoaded();
|
||||
void loadFinished(bool success);
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* @brief Prints the decklist to the provided QPrinter.
|
||||
* @param printer The printer to render the decklist to.
|
||||
*/
|
||||
void printDeckList(QPrinter *printer);
|
||||
|
||||
public:
|
||||
enum FileFormat
|
||||
{
|
||||
PlainTextFormat,
|
||||
CockatriceFormat
|
||||
};
|
||||
|
||||
/**
|
||||
* Supported file extensions for decklist files
|
||||
*/
|
||||
static const QStringList ACCEPTED_FILE_EXTENSIONS;
|
||||
|
||||
/**
|
||||
* For use with `QFileDialog::setNameFilters`
|
||||
*/
|
||||
static const QStringList FILE_NAME_FILTERS;
|
||||
|
||||
enum DecklistWebsite
|
||||
{
|
||||
DecklistOrg,
|
||||
DecklistXyz
|
||||
};
|
||||
|
||||
private:
|
||||
QString lastFileName;
|
||||
FileFormat lastFileFormat;
|
||||
int lastRemoteDeckId;
|
||||
|
||||
public:
|
||||
DeckLoader();
|
||||
explicit DeckLoader(const QString &nativeString);
|
||||
explicit DeckLoader(const DeckList &other);
|
||||
DeckLoader(const DeckLoader &other);
|
||||
const QString &getLastFileName() const
|
||||
{
|
||||
return lastFileName;
|
||||
}
|
||||
void setLastFileName(const QString &_lastFileName)
|
||||
{
|
||||
lastFileName = _lastFileName;
|
||||
}
|
||||
FileFormat getLastFileFormat() const
|
||||
{
|
||||
return lastFileFormat;
|
||||
}
|
||||
int getLastRemoteDeckId() const
|
||||
{
|
||||
return lastRemoteDeckId;
|
||||
}
|
||||
|
||||
bool hasNotBeenLoaded() const
|
||||
{
|
||||
return getLastFileName().isEmpty() && getLastRemoteDeckId() == -1;
|
||||
}
|
||||
|
||||
void clearSetNamesAndNumbers();
|
||||
static FileFormat getFormatFromName(const QString &fileName);
|
||||
|
||||
bool loadFromFile(const QString &fileName, FileFormat fmt, bool userRequest = false);
|
||||
bool loadFromFileAsync(const QString &fileName, FileFormat fmt, bool userRequest);
|
||||
bool loadFromRemote(const QString &nativeString, int remoteDeckId);
|
||||
bool saveToFile(const QString &fileName, FileFormat fmt);
|
||||
bool updateLastLoadedTimestamp(const QString &fileName, FileFormat fmt);
|
||||
QString exportDeckToDecklist(DecklistWebsite website);
|
||||
void setProviderIdToPreferredPrinting();
|
||||
|
||||
void resolveSetNameAndNumberToProviderID();
|
||||
|
||||
void saveToClipboard(bool addComments = true, bool addSetNameAndNumber = true) const;
|
||||
|
||||
// overload
|
||||
bool saveToStream_Plain(QTextStream &out, bool addComments = true, bool addSetNameAndNumber = true) const;
|
||||
bool convertToCockatriceFormat(QString fileName);
|
||||
|
||||
private:
|
||||
void printDeckListNode(QTextCursor *cursor, InnerDecklistNode *node);
|
||||
|
||||
protected:
|
||||
void saveToStream_DeckHeader(QTextStream &out) const;
|
||||
void saveToStream_DeckZone(QTextStream &out,
|
||||
const InnerDecklistNode *zoneNode,
|
||||
bool addComments = true,
|
||||
bool addSetNameAndNumber = true) const;
|
||||
void saveToStream_DeckZoneCards(QTextStream &out,
|
||||
const InnerDecklistNode *zoneNode,
|
||||
QList<DecklistCardNode *> cards,
|
||||
bool addComments = true,
|
||||
bool addSetNameAndNumber = true) const;
|
||||
[[nodiscard]] QString getCardZoneFromName(QString cardName, QString currentZoneName) override;
|
||||
[[nodiscard]] QString getCompleteCardName(const QString &cardName) const override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
#include "mana_base_widget.h"
|
||||
|
||||
#include "../../deck_loader/deck_loader.h"
|
||||
#include "../general/display/banner_widget.h"
|
||||
#include "../general/display/bar_widget.h"
|
||||
|
||||
|
|
@ -8,7 +9,6 @@
|
|||
#include <libcockatrice/card/database/card_database.h>
|
||||
#include <libcockatrice/card/database/card_database_manager.h>
|
||||
#include <libcockatrice/deck_list/deck_list.h>
|
||||
#include <libcockatrice/models/deck_list/deck_loader.h>
|
||||
|
||||
ManaBaseWidget::ManaBaseWidget(QWidget *parent, DeckListModel *_deckListModel)
|
||||
: QWidget(parent), deckListModel(_deckListModel)
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
#include "mana_curve_widget.h"
|
||||
|
||||
#include "../../../main.h"
|
||||
#include "../../deck_loader/deck_loader.h"
|
||||
#include "../general/display/banner_widget.h"
|
||||
#include "../general/display/bar_widget.h"
|
||||
|
||||
#include <libcockatrice/card/database/card_database.h>
|
||||
#include <libcockatrice/card/database/card_database_manager.h>
|
||||
#include <libcockatrice/deck_list/deck_list.h>
|
||||
#include <libcockatrice/models/deck_list/deck_loader.h>
|
||||
#include <unordered_map>
|
||||
|
||||
ManaCurveWidget::ManaCurveWidget(QWidget *parent, DeckListModel *_deckListModel)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "mana_devotion_widget.h"
|
||||
|
||||
#include "../../../main.h"
|
||||
#include "../../deck_loader/deck_loader.h"
|
||||
#include "../general/display/banner_widget.h"
|
||||
#include "../general/display/bar_widget.h"
|
||||
|
||||
|
|
@ -8,7 +9,6 @@
|
|||
#include <libcockatrice/card/database/card_database.h>
|
||||
#include <libcockatrice/card/database/card_database_manager.h>
|
||||
#include <libcockatrice/deck_list/deck_list.h>
|
||||
#include <libcockatrice/models/deck_list/deck_loader.h>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#include "deck_editor_deck_dock_widget.h"
|
||||
|
||||
#include "../../../client/settings/cache_settings.h"
|
||||
#include "../../deck_loader/deck_loader.h"
|
||||
#include "deck_list_style_proxy.h"
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QDockWidget>
|
||||
|
|
@ -29,9 +31,13 @@ void DeckEditorDeckDockWidget::createDeckDock()
|
|||
deckModel = new DeckListModel(this);
|
||||
deckModel->setObjectName("deckModel");
|
||||
connect(deckModel, &DeckListModel::deckHashChanged, this, &DeckEditorDeckDockWidget::updateHash);
|
||||
|
||||
DeckListStyleProxy *proxy = new DeckListStyleProxy(this);
|
||||
proxy->setSourceModel(deckModel);
|
||||
|
||||
deckView = new QTreeView();
|
||||
deckView->setObjectName("deckView");
|
||||
deckView->setModel(deckModel);
|
||||
deckView->setModel(proxy);
|
||||
deckView->setUniformRowHeights(true);
|
||||
deckView->setSortingEnabled(true);
|
||||
deckView->sortByColumn(1, Qt::AscendingOrder);
|
||||
|
|
@ -111,8 +117,8 @@ void DeckEditorDeckDockWidget::createDeckDock()
|
|||
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->setActiveGroupCriteria(static_cast<DeckListModelGroupCriteria::Type>(
|
||||
activeGroupCriteriaComboBox->currentData(Qt::UserRole).toInt()));
|
||||
deckModel->sort(deckView->header()->sortIndicatorSection(), deckView->header()->sortIndicatorOrder());
|
||||
deckView->expandAll();
|
||||
deckView->expandAll();
|
||||
|
|
@ -366,7 +372,11 @@ void DeckEditorDeckDockWidget::syncBannerCardComboBoxSelectionWithDeck()
|
|||
*/
|
||||
void DeckEditorDeckDockWidget::setDeck(DeckLoader *_deck)
|
||||
{
|
||||
deckLoader = _deck;
|
||||
|
||||
deckModel->setDeckList(_deck);
|
||||
connect(_deck, &DeckLoader::deckLoaded, deckModel, &DeckListModel::rebuildTree);
|
||||
connect(_deck, &DeckLoader::deckHashChanged, deckModel, &DeckListModel::deckHashChanged);
|
||||
|
||||
nameEdit->setText(deckModel->getDeckList()->getName());
|
||||
commentsEdit->setText(deckModel->getDeckList()->getComments());
|
||||
|
|
@ -383,9 +393,9 @@ void DeckEditorDeckDockWidget::setDeck(DeckLoader *_deck)
|
|||
emit deckChanged();
|
||||
}
|
||||
|
||||
DeckLoader *DeckEditorDeckDockWidget::getDeckList()
|
||||
DeckLoader *DeckEditorDeckDockWidget::getDeckLoader()
|
||||
{
|
||||
return deckModel->getDeckList();
|
||||
return deckLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ class DeckEditorDeckDockWidget : public QDockWidget
|
|||
Q_OBJECT
|
||||
public:
|
||||
explicit DeckEditorDeckDockWidget(AbstractTabDeckEditor *parent);
|
||||
DeckLoader *deckLoader;
|
||||
DeckListModel *deckModel;
|
||||
QTreeView *deckView;
|
||||
QComboBox *bannerCardComboBox;
|
||||
|
|
@ -50,7 +51,7 @@ public slots:
|
|||
void cleanDeck();
|
||||
void updateBannerCardComboBox();
|
||||
void setDeck(DeckLoader *_deck);
|
||||
DeckLoader *getDeckList();
|
||||
DeckLoader *getDeckLoader();
|
||||
void actIncrement();
|
||||
bool swapCard(const QModelIndex &idx);
|
||||
void actDecrementCard(const ExactCard &card, QString zoneName);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
#include "deck_list_style_proxy.h"
|
||||
|
||||
#include <QBrush>
|
||||
#include <QColor>
|
||||
#include <QFont>
|
||||
#include <libcockatrice/models/deck_list/deck_list_model.h>
|
||||
|
||||
QVariant DeckListStyleProxy::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
QVariant value = QIdentityProxyModel::data(index, role);
|
||||
|
||||
const bool isCard = QIdentityProxyModel::data(index, DeckRoles::IsCardRole).toBool();
|
||||
|
||||
if (role == Qt::FontRole && !isCard) {
|
||||
QFont f;
|
||||
f.setBold(true);
|
||||
return f;
|
||||
}
|
||||
|
||||
if (role == Qt::BackgroundRole) {
|
||||
if (isCard) {
|
||||
const bool legal = QIdentityProxyModel::data(index, DeckRoles::IsLegalRole).toBool();
|
||||
int base = 255 - (index.row() % 2) * 30;
|
||||
return legal ? QBrush(QColor(base, base, base)) : QBrush(QColor(255, base / 3, base / 3));
|
||||
} else {
|
||||
int depth = QIdentityProxyModel::data(index, DeckRoles::DepthRole).toInt();
|
||||
int color = 90 + 60 * depth;
|
||||
return QBrush(QColor(color, 255, color));
|
||||
}
|
||||
}
|
||||
|
||||
if (role == Qt::ForegroundRole) {
|
||||
return QBrush(QColor(0, 0, 0));
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef COCKATRICE_DECK_LIST_STYLE_PROXY_H
|
||||
#define COCKATRICE_DECK_LIST_STYLE_PROXY_H
|
||||
|
||||
#include <QIdentityProxyModel>
|
||||
|
||||
class DeckListStyleProxy : public QIdentityProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using QIdentityProxyModel::QIdentityProxyModel;
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_DECK_LIST_STYLE_PROXY_H
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
#include "dlg_load_deck.h"
|
||||
|
||||
#include "../../../client/settings/cache_settings.h"
|
||||
|
||||
#include <libcockatrice/models/deck_list/deck_loader.h>
|
||||
#include "../../deck_loader/deck_loader.h"
|
||||
|
||||
DlgLoadDeck::DlgLoadDeck(QWidget *parent) : QFileDialog(parent, tr("Load Deck"))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "dlg_load_deck_from_clipboard.h"
|
||||
|
||||
#include "../../../client/settings/cache_settings.h"
|
||||
#include "../../deck_loader/deck_loader.h"
|
||||
#include "dlg_settings.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
|
@ -12,7 +13,6 @@
|
|||
#include <QPushButton>
|
||||
#include <QTextStream>
|
||||
#include <QVBoxLayout>
|
||||
#include <libcockatrice/models/deck_list/deck_loader.h>
|
||||
|
||||
/**
|
||||
* Creates the main layout and connects the signals that are common to all versions of this window
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "dlg_select_set_for_cards.h"
|
||||
|
||||
#include "../../deck_loader/deck_loader.h"
|
||||
#include "../interface/widgets/cards/card_info_picture_widget.h"
|
||||
#include "../interface/widgets/general/layout_containers/flow_widget.h"
|
||||
#include "dlg_select_set_for_cards.h"
|
||||
|
|
@ -16,7 +17,6 @@
|
|||
#include <QVBoxLayout>
|
||||
#include <algorithm>
|
||||
#include <libcockatrice/card/database/card_database_manager.h>
|
||||
#include <libcockatrice/models/deck_list/deck_loader.h>
|
||||
#include <qdrag.h>
|
||||
#include <qevent.h>
|
||||
|
||||
|
|
@ -162,14 +162,14 @@ void DlgSelectSetForCards::actOK()
|
|||
|
||||
void DlgSelectSetForCards::actClear()
|
||||
{
|
||||
model->getDeckList()->clearSetNamesAndNumbers();
|
||||
qobject_cast<DeckLoader *>(model->getDeckList())->clearSetNamesAndNumbers();
|
||||
accept();
|
||||
}
|
||||
|
||||
void DlgSelectSetForCards::actSetAllToPreferred()
|
||||
{
|
||||
model->getDeckList()->clearSetNamesAndNumbers();
|
||||
model->getDeckList()->setProviderIdToPreferredPrinting();
|
||||
qobject_cast<DeckLoader *>(model->getDeckList())->clearSetNamesAndNumbers();
|
||||
qobject_cast<DeckLoader *>(model->getDeckList())->setProviderIdToPreferredPrinting();
|
||||
accept();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@
|
|||
|
||||
#ifndef ALL_ZONES_CARD_AMOUNT_WIDGET_H
|
||||
#define ALL_ZONES_CARD_AMOUNT_WIDGET_H
|
||||
#include "../../deck_loader/deck_loader.h"
|
||||
#include "card_amount_widget.h"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
#include <libcockatrice/models/deck_list/deck_list_model.h>
|
||||
#include <libcockatrice/models/deck_list/deck_loader.h>
|
||||
|
||||
class AllZonesCardAmountWidget : public QWidget
|
||||
{
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#define CARD_AMOUNT_WIDGET_H
|
||||
|
||||
#include "../../../interface/widgets/tabs/abstract_tab_deck_editor.h"
|
||||
#include "../../deck_loader/deck_loader.h"
|
||||
#include "../general/display/dynamic_font_size_push_button.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
|
|
@ -18,7 +19,6 @@
|
|||
#include <QWidget>
|
||||
#include <libcockatrice/card/card_info.h>
|
||||
#include <libcockatrice/models/deck_list/deck_list_model.h>
|
||||
#include <libcockatrice/models/deck_list/deck_loader.h>
|
||||
|
||||
class CardAmountWidget : public QWidget
|
||||
{
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ void AbstractTabDeckEditor::openDeck(DeckLoader *deck)
|
|||
void AbstractTabDeckEditor::setDeck(DeckLoader *_deck)
|
||||
{
|
||||
deckDockWidget->setDeck(_deck);
|
||||
CardPictureLoader::cacheCardPixmaps(CardDatabaseManager::query()->getCards(getDeckList()->getCardRefList()));
|
||||
CardPictureLoader::cacheCardPixmaps(CardDatabaseManager::query()->getCards(getDeckLoader()->getCardRefList()));
|
||||
setModified(false);
|
||||
|
||||
aDeckDockVisible->setChecked(true);
|
||||
|
|
@ -217,9 +217,9 @@ void AbstractTabDeckEditor::setDeck(DeckLoader *_deck)
|
|||
}
|
||||
|
||||
/** @brief Returns the currently loaded deck. */
|
||||
DeckLoader *AbstractTabDeckEditor::getDeckList() const
|
||||
DeckLoader *AbstractTabDeckEditor::getDeckLoader() const
|
||||
{
|
||||
return deckDockWidget->getDeckList();
|
||||
return deckDockWidget->getDeckLoader();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -237,7 +237,7 @@ void AbstractTabDeckEditor::setModified(bool _modified)
|
|||
*/
|
||||
bool AbstractTabDeckEditor::isBlankNewDeck() const
|
||||
{
|
||||
DeckLoader *deck = getDeckList();
|
||||
DeckLoader *deck = deckDockWidget->getDeckLoader();
|
||||
return !modified && deck->isBlankDeck() && deck->hasNotBeenLoaded();
|
||||
}
|
||||
|
||||
|
|
@ -377,7 +377,7 @@ void AbstractTabDeckEditor::openDeckFromFile(const QString &fileName, DeckOpenLo
|
|||
*/
|
||||
bool AbstractTabDeckEditor::actSaveDeck()
|
||||
{
|
||||
DeckLoader *const deck = getDeckList();
|
||||
DeckLoader *const deck = getDeckLoader();
|
||||
if (deck->getLastRemoteDeckId() != -1) {
|
||||
QString deckString = deck->writeToString_Native();
|
||||
if (deckString.length() > MAX_FILE_LENGTH) {
|
||||
|
|
@ -418,7 +418,7 @@ bool AbstractTabDeckEditor::actSaveDeckAs()
|
|||
dialog.setAcceptMode(QFileDialog::AcceptSave);
|
||||
dialog.setDefaultSuffix("cod");
|
||||
dialog.setNameFilters(DeckLoader::FILE_NAME_FILTERS);
|
||||
dialog.selectFile(getDeckList()->getName().trimmed());
|
||||
dialog.selectFile(getDeckLoader()->getName().trimmed());
|
||||
|
||||
if (!dialog.exec())
|
||||
return false;
|
||||
|
|
@ -426,7 +426,7 @@ bool AbstractTabDeckEditor::actSaveDeckAs()
|
|||
QString fileName = dialog.selectedFiles().at(0);
|
||||
DeckLoader::FileFormat fmt = DeckLoader::getFormatFromName(fileName);
|
||||
|
||||
if (!getDeckList()->saveToFile(fileName, fmt)) {
|
||||
if (!getDeckLoader()->saveToFile(fileName, fmt)) {
|
||||
QMessageBox::critical(
|
||||
this, tr("Error"),
|
||||
tr("The deck could not be saved.\nPlease check that the directory is writable and try again."));
|
||||
|
|
@ -480,7 +480,7 @@ void AbstractTabDeckEditor::actLoadDeckFromClipboard()
|
|||
*/
|
||||
void AbstractTabDeckEditor::editDeckInClipboard(bool annotated)
|
||||
{
|
||||
DlgEditDeckInClipboard dlg(*getDeckList(), annotated, this);
|
||||
DlgEditDeckInClipboard dlg(*getDeckLoader(), annotated, this);
|
||||
if (!dlg.exec())
|
||||
return;
|
||||
|
||||
|
|
@ -504,32 +504,32 @@ void AbstractTabDeckEditor::actEditDeckInClipboardRaw()
|
|||
/** @brief Saves deck to clipboard with set info and annotation. */
|
||||
void AbstractTabDeckEditor::actSaveDeckToClipboard()
|
||||
{
|
||||
getDeckList()->saveToClipboard(true, true);
|
||||
getDeckLoader()->saveToClipboard(true, true);
|
||||
}
|
||||
|
||||
/** @brief Saves deck to clipboard with annotation, without set info. */
|
||||
void AbstractTabDeckEditor::actSaveDeckToClipboardNoSetInfo()
|
||||
{
|
||||
getDeckList()->saveToClipboard(true, false);
|
||||
getDeckLoader()->saveToClipboard(true, false);
|
||||
}
|
||||
|
||||
/** @brief Saves deck to clipboard without annotations, with set info. */
|
||||
void AbstractTabDeckEditor::actSaveDeckToClipboardRaw()
|
||||
{
|
||||
getDeckList()->saveToClipboard(false, true);
|
||||
getDeckLoader()->saveToClipboard(false, true);
|
||||
}
|
||||
|
||||
/** @brief Saves deck to clipboard without annotations or set info. */
|
||||
void AbstractTabDeckEditor::actSaveDeckToClipboardRawNoSetInfo()
|
||||
{
|
||||
getDeckList()->saveToClipboard(false, false);
|
||||
getDeckLoader()->saveToClipboard(false, false);
|
||||
}
|
||||
|
||||
/** @brief Prints the deck using a QPrintPreviewDialog. */
|
||||
void AbstractTabDeckEditor::actPrintDeck()
|
||||
{
|
||||
auto *dlg = new QPrintPreviewDialog(this);
|
||||
connect(dlg, &QPrintPreviewDialog::paintRequested, deckDockWidget->deckModel, &DeckListModel::printDeckList);
|
||||
connect(dlg, &QPrintPreviewDialog::paintRequested, deckDockWidget->getDeckLoader(), &DeckLoader::printDeckList);
|
||||
dlg->exec();
|
||||
}
|
||||
|
||||
|
|
@ -562,7 +562,7 @@ void AbstractTabDeckEditor::actLoadDeckFromWebsite()
|
|||
*/
|
||||
void AbstractTabDeckEditor::exportToDecklistWebsite(DeckLoader::DecklistWebsite website)
|
||||
{
|
||||
if (DeckLoader *const deck = getDeckList()) {
|
||||
if (DeckLoader *const deck = getDeckLoader()) {
|
||||
QString decklistUrlString = deck->exportDeckToDecklist(website);
|
||||
// Check to make sure the string isn't empty.
|
||||
if (decklistUrlString.isEmpty()) {
|
||||
|
|
@ -600,14 +600,14 @@ void AbstractTabDeckEditor::actExportDeckDecklistXyz()
|
|||
void AbstractTabDeckEditor::actAnalyzeDeckDeckstats()
|
||||
{
|
||||
auto *interface = new DeckStatsInterface(*databaseDisplayDockWidget->databaseModel->getDatabase(), this);
|
||||
interface->analyzeDeck(getDeckList());
|
||||
interface->analyzeDeck(getDeckLoader());
|
||||
}
|
||||
|
||||
/** @brief Analyzes the deck using TappedOut. */
|
||||
void AbstractTabDeckEditor::actAnalyzeDeckTappedout()
|
||||
{
|
||||
auto *interface = new TappedOutInterface(*databaseDisplayDockWidget->databaseModel->getDatabase(), this);
|
||||
interface->analyzeDeck(getDeckList());
|
||||
interface->analyzeDeck(getDeckLoader());
|
||||
}
|
||||
|
||||
/** @brief Applies a new filter tree to the database display. */
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ public:
|
|||
void openDeck(DeckLoader *deck);
|
||||
|
||||
/** @brief Returns the currently active deck. */
|
||||
DeckLoader *getDeckList() const;
|
||||
DeckLoader *getDeckLoader() const;
|
||||
|
||||
/** @brief Sets the modified state of the tab.
|
||||
* @param _windowModified Whether the tab is modified.
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
#include "edhrec_deck_api_response.h"
|
||||
|
||||
#include "../../../../../../deck_loader/deck_loader.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QMainWindow>
|
||||
#include <libcockatrice/models/deck_list/deck_loader.h>
|
||||
|
||||
void EdhrecDeckApiResponse::fromJson(const QJsonArray &json)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,12 +7,13 @@
|
|||
#ifndef EDHREC_DECK_API_RESPONSE_H
|
||||
#define EDHREC_DECK_API_RESPONSE_H
|
||||
|
||||
#include "../../../../../../deck_loader/deck_loader.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
#include <libcockatrice/models/deck_list/deck_loader.h>
|
||||
|
||||
class EdhrecDeckApiResponse
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "tab_deck_storage.h"
|
||||
|
||||
#include "../../../client/settings/cache_settings.h"
|
||||
#include "../../deck_loader/deck_loader.h"
|
||||
#include "../interface/widgets/server/remote/remote_decklist_tree_widget.h"
|
||||
#include "../interface/widgets/utility/get_text_with_max.h"
|
||||
|
||||
|
|
@ -19,7 +20,6 @@
|
|||
#include <QUrl>
|
||||
#include <QVBoxLayout>
|
||||
#include <libcockatrice/deck_list/deck_list.h>
|
||||
#include <libcockatrice/models/deck_list/deck_loader.h>
|
||||
#include <libcockatrice/protocol/pb/command_deck_del.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_deck_del_dir.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_deck_download.pb.h>
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#ifndef TAB_SUPERVISOR_H
|
||||
#define TAB_SUPERVISOR_H
|
||||
|
||||
#include "../../deck_loader/deck_loader.h"
|
||||
#include "../interface/widgets/server/user/user_list_proxy.h"
|
||||
#include "abstract_tab_deck_editor.h"
|
||||
#include "api/edhrec/tab_edhrec.h"
|
||||
|
|
@ -23,7 +24,6 @@
|
|||
#include <QMap>
|
||||
#include <QProxyStyle>
|
||||
#include <QTabWidget>
|
||||
#include <libcockatrice/models/deck_list/deck_loader.h>
|
||||
|
||||
inline Q_LOGGING_CATEGORY(TabSupervisorLog, "tab_supervisor");
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
#include "visual_deck_editor_sample_hand_widget.h"
|
||||
|
||||
#include "../../../client/settings/cache_settings.h"
|
||||
#include "../../deck_loader/deck_loader.h"
|
||||
#include "../cards/card_info_picture_widget.h"
|
||||
|
||||
#include <libcockatrice/card/database/card_database_manager.h>
|
||||
#include <libcockatrice/models/deck_list/deck_loader.h>
|
||||
#include <random>
|
||||
|
||||
VisualDeckEditorSampleHandWidget::VisualDeckEditorSampleHandWidget(QWidget *parent, DeckListModel *_deckListModel)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "visual_deck_editor_widget.h"
|
||||
|
||||
#include "../../../main.h"
|
||||
#include "../../deck_loader/deck_loader.h"
|
||||
#include "../../layouts/overlap_layout.h"
|
||||
#include "../cards/card_info_picture_with_text_overlay_widget.h"
|
||||
#include "../cards/deck_card_zone_display_widget.h"
|
||||
|
|
@ -22,7 +23,6 @@
|
|||
#include <libcockatrice/models/database/card/card_search_model.h>
|
||||
#include <libcockatrice/models/database/card_database_model.h>
|
||||
#include <libcockatrice/models/deck_list/deck_list_model.h>
|
||||
#include <libcockatrice/models/deck_list/deck_loader.h>
|
||||
#include <qscrollarea.h>
|
||||
|
||||
VisualDeckEditorWidget::VisualDeckEditorWidget(QWidget *parent, DeckListModel *_deckListModel)
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@
|
|||
#ifndef DECK_PREVIEW_DECK_TAGS_DISPLAY_WIDGET_H
|
||||
#define DECK_PREVIEW_DECK_TAGS_DISPLAY_WIDGET_H
|
||||
|
||||
#include "../../../deck_loader/deck_loader.h"
|
||||
#include "deck_preview_widget.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <libcockatrice/models/deck_list/deck_loader.h>
|
||||
|
||||
inline bool confirmOverwriteIfExists(QWidget *parent, const QString &filePath);
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#ifndef DECK_PREVIEW_WIDGET_H
|
||||
#define DECK_PREVIEW_WIDGET_H
|
||||
|
||||
#include "../../../deck_loader/deck_loader.h"
|
||||
#include "../../cards/additional_info/color_identity_widget.h"
|
||||
#include "../../cards/deck_preview_card_picture_widget.h"
|
||||
#include "../visual_deck_storage_widget.h"
|
||||
|
|
@ -18,7 +19,6 @@
|
|||
#include <QEvent>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
#include <libcockatrice/models/deck_list/deck_loader.h>
|
||||
|
||||
class QMenu;
|
||||
class VisualDeckStorageWidget;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#ifndef VISUAL_DECK_STORAGE_WIDGET_H
|
||||
#define VISUAL_DECK_STORAGE_WIDGET_H
|
||||
|
||||
#include "../../deck_loader/deck_loader.h"
|
||||
#include "../cards/card_size_widget.h"
|
||||
#include "../general/layout_containers/flow_widget.h"
|
||||
#include "../quick_settings/settings_button_widget.h"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue