Add a button to fetch card prices.

This commit is contained in:
Lukas Brübach 2025-05-09 03:34:02 +02:00
parent 278d0052f5
commit db79534530
5 changed files with 135 additions and 40 deletions

View file

@ -145,6 +145,7 @@ set(cockatrice_SOURCES
src/deck/deck_list_model.cpp src/deck/deck_list_model.cpp
src/deck/deck_loader.cpp src/deck/deck_loader.cpp
src/deck/deck_stats_interface.cpp src/deck/deck_stats_interface.cpp
src/dialogs/dlg_get_card_prices.cpp
src/dialogs/dlg_connect.cpp src/dialogs/dlg_connect.cpp
src/dialogs/dlg_convert_deck_to_cod_format.cpp src/dialogs/dlg_convert_deck_to_cod_format.cpp
src/dialogs/dlg_create_game.cpp src/dialogs/dlg_create_game.cpp

View file

@ -1,5 +1,6 @@
#include "deck_editor_deck_dock_widget.h" #include "deck_editor_deck_dock_widget.h"
#include "../../../../../../../../../../../mnt/games-hdd/coding/CLionProjects/Cockatrice/cockatrice/src/dialogs/dlg_get_card_prices.h"
#include "../../../../game/cards/card_database_manager.h" #include "../../../../game/cards/card_database_manager.h"
#include "../../../../settings/cache_settings.h" #include "../../../../settings/cache_settings.h"
@ -144,6 +145,14 @@ void DeckEditorDeckDockWidget::createDeckDock()
upperLayout->addWidget(deckTagsDisplayWidget, 3, 1); upperLayout->addWidget(deckTagsDisplayWidget, 3, 1);
cardPricesButton = new QPushButton(this);
connect(cardPricesButton, &QPushButton::clicked, this, [this]() {
auto pricesDialog = new DlgGetCardPrices(this, deckModel);
pricesDialog->exec();
});
upperLayout->addWidget(cardPricesButton, 4, 1);
hashLabel1 = new QLabel(); hashLabel1 = new QLabel();
hashLabel1->setObjectName("hashLabel1"); hashLabel1->setObjectName("hashLabel1");
auto *hashSizePolicy = new QSizePolicy(); auto *hashSizePolicy = new QSizePolicy();
@ -566,6 +575,7 @@ void DeckEditorDeckDockWidget::retranslateUi()
showBannerCardCheckBox->setText(tr("Show banner card selection menu")); showBannerCardCheckBox->setText(tr("Show banner card selection menu"));
showTagsWidgetCheckBox->setText(tr("Show tags selection menu")); showTagsWidgetCheckBox->setText(tr("Show tags selection menu"));
commentsLabel->setText(tr("&Comments:")); commentsLabel->setText(tr("&Comments:"));
cardPricesButton->setText(tr("Fetch Card Prices"));
hashLabel1->setText(tr("Hash:")); hashLabel1->setText(tr("Hash:"));
aIncrement->setText(tr("&Increment number")); aIncrement->setText(tr("&Increment number"));

View file

@ -64,6 +64,7 @@ private:
QTextEdit *commentsEdit; QTextEdit *commentsEdit;
QLabel *bannerCardLabel; QLabel *bannerCardLabel;
DeckPreviewDeckTagsDisplayWidget *deckTagsDisplayWidget; DeckPreviewDeckTagsDisplayWidget *deckTagsDisplayWidget;
QPushButton *cardPricesButton;
QLabel *hashLabel1; QLabel *hashLabel1;
LineEditUnfocusable *hashLabel; LineEditUnfocusable *hashLabel;

View file

@ -6,6 +6,7 @@
#include "../game/cards/card_database_manager.h" #include "../game/cards/card_database_manager.h"
#include <QCheckBox> #include <QCheckBox>
#include <QComboBox>
#include <QDialogButtonBox> #include <QDialogButtonBox>
#include <QHeaderView> #include <QHeaderView>
#include <QItemSelectionModel> #include <QItemSelectionModel>
@ -14,6 +15,7 @@
#include <QLabel> #include <QLabel>
#include <QNetworkRequest> #include <QNetworkRequest>
#include <QProgressBar> #include <QProgressBar>
#include <QPushButton>
#include <QScrollArea> #include <QScrollArea>
#include <QSplitter> #include <QSplitter>
#include <QTableWidget> #include <QTableWidget>
@ -21,6 +23,7 @@
#include <QUrlQuery> #include <QUrlQuery>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <limits> #include <limits>
#include <qdialogbuttonbox.h>
DlgGetCardPrices::DlgGetCardPrices(QWidget *parent, DeckListModel *_model) : QDialog(parent), model(_model) DlgGetCardPrices::DlgGetCardPrices(QWidget *parent, DeckListModel *_model) : QDialog(parent), model(_model)
{ {
@ -31,18 +34,34 @@ DlgGetCardPrices::DlgGetCardPrices(QWidget *parent, DeckListModel *_model) : QDi
instructionLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); instructionLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
minTotalLabel = new QLabel(this); minTotalLabel = new QLabel(this);
minTotalLabel->setHidden(true);
maxTotalLabel = new QLabel(this); maxTotalLabel = new QLabel(this);
maxTotalLabel->setHidden(true);
QVBoxLayout *mainLayout = new QVBoxLayout(this); QVBoxLayout *mainLayout = new QVBoxLayout(this);
setLayout(mainLayout); setLayout(mainLayout);
allPrintingsCheckBox = new QCheckBox("Check prices for all printings of every card", this);
allPrintingsCheckBox->setChecked(false);
connect(allPrintingsCheckBox, &QCheckBox::toggled, this, &DlgGetCardPrices::onAllPrintingsChanged);
excludeLandsCheckBox = new QCheckBox("Exclude Lands", this); excludeLandsCheckBox = new QCheckBox("Exclude Lands", this);
excludeLandsCheckBox->setChecked(true); excludeLandsCheckBox->setChecked(true);
connect(excludeLandsCheckBox, &QCheckBox::toggled, this, &DlgGetCardPrices::onExcludeLandsChanged); connect(excludeLandsCheckBox, &QCheckBox::toggled, this, &DlgGetCardPrices::onExcludeLandsChanged);
currencyComboBox = new QComboBox(this);
currencyComboBox->addItem("Euro (€)", QVariant(QString("eur")));
currencyComboBox->addItem("US Dollar ($)", QVariant(QString("usd")));
currencyComboBox->setCurrentIndex(0);
connect(currencyComboBox, &QComboBox::currentIndexChanged, this, &DlgGetCardPrices::onCurrencyChanged);
tableWidget = new QTableWidget(this); tableWidget = new QTableWidget(this);
tableWidget->setColumnCount(4); tableWidget->setColumnCount(7);
tableWidget->setHorizontalHeaderLabels({"Card Name", "Actual", "Min", "Max"}); tableWidget->setHorizontalHeaderLabels({"Card Name", "Actual", "Actual Set", "Min", "Min Set", "Max", "Max Set"});
tableWidget->setColumnHidden(3, true);
tableWidget->setColumnHidden(4, true);
tableWidget->setColumnHidden(5, true);
tableWidget->setColumnHidden(6, true);
tableWidget->setSelectionMode(QAbstractItemView::MultiSelection); tableWidget->setSelectionMode(QAbstractItemView::MultiSelection);
tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
@ -57,16 +76,18 @@ DlgGetCardPrices::DlgGetCardPrices(QWidget *parent, DeckListModel *_model) : QDi
scrollArea->setWidgetResizable(true); scrollArea->setWidgetResizable(true);
scrollArea->setWidget(tableWidget); scrollArea->setWidget(tableWidget);
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
connect(buttonBox, &QDialogButtonBox::accepted, this, &DlgGetCardPrices::actOK); fetchButton = new QPushButton(this);
buttonBox->addButton(fetchButton, QDialogButtonBox::ButtonRole::ActionRole);
connect(fetchButton, &QPushButton::clicked, this, &DlgGetCardPrices::actOK);
connect(buttonBox, &QDialogButtonBox::rejected, this, &DlgGetCardPrices::reject); connect(buttonBox, &QDialogButtonBox::rejected, this, &DlgGetCardPrices::reject);
QHBoxLayout *progressLayout = new QHBoxLayout(); QHBoxLayout *progressLayout = new QHBoxLayout();
progressBar = new QProgressBar(this); progressBar = new QProgressBar(this);
progressLabel = new QLabel("0/0 cards loaded", this); progressLabel = new QLabel(this);
uuidProgressBar = new QProgressBar(this); uuidProgressBar = new QProgressBar(this);
uuidProgressLabel = new QLabel("0/0 prices fetched", this); uuidProgressLabel = new QLabel(this);
progressBar->setMinimum(0); progressBar->setMinimum(0);
progressBar->setMaximum(0); // Set to 0 until we know how many cards progressBar->setMaximum(0); // Set to 0 until we know how many cards
@ -84,7 +105,9 @@ DlgGetCardPrices::DlgGetCardPrices(QWidget *parent, DeckListModel *_model) : QDi
mainLayout->addWidget(instructionLabel); mainLayout->addWidget(instructionLabel);
mainLayout->addWidget(minTotalLabel); mainLayout->addWidget(minTotalLabel);
mainLayout->addWidget(maxTotalLabel); mainLayout->addWidget(maxTotalLabel);
mainLayout->addWidget(allPrintingsCheckBox);
mainLayout->addWidget(excludeLandsCheckBox); mainLayout->addWidget(excludeLandsCheckBox);
mainLayout->addWidget(currencyComboBox);
mainLayout->addWidget(scrollArea); mainLayout->addWidget(scrollArea);
mainLayout->addWidget(buttonBox); mainLayout->addWidget(buttonBox);
mainLayout->addLayout(progressLayout); mainLayout->addLayout(progressLayout);
@ -92,8 +115,6 @@ DlgGetCardPrices::DlgGetCardPrices(QWidget *parent, DeckListModel *_model) : QDi
retranslateUi(); retranslateUi();
connect(this, &DlgGetCardPrices::allRequestsFinished, this, &DlgGetCardPrices::onAllRequestsFinished); connect(this, &DlgGetCardPrices::allRequestsFinished, this, &DlgGetCardPrices::onAllRequestsFinished);
startCardPriceRequests();
} }
void DlgGetCardPrices::startCardPriceRequests() void DlgGetCardPrices::startCardPriceRequests()
@ -141,7 +162,7 @@ void DlgGetCardPrices::startCardPriceRequests()
if (excludeLandsCheckBox->isChecked()) { if (excludeLandsCheckBox->isChecked()) {
CardInfoPtr card = CardDatabaseManager::getInstance()->getCard(cardName); CardInfoPtr card = CardDatabaseManager::getInstance()->getCard(cardName);
if (card->getMainCardType() == "Land") if (!card || card->getMainCardType() == "Land")
continue; continue;
} }
@ -152,16 +173,20 @@ void DlgGetCardPrices::startCardPriceRequests()
QString actualUuid = currentCard->getCardProviderId(); QString actualUuid = currentCard->getCardProviderId();
QList<QString> &uuidList = printingsByCardName[cardName]; QList<QString> &uuidList = printingsByCardName[cardName];
CardInfoPerSetMap allSets = info->getSets(); if (allPrintingsCheckBox->isChecked()) {
for (QList cardsInSet : allSets) { CardInfoPerSetMap allSets = info->getSets();
for (CardInfoPerSet cardInSet : cardsInSet) { for (QList cardsInSet : allSets) {
QString uuid = cardInSet.getProperty("uuid"); for (CardInfoPerSet cardInSet : cardsInSet) {
uuidList.append(uuid); QString uuid = cardInSet.getProperty("uuid");
uuidToCardName[uuid] = cardName; uuidList.append(uuid);
uuidToCardName[uuid] = cardName;
}
} }
} else {
uuidList.append(actualUuid);
uuidToCardName[actualUuid] = cardName;
} }
// Make sure no duplicates
uuidList.removeDuplicates(); uuidList.removeDuplicates();
pendingPerCard[cardName] = uuidList.size(); pendingPerCard[cardName] = uuidList.size();
@ -169,7 +194,7 @@ void DlgGetCardPrices::startCardPriceRequests()
totalCardsToProcess++; totalCardsToProcess++;
progressBar->setMaximum(totalCardsToProcess); progressBar->setMaximum(totalCardsToProcess);
progressBar->setValue(0); progressBar->setValue(0);
progressLabel->setText(QString("0/%1 cards loaded").arg(totalCardsToProcess)); progressLabel->setText(QString(tr("0/%1 cards loaded")).arg(totalCardsToProcess));
finishedCardCount = 0; finishedCardCount = 0;
for (const QString &uuid : uuidList) { for (const QString &uuid : uuidList) {
@ -213,7 +238,7 @@ void DlgGetCardPrices::onCardPriceReply()
QJsonObject obj = jsonDoc.object(); QJsonObject obj = jsonDoc.object();
if (obj.contains("prices") && obj["prices"].isObject()) { if (obj.contains("prices") && obj["prices"].isObject()) {
QJsonObject prices = obj["prices"].toObject(); QJsonObject prices = obj["prices"].toObject();
double eurValue = prices["eur"].toString().toDouble(); double eurValue = prices[currencyComboBox->currentData(Qt::UserRole).toString()].toString().toDouble();
uuidPrices[uuid] = eurValue; uuidPrices[uuid] = eurValue;
} }
} }
@ -225,15 +250,17 @@ void DlgGetCardPrices::onCardPriceReply()
finishedRequests++; finishedRequests++;
uuidProgressBar->setValue(finishedRequests); uuidProgressBar->setValue(finishedRequests);
uuidProgressLabel->setText(QString("%1/%2 prices fetched").arg(finishedRequests).arg(totalRequests)); uuidProgressLabel->setText(QString(tr("%1/%2 prices fetched")).arg(finishedRequests).arg(totalRequests));
if (--pendingPerCard[cardName] == 0) { if (--pendingPerCard[cardName] == 0) {
finishedCardCount++; finishedCardCount++;
progressBar->setValue(finishedCardCount); progressBar->setValue(finishedCardCount);
progressLabel->setText(QString("%1/%2 cards loaded").arg(finishedCardCount).arg(totalCardsToProcess)); progressLabel->setText(QString(tr("%1/%2 cards loaded")).arg(finishedCardCount).arg(totalCardsToProcess));
const QList<QString> &uuids = printingsByCardName.value(cardName); const QList<QString> &uuids = printingsByCardName.value(cardName);
QString actualUuid = actualUuidsByCardName.value(cardName); QString actualUuid = actualUuidsByCardName.value(cardName);
QString minUuid = "";
QString maxUuid = "";
double minPrice = std::numeric_limits<double>::max(); double minPrice = std::numeric_limits<double>::max();
double maxPrice = std::numeric_limits<double>::lowest(); double maxPrice = std::numeric_limits<double>::lowest();
@ -243,18 +270,24 @@ void DlgGetCardPrices::onCardPriceReply()
for (const QString &u : uuids) { for (const QString &u : uuids) {
double price = uuidPrices.value(u, -1.0); double price = uuidPrices.value(u, -1.0);
if (price <= 0.0) if (price <= 0.0) {
continue; continue;
}
hasValidPrice = true; hasValidPrice = true;
if (u == actualUuid) if (u == actualUuid) {
actualPrice = price; actualPrice = price;
}
if (price <= minPrice) if (price <= minPrice) {
minPrice = price; minPrice = price;
if (price >= maxPrice) minUuid = u;
}
if (price >= maxPrice) {
maxPrice = price; maxPrice = price;
maxUuid = u;
}
} }
if (!hasValidPrice) { if (!hasValidPrice) {
@ -265,9 +298,13 @@ void DlgGetCardPrices::onCardPriceReply()
tableWidget->setItem(row, 1, new CardPriceTableWidgetItem("N/A")); tableWidget->setItem(row, 1, new CardPriceTableWidgetItem("N/A"));
tableWidget->setItem(row, 2, new CardPriceTableWidgetItem("N/A")); tableWidget->setItem(row, 2, new CardPriceTableWidgetItem("N/A"));
tableWidget->setItem(row, 3, new CardPriceTableWidgetItem("N/A")); tableWidget->setItem(row, 3, new CardPriceTableWidgetItem("N/A"));
tableWidget->setItem(row, 4, new CardPriceTableWidgetItem("N/A"));
tableWidget->setItem(row, 5, new CardPriceTableWidgetItem("N/A"));
tableWidget->setItem(row, 6, new CardPriceTableWidgetItem("N/A"));
} else { } else {
if (actualPrice < 0.0) if (actualPrice < 0.0) {
actualPrice = minPrice; // fallback actualPrice = minPrice; // fallback
}
totalPrice += actualPrice; totalPrice += actualPrice;
totalMinPrice += minPrice; totalMinPrice += minPrice;
@ -277,8 +314,23 @@ void DlgGetCardPrices::onCardPriceReply()
tableWidget->insertRow(row); tableWidget->insertRow(row);
tableWidget->setItem(row, 0, new CardPriceTableWidgetItem(cardName)); tableWidget->setItem(row, 0, new CardPriceTableWidgetItem(cardName));
tableWidget->setItem(row, 1, new CardPriceTableWidgetItem(QString::number(actualPrice, 'f', 2))); tableWidget->setItem(row, 1, new CardPriceTableWidgetItem(QString::number(actualPrice, 'f', 2)));
tableWidget->setItem(row, 2, new CardPriceTableWidgetItem(QString::number(minPrice, 'f', 2))); tableWidget->setItem(row, 2,
tableWidget->setItem(row, 3, new CardPriceTableWidgetItem(QString::number(maxPrice, 'f', 2))); new CardPriceTableWidgetItem(CardDatabaseManager::getInstance()
->getSpecificSetForCard(cardName, actualUuid)
.getPtr()
->getShortName()));
tableWidget->setItem(row, 3, new CardPriceTableWidgetItem(QString::number(minPrice, 'f', 2)));
tableWidget->setItem(row, 4,
new CardPriceTableWidgetItem(CardDatabaseManager::getInstance()
->getSpecificSetForCard(cardName, minUuid)
.getPtr()
->getShortName()));
tableWidget->setItem(row, 5, new CardPriceTableWidgetItem(QString::number(maxPrice, 'f', 2)));
tableWidget->setItem(row, 6,
new CardPriceTableWidgetItem(CardDatabaseManager::getInstance()
->getSpecificSetForCard(cardName, maxUuid)
.getPtr()
->getShortName()));
} }
} }
@ -290,12 +342,18 @@ void DlgGetCardPrices::onCardPriceReply()
void DlgGetCardPrices::onAllRequestsFinished() void DlgGetCardPrices::onAllRequestsFinished()
{ {
instructionLabel->setText(tr("Total Price: %1 EUR (%2%)") instructionLabel->setText(tr("Total Price: %1 %2 (%3%)")
.arg(totalPrice, 0, 'f', 2) .arg(totalPrice, 0, 'f', 2)
.arg(100.0, 0, 'f', 2)); .arg(currencyComboBox->currentData(Qt::DisplayRole).toString())
.arg(100.0, 0, 'f', 2));
minTotalLabel->setText(tr("Minimum Possible Total: %1 EUR").arg(totalMinPrice, 0, 'f', 2)); minTotalLabel->setText(tr("Minimum Possible Total: %1 %2")
maxTotalLabel->setText(tr("Maximum Possible Total: %1 EUR").arg(totalMaxPrice, 0, 'f', 2)); .arg(totalMinPrice, 0, 'f', 2)
.arg(currencyComboBox->currentData(Qt::DisplayRole).toString()));
maxTotalLabel->setText(tr("Maximum Possible Total: %1 %2")
.arg(totalMaxPrice, 0, 'f', 2)
.arg(currencyComboBox->currentData(Qt::DisplayRole).toString()));
fetchButton->setDisabled(false);
} }
void DlgGetCardPrices::onSelectionChanged() void DlgGetCardPrices::onSelectionChanged()
@ -314,15 +372,33 @@ void DlgGetCardPrices::onSelectionChanged()
void DlgGetCardPrices::onExcludeLandsChanged(bool checked) void DlgGetCardPrices::onExcludeLandsChanged(bool checked)
{ {
Q_UNUSED(checked) Q_UNUSED(checked)
startCardPriceRequests(); }
void DlgGetCardPrices::onCurrencyChanged(int index)
{
Q_UNUSED(index);
}
void DlgGetCardPrices::onAllPrintingsChanged(bool checked)
{
minTotalLabel->setHidden(!checked);
maxTotalLabel->setHidden(!checked);
tableWidget->setColumnHidden(3, !checked);
tableWidget->setColumnHidden(4, !checked);
tableWidget->setColumnHidden(5, !checked);
tableWidget->setColumnHidden(6, !checked);
} }
void DlgGetCardPrices::retranslateUi() void DlgGetCardPrices::retranslateUi()
{ {
instructionLabel->setText(tr("Fetching card prices... Please wait.")); instructionLabel->setText(tr("Press fetch to start."));
fetchButton->setText(tr("Fetch!"));
progressLabel->setText(tr("0/0 cards loaded"));
uuidProgressLabel->setText(tr("0/0 prices fetched"));
} }
void DlgGetCardPrices::actOK() void DlgGetCardPrices::actOK()
{ {
accept(); fetchButton->setDisabled(true);
startCardPriceRequests();
} }

View file

@ -5,10 +5,12 @@
#include "../deck/deck_list_model.h" #include "../deck/deck_list_model.h"
#include <QCheckBox> // Include for the checkbox #include <QCheckBox> // Include for the checkbox
#include <QComboBox>
#include <QDialog> #include <QDialog>
#include <QMap> #include <QMap>
#include <QNetworkAccessManager> #include <QNetworkAccessManager>
#include <QNetworkReply> #include <QNetworkReply>
#include <QPushButton>
#include <QProgressBar> #include <QProgressBar>
#include <QStringList> #include <QStringList>
#include <QTableWidget> #include <QTableWidget>
@ -54,7 +56,9 @@ public:
void onAllRequestsFinished(); void onAllRequestsFinished();
void actOK(); void actOK();
void onSelectionChanged(); void onSelectionChanged();
void onExcludeLandsChanged(bool checked); // Slot for handling checkbox state change void onExcludeLandsChanged(bool checked);
void onAllPrintingsChanged(bool checked);
void onCurrencyChanged(int index);
private: private:
void retranslateUi(); void retranslateUi();
@ -71,16 +75,19 @@ private:
int pendingRequests = 0; int pendingRequests = 0;
int totalRequests = 0; int totalRequests = 0;
int finishedRequests = 0; int finishedRequests = 0;
QMap<QString, QStringList> setCards; // Result storage QMap<QString, QStringList> setCards;
double totalPrice = 0.0; // Tracks total price of all cards double totalPrice = 0.0;
double totalMinPrice = 0.0; double totalMinPrice = 0.0;
double totalMaxPrice = 0.0; double totalMaxPrice = 0.0;
QCheckBox *excludeLandsCheckBox; // CheckBox to exclude lands QCheckBox *allPrintingsCheckBox;
QCheckBox *excludeLandsCheckBox;
QComboBox *currencyComboBox;
QMap<QString, QList<QString>> printingsByCardName; QMap<QString, QList<QString>> printingsByCardName;
QMap<QString, double> uuidPrices; QMap<QString, double> uuidPrices;
QMap<QString, QString> uuidToCardName; QMap<QString, QString> uuidToCardName;
QMap<QString, int> pendingPerCard; QMap<QString, int> pendingPerCard;
QMap<QString, QString> actualUuidsByCardName; QMap<QString, QString> actualUuidsByCardName;
QPushButton *fetchButton;
QProgressBar *progressBar; QProgressBar *progressBar;
QProgressBar *uuidProgressBar; QProgressBar *uuidProgressBar;
QLabel *progressLabel; QLabel *progressLabel;