Deck export (#2938)

* Added “export deck” option to export deck to decklist.org for viewing/printing. Implemented using a new menu item, added shortcut ability, and functionality to parse the deck correctly and add main/sideboard cards to decklist. Per issue #2931
This commit is contained in:
John Robe 2017-12-05 20:34:19 -07:00 committed by Zach H
parent 4d641eb0e7
commit 6c038a91e4
6 changed files with 126 additions and 5 deletions

View file

@ -103,6 +103,73 @@ bool DeckLoader::saveToFile(const QString &fileName, FileFormat fmt)
return result;
}
//This struct is here to support the forEachCard function call, defined in decklist. It
//requires a function to be called for each card, and passes an inner node and a card for
//each card in the decklist.
struct FormatDeckListForExport
{
//Create refrences for the strings that will be passed in.
QString &mainBoardCards;
QString &sideBoardCards;
//create main operator for struct, allowing the foreachcard to work.
FormatDeckListForExport(
QString &_mainBoardCards, QString &_sideBoardCards
) : mainBoardCards(_mainBoardCards),
sideBoardCards(_sideBoardCards){};
void operator()(const InnerDecklistNode *node, const DecklistCardNode *card) const{
//Get the card name
CardInfo * dbCard = db->getCard(card->getName());
if (!dbCard || dbCard->getIsToken()){
//If it's a token, we don't care about the card.
return;
}
//Check if it's a sideboard card.
if(node->getName() == DECK_ZONE_SIDE){
//Get the number of cards and add the card name
sideBoardCards+=QString::number(card->getNumber());
//Add a space between card num and name
sideBoardCards+="%20";
//Add card name
sideBoardCards+=card->getName();
//Add a return at the end of the card
sideBoardCards+="%0A";
}
//If it's a mainboard card, do the same thing, but for the mainboard card string
else{
mainBoardCards+=QString::number(card->getNumber());
mainBoardCards+="%20";
mainBoardCards+=card->getName();
mainBoardCards+="%0A";
}
}
};
//Export deck to decklist function, called to format the deck in a way to be sent to a server
QString DeckLoader::exportDeckToDecklist()
{
//Add the base url
QString deckString = "https://www.decklist.org/?";
//Create two strings to pass to function
QString mainBoardCards, sideBoardCards;
//Set up the struct to call.
FormatDeckListForExport formatDeckListForExport(mainBoardCards, sideBoardCards);
//call our struct function for each card in the deck
forEachCard(formatDeckListForExport);
//Remove the extra return at the end of the last cards
mainBoardCards.chop(3);
sideBoardCards.chop(3);
//if after we've called it for each card, and the strings are empty, we know that
//there were no non-token cards in the deck, so show an error message.
if((QString::compare(mainBoardCards, "", Qt::CaseInsensitive) == 0) &&
(QString::compare(sideBoardCards, "", Qt::CaseInsensitive) == 0)) {
return "";
}
//return a string with the url for decklist export
deckString+="deckmain="+mainBoardCards+"&deckside="+sideBoardCards;
return deckString;
}
DeckLoader::FileFormat DeckLoader::getFormatFromName(const QString &fileName)
{
if (fileName.endsWith(".cod", Qt::CaseInsensitive)) {
@ -215,4 +282,4 @@ QString DeckLoader::getCompleteCardName(const QString cardName) const
}
return cardName;
}
}

View file

@ -28,6 +28,7 @@ public:
bool loadFromFile(const QString &fileName, FileFormat fmt);
bool loadFromRemote(const QString &nativeString, int remoteDeckId);
bool saveToFile(const QString &fileName, FileFormat fmt);
QString exportDeckToDecklist();
// overload
bool saveToStream_Plain(QTextStream &out);

View file

@ -80,6 +80,8 @@ public:
SequenceEdit *TabDeckEditor_aIncrement;
QLabel *lbl_TabDeckEditor_aSaveDeck;
SequenceEdit *TabDeckEditor_aSaveDeck;
QLabel *lbl_TabDeckEditor_aExportDeckDecklist;
SequenceEdit *TabDeckEditor_aExportDeckDecklist;
QLabel *lbl_TabDeckEditor_aDecrement;
SequenceEdit *TabDeckEditor_aDecrement;
QLabel *lbl_TabDeckEditor_aSaveDeckAs;
@ -642,6 +644,16 @@ public:
TabDeckEditor_aSaveDeckToClipboard->setObjectName("TabDeckEditor_aSaveDeckToClipboard");
gridLayout->addWidget(TabDeckEditor_aSaveDeckToClipboard, 8, 3, 1, 1);
lbl_TabDeckEditor_aExportDeckDecklist = new QLabel(groupBox_2);
lbl_TabDeckEditor_aExportDeckDecklist->setObjectName("lbl_TabDeckEditor_aExportDeckDecklist");
gridLayout->addWidget(lbl_TabDeckEditor_aExportDeckDecklist, 9, 2, 1, 1);
TabDeckEditor_aExportDeckDecklist = new SequenceEdit("TabDeckEditor/aExportDeckDecklist",groupBox_2);
TabDeckEditor_aExportDeckDecklist->setObjectName("TabDeckEditor_aExportDeckDecklist");
gridLayout->addWidget(TabDeckEditor_aExportDeckDecklist, 9, 3, 1, 1);
gridLayout_3->addWidget(groupBox_2, 0, 1, 1, 1);
@ -1749,6 +1761,7 @@ public:
lbl_TabDeckEditor_aResetLayout->setText(QApplication::translate("shortcutsTab", "Reset layout", 0));
lbl_TabDeckEditor_aIncrement->setText(QApplication::translate("shortcutsTab", "Add card", 0));
lbl_TabDeckEditor_aSaveDeck->setText(QApplication::translate("shortcutsTab", "Save deck", 0));
lbl_TabDeckEditor_aExportDeckDecklist->setText(QApplication::translate("shortcutsTab", "Export deck", 0));
lbl_TabDeckEditor_aDecrement->setText(QApplication::translate("shortcutsTab", "Remove card", 0));
lbl_TabDeckEditor_aSaveDeckAs->setText(QApplication::translate("shortcutsTab", "Save deck as", 0));
lbl_TabDeckEditor_aLoadDeck->setText(QApplication::translate("shortcutsTab", "Load deck", 0));

View file

@ -157,6 +157,7 @@ void ShortcutsSettings::fillDefaultShorcuts()
defaultShortCuts["TabDeckEditor/aDecrement"] = parseSequenceString("-");
defaultShortCuts["TabDeckEditor/aEditSets"] = parseSequenceString("");
defaultShortCuts["TabDeckEditor/aEditTokens"] = parseSequenceString("");
defaultShortCuts["TabDeckEditor/aExportDeckDecklist"] = parseSequenceString("");
defaultShortCuts["TabDeckEditor/aIncrement"] = parseSequenceString("+");
defaultShortCuts["TabDeckEditor/aLoadDeck"] = parseSequenceString("Ctrl+O");
defaultShortCuts["TabDeckEditor/aLoadDeckFromClipboard"] = parseSequenceString("Ctrl+Shift+V");

View file

@ -23,6 +23,7 @@
#include <QPushButton>
#include <QDir>
#include <QDesktopServices>
#include <QUrl>
#include "tab_deck_editor.h"
#include "carddatabase.h"
#include "pictureloader.h"
@ -226,6 +227,9 @@ void TabDeckEditor::createMenus()
aPrintDeck = new QAction(QString(), this);
connect(aPrintDeck, SIGNAL(triggered()), this, SLOT(actPrintDeck()));
aExportDeckDecklist = new QAction(QString(), this);
connect(aExportDeckDecklist, SIGNAL(triggered()), this, SLOT(actExportDeckDecklist()));
aAnalyzeDeckDeckstats = new QAction(QString(), this);
connect(aAnalyzeDeckDeckstats, SIGNAL(triggered()), this, SLOT(actAnalyzeDeckDeckstats()));
@ -233,6 +237,7 @@ void TabDeckEditor::createMenus()
connect(aAnalyzeDeckTappedout, SIGNAL(triggered()), this, SLOT(actAnalyzeDeckTappedout()));
analyzeDeckMenu = new QMenu(this);
analyzeDeckMenu->addAction(aExportDeckDecklist);
analyzeDeckMenu->addAction(aAnalyzeDeckDeckstats);
analyzeDeckMenu->addAction(aAnalyzeDeckTappedout);
@ -453,6 +458,7 @@ void TabDeckEditor::refreshShortcuts()
aNewDeck->setShortcuts(settingsCache->shortcuts().getShortcut("TabDeckEditor/aNewDeck"));
aLoadDeck->setShortcuts(settingsCache->shortcuts().getShortcut("TabDeckEditor/aLoadDeck"));
aSaveDeck->setShortcuts(settingsCache->shortcuts().getShortcut("TabDeckEditor/aSaveDeck"));
aExportDeckDecklist->setShortcuts(settingsCache->shortcuts().getShortcut("TabDeckEditor/aExportDeckDecklist"));
aSaveDeckAs->setShortcuts(settingsCache->shortcuts().getShortcut("TabDeckEditor/aSaveDeckAs"));
aLoadDeckFromClipboard->setShortcuts(settingsCache->shortcuts().getShortcut("TabDeckEditor/aLoadDeckFromClipboard"));
aPrintDeck->setShortcuts(settingsCache->shortcuts().getShortcut("TabDeckEditor/aPrintDeck"));
@ -546,9 +552,10 @@ void TabDeckEditor::retranslateUi()
aSaveDeckToClipboard->setText(tr("Save deck to clip&board"));
aPrintDeck->setText(tr("&Print deck..."));
analyzeDeckMenu->setTitle(tr("&Analyze deck online"));
aAnalyzeDeckDeckstats->setText("deckstats.net");
aAnalyzeDeckTappedout->setText("tappedout.net");
analyzeDeckMenu->setTitle(tr("&Send deck to online service"));
aExportDeckDecklist->setText(tr("Create decklist (decklist.org)"));
aAnalyzeDeckDeckstats->setText(tr("Analyze deck (deckstats.net)"));
aAnalyzeDeckTappedout->setText(tr("Analyze deck (tappedout.net)"));
aClose->setText(tr("&Close"));
@ -764,6 +771,37 @@ void TabDeckEditor::actPrintDeck()
dlg->exec();
}
//Action called when export deck to decklist menu item is pressed.
void TabDeckEditor::actExportDeckDecklist()
{
//Get the decklist class for the deck.
DeckLoader *const deck = deckModel->getDeckList();
//create a string to load the decklist url into.
QString decklistUrlString;
//check if deck is not null
if(deck){
//Get the decklist url string from the deck loader class.
decklistUrlString = deck->exportDeckToDecklist();
//Check to make sure the string isn't empty.
if(QString::compare(decklistUrlString, "", Qt::CaseInsensitive) == 0){
//Show an error if the deck is empty, and return.
QMessageBox::critical(this, tr("Error"), tr("There are no cards in your deck to be exported"));
return;
}
//Encode the string recieved from the model to make sure all characters are encoded.
//first we put it into a qurl object
QUrl decklistUrl = QUrl(decklistUrlString);
//we get the correctly encoded url.
decklistUrlString = decklistUrl.toEncoded();
//We open the url in the user's default browser
QDesktopServices::openUrl(decklistUrlString);
}
else{
//if there's no deck loader object, return an error
QMessageBox::critical(this, tr("Error"), tr("No deck was selected to be saved."));
}
}
void TabDeckEditor::actAnalyzeDeckDeckstats()
{
DeckStatsInterface *interface = new DeckStatsInterface(

View file

@ -52,6 +52,7 @@ class TabDeckEditor : public Tab {
void actLoadDeckFromClipboard();
void actSaveDeckToClipboard();
void actPrintDeck();
void actExportDeckDecklist();
void actAnalyzeDeckDeckstats();
void actAnalyzeDeckTappedout();
@ -110,7 +111,7 @@ private:
QWidget *filterBox;
QMenu *deckMenu, *viewMenu, *cardInfoDockMenu, *deckDockMenu, *filterDockMenu, *analyzeDeckMenu;
QAction *aNewDeck, *aLoadDeck, *aSaveDeck, *aSaveDeckAs, *aLoadDeckFromClipboard, *aSaveDeckToClipboard, *aPrintDeck, *aAnalyzeDeckDeckstats, *aAnalyzeDeckTappedout, *aClose;
QAction *aNewDeck, *aLoadDeck, *aSaveDeck, *aSaveDeckAs, *aLoadDeckFromClipboard, *aSaveDeckToClipboard, *aPrintDeck, *aExportDeckDecklist, *aAnalyzeDeckDeckstats, *aAnalyzeDeckTappedout, *aClose;
QAction *aClearFilterAll, *aClearFilterOne;
QAction *aAddCard, *aAddCardToSideboard, *aRemoveCard, *aIncrement, *aDecrement;
QAction *aResetLayout;