fixed issue #49: when editing a remote deck, be able to directly save it there

This commit is contained in:
Max-Wilhelm Bruker 2012-05-09 21:52:09 +02:00
parent f00eaa83d4
commit 0eee6d7ab9
23 changed files with 324 additions and 181 deletions

View file

@ -28,6 +28,7 @@ SET(cockatrice_SOURCES
src/gameview.cpp
src/gameselector.cpp
src/decklistmodel.cpp
src/deck_loader.cpp
src/dlg_load_deck_from_clipboard.cpp
src/dlg_load_remote_deck.cpp
src/cardinfowidget.cpp
@ -101,6 +102,7 @@ SET(cockatrice_HEADERS
src/gameview.h
src/gameselector.h
src/decklistmodel.h
src/deck_loader.h
src/dlg_load_deck_from_clipboard.h
src/dlg_load_remote_deck.h
src/cardinfowidget.h

View file

@ -0,0 +1,101 @@
#include <QStringList>
#include <QFile>
#include "deck_loader.h"
#include "decklist.h"
const QStringList DeckLoader::fileNameFilters = QStringList()
<< QObject::tr("Cockatrice decks (*.cod)")
<< QObject::tr("Plain text decks (*.dec *.mwDeck)")
<< QObject::tr("All files (*.*)");
DeckLoader::DeckLoader()
: DeckList(),
lastFileName(QString()),
lastFileFormat(CockatriceFormat),
lastRemoteDeckId(-1)
{
}
DeckLoader::DeckLoader(const QString &nativeString)
: DeckList(nativeString),
lastFileName(QString()),
lastFileFormat(CockatriceFormat),
lastRemoteDeckId(-1)
{
}
DeckLoader::DeckLoader(const DeckList &other)
: DeckList(other),
lastFileName(QString()),
lastFileFormat(CockatriceFormat),
lastRemoteDeckId(-1)
{
}
DeckLoader::DeckLoader(const DeckLoader &other)
: DeckList(other),
lastFileName(other.lastFileName),
lastFileFormat(other.lastFileFormat),
lastRemoteDeckId(other.lastRemoteDeckId)
{
}
bool DeckLoader::loadFromFile(const QString &fileName, FileFormat fmt)
{
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return false;
bool result = false;
switch (fmt) {
case PlainTextFormat: result = loadFromFile_Plain(&file); break;
case CockatriceFormat: result = loadFromFile_Native(&file); break;
}
if (result) {
lastFileName = fileName;
lastFileFormat = fmt;
emit deckLoaded();
}
return result;
}
bool DeckLoader::loadFromRemote(const QString &nativeString, int remoteDeckId)
{
bool result = loadFromString_Native(nativeString);
if (result) {
lastFileName = QString();
lastFileFormat = CockatriceFormat;
lastRemoteDeckId = remoteDeckId;
emit deckLoaded();
}
return result;
}
bool DeckLoader::saveToFile(const QString &fileName, FileFormat fmt)
{
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
return false;
bool result = false;
switch (fmt) {
case PlainTextFormat: result = saveToFile_Plain(&file); break;
case CockatriceFormat: result = saveToFile_Native(&file); break;
}
if (result) {
lastFileName = fileName;
lastFileFormat = fmt;
}
return result;
}
DeckLoader::FileFormat DeckLoader::getFormatFromNameFilter(const QString &selectedNameFilter)
{
switch (fileNameFilters.indexOf(selectedNameFilter)) {
case 0: return CockatriceFormat;
case 1: return PlainTextFormat;
}
return PlainTextFormat;
}

View file

@ -0,0 +1,33 @@
#ifndef DECK_LOADER_H
#define DECK_LOADER_H
#include "decklist.h"
class DeckLoader : public DeckList {
Q_OBJECT
signals:
void deckLoaded();
public:
enum FileFormat { PlainTextFormat, CockatriceFormat };
static const QStringList fileNameFilters;
private:
QString lastFileName;
FileFormat lastFileFormat;
int lastRemoteDeckId;
public:
DeckLoader();
DeckLoader(const QString &nativeString);
DeckLoader(const DeckList &other);
DeckLoader(const DeckLoader &other);
const QString &getLastFileName() const { return lastFileName; }
FileFormat getLastFileFormat() const { return lastFileFormat; }
int getLastRemoteDeckId() const { return lastRemoteDeckId; }
static FileFormat getFormatFromNameFilter(const QString &selectedNameFilter);
bool loadFromFile(const QString &fileName, FileFormat fmt);
bool loadFromRemote(const QString &nativeString, int remoteDeckId);
bool saveToFile(const QString &fileName, FileFormat fmt);
};
#endif

View file

@ -11,11 +11,12 @@
#include "decklistmodel.h"
#include "carddatabase.h"
#include "settingscache.h"
#include "deck_loader.h"
DeckListModel::DeckListModel(QObject *parent)
: QAbstractItemModel(parent)
{
deckList = new DeckList;
deckList = new DeckLoader;
connect(deckList, SIGNAL(deckLoaded()), this, SLOT(rebuildTree()));
connect(deckList, SIGNAL(deckHashChanged()), this, SIGNAL(deckHashChanged()));
root = new InnerDecklistNode;
@ -304,12 +305,10 @@ void DeckListModel::sort(int /*column*/, Qt::SortOrder order)
void DeckListModel::cleanList()
{
root->clearTree();
deckList->cleanList();
reset();
setDeckList(new DeckLoader);
}
void DeckListModel::setDeckList(DeckList *_deck)
void DeckListModel::setDeckList(DeckLoader *_deck)
{
delete deckList;
deckList = _deck;

View file

@ -5,6 +5,7 @@
#include <QList>
#include "decklist.h"
class DeckLoader;
class CardDatabase;
class QProgressDialog;
class QPrinter;
@ -47,11 +48,11 @@ public:
QModelIndex addCard(const QString &cardName, const QString &zoneName);
void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
void cleanList();
DeckList *getDeckList() const { return deckList; }
void setDeckList(DeckList *_deck);
DeckLoader *getDeckList() const { return deckList; }
void setDeckList(DeckLoader *_deck);
void pricesUpdated(InnerDecklistNode *node = 0);
private:
DeckList *deckList;
DeckLoader *deckList;
InnerDecklistNode *root;
InnerDecklistNode *createNodeIfNeeded(const QString &name, InnerDecklistNode *parent);
QModelIndex nodeToIndex(AbstractDecklistNode *node) const;

View file

@ -285,12 +285,12 @@ void DeckViewScene::clearContents()
cardContainers.clear();
}
void DeckViewScene::setDeck(DeckList *_deck)
void DeckViewScene::setDeck(const DeckList &_deck)
{
if (deck)
delete deck;
deck = _deck;
deck = new DeckList(_deck);
rebuildTree();
applySideboardPlan(deck->getCurrentSideboardPlan());
rearrangeItems();
@ -475,7 +475,7 @@ void DeckView::updateSceneRect(const QRectF &rect)
fitInView(rect, Qt::KeepAspectRatio);
}
void DeckView::setDeck(DeckList *_deck)
void DeckView::setDeck(const DeckList &_deck)
{
deckViewScene->setDeck(_deck);
}

View file

@ -89,7 +89,7 @@ public:
~DeckViewScene();
void setLocked(bool _locked) { locked = _locked; }
bool getLocked() const { return locked; }
void setDeck(DeckList *_deck);
void setDeck(const DeckList &_deck);
void setOptimalAspectRatio(qreal _optimalAspectRatio) { optimalAspectRatio = _optimalAspectRatio; }
void rearrangeItems();
void updateContents();
@ -110,7 +110,7 @@ signals:
void sideboardPlanChanged();
public:
DeckView(QWidget *parent = 0);
void setDeck(DeckList *_deck);
void setDeck(const DeckList &_deck);
void setLocked(bool _locked) { deckViewScene->setLocked(_locked); }
QList<MoveCard_ToZone> getSideboardPlan() const { return deckViewScene->getSideboardPlan(); }
void resetSideboardPlan();

View file

@ -9,7 +9,7 @@
#include <QDialogButtonBox>
#include <QMessageBox>
#include "dlg_load_deck_from_clipboard.h"
#include "decklist.h"
#include "deck_loader.h"
DlgLoadDeckFromClipboard::DlgLoadDeckFromClipboard(QWidget *parent)
: QDialog(parent), deckList(0)
@ -47,7 +47,7 @@ void DlgLoadDeckFromClipboard::actOK()
QString buffer = contentsEdit->toPlainText();
QTextStream stream(&buffer);
DeckList *l = new DeckList;
DeckLoader *l = new DeckLoader;
if (l->loadFromStream_Plain(stream)) {
deckList = l;
accept();

View file

@ -3,7 +3,7 @@
#include <QDialog>
class DeckList;
class DeckLoader;
class QPlainTextEdit;
class QPushButton;
@ -13,10 +13,10 @@ private slots:
void actOK();
void actRefresh();
private:
DeckList *deckList;
DeckLoader *deckList;
public:
DlgLoadDeckFromClipboard(QWidget *parent = 0);
DeckList *getDeckList() const { return deckList; }
DeckLoader *getDeckList() const { return deckList; }
private:
QPlainTextEdit *contentsEdit;
QPushButton *refreshButton;

View file

@ -18,7 +18,7 @@
#include "dlg_create_token.h"
#include "carddatabase.h"
#include "color.h"
#include "decklist.h"
#include "deck_loader.h"
#include "main.h"
#include <QSettings>
#include <QPainter>
@ -747,9 +747,9 @@ void Player::initSayMenu()
}
}
void Player::setDeck(DeckList *_deck)
void Player::setDeck(const DeckLoader &_deck)
{
deck = _deck;
deck = new DeckLoader(_deck);
aOpenDeckInDeckEditor->setEnabled(deck);
createPredefinedTokenMenu->clear();
@ -792,7 +792,7 @@ void Player::actAlwaysRevealTopCard()
void Player::actOpenDeckInDeckEditor()
{
emit openDeckEditor(new DeckList(deck));
emit openDeckEditor(*deck);
}
void Player::actViewGraveyard()

View file

@ -10,7 +10,7 @@
namespace google { namespace protobuf { class Message; } }
class CardDatabase;
class DeckList;
class DeckLoader;
class QMenu;
class QAction;
class ZoneViewZone;
@ -77,7 +77,7 @@ public:
class Player : public QObject, public QGraphicsItem {
Q_OBJECT
signals:
void openDeckEditor(DeckList *deck);
void openDeckEditor(const DeckLoader &deck);
void newCardAdded(AbstractCardItem *card);
// Log events
void logSay(Player *player, QString message);
@ -191,7 +191,7 @@ private:
bool clearCardsToDelete();
QList<CardItem *> cardsToDelete;
DeckList *deck;
DeckLoader *deck;
QStringList predefinedTokens;
PlayerArea *playerArea;
@ -263,7 +263,7 @@ public:
void retranslateUi();
void clear();
TabGame *getGame() const { return game; }
void setDeck(DeckList *_deck);
void setDeck(const DeckLoader &_deck);
QMenu *getPlayerMenu() const { return playerMenu; }
int getId() const { return id; }
QString getName() const;

View file

@ -27,6 +27,11 @@
#include "main.h"
#include "settingscache.h"
#include "priceupdater.h"
#include "tab_supervisor.h"
#include "abstractclient.h"
#include "pending_command.h"
#include "pb/response.pb.h"
#include "pb/command_deck_upload.pb.h"
void SearchLineEdit::keyPressEvent(QKeyEvent *event)
{
@ -351,7 +356,7 @@ void TabDeckEditor::actNewDeck()
deckModel->cleanList();
nameEdit->setText(QString());
commentsEdit->setText(QString());
lastFileName = QString();
hashLabel->setText(QString());
setWindowModified(false);
}
@ -362,24 +367,44 @@ void TabDeckEditor::actLoadDeck()
QFileDialog dialog(this, tr("Load deck"));
dialog.setDirectory(settingsCache->getDeckPath());
dialog.setNameFilters(DeckList::fileNameFilters);
dialog.setNameFilters(DeckLoader::fileNameFilters);
if (!dialog.exec())
return;
QString fileName = dialog.selectedFiles().at(0);
DeckList::FileFormat fmt = DeckList::getFormatFromNameFilter(dialog.selectedNameFilter());
DeckList *l = new DeckList;
DeckLoader::FileFormat fmt = DeckLoader::getFormatFromNameFilter(dialog.selectedNameFilter());
DeckLoader *l = new DeckLoader;
if (l->loadFromFile(fileName, fmt))
setDeck(l, fileName, fmt);
setDeck(l);
else
delete l;
}
void TabDeckEditor::saveDeckRemoteFinished(const Response &response)
{
if (response.response_code() != Response::RespOk)
QMessageBox::critical(this, tr("Error"), tr("The deck could not be saved."));
else
setWindowModified(false);
}
bool TabDeckEditor::actSaveDeck()
{
if (lastFileName.isEmpty())
DeckLoader *const deck = deckModel->getDeckList();
if (deck->getLastRemoteDeckId() != -1) {
Command_DeckUpload cmd;
cmd.set_deck_id(deck->getLastRemoteDeckId());
cmd.set_deck_list(deck->writeToString_Native().toStdString());
PendingCommand *pend = AbstractClient::prepareSessionCommand(cmd);
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(saveDeckRemoteFinished(Response)));
tabSupervisor->getClient()->sendCommand(pend);
return true;
} else if (deck->getLastFileName().isEmpty())
return actSaveDeckAs();
else if (deckModel->getDeckList()->saveToFile(lastFileName, lastFileFormat)) {
else if (deck->saveToFile(deck->getLastFileName(), deck->getLastFileFormat())) {
setWindowModified(false);
return true;
}
@ -394,23 +419,21 @@ bool TabDeckEditor::actSaveDeckAs()
dialog.setAcceptMode(QFileDialog::AcceptSave);
dialog.setConfirmOverwrite(true);
dialog.setDefaultSuffix("cod");
dialog.setNameFilters(DeckList::fileNameFilters);
dialog.setNameFilters(DeckLoader::fileNameFilters);
dialog.selectFile(deckModel->getDeckList()->getName());
if (!dialog.exec())
return false;
QString fileName = dialog.selectedFiles().at(0);
DeckList::FileFormat fmt = DeckList::getFormatFromNameFilter(dialog.selectedNameFilter());
DeckLoader::FileFormat fmt = DeckLoader::getFormatFromNameFilter(dialog.selectedNameFilter());
if (deckModel->getDeckList()->saveToFile(fileName, fmt)) {
lastFileName = fileName;
lastFileFormat = fmt;
setWindowModified(false);
return true;
}
if (!deckModel->getDeckList()->saveToFile(fileName, fmt)) {
QMessageBox::critical(this, tr("Error"), tr("The deck could not be saved.\nPlease check that the directory is writable and try again."));
return false;
}
setWindowModified(false);
return true;
}
void TabDeckEditor::actLoadDeckFromClipboard()
{
@ -550,20 +573,18 @@ void TabDeckEditor::finishedUpdatingPrices()
aUpdatePrices->setDisabled(false);
}
void TabDeckEditor::setDeck(DeckList *_deck, const QString &_lastFileName, DeckList::FileFormat _lastFileFormat)
void TabDeckEditor::setDeck(DeckLoader *_deck)
{
deckModel->setDeckList(_deck);
lastFileName = _lastFileName;
lastFileFormat = _lastFileFormat;
nameEdit->setText(_deck->getName());
commentsEdit->setText(_deck->getComments());
nameEdit->setText(deckModel->getDeckList()->getName());
commentsEdit->setText(deckModel->getDeckList()->getComments());
updateHash();
deckModel->sort(1);
deckView->expandAll();
setWindowModified(false);
db->cacheCardPixmaps(_deck->getCardList());
db->cacheCardPixmaps(deckModel->getDeckList()->getCardList());
deckView->expandAll();
setWindowModified(false);
}

View file

@ -4,7 +4,6 @@
#include "tab.h"
#include <QAbstractItemModel>
#include <QLineEdit>
#include "decklist.h"
class CardDatabaseModel;
class CardDatabaseDisplayModel;
@ -15,6 +14,8 @@ class CardInfoWidget;
class QTextEdit;
class DlgCardSearch;
class QLabel;
class DeckLoader;
class Response;
class SearchLineEdit : public QLineEdit {
private:
@ -57,14 +58,12 @@ private slots:
void actUpdatePrices();
void finishedUpdatingPrices();
void saveDeckRemoteFinished(const Response &r);
private:
void addCardHelper(QString zoneName);
void recursiveExpand(const QModelIndex &index);
bool confirmClose();
QString lastFileName;
DeckList::FileFormat lastFileFormat;
CardDatabaseModel *databaseModel;
CardDatabaseDisplayModel *databaseDisplayModel;
DeckListModel *deckModel;
@ -90,7 +89,7 @@ public:
~TabDeckEditor();
void retranslateUi();
QString getTabText() const;
void setDeck(DeckList *_deck, const QString &_lastFileName = QString(), DeckList::FileFormat _lastFileFormat = DeckList::CockatriceFormat);
void setDeck(DeckLoader *_deckLoader);
void setWindowModified(bool _windowModified);
public slots:
void closeRequest();

View file

@ -14,6 +14,7 @@
#include "abstractclient.h"
#include "decklist.h"
#include "settingscache.h"
#include "deck_loader.h"
#include "pending_command.h"
#include "pb/response.pb.h"
@ -128,13 +129,12 @@ void TabDeckStorage::actOpenLocalDeck()
if (localDirModel->isDir(curLeft))
return;
QString filePath = localDirModel->filePath(curLeft);
DeckList *deck = new DeckList;
if (!deck->loadFromFile(filePath, DeckList::CockatriceFormat))
DeckLoader deckLoader;
if (!deckLoader.loadFromFile(filePath, DeckLoader::CockatriceFormat))
return;
// WndDeckEditor *deckEditor = new WndDeckEditor;
// deckEditor->setDeck(deck, filePath, DeckList::CockatriceFormat);
// deckEditor->show();
emit openDeckEditor(&deckLoader);
}
void TabDeckStorage::actUpload()
@ -145,8 +145,8 @@ void TabDeckStorage::actUpload()
QString filePath = localDirModel->filePath(curLeft);
QFile deckFile(filePath);
QFileInfo deckFileInfo(deckFile);
DeckList deck;
if (!deck.loadFromFile(filePath, DeckList::CockatriceFormat))
DeckLoader deck;
if (!deck.loadFromFile(filePath, DeckLoader::CockatriceFormat))
return;
if (deck.getName().isEmpty()) {
bool ok;
@ -205,20 +205,23 @@ void TabDeckStorage::actOpenRemoteDeck()
cmd.set_deck_id(curRight->getId());
PendingCommand *pend = client->prepareSessionCommand(cmd);
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(openRemoteDeckFinished(const Response &)));
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(openRemoteDeckFinished(Response, CommandContainer)));
client->sendCommand(pend);
}
void TabDeckStorage::openRemoteDeckFinished(const Response &r)
void TabDeckStorage::openRemoteDeckFinished(const Response &r, const CommandContainer &commandContainer)
{
if (r.response_code() != Response::RespOk)
return;
const Response_DeckDownload &resp = r.GetExtension(Response_DeckDownload::ext);
const Command_DeckDownload &cmd = commandContainer.session_command(0).GetExtension(Command_DeckDownload::ext);
// WndDeckEditor *deckEditor = new WndDeckEditor;
// deckEditor->setDeck(new DeckList(QString::fromStdString(resp.deck())));
// deckEditor->show();
DeckLoader loader;
if (!loader.loadFromRemote(QString::fromStdString(resp.deck()), cmd.deck_id()))
return;
emit openDeckEditor(&loader);
}
void TabDeckStorage::actDownload()
@ -255,8 +258,8 @@ void TabDeckStorage::downloadFinished(const Response &r, const CommandContainer
const Response_DeckDownload &resp = r.GetExtension(Response_DeckDownload::ext);
QString filePath = extraData.toString();
DeckList deck(QString::fromStdString(resp.deck()));
deck.saveToFile(filePath, DeckList::CockatriceFormat);
DeckLoader deck(QString::fromStdString(resp.deck()));
deck.saveToFile(filePath, DeckLoader::CockatriceFormat);
}
void TabDeckStorage::actNewFolder()

View file

@ -13,6 +13,7 @@ class QGroupBox;
class RemoteDeckList_TreeWidget;
class CommandContainer;
class Response;
class DeckLoader;
class TabDeckStorage : public Tab {
Q_OBJECT
@ -34,7 +35,7 @@ private slots:
void actDeleteLocalDeck();
void actOpenRemoteDeck();
void openRemoteDeckFinished(const Response &r);
void openRemoteDeckFinished(const Response &r, const CommandContainer &commandContainer);
void actDownload();
void downloadFinished(const Response &r, const CommandContainer &commandContainer, const QVariant &extraData);
@ -49,6 +50,8 @@ public:
TabDeckStorage(TabSupervisor *_tabSupervisor, AbstractClient *_client);
void retranslateUi();
QString getTabText() const { return tr("Deck storage"); }
signals:
void openDeckEditor(const DeckLoader *deckLoader);
};
#endif

View file

@ -22,7 +22,7 @@
#include "zoneviewzone.h"
#include "zoneviewwidget.h"
#include "deckview.h"
#include "decklist.h"
#include "deck_loader.h"
#include "dlg_load_remote_deck.h"
#include "abstractclient.h"
#include "carditem.h"
@ -149,21 +149,20 @@ void DeckViewContainer::loadLocalDeck()
{
QFileDialog dialog(this, tr("Load deck"));
dialog.setDirectory(settingsCache->getDeckPath());
dialog.setNameFilters(DeckList::fileNameFilters);
dialog.setNameFilters(DeckLoader::fileNameFilters);
if (!dialog.exec())
return;
QString fileName = dialog.selectedFiles().at(0);
DeckList::FileFormat fmt = DeckList::getFormatFromNameFilter(dialog.selectedNameFilter());
DeckList *deck = new DeckList;
if (!deck->loadFromFile(fileName, fmt)) {
delete deck;
// Error message
DeckLoader::FileFormat fmt = DeckLoader::getFormatFromNameFilter(dialog.selectedNameFilter());
DeckLoader deck;
if (!deck.loadFromFile(fileName, fmt)) {
QMessageBox::critical(this, tr("Error"), tr("The selected file could not be loaded."));
return;
}
Command_DeckSelect cmd;
cmd.set_deck(deck->writeToString_Native().toStdString());
cmd.set_deck(deck.writeToString_Native().toStdString());
PendingCommand *pend = static_cast<TabGame *>(parent())->prepareGameCommand(cmd);
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(deckSelectFinished(const Response &)));
static_cast<TabGame *>(parent())->sendGameCommand(pend, playerId);
@ -184,8 +183,8 @@ void DeckViewContainer::loadRemoteDeck()
void DeckViewContainer::deckSelectFinished(const Response &r)
{
const Response_DeckDownload &resp = r.GetExtension(Response_DeckDownload::ext);
DeckList *newDeck = new DeckList(QString::fromStdString(resp.deck()));
db->cacheCardPixmaps(newDeck->getCardList());
DeckLoader newDeck(QString::fromStdString(resp.deck()));
db->cacheCardPixmaps(newDeck.getCardList());
setDeck(newDeck);
}
@ -227,7 +226,7 @@ void DeckViewContainer::setSideboardLocked(bool locked)
deckView->resetSideboardPlan();
}
void DeckViewContainer::setDeck(DeckList *deck)
void DeckViewContainer::setDeck(const DeckLoader &deck)
{
deckView->setDeck(deck);
readyStartButton->setEnabled(true);
@ -949,8 +948,8 @@ void TabGame::eventGameStateChanged(const Event_GameStateChanged &event, int /*e
if (player->getLocal()) {
DeckViewContainer *deckViewContainer = deckViewContainers.value(playerId);
if (playerInfo.has_deck_list()) {
DeckList *newDeck = new DeckList(QString::fromStdString(playerInfo.deck_list()));
db->cacheCardPixmaps(newDeck->getCardList());
DeckLoader newDeck(QString::fromStdString(playerInfo.deck_list()));
db->cacheCardPixmaps(newDeck.getCardList());
deckViewContainer->setDeck(newDeck);
player->setDeck(newDeck);
}

View file

@ -48,7 +48,7 @@ class CardZone;
class AbstractCardItem;
class CardItem;
class TabGame;
class DeckList;
class DeckLoader;
class QVBoxLayout;
class QHBoxLayout;
class GameReplay;
@ -92,7 +92,7 @@ public:
void setButtonsVisible(bool _visible);
void setReadyStart(bool ready);
void setSideboardLocked(bool locked);
void setDeck(DeckList *deck);
void setDeck(const DeckLoader &deck);
};
class TabGame : public Tab {
@ -171,7 +171,7 @@ signals:
void containerProcessingStarted(const GameEventContext &context);
void containerProcessingDone();
void openMessageDialog(const QString &userName, bool focus);
void openDeckEditor(DeckList *deck);
void openDeckEditor(const DeckLoader &deck);
private slots:
void replayNextEvent();
void replayFinished();

View file

@ -155,6 +155,7 @@ void TabSupervisor::start(const ServerInfo_User &_userInfo)
if (userInfo->user_level() & ServerInfo_User::IsRegistered) {
tabDeckStorage = new TabDeckStorage(this, client);
connect(tabDeckStorage, SIGNAL(openDeckEditor(const DeckLoader *)), this, SLOT(addDeckEditorTab(const DeckLoader *)));
myAddTab(tabDeckStorage);
tabReplays = new TabReplays(this, client);
@ -279,7 +280,8 @@ void TabSupervisor::gameJoined(const Event_GameJoined &event)
TabGame *tab = new TabGame(this, QList<AbstractClient *>() << client, event, roomGameTypes);
connect(tab, SIGNAL(gameClosing(TabGame *)), this, SLOT(gameLeft(TabGame *)));
connect(tab, SIGNAL(openMessageDialog(const QString &, bool)), this, SLOT(addMessageTab(const QString &, bool)));
connect(tab, SIGNAL(openDeckEditor(DeckList *)), this, SLOT(addDeckEditorTab(DeckList *)));
connect(tab, SIGNAL(openDeckEditor(DeckList *, QString, DeckList::FileFormat)), this, SLOT(addDeckEditorTab(DeckList *, QString, DeckList::FileFormat)));
connect(tab, SIGNAL(openDeckEditor(DeckList *, int)), this, SLOT(addDeckEditorTab(DeckList *, int)));
int tabIndex = myAddTab(tab);
addCloseButtonToTab(tab, tabIndex);
gameTabs.insert(event.game_info().game_id(), tab);
@ -384,11 +386,11 @@ void TabSupervisor::talkLeft(TabMessage *tab)
removeTab(indexOf(tab));
}
TabDeckEditor *TabSupervisor::addDeckEditorTab(DeckList *deckToOpen)
TabDeckEditor *TabSupervisor::addDeckEditorTab(const DeckLoader *deckToOpen)
{
TabDeckEditor *tab = new TabDeckEditor(this);
if (deckToOpen)
tab->setDeck(deckToOpen);
tab->setDeck(new DeckLoader(*deckToOpen));
connect(tab, SIGNAL(deckEditorClosing(TabDeckEditor *)), this, SLOT(deckEditorClosed(TabDeckEditor *)));
int tabIndex = myAddTab(tab);
addCloseButtonToTab(tab, tabIndex);

View file

@ -4,6 +4,7 @@
#include <QTabWidget>
#include <QMap>
#include <QAbstractButton>
#include "deck_loader.h"
class QMenu;
class AbstractClient;
@ -75,7 +76,7 @@ signals:
void localGameEnded();
void adminLockChanged(bool lock);
public slots:
TabDeckEditor *addDeckEditorTab(DeckList *deckToOpen);
TabDeckEditor *addDeckEditorTab(const DeckLoader *deckToOpen);
void openReplay(GameReplay *replay);
private slots:
void closeButtonPressed();

View file

@ -264,21 +264,19 @@ QVector<QPair<int, int> > InnerDecklistNode::sort(Qt::SortOrder order)
return result;
}
const QStringList DeckList::fileNameFilters = QStringList()
<< QObject::tr("Cockatrice decks (*.cod)")
<< QObject::tr("Plain text decks (*.dec *.mwDeck)")
<< QObject::tr("All files (*.*)");
DeckList::DeckList()
{
root = new InnerDecklistNode;
}
DeckList::DeckList(DeckList *other)
DeckList::DeckList(const DeckList &other)
: name(other.name),
comments(other.comments),
deckHash(other.deckHash)
{
root = new InnerDecklistNode(other->getRoot());
root = new InnerDecklistNode(other.getRoot());
QMapIterator<QString, SideboardPlan *> spIterator(other->getSideboardPlans());
QMapIterator<QString, SideboardPlan *> spIterator(other.getSideboardPlans());
while (spIterator.hasNext()) {
spIterator.next();
sideboardPlans.insert(spIterator.key(), new SideboardPlan(spIterator.key(), spIterator.value()->getMoveList()));
@ -289,9 +287,7 @@ DeckList::DeckList(DeckList *other)
DeckList::DeckList(const QString &nativeString)
{
root = new InnerDecklistNode;
QXmlStreamReader xml(nativeString);
loadFromXml(&xml);
loadFromString_Native(nativeString);
}
DeckList::~DeckList()
@ -362,13 +358,14 @@ void DeckList::write(QXmlStreamWriter *xml)
xml->writeEndElement();
}
void DeckList::loadFromXml(QXmlStreamReader *xml)
bool DeckList::loadFromXml(QXmlStreamReader *xml)
{
cleanList();
while (!xml->atEnd()) {
xml->readNext();
if (xml->isStartElement()) {
if (xml->name() != "cockatrice_deck")
return;
return false;
while (!xml->atEnd()) {
xml->readNext();
if (!readElement(xml))
@ -377,6 +374,13 @@ void DeckList::loadFromXml(QXmlStreamReader *xml)
}
}
updateDeckHash();
return true;
}
bool DeckList::loadFromString_Native(const QString &nativeString)
{
QXmlStreamReader xml(nativeString);
return loadFromXml(&xml);
}
QString DeckList::writeToString_Native()
@ -410,6 +414,8 @@ bool DeckList::saveToFile_Native(QIODevice *device)
bool DeckList::loadFromStream_Plain(QTextStream &in)
{
cleanList();
InnerDecklistNode *main = 0, *side = 0;
int okRows = 0;
@ -474,52 +480,13 @@ bool DeckList::saveToFile_Plain(QIODevice *device)
return saveToStream_Plain(out);
}
bool DeckList::loadFromFile(const QString &fileName, FileFormat fmt)
{
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return false;
cleanList();
bool result = false;
switch (fmt) {
case PlainTextFormat: result = loadFromFile_Plain(&file); break;
case CockatriceFormat: result = loadFromFile_Native(&file); break;
}
if (result)
emit deckLoaded();
return result;
}
bool DeckList::saveToFile(const QString &fileName, FileFormat fmt)
{
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
return false;
bool result = false;
switch (fmt) {
case PlainTextFormat: result = saveToFile_Plain(&file); break;
case CockatriceFormat: result = saveToFile_Native(&file); break;
}
return result;
}
DeckList::FileFormat DeckList::getFormatFromNameFilter(const QString &selectedNameFilter)
{
switch (fileNameFilters.indexOf(selectedNameFilter)) {
case 0: return CockatriceFormat;
case 1: return PlainTextFormat;
}
return PlainTextFormat;
}
void DeckList::cleanList()
{
root->clearTree();
setName();
setComments();
updateDeckHash();
deckHash = QString();
emit deckHashChanged();
}
void DeckList::getCardListHelper(InnerDecklistNode *item, QSet<QString> &result) const

View file

@ -111,40 +111,32 @@ public:
class DeckList : public QObject {
Q_OBJECT
public:
enum FileFormat { PlainTextFormat, CockatriceFormat };
private:
QString name, comments;
QString lastFileName;
QString deckHash;
FileFormat lastFileFormat;
QMap<QString, SideboardPlan *> sideboardPlans;
InnerDecklistNode *root;
QString currentElementText;
void getCardListHelper(InnerDecklistNode *node, QSet<QString> &result) const;
signals:
void deckLoaded();
void deckHashChanged();
public slots:
void setName(const QString &_name = QString()) { name = _name; }
void setComments(const QString &_comments = QString()) { comments = _comments; }
public:
static const QStringList fileNameFilters;
DeckList();
DeckList(DeckList *other);
DeckList(const DeckList &other);
DeckList(const QString &nativeString);
~DeckList();
QString getName() const { return name; }
QString getComments() const { return comments; }
QString getLastFileName() const { return lastFileName; }
FileFormat getLastFileFormat() const { return lastFileFormat; }
QList<MoveCard_ToZone> getCurrentSideboardPlan();
void setCurrentSideboardPlan(const QList<MoveCard_ToZone> &plan);
const QMap<QString, SideboardPlan *> &getSideboardPlans() const { return sideboardPlans; }
bool readElement(QXmlStreamReader *xml);
void write(QXmlStreamWriter *xml);
void loadFromXml(QXmlStreamReader *xml);
bool loadFromXml(QXmlStreamReader *xml);
bool loadFromString_Native(const QString &nativeString);
QString writeToString_Native();
bool loadFromFile_Native(QIODevice *device);
bool saveToFile_Native(QIODevice *device);
@ -152,9 +144,6 @@ public:
bool loadFromFile_Plain(QIODevice *device);
bool saveToStream_Plain(QTextStream &stream);
bool saveToFile_Plain(QIODevice *device);
bool loadFromFile(const QString &fileName, FileFormat fmt);
bool saveToFile(const QString &fileName, FileFormat fmt);
static FileFormat getFormatFromNameFilter(const QString &selectedNameFilter);
void cleanList();
bool isEmpty() const { return root->isEmpty() && name.isEmpty() && comments.isEmpty() && sideboardPlans.isEmpty(); }

View file

@ -4,7 +4,7 @@ message Command_DeckUpload {
extend SessionCommand {
optional Command_DeckUpload ext = 1013;
}
optional string path = 1;
optional string deck_list = 2;
optional string path = 1; // to upload a new deck
optional uint32 deck_id = 2; // to replace an existing deck
optional string deck_list = 3;
}

View file

@ -455,13 +455,10 @@ Response::ResponseCode ServerSocketInterface::cmdDeckUpload(const Command_DeckUp
if (authState != PasswordRight)
return Response::RespFunctionNotAllowed;
servatrice->checkSql();
if (!cmd.has_deck_list())
return Response::RespInvalidData;
int folderId = getDeckPathId(QString::fromStdString(cmd.path()));
if (folderId == -1)
return Response::RespNameNotFound;
servatrice->checkSql();
QString deckStr = QString::fromStdString(cmd.deck_list());
DeckList deck(deckStr);
@ -470,6 +467,11 @@ Response::ResponseCode ServerSocketInterface::cmdDeckUpload(const Command_DeckUp
if (deckName.isEmpty())
deckName = "Unnamed deck";
if (cmd.has_path()) {
int folderId = getDeckPathId(QString::fromStdString(cmd.path()));
if (folderId == -1)
return Response::RespNameNotFound;
QMutexLocker locker(&servatrice->dbMutex);
QSqlQuery query;
query.prepare("insert into " + servatrice->getDbPrefix() + "_decklist_files (id_folder, user, name, upload_time, content) values(:id_folder, :user, :name, NOW(), :content)");
@ -485,6 +487,27 @@ Response::ResponseCode ServerSocketInterface::cmdDeckUpload(const Command_DeckUp
fileInfo->set_name(deckName.toStdString());
fileInfo->mutable_file()->set_creation_time(QDateTime::currentDateTime().toTime_t());
rc.setResponseExtension(re);
} else if (cmd.has_deck_id()) {
QMutexLocker locker(&servatrice->dbMutex);
QSqlQuery query;
query.prepare("update " + servatrice->getDbPrefix() + "_decklist_files set name=:name, upload_time=NOW(), content=:content where id = :id_deck and user = :user");
query.bindValue(":id_deck", cmd.deck_id());
query.bindValue(":user", QString::fromStdString(userInfo->name()));
query.bindValue(":name", deckName);
query.bindValue(":content", deckStr);
servatrice->execSqlQuery(query);
if (query.numRowsAffected() == 0)
return Response::RespNameNotFound;
Response_DeckUpload *re = new Response_DeckUpload;
ServerInfo_DeckStorage_TreeItem *fileInfo = re->mutable_new_file();
fileInfo->set_id(cmd.deck_id());
fileInfo->set_name(deckName.toStdString());
fileInfo->mutable_file()->set_creation_time(QDateTime::currentDateTime().toTime_t());
rc.setResponseExtension(re);
} else
return Response::RespInvalidData;
return Response::RespOk;
}