[Move refactor] Move tabs to interface/widgets (#6235)

* Move tabs to interface/widgets.

---------

Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
BruebachL 2025-10-09 14:51:47 +02:00 committed by GitHub
parent d9c65d4ae0
commit b8983f27ab
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
134 changed files with 111 additions and 112 deletions

View file

@ -0,0 +1,43 @@
#include "edhrec_api_response_archidekt_links.h"
#include <QDebug>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
void EdhrecApiResponseArchidektLink::fromJson(const QJsonObject &json)
{
c = json.value("c").toString();
f = json.value("f").toInt(0);
q = json.value("q").toInt(0);
u = json.value("u").toString();
}
void EdhrecApiResponseArchidektLink::debugPrint() const
{
qDebug() << " C:" << c;
qDebug() << " F:" << f;
qDebug() << " Q:" << q;
qDebug() << " U:" << u;
}
void EdhrecCommanderApiResponseArchidektLinks::fromJson(const QJsonArray &json)
{
entries.clear();
for (const QJsonValue &value : json) {
if (value.isObject()) {
QJsonObject entryJson = value.toObject();
EdhrecApiResponseArchidektLink entry;
entry.fromJson(entryJson);
entries.append(entry);
}
}
}
void EdhrecCommanderApiResponseArchidektLinks::debugPrint() const
{
qDebug() << "Archidekt Entries:";
for (const auto &entry : entries) {
entry.debugPrint();
}
}

View file

@ -0,0 +1,40 @@
#ifndef ARCHIDEKTENTRY_H
#define ARCHIDEKTENTRY_H
#include <QDebug>
#include <QJsonObject>
#include <QString>
#include <QVector>
/**
* @class EdhrecApiResponseArchidektLink
* @ingroup ApiResponses
* @brief Represents a single Archidekt entry
*/
class EdhrecApiResponseArchidektLink
{
public:
QString c;
int f = 0;
int q = 0;
QString u;
void fromJson(const QJsonObject &json);
void debugPrint() const;
};
/**
* @class EdhrecCommanderApiResponseArchidektLinks
* @ingroup ApiResponses
* @brief Represents the Archidekt section as a list of entries
*/
class EdhrecCommanderApiResponseArchidektLinks
{
public:
QVector<EdhrecApiResponseArchidektLink> entries;
void fromJson(const QJsonArray &json);
void debugPrint() const;
};
#endif // ARCHIDEKTENTRY_H

View file

@ -0,0 +1,47 @@
#include "edhrec_average_deck_api_response.h"
#include <QDebug>
#include <QJsonArray>
void EdhrecAverageDeckApiResponse::fromJson(const QJsonObject &json)
{
// Parse the collapsed DeckStatistics
deckStats.fromJson(json);
// Parse Archidekt section
QJsonArray archidektJson = json.value("archidekt").toArray();
archidekt.fromJson(archidektJson);
// Parse other fields
similar = json.value("similar").toObject();
header = json.value("header").toString();
panels = json.value("panels").toObject();
description = json.value("description").toString();
QJsonObject containerJson = json.value("container").toObject();
container.fromJson(containerJson);
QJsonArray cardsJson = json.value("deck").toArray();
deck.fromJson(cardsJson);
}
void EdhrecAverageDeckApiResponse::debugPrint() const
{
qDebug() << "Deck Statistics:";
qDebug() << " Creature:" << deckStats.creature;
qDebug() << " Instant:" << deckStats.instant;
qDebug() << " Sorcery:" << deckStats.sorcery;
qDebug() << " Artifact:" << deckStats.artifact;
qDebug() << " Enchantment:" << deckStats.enchantment;
qDebug() << " Battle:" << deckStats.battle;
qDebug() << " Planeswalker:" << deckStats.planeswalker;
qDebug() << " Land:" << deckStats.land;
qDebug() << " Basic:" << deckStats.basic;
qDebug() << " Nonbasic:" << deckStats.nonbasic;
archidekt.debugPrint();
qDebug() << "Similar:" << similar;
qDebug() << "Header:" << header;
qDebug() << "Panels:" << panels;
qDebug() << "Description:" << description;
container.debugPrint();
}

View file

@ -0,0 +1,34 @@
#ifndef EDHREC_AVERAGE_DECK_API_RESPONSE_H
#define EDHREC_AVERAGE_DECK_API_RESPONSE_H
#include "../archidekt_links/edhrec_api_response_archidekt_links.h"
#include "../cards/edhrec_api_response_card_container.h"
#include "../commander/edhrec_commander_api_response_average_deck_statistics.h"
#include "edhrec_deck_api_response.h"
#include <QDebug>
#include <QJsonObject>
#include <QString>
/**
* @class EdhrecAverageDeckApiResponse
* @ingroup ApiResponses
* @brief Represents the main structure of the JSON
*/
class EdhrecAverageDeckApiResponse
{
public:
EdhrecCommanderApiResponseAverageDeckStatistics deckStats;
EdhrecCommanderApiResponseArchidektLinks archidekt;
QJsonObject similar;
QString header;
QJsonObject panels;
QString description;
EdhrecApiResponseCardContainer container;
EdhrecDeckApiResponse deck;
void fromJson(const QJsonObject &json);
void debugPrint() const;
};
#endif // EDHREC_AVERAGE_DECK_API_RESPONSE_H

View file

@ -0,0 +1,26 @@
#include "edhrec_deck_api_response.h"
#include <QApplication>
#include <QDebug>
#include <QJsonArray>
#include <QJsonObject>
#include <QMainWindow>
#include <libcockatrice/deck_list/deck_loader.h>
void EdhrecDeckApiResponse::fromJson(const QJsonArray &json)
{
QString deckList;
for (const QJsonValue &cardlistValue : json) {
deckList += cardlistValue.toString() + "\n";
}
deckLoader = new DeckLoader();
QTextStream stream(&deckList);
deckLoader->loadFromStream_Plain(stream, true);
}
void EdhrecDeckApiResponse::debugPrint() const
{
qDebug() << "Breadcrumb:";
}

View file

@ -0,0 +1,32 @@
/**
* @file edhrec_deck_api_response.h
* @ingroup ApiResponses
* @brief TODO: Document this.
*/
#ifndef EDHREC_DECK_API_RESPONSE_H
#define EDHREC_DECK_API_RESPONSE_H
#include <QDebug>
#include <QJsonArray>
#include <QJsonObject>
#include <QString>
#include <QVector>
#include <libcockatrice/deck_list/deck_loader.h>
class EdhrecDeckApiResponse
{
public:
// Constructor
EdhrecDeckApiResponse() = default;
// Parse deck-related data from JSON
void fromJson(const QJsonArray &json);
// Debug method for logging
void debugPrint() const;
DeckLoader *deckLoader;
};
#endif // EDHREC_DECK_API_RESPONSE_H

View file

@ -0,0 +1,31 @@
#include "edhrec_api_response_card_prices.h"
#include <QDebug>
void CardPrices::fromJson(const QJsonObject &json)
{
// Parse prices from various sources
cardhoarder = json.value("cardhoarder").toObject();
cardkingdom = json.value("cardkingdom").toObject();
cardmarket = json.value("cardmarket").toObject();
face2face = json.value("face2face").toObject();
manapool = json.value("manapool").toObject();
mtgstocks = json.value("mtgstocks").toObject();
scg = json.value("scg").toObject();
tcgl = json.value("tcgl").toObject();
tcgplayer = json.value("tcgplayer").toObject();
}
void CardPrices::debugPrint() const
{
qInfo() << "Card Prices:";
qInfo() << "Cardhoarder:" << cardhoarder;
qInfo() << "Cardkingdom:" << cardkingdom;
qInfo() << "Cardmarket:" << cardmarket;
qInfo() << "Face2Face:" << face2face;
qInfo() << "Manapool:" << manapool;
qInfo() << "Mtgstocks:" << mtgstocks;
qInfo() << "SCG:" << scg;
qInfo() << "TCGL:" << tcgl;
qInfo() << "Tcgplayer:" << tcgplayer;
}

View file

@ -0,0 +1,72 @@
/**
* @file edhrec_api_response_card_prices.h
* @ingroup ApiResponses
* @brief TODO: Document this.
*/
#ifndef EDHREC_COMMANDER_API_RESPONSE_CARD_PRICES_H
#define EDHREC_COMMANDER_API_RESPONSE_CARD_PRICES_H
#include <QJsonObject>
class CardPrices
{
public:
// Constructor
CardPrices() = default;
// Parse prices from JSON
void fromJson(const QJsonObject &json);
void debugPrint() const;
// Getter methods for card prices
const QJsonObject &getCardhoarder() const
{
return cardhoarder;
}
const QJsonObject &getCardkingdom() const
{
return cardkingdom;
}
const QJsonObject &getCardmarket() const
{
return cardmarket;
}
const QJsonObject &getFace2face() const
{
return face2face;
}
const QJsonObject &getManapool() const
{
return manapool;
}
const QJsonObject &getMtgstocks() const
{
return mtgstocks;
}
const QJsonObject &getScg() const
{
return scg;
}
const QJsonObject &getTcgl() const
{
return tcgl;
}
const QJsonObject &getTcgplayer() const
{
return tcgplayer;
}
private:
QJsonObject cardhoarder;
QJsonObject cardkingdom;
QJsonObject cardmarket;
QJsonObject face2face;
QJsonObject manapool;
QJsonObject mtgstocks;
QJsonObject scg;
QJsonObject tcgl;
QJsonObject tcgplayer;
};
#endif // EDHREC_COMMANDER_API_RESPONSE_CARD_PRICES_H

View file

@ -0,0 +1,49 @@
#include "edhrec_api_response_card_container.h"
#include <QDebug>
#include <QJsonArray>
#include <QJsonObject>
void EdhrecApiResponseCardContainer::fromJson(const QJsonObject &json)
{
// Parse breadcrumb
QJsonArray breadcrumbArray = json.value("breadcrumb").toArray();
for (const QJsonValue &breadcrumbValue : breadcrumbArray) {
breadcrumb.push_back(breadcrumbValue.toObject());
}
description = json.value("description").toString();
QJsonObject jsonDict = json.value("json_dict").toObject();
card.fromJson(jsonDict.value("card").toObject());
QJsonArray cardlistsArray = jsonDict.value("cardlists").toArray();
for (const QJsonValue &cardlistValue : cardlistsArray) {
QJsonObject cardlistObj = cardlistValue.toObject();
QJsonArray cardviewsArray = cardlistObj.value("cardviews").toArray();
EdhrecApiResponseCardList cardView;
cardView.fromJson(cardlistValue.toObject());
cardlists.push_back(cardView);
}
keywords = json.value("keywords").toString();
title = json.value("title").toString();
}
void EdhrecApiResponseCardContainer::debugPrint() const
{
qDebug() << "Breadcrumb:";
for (const auto &breadcrumbEntry : breadcrumb) {
qDebug() << breadcrumbEntry;
}
qDebug() << "Description:" << description;
card.debugPrint();
qDebug() << "Cardlists:";
for (const auto &cardlist : cardlists) {
cardlist.debugPrint();
}
qDebug() << "Keywords:" << keywords;
qDebug() << "Title:" << title;
}

View file

@ -0,0 +1,66 @@
/**
* @file edhrec_api_response_card_container.h
* @ingroup ApiResponses
* @brief TODO: Document this.
*/
#ifndef CONTAINER_ENTRY_H
#define CONTAINER_ENTRY_H
#include "edhrec_api_response_card_list.h"
#include "edhrec_commander_api_response_commander_details.h"
#include <QDebug>
#include <QJsonArray>
#include <QJsonObject>
#include <QString>
#include <QVector>
class EdhrecApiResponseCardContainer
{
public:
// Constructor
EdhrecApiResponseCardContainer() = default;
// Parse deck-related data from JSON
void fromJson(const QJsonObject &json);
// Debug method for logging
void debugPrint() const;
// Getter methods for deck container
const QString &getDescription() const
{
return description;
}
const QVector<QJsonObject> &getBreadcrumb() const
{
return breadcrumb;
}
const EdhrecCommanderApiResponseCommanderDetails &getCommanderDetails() const
{
return card;
}
const QVector<EdhrecApiResponseCardList> &getCardlists() const
{
return cardlists;
}
const QString &getKeywords() const
{
return keywords;
}
const QString &getTitle() const
{
return title;
}
private:
QString description;
QVector<QJsonObject> breadcrumb;
EdhrecCommanderApiResponseCommanderDetails card;
QVector<EdhrecApiResponseCardList> cardlists;
QString keywords;
QString title;
};
#endif // CONTAINER_ENTRY_H

View file

@ -0,0 +1,36 @@
#include "edhrec_api_response_card_details.h"
#include <QDebug>
EdhrecApiResponseCardDetails::EdhrecApiResponseCardDetails()
: synergy(0.0), inclusion(0), numDecks(0), potentialDecks(0)
{
}
void EdhrecApiResponseCardDetails::fromJson(const QJsonObject &json)
{
// Parse the fields from the JSON object
name = json.value("name").toString();
sanitized = json.value("sanitized").toString();
sanitizedWo = json.value("sanitized_wo").toString();
url = json.value("url").toString();
synergy = json.value("synergy").toDouble(0.0);
inclusion = json.value("inclusion").toInt(0);
label = json.value("label").toString();
numDecks = json.value("num_decks").toInt(0);
potentialDecks = json.value("potential_decks").toInt(0);
}
void EdhrecApiResponseCardDetails::debugPrint() const
{
// Print out all the fields for debugging
qDebug() << "Name:" << name;
qDebug() << "Sanitized:" << sanitized;
qDebug() << "Sanitized Wo:" << sanitizedWo;
qDebug() << "URL:" << url;
qDebug() << "Synergy:" << synergy;
qDebug() << "Inclusion:" << inclusion;
qDebug() << "Label:" << label;
qDebug() << "Num Decks:" << numDecks;
qDebug() << "Potential Decks:" << potentialDecks;
}

View file

@ -0,0 +1,35 @@
/**
* @file edhrec_api_response_card_details.h
* @ingroup ApiResponses
* @brief TODO: Document this.
*/
#ifndef CARD_VIEW_H
#define CARD_VIEW_H
#include <QJsonObject>
#include <QString>
class EdhrecApiResponseCardDetails
{
public:
QString name;
QString sanitized;
QString sanitizedWo;
QString url;
double synergy;
int inclusion;
QString label;
int numDecks;
int potentialDecks;
EdhrecApiResponseCardDetails();
// Method to populate the object from a JSON object
void fromJson(const QJsonObject &json);
// Debug method to print out the data
void debugPrint() const;
};
#endif // CARD_VIEW_H

View file

@ -0,0 +1,33 @@
#include "edhrec_api_response_card_list.h"
#include <QDebug>
EdhrecApiResponseCardList::EdhrecApiResponseCardList()
{
}
void EdhrecApiResponseCardList::fromJson(const QJsonObject &json)
{
// Parse the header from the JSON object
header = json.value("header").toString();
// Parse the cardviews array and populate cardViews
QJsonArray cardviewsArray = json.value("cardviews").toArray();
for (const QJsonValue &value : cardviewsArray) {
QJsonObject cardviewObj = value.toObject();
EdhrecApiResponseCardDetails cardView;
cardView.fromJson(cardviewObj);
cardViews.append(cardView);
}
}
void EdhrecApiResponseCardList::debugPrint() const
{
// Print out the header
qDebug() << "Header:" << header;
// Print out all the CardView objects
for (const EdhrecApiResponseCardDetails &cardView : cardViews) {
cardView.debugPrint();
}
}

View file

@ -0,0 +1,33 @@
/**
* @file edhrec_api_response_card_list.h
* @ingroup ApiResponses
* @brief TODO: Document this.
*/
#ifndef CARD_LIST_H
#define CARD_LIST_H
#include "edhrec_api_response_card_details.h"
#include <QJsonArray>
#include <QJsonObject>
#include <QList>
#include <QString>
class EdhrecApiResponseCardList
{
public:
QString header;
QList<EdhrecApiResponseCardDetails> cardViews;
// Default constructor
EdhrecApiResponseCardList();
// Method to populate the object from a JSON object
void fromJson(const QJsonObject &json);
// Debug method to print out the data
void debugPrint() const;
};
#endif // CARD_LIST_H

View file

@ -0,0 +1,90 @@
#include "edhrec_commander_api_response_commander_details.h"
#include <QDebug>
void EdhrecCommanderApiResponseCommanderDetails::fromJson(const QJsonObject &json)
{
// Parse card-related data
aetherhubUri = json.value("aetherhub_uri").toString();
archidektUri = json.value("archidekt_uri").toString();
cmc = json.value("cmc").toInt(0);
colorIdentity = json.value("color_identity").toArray();
combos = json.value("combos").toBool(false);
deckstatsUri = json.value("deckstats_uri").toString();
// Parse image URIs
QJsonArray imageUrisArray = json.value("image_uris").toArray();
for (const QJsonValue &imageValue : imageUrisArray) {
QJsonObject imageObject = imageValue.toObject();
imageUris.push_back(imageObject.value("normal").toString());
imageUris.push_back(imageObject.value("art_crop").toString());
}
inclusion = json.value("inclusion").toInt(0);
isCommander = json.value("is_commander").toBool(false);
label = json.value("label").toString();
layout = json.value("layout").toString();
legalCommander = json.value("legal_commander").toBool(false);
moxfieldUri = json.value("moxfield_uri").toString();
mtggoldfishUri = json.value("mtggoldfish_uri").toString();
name = json.value("name").toString();
names = json.value("names").toArray();
numDecks = json.value("num_decks").toInt(0);
potentialDecks = json.value("potential_decks").toInt(0);
precon = json.value("precon").toString();
// Parse prices
prices.fromJson(json.value("prices").toObject());
primaryType = json.value("primary_type").toString();
rarity = json.value("rarity").toString();
salt = json.value("salt").toDouble(0.0);
sanitized = json.value("sanitized").toString();
sanitizedWo = json.value("sanitized_wo").toString();
scryfallUri = json.value("scryfall_uri").toString();
spellbookUri = json.value("spellbook_uri").toString();
type = json.value("type").toString();
url = json.value("url").toString();
}
void EdhrecCommanderApiResponseCommanderDetails::debugPrint() const
{
qDebug() << "Card Data:";
qDebug() << "Aetherhub URI:" << aetherhubUri;
qDebug() << "Archidekt URI:" << archidektUri;
qDebug() << "CMC:" << cmc;
qDebug() << "Color Identity:" << colorIdentity;
qDebug() << "Combos:" << combos;
qDebug() << "Deckstats URI:" << deckstatsUri;
qDebug() << "Image URIs:";
for (const auto &uri : imageUris) {
qDebug() << uri;
}
qDebug() << "Inclusion:" << inclusion;
qDebug() << "Is Commander:" << isCommander;
qDebug() << "Label:" << label;
qDebug() << "Layout:" << layout;
qDebug() << "Legal Commander:" << legalCommander;
qDebug() << "Moxfield URI:" << moxfieldUri;
qDebug() << "MTGGoldfish URI:" << mtggoldfishUri;
qDebug() << "Name:" << name;
qDebug() << "Names:" << names;
qDebug() << "Number of Decks:" << numDecks;
qDebug() << "Potential Decks:" << potentialDecks;
qDebug() << "Precon:" << precon;
// Print the prices using the debugPrint method from CardPrices
prices.debugPrint();
qDebug() << "Primary Type:" << primaryType;
qDebug() << "Rarity:" << rarity;
qDebug() << "Salt:" << salt;
qDebug() << "Sanitized:" << sanitized;
qDebug() << "Sanitized WO:" << sanitizedWo;
qDebug() << "Scryfall URI:" << scryfallUri;
qDebug() << "Spellbook URI:" << spellbookUri;
qDebug() << "Type:" << type;
qDebug() << "URL:" << url;
}

View file

@ -0,0 +1,179 @@
/**
* @file edhrec_commander_api_response_commander_details.h
* @ingroup ApiResponses
* @brief TODO: Document this.
*/
#ifndef EDHREC_COMMANDER_API_RESPONSE_COMMANDER_DETAILS_H
#define EDHREC_COMMANDER_API_RESPONSE_COMMANDER_DETAILS_H
#include "../card_prices/edhrec_api_response_card_prices.h"
#include <QJsonArray>
#include <QJsonObject>
#include <QString>
#include <QVector>
class EdhrecCommanderApiResponseCommanderDetails
{
public:
// Constructor
EdhrecCommanderApiResponseCommanderDetails() = default;
// Parse card-related data from JSON
void fromJson(const QJsonObject &json);
// Debug method for logging
void debugPrint() const;
// Getters for the card data
const QString &getAetherhubUri() const
{
return aetherhubUri;
}
const QString &getArchidektUri() const
{
return archidektUri;
}
int getCmc() const
{
return cmc;
}
const QJsonArray &getColorIdentity() const
{
return colorIdentity;
}
bool isCombos() const
{
return combos;
}
const QString &getDeckstatsUri() const
{
return deckstatsUri;
}
const QVector<QString> &getImageUris() const
{
return imageUris;
}
int getInclusion() const
{
return inclusion;
}
bool getIsCommander() const
{
return isCommander;
}
const QString &getLabel() const
{
return label;
}
const QString &getLayout() const
{
return layout;
}
bool getLegalCommander() const
{
return legalCommander;
}
const QString &getMoxfieldUri() const
{
return moxfieldUri;
}
const QString &getMtggoldfishUri() const
{
return mtggoldfishUri;
}
const QString &getName() const
{
return name;
}
const QJsonArray &getNames() const
{
return names;
}
int getNumDecks() const
{
return numDecks;
}
int getPotentialDecks() const
{
return potentialDecks;
}
const QString &getPrecon() const
{
return precon;
}
const CardPrices &getPrices() const
{
return prices;
}
const QString &getPrimaryType() const
{
return primaryType;
}
const QString &getRarity() const
{
return rarity;
}
double getSalt() const
{
return salt;
}
const QString &getSanitized() const
{
return sanitized;
}
const QString &getSanitizedWo() const
{
return sanitizedWo;
}
const QString &getScryfallUri() const
{
return scryfallUri;
}
const QString &getSpellbookUri() const
{
return spellbookUri;
}
const QString &getType() const
{
return type;
}
const QString &getUrl() const
{
return url;
}
private:
QString aetherhubUri;
QString archidektUri;
int cmc = 0;
QJsonArray colorIdentity;
bool combos = false;
QString deckstatsUri;
QVector<QString> imageUris;
int inclusion = 0;
bool isCommander = false;
QString label;
QString layout;
bool legalCommander = false;
QString moxfieldUri;
QString mtggoldfishUri;
QString name;
QJsonArray names;
int numDecks = 0;
int potentialDecks = 0;
QString precon;
CardPrices prices;
QString primaryType;
QString rarity;
double salt = 0.0;
QString sanitized;
QString sanitizedWo;
QString scryfallUri;
QString spellbookUri;
QString type;
QString url;
};
#endif // EDHREC_COMMANDER_API_RESPONSE_COMMANDER_DETAILS_H

View file

@ -0,0 +1,45 @@
#include "edhrec_commander_api_response.h"
#include <QDebug>
#include <QJsonArray>
void EdhrecCommanderApiResponse::fromJson(const QJsonObject &json)
{
// Parse the collapsed DeckStatistics
deckStats.fromJson(json);
// Parse Archidekt section
QJsonArray archidektJson = json.value("archidekt").toArray();
archidekt.fromJson(archidektJson);
// Parse other fields
similar = json.value("similar").toObject();
header = json.value("header").toString();
panels = json.value("panels").toObject();
description = json.value("description").toString();
QJsonObject containerJson = json.value("container").toObject();
container.fromJson(containerJson);
}
void EdhrecCommanderApiResponse::debugPrint() const
{
qDebug() << "Deck Statistics:";
qDebug() << " Creature:" << deckStats.creature;
qDebug() << " Instant:" << deckStats.instant;
qDebug() << " Sorcery:" << deckStats.sorcery;
qDebug() << " Artifact:" << deckStats.artifact;
qDebug() << " Enchantment:" << deckStats.enchantment;
qDebug() << " Battle:" << deckStats.battle;
qDebug() << " Planeswalker:" << deckStats.planeswalker;
qDebug() << " Land:" << deckStats.land;
qDebug() << " Basic:" << deckStats.basic;
qDebug() << " Nonbasic:" << deckStats.nonbasic;
archidekt.debugPrint();
qDebug() << "Similar:" << similar;
qDebug() << "Header:" << header;
qDebug() << "Panels:" << panels;
qDebug() << "Description:" << description;
container.debugPrint();
}

View file

@ -0,0 +1,32 @@
#ifndef DECKDATA_H
#define DECKDATA_H
#include "../archidekt_links/edhrec_api_response_archidekt_links.h"
#include "../cards/edhrec_api_response_card_container.h"
#include "edhrec_commander_api_response_average_deck_statistics.h"
#include <QDebug>
#include <QJsonObject>
#include <QString>
/**
* @class EdhrecCommanderApiResponse
* @ingroup ApiResponses
* @brief Represents the main structure of the JSON
*/
class EdhrecCommanderApiResponse
{
public:
EdhrecCommanderApiResponseAverageDeckStatistics deckStats;
EdhrecCommanderApiResponseArchidektLinks archidekt;
QJsonObject similar;
QString header;
QJsonObject panels;
QString description;
EdhrecApiResponseCardContainer container;
void fromJson(const QJsonObject &json);
void debugPrint() const;
};
#endif // DECKDATA_H

View file

@ -0,0 +1,15 @@
#include "edhrec_commander_api_response_average_deck_statistics.h"
void EdhrecCommanderApiResponseAverageDeckStatistics::fromJson(const QJsonObject &json)
{
creature = json.value("creature").toInt(0);
instant = json.value("instant").toInt(0);
sorcery = json.value("sorcery").toInt(0);
artifact = json.value("artifact").toInt(0);
enchantment = json.value("enchantment").toInt(0);
battle = json.value("battle").toInt(0);
planeswalker = json.value("planeswalker").toInt(0);
land = json.value("land").toInt(0);
basic = json.value("basic").toInt(0);
nonbasic = json.value("nonbasic").toInt(0);
}

View file

@ -0,0 +1,26 @@
#ifndef AVERAGE_DECK_STATISTICS_H
#define AVERAGE_DECK_STATISTICS_H
#include <QJsonObject>
/**
* @struct EdhrecCommanderApiResponseAverageDeckStatistics
* @ingroup ApiResponses
* @brief Represents the typical deck statistics (collapsed section)
*/
struct EdhrecCommanderApiResponseAverageDeckStatistics
{
int creature = 0;
int instant = 0;
int sorcery = 0;
int artifact = 0;
int enchantment = 0;
int battle = 0;
int planeswalker = 0;
int land = 0;
int basic = 0;
int nonbasic = 0;
void fromJson(const QJsonObject &json);
};
#endif // AVERAGE_DECK_STATISTICS_H

View file

@ -0,0 +1,19 @@
#include "edhrec_top_cards_api_response.h"
#include <QDebug>
#include <QJsonArray>
void EdhrecTopCardsApiResponse::fromJson(const QJsonObject &json)
{
header = json.value("header").toString();
description = json.value("description").toString();
QJsonObject containerJson = json.value("container").toObject();
container.fromJson(containerJson);
}
void EdhrecTopCardsApiResponse::debugPrint() const
{
qDebug() << "Header:" << header;
qDebug() << "Description:" << description;
container.debugPrint();
}

View file

@ -0,0 +1,26 @@
/**
* @file edhrec_top_cards_api_response.h
* @ingroup ApiResponses
* @brief TODO: Document this.
*/
#ifndef EDHREC_TOP_CARDS_API_RESPONSE_H
#define EDHREC_TOP_CARDS_API_RESPONSE_H
#include "../cards/edhrec_api_response_card_container.h"
#include <QDebug>
#include <QString>
class EdhrecTopCardsApiResponse
{
public:
QString header;
QString description;
EdhrecApiResponseCardContainer container;
void fromJson(const QJsonObject &json);
void debugPrint() const;
};
#endif // EDHREC_TOP_CARDS_API_RESPONSE_H

View file

@ -0,0 +1,19 @@
#include "edhrec_top_commanders_api_response.h"
#include <QDebug>
#include <QJsonArray>
void EdhrecTopCommandersApiResponse::fromJson(const QJsonObject &json)
{
header = json.value("header").toString();
description = json.value("description").toString();
QJsonObject containerJson = json.value("container").toObject();
container.fromJson(containerJson);
}
void EdhrecTopCommandersApiResponse::debugPrint() const
{
qDebug() << "Header:" << header;
qDebug() << "Description:" << description;
container.debugPrint();
}

View file

@ -0,0 +1,26 @@
/**
* @file edhrec_top_commanders_api_response.h
* @ingroup ApiResponses
* @brief TODO: Document this.
*/
#ifndef EDHREC_TOP_COMMANDERS_API_RESPONSE_H
#define EDHREC_TOP_COMMANDERS_API_RESPONSE_H
#include "../cards/edhrec_api_response_card_container.h"
#include <QDebug>
#include <QString>
class EdhrecTopCommandersApiResponse
{
public:
QString header;
QString description;
EdhrecApiResponseCardContainer container;
void fromJson(const QJsonObject &json);
void debugPrint() const;
};
#endif // EDHREC_TOP_COMMANDERS_API_RESPONSE_H

View file

@ -0,0 +1,19 @@
#include "edhrec_top_tags_api_response.h"
#include <QDebug>
#include <QJsonArray>
void EdhrecTopTagsApiResponse::fromJson(const QJsonObject &json)
{
header = json.value("header").toString();
description = json.value("description").toString();
QJsonObject containerJson = json.value("container").toObject();
container.fromJson(containerJson);
}
void EdhrecTopTagsApiResponse::debugPrint() const
{
qDebug() << "Header:" << header;
qDebug() << "Description:" << description;
container.debugPrint();
}

View file

@ -0,0 +1,26 @@
/**
* @file edhrec_top_tags_api_response.h
* @ingroup ApiResponses
* @brief TODO: Document this.
*/
#ifndef EDHREC_TOP_TAGS_API_RESPONSE_H
#define EDHREC_TOP_TAGS_API_RESPONSE_H
#include "../cards/edhrec_api_response_card_container.h"
#include <QDebug>
#include <QString>
class EdhrecTopTagsApiResponse
{
public:
QString header;
QString description;
EdhrecApiResponseCardContainer container;
void fromJson(const QJsonObject &json);
void debugPrint() const;
};
#endif // EDHREC_TOP_TAGS_API_RESPONSE_H

View file

@ -0,0 +1,66 @@
#include "edhrec_api_response_card_prices_display_widget.h"
EdhrecApiResponseCardPricesDisplayWidget::EdhrecApiResponseCardPricesDisplayWidget(QWidget *parent,
const CardPrices &_cardPrices)
: QWidget(parent), cardPrices(_cardPrices)
{
layout = new QGridLayout(this);
setLayout(layout);
cardHoarderLabel = new QLabel(this);
cardHoarderPrice = new QLabel(QString::number(cardPrices.getCardhoarder().value("price").toDouble()), this);
cardKingdomLabel = new QLabel(this);
cardKingdomPrice = new QLabel(QString::number(cardPrices.getCardkingdom().value("price").toDouble()), this);
cardMarketLabel = new QLabel(this);
cardMarketPrice = new QLabel(QString::number(cardPrices.getCardmarket().value("price").toDouble()), this);
face2faceLabel = new QLabel(this);
face2facePrice = new QLabel(QString::number(cardPrices.getFace2face().value("price").toDouble()), this);
manaPoolLabel = new QLabel(this);
manaPoolPrice = new QLabel(QString::number(cardPrices.getManapool().value("price").toDouble()), this);
mtgStocksLabel = new QLabel(this);
mtgStocksPrice = new QLabel(QString::number(cardPrices.getMtgstocks().value("price").toDouble()), this);
scgLabel = new QLabel(this);
scgPrice = new QLabel(QString::number(cardPrices.getScg().value("price").toDouble()), this);
tcglLabel = new QLabel(this);
tcglPrice = new QLabel(QString::number(cardPrices.getTcgl().value("price").toDouble()), this);
tcgplayerLabel = new QLabel(this);
tcgplayerPrice = new QLabel(QString::number(cardPrices.getTcgplayer().value("price").toDouble()), this);
layout->addWidget(cardHoarderLabel, 0, 0);
layout->addWidget(cardHoarderPrice, 0, 1);
layout->addWidget(cardKingdomLabel, 0, 2);
layout->addWidget(cardKingdomPrice, 0, 3);
layout->addWidget(cardMarketLabel, 1, 0);
layout->addWidget(cardMarketPrice, 1, 1);
layout->addWidget(face2faceLabel, 1, 2);
layout->addWidget(face2facePrice, 1, 3);
layout->addWidget(manaPoolLabel, 2, 0);
layout->addWidget(manaPoolPrice, 2, 1);
layout->addWidget(mtgStocksLabel, 2, 2);
layout->addWidget(mtgStocksPrice, 2, 3);
layout->addWidget(scgLabel, 3, 0);
layout->addWidget(scgPrice, 3, 1);
layout->addWidget(tcglLabel, 3, 2);
layout->addWidget(tcglPrice, 3, 3);
layout->addWidget(tcgplayerLabel, 4, 0);
layout->addWidget(tcgplayerPrice, 4, 1);
retranslateUi();
}
void EdhrecApiResponseCardPricesDisplayWidget::retranslateUi()
{
cardHoarderLabel->setText(tr("Card Hoarder"));
cardKingdomLabel->setText(tr("Card Kingdom"));
cardMarketLabel->setText(tr("Card Market"));
face2faceLabel->setText(tr("Face 2-Face"));
manaPoolLabel->setText(tr("Mana Pool"));
mtgStocksLabel->setText(tr("MTG Stocks"));
scgLabel->setText(tr("Scg"));
tcglLabel->setText(tr("Tcgl"));
tcgplayerLabel->setText(tr("Tcgplayer"));
}

View file

@ -0,0 +1,48 @@
/**
* @file edhrec_api_response_card_prices_display_widget.h
* @ingroup ApiResponseDisplayWidgets
* @brief TODO: Document this.
*/
#ifndef EDHREC_API_RESPONSE_CARD_PRICES_DISPLAY_WIDGET_H
#define EDHREC_API_RESPONSE_CARD_PRICES_DISPLAY_WIDGET_H
#include "../../api_response/card_prices/edhrec_api_response_card_prices.h"
#include <QGridLayout>
#include <QLabel>
#include <QWidget>
class EdhrecApiResponseCardPricesDisplayWidget : public QWidget
{
Q_OBJECT
public:
EdhrecApiResponseCardPricesDisplayWidget(QWidget *parent, const CardPrices &cardPrices);
public slots:
void retranslateUi();
private:
CardPrices cardPrices;
QGridLayout *layout;
QLabel *cardHoarderLabel;
QLabel *cardHoarderPrice;
QLabel *cardKingdomLabel;
QLabel *cardKingdomPrice;
QLabel *cardMarketLabel;
QLabel *cardMarketPrice;
QLabel *face2faceLabel;
QLabel *face2facePrice;
QLabel *manaPoolLabel;
QLabel *manaPoolPrice;
QLabel *mtgStocksLabel;
QLabel *mtgStocksPrice;
QLabel *scgLabel;
QLabel *scgPrice;
QLabel *tcglLabel;
QLabel *tcglPrice;
QLabel *tcgplayerLabel;
QLabel *tcgplayerPrice;
};
#endif // EDHREC_API_RESPONSE_CARD_PRICES_DISPLAY_WIDGET_H

View file

@ -0,0 +1,55 @@
#include "edhrec_api_response_card_details_display_widget.h"
#include "../../tab_edhrec_main.h"
#include <libcockatrice/card/card_database/card_database_manager.h>
EdhrecApiResponseCardDetailsDisplayWidget::EdhrecApiResponseCardDetailsDisplayWidget(
QWidget *parent,
const EdhrecApiResponseCardDetails &_toDisplay)
: QWidget(parent), toDisplay(_toDisplay)
{
layout = new QVBoxLayout(this);
setLayout(layout);
cardPictureWidget = new CardInfoPictureWidget(this);
cardPictureWidget->setCard(CardDatabaseManager::query()->guessCard({toDisplay.sanitized}));
nameLabel = new QLabel(this);
nameLabel->setText(toDisplay.name);
nameLabel->setAlignment(Qt::AlignHCenter);
inclusionDisplayWidget = new EdhrecApiResponseCardInclusionDisplayWidget(this, toDisplay);
synergyDisplayWidget = new EdhrecApiResponseCardSynergyDisplayWidget(this, toDisplay);
layout->addWidget(nameLabel);
layout->addWidget(cardPictureWidget);
layout->addWidget(inclusionDisplayWidget);
layout->addWidget(synergyDisplayWidget);
QWidget *currentParent = parentWidget();
TabEdhRecMain *parentTab = nullptr;
while (currentParent) {
if ((parentTab = qobject_cast<TabEdhRecMain *>(currentParent))) {
break;
}
currentParent = currentParent->parentWidget();
}
if (parentTab) {
cardPictureWidget->setScaleFactor(parentTab->getCardSizeSlider()->getSlider()->value());
connect(cardPictureWidget, &CardInfoPictureWidget::cardClicked, this,
&EdhrecApiResponseCardDetailsDisplayWidget::actRequestPageNavigation);
connect(parentTab->getCardSizeSlider()->getSlider(), &QSlider::valueChanged, cardPictureWidget,
&CardInfoPictureWidget::setScaleFactor);
connect(this, &EdhrecApiResponseCardDetailsDisplayWidget::requestUrl, parentTab,
&TabEdhRecMain::actNavigatePage);
}
}
void EdhrecApiResponseCardDetailsDisplayWidget::actRequestPageNavigation()
{
emit requestUrl(toDisplay.url);
}

View file

@ -0,0 +1,38 @@
/**
* @file edhrec_api_response_card_details_display_widget.h
* @ingroup ApiResponseDisplayWidgets
* @brief TODO: Document this.
*/
#ifndef EDHREC_COMMANDER_API_RESPONSE_CARD_DETAILS_DISPLAY_WIDGET_H
#define EDHREC_COMMANDER_API_RESPONSE_CARD_DETAILS_DISPLAY_WIDGET_H
#include "../../../../../cards/card_info_picture_widget.h"
#include "../../api_response/cards/edhrec_api_response_card_details.h"
#include "edhrec_api_response_card_inclusion_display_widget.h"
#include "edhrec_api_response_card_synergy_display_widget.h"
#include <QHBoxLayout>
#include <QLabel>
#include <QWidget>
class EdhrecApiResponseCardDetailsDisplayWidget : public QWidget
{
Q_OBJECT
public:
explicit EdhrecApiResponseCardDetailsDisplayWidget(QWidget *parent, const EdhrecApiResponseCardDetails &_toDisplay);
public slots:
void actRequestPageNavigation();
signals:
void requestUrl(QString url);
private:
EdhrecApiResponseCardDetails toDisplay;
QVBoxLayout *layout;
CardInfoPictureWidget *cardPictureWidget;
QLabel *nameLabel;
EdhrecApiResponseCardInclusionDisplayWidget *inclusionDisplayWidget;
EdhrecApiResponseCardSynergyDisplayWidget *synergyDisplayWidget;
};
#endif // EDHREC_COMMANDER_API_RESPONSE_CARD_DETAILS_DISPLAY_WIDGET_H

View file

@ -0,0 +1,41 @@
#include "edhrec_api_response_card_inclusion_display_widget.h"
EdhrecApiResponseCardInclusionDisplayWidget::EdhrecApiResponseCardInclusionDisplayWidget(
QWidget *parent,
const EdhrecApiResponseCardDetails &_toDisplay)
: QWidget(parent), toDisplay(_toDisplay)
{
layout = new QVBoxLayout(this);
setLayout(layout);
commanderLabel = new QLabel(this);
commanderLabel->setAlignment(Qt::AlignCenter);
amountLabel = new QLabel(this);
amountLabel->setAlignment(Qt::AlignCenter);
inclusionLabel = new QLabel(this);
inclusionLabel->setAlignment(Qt::AlignCenter);
percentBarWidget = new PercentBarWidget(this, toDisplay.inclusion / (toDisplay.potentialDecks / 100.0));
if (toDisplay.inclusion != 0 && toDisplay.potentialDecks != 0) {
layout->addWidget(amountLabel);
layout->addWidget(inclusionLabel);
layout->addWidget(percentBarWidget);
commanderLabel->hide();
} else {
amountLabel->hide();
inclusionLabel->hide();
percentBarWidget->hide();
layout->addWidget(commanderLabel);
}
retranslateUi();
}
void EdhrecApiResponseCardInclusionDisplayWidget::retranslateUi()
{
commanderLabel->setText(toDisplay.label);
amountLabel->setText(tr("In %1 decks").arg(QString::number(toDisplay.inclusion)));
inclusionLabel->setText(tr("%1% of %2 decks")
.arg(QString::number(toDisplay.inclusion / (toDisplay.potentialDecks / 100.0), 'f', 2),
QString::number(toDisplay.potentialDecks)));
}

View file

@ -0,0 +1,33 @@
/**
* @file edhrec_api_response_card_inclusion_display_widget.h
* @ingroup ApiResponseDisplayWidgets
* @brief TODO: Document this.
*/
#ifndef EDHREC_API_RESPONSE_CARD_INCLUSION_DISPLAY_WIDGET_H
#define EDHREC_API_RESPONSE_CARD_INCLUSION_DISPLAY_WIDGET_H
#include "../../../../../general/display/percent_bar_widget.h"
#include "../../api_response/cards/edhrec_api_response_card_details.h"
#include <QLabel>
#include <QVBoxLayout>
#include <QWidget>
class EdhrecApiResponseCardInclusionDisplayWidget : public QWidget
{
Q_OBJECT
public:
EdhrecApiResponseCardInclusionDisplayWidget(QWidget *parent, const EdhrecApiResponseCardDetails &_toDisplay);
void retranslateUi();
private:
QVBoxLayout *layout;
EdhrecApiResponseCardDetails toDisplay;
QLabel *commanderLabel;
QLabel *amountLabel;
QLabel *inclusionLabel;
PercentBarWidget *percentBarWidget;
};
#endif // EDHREC_API_RESPONSE_CARD_INCLUSION_DISPLAY_WIDGET_H

View file

@ -0,0 +1,33 @@
#include "edhrec_api_response_card_list_display_widget.h"
#include "../../../../../general/display/banner_widget.h"
#include "edhrec_api_response_card_details_display_widget.h"
#include <QLabel>
EdhrecApiResponseCardListDisplayWidget::EdhrecApiResponseCardListDisplayWidget(QWidget *parent,
EdhrecApiResponseCardList toDisplay)
: QWidget(parent)
{
layout = new QVBoxLayout(this);
setLayout(layout);
header = new BannerWidget(this, toDisplay.header);
flowWidget = new FlowWidget(this, Qt::Horizontal, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAlwaysOff);
header->setBuddy(flowWidget);
foreach (EdhrecApiResponseCardDetails card_detail, toDisplay.cardViews) {
auto widget = new EdhrecApiResponseCardDetailsDisplayWidget(flowWidget, card_detail);
flowWidget->addWidget(widget);
}
layout->addWidget(header);
layout->addWidget(flowWidget);
}
void EdhrecApiResponseCardListDisplayWidget::resizeEvent(QResizeEvent *event)
{
QWidget::resizeEvent(event);
qDebug() << event->size();
}

View file

@ -0,0 +1,35 @@
/**
* @file edhrec_api_response_card_list_display_widget.h
* @ingroup ApiResponseDisplayWidgets
* @brief TODO: Document this.
*/
#ifndef EDHREC_COMMANDER_API_RESPONSE_CARD_LIST_DISPLAY_WIDGET_H
#define EDHREC_COMMANDER_API_RESPONSE_CARD_LIST_DISPLAY_WIDGET_H
#include "../../../../../general/display/banner_widget.h"
#include "../../../../../general/layout_containers/flow_widget.h"
#include "../../api_response/cards/edhrec_api_response_card_list.h"
#include <QResizeEvent>
#include <QVBoxLayout>
#include <QWidget>
class EdhrecApiResponseCardListDisplayWidget : public QWidget
{
Q_OBJECT
public:
explicit EdhrecApiResponseCardListDisplayWidget(QWidget *parent, EdhrecApiResponseCardList toDisplay);
void resizeEvent(QResizeEvent *event) override;
[[nodiscard]] QString getBannerText() const
{
return header->getText();
};
private:
QVBoxLayout *layout;
BannerWidget *header;
FlowWidget *flowWidget;
};
#endif // EDHREC_COMMANDER_API_RESPONSE_CARD_LIST_DISPLAY_WIDGET_H

View file

@ -0,0 +1,28 @@
#include "edhrec_api_response_card_synergy_display_widget.h"
EdhrecApiResponseCardSynergyDisplayWidget::EdhrecApiResponseCardSynergyDisplayWidget(
QWidget *parent,
const EdhrecApiResponseCardDetails &_toDisplay)
: QWidget(parent), toDisplay(_toDisplay)
{
layout = new QVBoxLayout(this);
setLayout(layout);
label = new QLabel(this);
label->setAlignment(Qt::AlignCenter);
percentBarWidget = new PercentBarWidget(this, toDisplay.synergy * 100.0);
if (toDisplay.synergy != 0) {
layout->addWidget(label);
layout->addWidget(percentBarWidget);
} else {
hide();
}
retranslateUi();
}
void EdhrecApiResponseCardSynergyDisplayWidget::retranslateUi()
{
label->setText(tr("%1% Synergy").arg(QString::number(toDisplay.synergy * 100.0, 'f', 1)));
}

View file

@ -0,0 +1,31 @@
/**
* @file edhrec_api_response_card_synergy_display_widget.h
* @ingroup ApiResponseDisplayWidgets
* @brief TODO: Document this.
*/
#ifndef EDHREC_API_RESPONSE_CARD_SYNERGY_DISPLAY_WIDGET_H
#define EDHREC_API_RESPONSE_CARD_SYNERGY_DISPLAY_WIDGET_H
#include "../../../../../general/display/percent_bar_widget.h"
#include "../../api_response/cards/edhrec_api_response_card_details.h"
#include <QLabel>
#include <QVBoxLayout>
#include <QWidget>
class EdhrecApiResponseCardSynergyDisplayWidget : public QWidget
{
Q_OBJECT
public:
EdhrecApiResponseCardSynergyDisplayWidget(QWidget *parent, const EdhrecApiResponseCardDetails &_toDisplay);
void retranslateUi();
private:
QVBoxLayout *layout;
EdhrecApiResponseCardDetails toDisplay;
QLabel *label;
PercentBarWidget *percentBarWidget;
};
#endif // EDHREC_API_RESPONSE_CARD_SYNERGY_DISPLAY_WIDGET_H

View file

@ -0,0 +1,61 @@
#include "edhrec_api_response_commander_details_display_widget.h"
#include "../../../../../cards/card_info_picture_widget.h"
#include "../../tab_edhrec_main.h"
#include "../card_prices/edhrec_api_response_card_prices_display_widget.h"
#include <libcockatrice/card/card_database/card_database_manager.h>
EdhrecCommanderResponseCommanderDetailsDisplayWidget::EdhrecCommanderResponseCommanderDetailsDisplayWidget(
QWidget *parent,
const EdhrecCommanderApiResponseCommanderDetails &_commanderDetails,
QString baseUrl)
: QWidget(parent), commanderDetails(_commanderDetails)
{
layout = new QVBoxLayout(this);
setLayout(layout);
commanderPicture = new CardInfoPictureWidget(this);
commanderPicture->setCard(CardDatabaseManager::query()->getCard({commanderDetails.getName()}));
QWidget *currentParent = parentWidget();
TabEdhRecMain *parentTab = nullptr;
while (currentParent) {
if ((parentTab = qobject_cast<TabEdhRecMain *>(currentParent))) {
break;
}
currentParent = currentParent->parentWidget();
}
if (parentTab) {
connect(parentTab->getCardSizeSlider()->getSlider(), &QSlider::valueChanged, commanderPicture,
&CardInfoPictureWidget::setScaleFactor);
commanderPicture->setScaleFactor(parentTab->getCardSizeSlider()->getSlider()->value());
}
commanderDetails.debugPrint();
label = new QLabel(this);
label->setAlignment(Qt::AlignCenter);
salt = new QLabel(this);
salt->setAlignment(Qt::AlignCenter);
cardPricesDisplayWidget = new EdhrecApiResponseCardPricesDisplayWidget(this, commanderDetails.getPrices());
navigationWidget = new EdhrecCommanderApiResponseNavigationWidget(this, commanderDetails, baseUrl);
layout->addWidget(commanderPicture);
layout->addWidget(label);
layout->addWidget(salt);
layout->addWidget(cardPricesDisplayWidget);
layout->addWidget(navigationWidget);
retranslateUi();
}
void EdhrecCommanderResponseCommanderDetailsDisplayWidget::retranslateUi()
{
label->setText(commanderDetails.getLabel());
salt->setText(tr("Salt: ") + QString::number(commanderDetails.getSalt()));
}

View file

@ -0,0 +1,40 @@
/**
* @file edhrec_api_response_commander_details_display_widget.h
* @ingroup ApiResponseDisplayWidgets
* @brief TODO: Document this.
*/
#ifndef EDHREC_COMMANDER_API_RESPONSE_COMMANDER_DETAILS_DISPLAY_WIDGET_H
#define EDHREC_COMMANDER_API_RESPONSE_COMMANDER_DETAILS_DISPLAY_WIDGET_H
#include "../../../../../cards/card_info_picture_widget.h"
#include "../../api_response/cards/edhrec_commander_api_response_commander_details.h"
#include "../card_prices/edhrec_api_response_card_prices_display_widget.h"
#include "edhrec_commander_api_response_navigation_widget.h"
#include <QLabel>
#include <QVBoxLayout>
#include <QWidget>
class EdhrecCommanderApiResponseNavigationWidget;
class EdhrecCommanderResponseCommanderDetailsDisplayWidget : public QWidget
{
Q_OBJECT
public:
explicit EdhrecCommanderResponseCommanderDetailsDisplayWidget(
QWidget *parent,
const EdhrecCommanderApiResponseCommanderDetails &_commanderDetails,
QString baseUrl);
void retranslateUi();
private:
EdhrecCommanderApiResponseCommanderDetails commanderDetails;
QVBoxLayout *layout;
CardInfoPictureWidget *commanderPicture;
QLabel *label;
QLabel *salt;
EdhrecApiResponseCardPricesDisplayWidget *cardPricesDisplayWidget;
EdhrecCommanderApiResponseNavigationWidget *navigationWidget;
};
#endif // EDHREC_COMMANDER_API_RESPONSE_COMMANDER_DETAILS_DISPLAY_WIDGET_H

View file

@ -0,0 +1,103 @@
#include "edhrec_commander_api_response_display_widget.h"
#include "../../../../../cards/card_info_picture_widget.h"
#include "../../api_response/commander/edhrec_commander_api_response.h"
#include "../cards/edhrec_api_response_card_list_display_widget.h"
#include "edhrec_api_response_commander_details_display_widget.h"
#include <QListView>
#include <QResizeEvent>
#include <QScrollArea>
#include <QSplitter>
#include <QStringListModel>
EdhrecCommanderApiResponseDisplayWidget::EdhrecCommanderApiResponseDisplayWidget(QWidget *parent,
EdhrecCommanderApiResponse response,
QString baseUrl)
: QWidget(parent)
{
layout = new QHBoxLayout(this);
setLayout(layout);
cardDisplayLayout = new QVBoxLayout(this);
// Create a QSplitter to hold the ListView and ScrollArea holding CardListdisplayWidgets side by side
auto splitter = new QSplitter(this);
splitter->setOrientation(Qt::Horizontal);
auto listView = new QListView(splitter);
listView->setMinimumWidth(50);
listView->setMaximumWidth(150);
auto listModel = new QStringListModel(this);
QStringList widgetNames;
// Add commander details
auto commanderPicture = new EdhrecCommanderResponseCommanderDetailsDisplayWidget(
this, response.container.getCommanderDetails(), baseUrl);
cardDisplayLayout->addWidget(commanderPicture);
widgetNames.append("Commander Details");
// Add card list widgets
auto edhrec_commander_api_response_card_lists = response.container.getCardlists();
for (const EdhrecApiResponseCardList &card_list : edhrec_commander_api_response_card_lists) {
auto cardListDisplayWidget = new EdhrecApiResponseCardListDisplayWidget(this, card_list);
cardDisplayLayout->addWidget(cardListDisplayWidget);
widgetNames.append(cardListDisplayWidget->getBannerText());
}
// Create a QScrollArea to hold the card display widgets
scrollArea = new QScrollArea(splitter);
scrollArea->setWidgetResizable(true);
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
// Set the cardDisplayLayout inside the scroll area
auto scrollWidget = new QWidget(scrollArea);
scrollWidget->setLayout(cardDisplayLayout);
connect(splitter, &QSplitter::splitterMoved, this, &EdhrecCommanderApiResponseDisplayWidget::onSplitterChange);
scrollArea->setWidget(scrollWidget);
// Configure the list view
listModel->setStringList(widgetNames);
listView->setModel(listModel);
listView->setEditTriggers(QAbstractItemView::NoEditTriggers);
// Connect the list view to ensure the corresponding widget is visible
connect(listView, &QListView::clicked, this, [this](const QModelIndex &index) {
int widgetIndex = index.row();
qDebug() << "clicked: " << widgetIndex;
auto targetWidget = cardDisplayLayout->itemAt(widgetIndex)->widget();
if (targetWidget) {
qDebug() << "Found targetWidget" << targetWidget;
// Attempt to cast the parent to QScrollArea
auto scrollArea = qobject_cast<QScrollArea *>(this->scrollArea); // Use the scroll area instance
if (scrollArea) {
qDebug() << "ScrollArea" << scrollArea;
scrollArea->ensureWidgetVisible(targetWidget);
}
}
});
// Add splitter to the main layout
splitter->addWidget(listView);
splitter->addWidget(scrollArea);
layout->addWidget(splitter);
}
void EdhrecCommanderApiResponseDisplayWidget::onSplitterChange()
{
scrollArea->widget()->resize(scrollArea->size());
}
void EdhrecCommanderApiResponseDisplayWidget::resizeEvent(QResizeEvent *event)
{
QWidget::resizeEvent(event);
qDebug() << event->size();
layout->invalidate();
layout->activate();
layout->update();
if (scrollArea && scrollArea->widget()) {
scrollArea->widget()->resize(event->size());
}
}

View file

@ -0,0 +1,35 @@
/**
* @file edhrec_commander_api_response_display_widget.h
* @ingroup ApiResponseDisplayWidgets
* @brief TODO: Document this.
*/
#ifndef EDHREC_COMMANDER_API_RESPONSE_DISPLAY_WIDGET_H
#define EDHREC_COMMANDER_API_RESPONSE_DISPLAY_WIDGET_H
#include "../../api_response/commander/edhrec_commander_api_response.h"
#include <QScrollArea>
#include <QVBoxLayout>
#include <QWidget>
class EdhrecCommanderApiResponseDisplayWidget : public QWidget
{
Q_OBJECT
public:
explicit EdhrecCommanderApiResponseDisplayWidget(QWidget *parent,
EdhrecCommanderApiResponse response,
QString baseUrl);
void resizeEvent(QResizeEvent *event) override;
public slots:
void onSplitterChange();
private:
QHBoxLayout *layout;
QVBoxLayout *cardDisplayLayout;
QScrollArea *scrollArea;
};
#endif // EDHREC_COMMANDER_API_RESPONSE_DISPLAY_WIDGET_H

View file

@ -0,0 +1,174 @@
#include "edhrec_commander_api_response_navigation_widget.h"
#include "../../tab_edhrec_main.h"
EdhrecCommanderApiResponseNavigationWidget::EdhrecCommanderApiResponseNavigationWidget(
QWidget *parent,
const EdhrecCommanderApiResponseCommanderDetails &_commanderDetails,
QString baseUrl)
: QWidget(parent), commanderDetails(_commanderDetails)
{
layout = new QGridLayout(this);
setLayout(layout);
gameChangerLabel = new QLabel(this);
budgetLabel = new QLabel(this);
comboPushButton = new QPushButton(this);
averageDeckPushButton = new QPushButton(this);
layout->addWidget(comboPushButton, 0, 0, 1, 1);
layout->addWidget(averageDeckPushButton, 0, 1, 1, 1);
layout->addWidget(gameChangerLabel, 1, 0, 1, 2);
for (int i = 0; i < gameChangerOptions.length(); i++) {
QString option = gameChangerOptions.at(i);
QString label = option.isEmpty() ? "All" : option.at(0).toUpper() + option.mid(1);
QPushButton *optionButton = new QPushButton(label, this);
gameChangerButtons[option] = optionButton;
layout->addWidget(optionButton, 2, i);
connect(optionButton, &QPushButton::clicked, this, [=, this]() {
selectedGameChanger = option;
updateOptionButtonSelection(gameChangerButtons, option);
actRequestCommanderNavigation();
});
}
layout->addWidget(budgetLabel, 3, 0, 1, 2);
for (int i = 0; i < budgetOptions.length(); i++) {
QString option = budgetOptions.at(i);
QString label = option.isEmpty() ? "Any" : option.at(0).toUpper() + option.mid(1);
QPushButton *btn = new QPushButton(label, this);
budgetButtons[option] = btn;
layout->addWidget(btn, 4, i);
connect(btn, &QPushButton::clicked, this, [=, this]() {
selectedBudget = option;
updateOptionButtonSelection(budgetButtons, option);
actRequestCommanderNavigation();
});
}
updateOptionButtonSelection(gameChangerButtons, "");
updateOptionButtonSelection(budgetButtons, "");
QWidget *currentParent = parentWidget();
TabEdhRecMain *parentTab = nullptr;
while (currentParent) {
if ((parentTab = qobject_cast<TabEdhRecMain *>(currentParent))) {
break;
}
currentParent = currentParent->parentWidget();
}
if (parentTab) {
connect(comboPushButton, &QPushButton::clicked, this,
&EdhrecCommanderApiResponseNavigationWidget::actRequestComboNavigation);
connect(averageDeckPushButton, &QPushButton::clicked, this,
&EdhrecCommanderApiResponseNavigationWidget::actRequestAverageDeckNavigation);
connect(this, &EdhrecCommanderApiResponseNavigationWidget::requestUrl, parentTab,
&TabEdhRecMain::actNavigatePage);
}
retranslateUi();
applyOptionsFromUrl(baseUrl);
}
void EdhrecCommanderApiResponseNavigationWidget::retranslateUi()
{
comboPushButton->setText(tr("Combos"));
averageDeckPushButton->setText(tr("Average Deck"));
gameChangerLabel->setText(tr("Game Changers"));
budgetLabel->setText(tr("Budget"));
}
void EdhrecCommanderApiResponseNavigationWidget::applyOptionsFromUrl(const QString &url)
{
QString cleanedUrl = url;
// Remove base and file extension
if (cleanedUrl.startsWith("https://json.edhrec.com/pages/")) {
cleanedUrl = cleanedUrl.mid(QString("https://json.edhrec.com/pages/").length());
}
if (cleanedUrl.endsWith(".json")) {
cleanedUrl.chop(5);
}
// Expecting something like: "commanders/the-ur-dragon/core/expensive"
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
QStringList parts = cleanedUrl.split('/', Qt::SkipEmptyParts);
#else
QStringList parts = cleanedUrl.split('/', QString::SkipEmptyParts);
#endif
if (parts.size() < 2) {
return;
}
QString commanderName = parts[1];
QString gameChangerOpt, budgetOpt;
// Define valid sets
QSet<QString> validGameChangers = {"core", "upgraded", "optimized"};
QSet<QString> validBudgets = {"budget", "expensive"};
// Check remaining parts after commander
for (int i = 2; i < parts.size(); ++i) {
QString part = parts[i].toLower();
if (validGameChangers.contains(part)) {
gameChangerOpt = part;
} else if (validBudgets.contains(part)) {
budgetOpt = part;
}
}
// Validate and apply
if (!gameChangerButtons.contains(gameChangerOpt)) {
gameChangerOpt.clear();
}
if (!budgetButtons.contains(budgetOpt)) {
budgetOpt.clear();
}
selectedGameChanger = gameChangerOpt;
selectedBudget = budgetOpt;
updateOptionButtonSelection(gameChangerButtons, selectedGameChanger);
updateOptionButtonSelection(budgetButtons, selectedBudget);
}
void EdhrecCommanderApiResponseNavigationWidget::updateOptionButtonSelection(QMap<QString, QPushButton *> &buttons,
const QString &selectedKey)
{
for (auto it = buttons.begin(); it != buttons.end(); ++it) {
it.value()->setStyleSheet(it.key() == selectedKey ? "background-color: lightblue; font-weight: bold;" : "");
}
}
QString EdhrecCommanderApiResponseNavigationWidget::addNavigationOptionsToUrl(QString baseUrl)
{
if (!selectedGameChanger.isEmpty()) {
baseUrl += "/" + selectedGameChanger;
}
if (!selectedBudget.isEmpty()) {
baseUrl += "/" + selectedBudget;
}
return baseUrl;
}
void EdhrecCommanderApiResponseNavigationWidget::actRequestCommanderNavigation()
{
emit requestUrl(addNavigationOptionsToUrl("/commanders/" + commanderDetails.getSanitized()));
}
void EdhrecCommanderApiResponseNavigationWidget::actRequestComboNavigation()
{
emit requestUrl("/combos/" + commanderDetails.getSanitized());
}
void EdhrecCommanderApiResponseNavigationWidget::actRequestAverageDeckNavigation()
{
emit requestUrl(addNavigationOptionsToUrl("/average-decks/" + commanderDetails.getSanitized()));
}

View file

@ -0,0 +1,60 @@
/**
* @file edhrec_commander_api_response_navigation_widget.h
* @ingroup ApiResponseDisplayWidgets
* @brief TODO: Document this.
*/
#ifndef EDHREC_COMMANDER_API_RESPONSE_NAVIGATION_WIDGET_H
#define EDHREC_COMMANDER_API_RESPONSE_NAVIGATION_WIDGET_H
#include "edhrec_api_response_commander_details_display_widget.h"
#include <QGridLayout>
#include <QLabel>
#include <QPushButton>
#include <QWidget>
class EdhrecCommanderApiResponseNavigationWidget : public QWidget
{
Q_OBJECT
public:
explicit EdhrecCommanderApiResponseNavigationWidget(
QWidget *parent,
const EdhrecCommanderApiResponseCommanderDetails &_commanderDetails,
QString baseUrl);
void retranslateUi();
void applyOptionsFromUrl(const QString &url);
public slots:
void actRequestCommanderNavigation();
void actRequestComboNavigation();
void actRequestAverageDeckNavigation();
signals:
void requestUrl(QString url);
private:
QGridLayout *layout;
QLabel *gameChangerLabel;
QLabel *budgetLabel;
QStringList gameChangerOptions = {"", "core", "upgraded", "optimized"};
QStringList budgetOptions = {"", "budget", "expensive"};
QString selectedGameChanger;
QString selectedBudget;
QMap<QString, QPushButton *> gameChangerButtons;
QMap<QString, QPushButton *> budgetButtons;
QPushButton *comboPushButton;
QPushButton *averageDeckPushButton;
EdhrecCommanderApiResponseCommanderDetails commanderDetails;
void updateOptionButtonSelection(QMap<QString, QPushButton *> &buttons, const QString &selectedKey);
QString addNavigationOptionsToUrl(QString baseUrl);
QString buildComboUrl() const;
};
#endif // EDHREC_COMMANDER_API_RESPONSE_NAVIGATION_WIDGET_H

View file

@ -0,0 +1,45 @@
#include "edhrec_top_cards_api_response_display_widget.h"
#include "../../api_response/top_cards/edhrec_top_cards_api_response.h"
#include "../cards/edhrec_api_response_card_list_display_widget.h"
EdhrecTopCardsApiResponseDisplayWidget::EdhrecTopCardsApiResponseDisplayWidget(QWidget *parent,
EdhrecTopCardsApiResponse response)
: QWidget(parent)
{
layout = new QHBoxLayout(this);
setLayout(layout);
cardDisplayLayout = new QVBoxLayout(this);
// Add card list widgets
auto edhrec_commander_api_response_card_lists = response.container.getCardlists();
for (const EdhrecApiResponseCardList &card_list : edhrec_commander_api_response_card_lists) {
auto cardListDisplayWidget = new EdhrecApiResponseCardListDisplayWidget(this, card_list);
cardDisplayLayout->addWidget(cardListDisplayWidget);
}
// Create a QScrollArea to hold the card display widgets
scrollArea = new QScrollArea(this);
scrollArea->setWidgetResizable(true);
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
// Set the cardDisplayLayout inside the scroll area
auto scrollWidget = new QWidget(scrollArea);
scrollWidget->setLayout(cardDisplayLayout);
scrollArea->setWidget(scrollWidget);
layout->addWidget(scrollArea);
}
void EdhrecTopCardsApiResponseDisplayWidget::resizeEvent(QResizeEvent *event)
{
QWidget::resizeEvent(event);
layout->invalidate();
layout->activate();
layout->update();
if (scrollArea && scrollArea->widget()) {
scrollArea->widget()->resize(event->size());
}
}

View file

@ -0,0 +1,31 @@
/**
* @file edhrec_top_cards_api_response_display_widget.h
* @ingroup ApiResponseDisplayWidgets
* @brief TODO: Document this.
*/
#ifndef EDHREC_TOP_CARDS_API_RESPONSE_DISPLAY_WIDGET_H
#define EDHREC_TOP_CARDS_API_RESPONSE_DISPLAY_WIDGET_H
#include "../../api_response/top_cards/edhrec_top_cards_api_response.h"
#include <QResizeEvent>
#include <QScrollArea>
#include <QVBoxLayout>
#include <QWidget>
class EdhrecTopCardsApiResponseDisplayWidget : public QWidget
{
Q_OBJECT
public:
explicit EdhrecTopCardsApiResponseDisplayWidget(QWidget *parent, EdhrecTopCardsApiResponse response);
void resizeEvent(QResizeEvent *event) override;
private:
QHBoxLayout *layout;
QVBoxLayout *cardDisplayLayout;
QScrollArea *scrollArea;
};
#endif // EDHREC_TOP_CARDS_API_RESPONSE_DISPLAY_WIDGET_H

View file

@ -0,0 +1,47 @@
#include "edhrec_top_commanders_api_response_display_widget.h"
#include "../../api_response/top_commanders/edhrec_top_commanders_api_response.h"
#include "../cards/edhrec_api_response_card_list_display_widget.h"
EdhrecTopCommandersApiResponseDisplayWidget::EdhrecTopCommandersApiResponseDisplayWidget(
QWidget *parent,
EdhrecTopCommandersApiResponse response)
: QWidget(parent)
{
layout = new QHBoxLayout(this);
setLayout(layout);
cardDisplayLayout = new QVBoxLayout(this);
// Add card list widgets
auto edhrec_commander_api_response_card_lists = response.container.getCardlists();
for (const EdhrecApiResponseCardList &card_list : edhrec_commander_api_response_card_lists) {
auto cardListDisplayWidget = new EdhrecApiResponseCardListDisplayWidget(this, card_list);
cardDisplayLayout->addWidget(cardListDisplayWidget);
}
// Create a QScrollArea to hold the card display widgets
scrollArea = new QScrollArea(this);
scrollArea->setWidgetResizable(true);
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
// Set the cardDisplayLayout inside the scroll area
auto scrollWidget = new QWidget(scrollArea);
scrollWidget->setLayout(cardDisplayLayout);
scrollArea->setWidget(scrollWidget);
layout->addWidget(scrollArea);
}
void EdhrecTopCommandersApiResponseDisplayWidget::resizeEvent(QResizeEvent *event)
{
QWidget::resizeEvent(event);
qDebug() << event->size();
layout->invalidate();
layout->activate();
layout->update();
if (scrollArea && scrollArea->widget()) {
scrollArea->widget()->resize(event->size());
}
}

View file

@ -0,0 +1,31 @@
/**
* @file edhrec_top_commanders_api_response_display_widget.h
* @ingroup ApiResponseDisplayWidgets
* @brief TODO: Document this.
*/
#ifndef EDHREC_TOP_COMMANDERS_API_RESPONSE_DISPLAY_WIDGET_H
#define EDHREC_TOP_COMMANDERS_API_RESPONSE_DISPLAY_WIDGET_H
#include "../../api_response/top_commanders/edhrec_top_commanders_api_response.h"
#include <QResizeEvent>
#include <QScrollArea>
#include <QVBoxLayout>
#include <QWidget>
class EdhrecTopCommandersApiResponseDisplayWidget : public QWidget
{
Q_OBJECT
public:
explicit EdhrecTopCommandersApiResponseDisplayWidget(QWidget *parent, EdhrecTopCommandersApiResponse response);
void resizeEvent(QResizeEvent *event) override;
private:
QHBoxLayout *layout;
QVBoxLayout *cardDisplayLayout;
QScrollArea *scrollArea;
};
#endif // EDHREC_TOP_COMMANDERS_API_RESPONSE_DISPLAY_WIDGET_H

View file

@ -0,0 +1,45 @@
#include "edhrec_top_tags_api_response_display_widget.h"
#include "../../api_response/top_tags/edhrec_top_tags_api_response.h"
#include "../cards/edhrec_api_response_card_list_display_widget.h"
EdhrecTopTagsApiResponseDisplayWidget::EdhrecTopTagsApiResponseDisplayWidget(QWidget *parent,
EdhrecTopTagsApiResponse response)
: QWidget(parent)
{
layout = new QHBoxLayout(this);
setLayout(layout);
cardDisplayLayout = new QVBoxLayout(this);
// Add card list widgets
auto edhrec_commander_api_response_card_lists = response.container.getCardlists();
for (const EdhrecApiResponseCardList &card_list : edhrec_commander_api_response_card_lists) {
auto cardListDisplayWidget = new EdhrecApiResponseCardListDisplayWidget(this, card_list);
cardDisplayLayout->addWidget(cardListDisplayWidget);
}
// Create a QScrollArea to hold the card display widgets
scrollArea = new QScrollArea(this);
scrollArea->setWidgetResizable(true);
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
// Set the cardDisplayLayout inside the scroll area
auto scrollWidget = new QWidget(scrollArea);
scrollWidget->setLayout(cardDisplayLayout);
scrollArea->setWidget(scrollWidget);
layout->addWidget(scrollArea);
}
void EdhrecTopTagsApiResponseDisplayWidget::resizeEvent(QResizeEvent *event)
{
QWidget::resizeEvent(event);
layout->invalidate();
layout->activate();
layout->update();
if (scrollArea && scrollArea->widget()) {
scrollArea->widget()->resize(event->size());
}
}

View file

@ -0,0 +1,31 @@
/**
* @file edhrec_top_tags_api_response_display_widget.h
* @ingroup ApiResponseDisplayWidgets
* @brief TODO: Document this.
*/
#ifndef EDHREC_TOP_TAGS_API_RESPONSE_DISPLAY_WIDGET_H
#define EDHREC_TOP_TAGS_API_RESPONSE_DISPLAY_WIDGET_H
#include "../../api_response/top_tags/edhrec_top_tags_api_response.h"
#include <QResizeEvent>
#include <QScrollArea>
#include <QVBoxLayout>
#include <QWidget>
class EdhrecTopTagsApiResponseDisplayWidget : public QWidget
{
Q_OBJECT
public:
explicit EdhrecTopTagsApiResponseDisplayWidget(QWidget *parent, EdhrecTopTagsApiResponse response);
void resizeEvent(QResizeEvent *event) override;
private:
QHBoxLayout *layout;
QVBoxLayout *cardDisplayLayout;
QScrollArea *scrollArea;
};
#endif // EDHREC_TOP_TAGS_API_RESPONSE_DISPLAY_WIDGET_H

View file

@ -0,0 +1,112 @@
#include "tab_edhrec.h"
#include "api_response/commander/edhrec_commander_api_response.h"
#include "display/commander/edhrec_commander_api_response_display_widget.h"
#include <QDebug>
#include <QHBoxLayout>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QRegularExpression>
#include <QResizeEvent>
TabEdhRec::TabEdhRec(TabSupervisor *_tabSupervisor) : Tab(_tabSupervisor)
{
networkManager = new QNetworkAccessManager(this);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
networkManager->setTransferTimeout(); // Use Qt's default timeout
#endif
networkManager->setRedirectPolicy(QNetworkRequest::ManualRedirectPolicy);
connect(networkManager, &QNetworkAccessManager::finished, this, &TabEdhRec::processApiJson);
}
void TabEdhRec::retranslateUi()
{
}
void TabEdhRec::setCard(CardInfoPtr _cardToQuery, bool isCommander)
{
cardToQuery = _cardToQuery;
if (!cardToQuery) {
qDebug() << "Invalid card information provided.";
return;
}
QString cardName = cardToQuery->getName();
QString formattedName = cardName.toLower().replace(" ", "-").remove(QRegularExpression("[^a-z0-9\\-]"));
QString url;
if (isCommander) {
url = QString("https://json.edhrec.com/pages/commanders/%1.json").arg(formattedName);
} else {
url = QString("https://json.edhrec.com/pages/card/%1.json").arg(formattedName);
}
QNetworkRequest request{QUrl(url)};
networkManager->get(request);
}
void TabEdhRec::processApiJson(QNetworkReply *reply)
{
if (reply->error() != QNetworkReply::NoError) {
qDebug() << "Network error occurred:" << reply->errorString();
reply->deleteLater();
return;
}
QByteArray responseData = reply->readAll();
QJsonDocument jsonDoc = QJsonDocument::fromJson(responseData);
if (!jsonDoc.isObject()) {
qDebug() << "Invalid JSON response received.";
reply->deleteLater();
return;
}
QJsonObject jsonObj = jsonDoc.object();
// qDebug() << jsonObj;
EdhrecCommanderApiResponse deckData;
deckData.fromJson(jsonObj);
displayWidget = new EdhrecCommanderApiResponseDisplayWidget(this, deckData, reply->url().toString());
// flowWidget->addWidget(displayWidget);
setCentralWidget(displayWidget);
reply->deleteLater();
update();
}
void TabEdhRec::prettyPrintJson(const QJsonValue &value, int indentLevel)
{
const QString indent(indentLevel * 2, ' '); // Adjust spacing as needed for pretty printing
if (value.isObject()) {
QJsonObject obj = value.toObject();
for (auto it = obj.begin(); it != obj.end(); ++it) {
qDebug().noquote() << indent + it.key() + ":";
prettyPrintJson(it.value(), indentLevel + 1);
}
} else if (value.isArray()) {
QJsonArray array = value.toArray();
for (int i = 0; i < array.size(); ++i) {
qDebug().noquote() << indent + QString("[%1]:").arg(i);
prettyPrintJson(array[i], indentLevel + 1);
}
} else if (value.isString()) {
qDebug().noquote() << indent + "\"" + value.toString() + "\"";
} else if (value.isDouble()) {
qDebug().noquote() << indent + QString::number(value.toDouble());
} else if (value.isBool()) {
qDebug().noquote() << indent + (value.toBool() ? "true" : "false");
} else if (value.isNull()) {
qDebug().noquote() << indent + "null";
}
}

View file

@ -0,0 +1,41 @@
/**
* @file tab_edhrec.h
* @ingroup Tabs
* @brief TODO: Document this.
*/
#ifndef TAB_EDHREC_H
#define TAB_EDHREC_H
#include "../../tab.h"
#include "display/commander/edhrec_commander_api_response_display_widget.h"
#include <QNetworkAccessManager>
#include <libcockatrice/card/card_info.h>
class TabEdhRec : public Tab
{
Q_OBJECT
public:
explicit TabEdhRec(TabSupervisor *_tabSupervisor);
void retranslateUi() override;
QString getTabText() const override
{
auto cardName = cardToQuery.isNull() ? QString() : cardToQuery->getName();
return tr("EDHREC: ") + cardName;
}
QNetworkAccessManager *networkManager;
public slots:
void processApiJson(QNetworkReply *reply);
void prettyPrintJson(const QJsonValue &value, int indentLevel);
void setCard(CardInfoPtr _cardToQuery, bool isCommander = false);
private:
CardInfoPtr cardToQuery;
EdhrecCommanderApiResponseDisplayWidget *displayWidget;
};
#endif // TAB_EDHREC_H

View file

@ -0,0 +1,387 @@
#include "tab_edhrec_main.h"
#include "../../tab_supervisor.h"
#include "api_response/average_deck/edhrec_average_deck_api_response.h"
#include "api_response/commander/edhrec_commander_api_response.h"
#include "api_response/top_cards/edhrec_top_cards_api_response.h"
#include "api_response/top_commanders/edhrec_top_commanders_api_response.h"
#include "api_response/top_tags/edhrec_top_tags_api_response.h"
#include "display/commander/edhrec_commander_api_response_display_widget.h"
#include "display/top_cards/edhrec_top_cards_api_response_display_widget.h"
#include "display/top_commander/edhrec_top_commanders_api_response_display_widget.h"
#include "display/top_tags/edhrec_top_tags_api_response_display_widget.h"
#include <QCompleter>
#include <QDebug>
#include <QHBoxLayout>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QPushButton>
#include <QRegularExpression>
#include <QResizeEvent>
#include <libcockatrice/card/card_database/card_database_manager.h>
#include <libcockatrice/card/card_database/model/card/card_completer_proxy_model.h>
#include <libcockatrice/card/card_database/model/card/card_search_model.h>
static bool canBeCommander(const CardInfoPtr &cardInfo)
{
return ((cardInfo->getCardType().contains("Legendary", Qt::CaseInsensitive) &&
cardInfo->getCardType().contains("Creature", Qt::CaseInsensitive))) ||
cardInfo->getText().contains("can be your commander", Qt::CaseInsensitive);
}
TabEdhRecMain::TabEdhRecMain(TabSupervisor *_tabSupervisor) : Tab(_tabSupervisor)
{
networkManager = new QNetworkAccessManager(this);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
networkManager->setTransferTimeout(); // Use Qt's default timeout
#endif
networkManager->setRedirectPolicy(QNetworkRequest::ManualRedirectPolicy);
connect(networkManager, SIGNAL(finished(QNetworkReply *)), this, SLOT(processApiJson(QNetworkReply *)));
container = new QWidget(this);
mainLayout = new QVBoxLayout(container);
container->setLayout(mainLayout);
navigationContainer = new QWidget(container);
navigationContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
navigationLayout = new QHBoxLayout(navigationContainer);
navigationLayout->setSpacing(5);
navigationContainer->setLayout(navigationLayout);
cardsPushButton = new QPushButton(navigationContainer);
connect(cardsPushButton, &QPushButton::clicked, this, &TabEdhRecMain::getTopCards);
topCommandersPushButton = new QPushButton(navigationContainer);
connect(topCommandersPushButton, &QPushButton::clicked, this, &TabEdhRecMain::getTopCommanders);
tagsPushButton = new QPushButton(navigationContainer);
connect(tagsPushButton, &QPushButton::clicked, this, &TabEdhRecMain::getTopTags);
searchBar = new QLineEdit(this);
auto cardDatabaseModel = new CardDatabaseModel(CardDatabaseManager::getInstance(), false, this);
auto displayModel = new CardDatabaseDisplayModel(this);
displayModel->setSourceModel(cardDatabaseModel);
CardSearchModel *searchModel = new CardSearchModel(displayModel, this);
CardCompleterProxyModel *proxyModel = new CardCompleterProxyModel(this);
proxyModel->setSourceModel(searchModel);
proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
proxyModel->setFilterRole(Qt::DisplayRole);
QCompleter *completer = new QCompleter(proxyModel, this);
completer->setCompletionRole(Qt::DisplayRole);
completer->setCompletionMode(QCompleter::PopupCompletion);
completer->setCaseSensitivity(Qt::CaseInsensitive);
completer->setFilterMode(Qt::MatchContains);
completer->setMaxVisibleItems(10);
searchBar->setCompleter(completer);
// Update suggestions dynamically
connect(searchBar, &QLineEdit::textChanged, searchModel, &CardSearchModel::updateSearchResults);
connect(searchBar, &QLineEdit::textChanged, this, [=](const QString &text) {
// Ensure substring matching
QString pattern = ".*" + QRegularExpression::escape(text) + ".*";
proxyModel->setFilterRegularExpression(QRegularExpression(pattern, QRegularExpression::CaseInsensitiveOption));
if (!text.isEmpty()) {
completer->complete(); // Force the dropdown to appear
}
});
searchPushButton = new QPushButton(navigationContainer);
connect(searchPushButton, &QPushButton::clicked, this, [=, this]() { doSearch(); });
settingsButton = new SettingsButtonWidget(this);
cardSizeSlider = new CardSizeWidget(this);
settingsButton->addSettingsWidget(cardSizeSlider);
navigationLayout->addWidget(cardsPushButton);
navigationLayout->addWidget(topCommandersPushButton);
navigationLayout->addWidget(tagsPushButton);
navigationLayout->addWidget(searchBar);
navigationLayout->addWidget(searchPushButton);
navigationLayout->addWidget(settingsButton);
currentPageDisplay = new QWidget(container);
currentPageLayout = new QVBoxLayout(currentPageDisplay);
currentPageDisplay->setLayout(currentPageLayout);
mainLayout->addWidget(navigationContainer);
mainLayout->addWidget(currentPageDisplay);
// Ensure navigation stays at the top and currentPageDisplay takes remaining space
mainLayout->setStretch(0, 0); // navigationContainer gets minimum space
mainLayout->setStretch(1, 1); // currentPageDisplay expands as much as possible
setCentralWidget(container);
TabEdhRecMain::retranslateUi();
getTopCards();
}
void TabEdhRecMain::retranslateUi()
{
cardsPushButton->setText(tr("&Cards"));
topCommandersPushButton->setText(tr("Top Commanders"));
tagsPushButton->setText(tr("Tags"));
searchBar->setPlaceholderText(tr("Search for a card ..."));
searchPushButton->setText(tr("Search"));
}
void TabEdhRecMain::doSearch()
{
CardInfoPtr searchedCard = CardDatabaseManager::query()->getCardInfo(searchBar->text());
if (!searchedCard) {
return;
}
setCard(searchedCard, canBeCommander(searchedCard));
}
void TabEdhRecMain::setCard(CardInfoPtr _cardToQuery, bool isCommander)
{
cardToQuery = _cardToQuery;
if (!cardToQuery) {
qDebug() << "Invalid card information provided.";
return;
}
QString cardName = cardToQuery->getName();
QString formattedName = cardName.toLower().replace(" ", "-").remove(QRegularExpression("[^a-z0-9\\-]"));
QString url;
if (isCommander) {
url = QString("https://json.edhrec.com/pages/commanders/%1.json").arg(formattedName);
} else {
url = QString("https://json.edhrec.com/pages/cards/%1.json").arg(formattedName);
}
QNetworkRequest request{QUrl(url)};
networkManager->get(request);
}
void TabEdhRecMain::actNavigatePage(QString url)
{
QNetworkRequest request{QUrl("https://json.edhrec.com/pages" + url + ".json")};
networkManager->get(request);
}
void TabEdhRecMain::getTopCards()
{
QNetworkRequest request{QUrl("https://json.edhrec.com/pages/top/year.json")};
networkManager->get(request);
}
void TabEdhRecMain::getTopCommanders()
{
QNetworkRequest request{QUrl("https://json.edhrec.com/pages/commanders/year.json")};
networkManager->get(request);
}
void TabEdhRecMain::getTopTags()
{
QNetworkRequest request{QUrl("https://json.edhrec.com/pages/tags.json")};
networkManager->get(request);
}
void TabEdhRecMain::processApiJson(QNetworkReply *reply)
{
if (reply->error() != QNetworkReply::NoError) {
qDebug() << "Network error occurred:" << reply->errorString();
reply->deleteLater();
return;
}
QByteArray responseData = reply->readAll();
QJsonDocument jsonDoc = QJsonDocument::fromJson(responseData);
if (!jsonDoc.isObject()) {
qDebug() << "Invalid JSON response received.";
reply->deleteLater();
return;
}
QJsonObject jsonObj = jsonDoc.object();
// Get the actual URL from the reply
QString responseUrl = reply->url().toString();
// Check if the response URL matches a commander request
if (responseUrl.startsWith("https://json.edhrec.com/pages/commanders/year.json")) {
processTopCommandersResponse(jsonObj);
} else if (responseUrl.startsWith("https://json.edhrec.com/pages/commanders/")) {
qInfo() << "Received top kek";
processCommanderResponse(jsonObj, responseUrl);
} else if (responseUrl.startsWith("https://json.edhrec.com/pages/cards/")) {
processCommanderResponse(jsonObj);
} else if (responseUrl.startsWith("https://json.edhrec.com/pages/tags/")) {
processCommanderResponse(jsonObj);
} else if (responseUrl.startsWith("https://json.edhrec.com/pages/tags.json")) {
processTopTagsResponse(jsonObj);
} else if (responseUrl.startsWith("https://json.edhrec.com/pages/top/year.json")) {
processTopCardsResponse(jsonObj);
} else if (responseUrl.startsWith("https://json.edhrec.com/pages/combos/")) {
qInfo() << "Received combos";
processCommanderResponse(jsonObj);
} else if (responseUrl.startsWith("https://json.edhrec.com/pages/average-decks/")) {
processAverageDeckResponse(jsonObj);
} else {
prettyPrintJson(jsonObj, 4);
}
reply->deleteLater();
}
void TabEdhRecMain::processTopCardsResponse(QJsonObject reply)
{
EdhrecTopCardsApiResponse deckData;
deckData.fromJson(reply);
// **Remove previous page display to prevent stacking**
if (currentPageDisplay) {
mainLayout->removeWidget(currentPageDisplay);
delete currentPageDisplay;
currentPageDisplay = nullptr;
}
// **Create new currentPageDisplay**
currentPageDisplay = new QWidget(container);
currentPageLayout = new QVBoxLayout(currentPageDisplay);
currentPageDisplay->setLayout(currentPageLayout);
auto display = new EdhrecTopCardsApiResponseDisplayWidget(currentPageDisplay, deckData);
currentPageLayout->addWidget(display);
mainLayout->addWidget(currentPageDisplay);
// **Ensure layout stays correct**
mainLayout->setStretch(0, 0); // Keep navigationContainer at the top
mainLayout->setStretch(1, 1); // Make sure currentPageDisplay takes remaining space
}
void TabEdhRecMain::processTopTagsResponse(QJsonObject reply)
{
EdhrecTopTagsApiResponse deckData;
deckData.fromJson(reply);
// **Remove previous page display to prevent stacking**
if (currentPageDisplay) {
mainLayout->removeWidget(currentPageDisplay);
delete currentPageDisplay;
currentPageDisplay = nullptr;
}
// **Create new currentPageDisplay**
currentPageDisplay = new QWidget(container);
currentPageLayout = new QVBoxLayout(currentPageDisplay);
currentPageDisplay->setLayout(currentPageLayout);
auto display = new EdhrecTopTagsApiResponseDisplayWidget(currentPageDisplay, deckData);
currentPageLayout->addWidget(display);
mainLayout->addWidget(currentPageDisplay);
// **Ensure layout stays correct**
mainLayout->setStretch(0, 0); // Keep navigationContainer at the top
mainLayout->setStretch(1, 1); // Make sure currentPageDisplay takes remaining space
}
void TabEdhRecMain::processTopCommandersResponse(QJsonObject reply)
{
EdhrecTopCommandersApiResponse deckData;
deckData.fromJson(reply);
// **Remove previous page display to prevent stacking**
if (currentPageDisplay) {
mainLayout->removeWidget(currentPageDisplay);
delete currentPageDisplay;
currentPageDisplay = nullptr;
}
// **Create new currentPageDisplay**
currentPageDisplay = new QWidget(container);
currentPageLayout = new QVBoxLayout(currentPageDisplay);
currentPageDisplay->setLayout(currentPageLayout);
auto display = new EdhrecTopCommandersApiResponseDisplayWidget(currentPageDisplay, deckData);
currentPageLayout->addWidget(display);
mainLayout->addWidget(currentPageDisplay);
// **Ensure layout stays correct**
mainLayout->setStretch(0, 0); // Keep navigationContainer at the top
mainLayout->setStretch(1, 1); // Make sure currentPageDisplay takes remaining space
}
void TabEdhRecMain::processCommanderResponse(QJsonObject reply, QString responseUrl)
{
EdhrecCommanderApiResponse deckData;
deckData.fromJson(reply);
// **Remove previous page display to prevent stacking**
if (currentPageDisplay) {
mainLayout->removeWidget(currentPageDisplay);
delete currentPageDisplay;
currentPageDisplay = nullptr;
}
// **Create new currentPageDisplay**
currentPageDisplay = new QWidget(container);
currentPageLayout = new QVBoxLayout(currentPageDisplay);
currentPageDisplay->setLayout(currentPageLayout);
auto display = new EdhrecCommanderApiResponseDisplayWidget(currentPageDisplay, deckData, responseUrl);
currentPageLayout->addWidget(display);
mainLayout->addWidget(currentPageDisplay);
// **Ensure layout stays correct**
mainLayout->setStretch(0, 0); // Keep navigationContainer at the top
mainLayout->setStretch(1, 1); // Make sure currentPageDisplay takes remaining space
}
void TabEdhRecMain::processAverageDeckResponse(QJsonObject reply)
{
EdhrecAverageDeckApiResponse deckData;
deckData.fromJson(reply);
tabSupervisor->openDeckInNewTab(deckData.deck.deckLoader);
}
void TabEdhRecMain::prettyPrintJson(const QJsonValue &value, int indentLevel)
{
const QString indent(indentLevel * 2, ' '); // Adjust spacing as needed for pretty printing
if (value.isObject()) {
QJsonObject obj = value.toObject();
for (auto it = obj.begin(); it != obj.end(); ++it) {
qDebug().noquote() << indent + it.key() + ":";
prettyPrintJson(it.value(), indentLevel + 1);
}
} else if (value.isArray()) {
QJsonArray array = value.toArray();
for (int i = 0; i < array.size(); ++i) {
qDebug().noquote() << indent + QString("[%1]:").arg(i);
prettyPrintJson(array[i], indentLevel + 1);
}
} else if (value.isString()) {
qDebug().noquote() << indent + "\"" + value.toString() + "\"";
} else if (value.isDouble()) {
qDebug().noquote() << indent + QString::number(value.toDouble());
} else if (value.isBool()) {
qDebug().noquote() << indent + (value.toBool() ? "true" : "false");
} else if (value.isNull()) {
qDebug().noquote() << indent + "null";
}
}

View file

@ -0,0 +1,75 @@
/**
* @file tab_edhrec_main.h
* @ingroup Tabs
* @brief TODO: Document this.
*/
#ifndef TAB_EDHREC_MAIN_H
#define TAB_EDHREC_MAIN_H
#include "../../interface/widgets/cards/card_size_widget.h"
#include "../../interface/widgets/general/layout_containers/flow_widget.h"
#include "../../interface/widgets/quick_settings/settings_button_widget.h"
#include "../../tab.h"
#include "display/commander/edhrec_commander_api_response_display_widget.h"
#include <QHBoxLayout>
#include <QLineEdit>
#include <QNetworkAccessManager>
#include <QPushButton>
#include <libcockatrice/card/card_database/card_database.h>
class TabEdhRecMain : public Tab
{
Q_OBJECT
public:
explicit TabEdhRecMain(TabSupervisor *_tabSupervisor);
void retranslateUi() override;
void doSearch();
QString getTabText() const override
{
auto cardName = cardToQuery.isNull() ? QString() : cardToQuery->getName();
return tr("EDHRec: ") + cardName;
}
CardSizeWidget *getCardSizeSlider()
{
return cardSizeSlider;
}
QNetworkAccessManager *networkManager;
public slots:
void processApiJson(QNetworkReply *reply);
void processCommanderResponse(QJsonObject reply, QString responseUrl = "");
void processTopCardsResponse(QJsonObject reply);
void processTopTagsResponse(QJsonObject reply);
void processTopCommandersResponse(QJsonObject reply);
void processAverageDeckResponse(QJsonObject reply);
void prettyPrintJson(const QJsonValue &value, int indentLevel);
void setCard(CardInfoPtr _cardToQuery, bool isCommander = false);
void actNavigatePage(QString url);
void getTopCards();
void getTopCommanders();
void getTopTags();
private:
QWidget *container;
QWidget *navigationContainer;
QWidget *currentPageDisplay;
QVBoxLayout *mainLayout;
QHBoxLayout *navigationLayout;
QVBoxLayout *currentPageLayout;
QPushButton *cardsPushButton;
QPushButton *topCommandersPushButton;
QPushButton *tagsPushButton;
QLineEdit *searchBar;
QPushButton *searchPushButton;
SettingsButtonWidget *settingsButton;
CardSizeWidget *cardSizeSlider;
CardInfoPtr cardToQuery;
EdhrecCommanderApiResponseDisplayWidget *displayWidget;
};
#endif // TAB_EDHREC_MAIN_H