new decklist file format

This commit is contained in:
Max-Wilhelm Bruker 2009-05-19 21:57:23 +02:00
parent c756762171
commit 0ef00dd437
8 changed files with 311 additions and 97 deletions

222
cockatrice/src/decklist.cpp Normal file
View file

@ -0,0 +1,222 @@
#include <QFile>
#include <QFileDialog>
#include <QTextStream>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
#include "decklist.h"
#include "carddatabase.h"
DeckList::DeckList(CardDatabase *_db)
: db(_db)
{
}
DeckList::~DeckList()
{
cleanList();
}
bool DeckList::loadFromFile_Native(QIODevice *device)
{
QXmlStreamReader xml(device);
while (!xml.atEnd()) {
if (xml.readNext() == QXmlStreamReader::StartElement) {
if (xml.name() != "cockatrice_deck")
return false;
while (!xml.atEnd()) {
if (xml.readNext() == QXmlStreamReader::EndElement)
break;
if (xml.name() == "deckname")
name = xml.readElementText();
else if (xml.name() == "comments")
comments = xml.readElementText();
else if (xml.name() == "decklist") {
while (!xml.atEnd()) {
if (xml.readNext() == QXmlStreamReader::EndElement)
break;
if (xml.name() == "card") {
const int number = xml.attributes().value("number").toString().toInt();
const QString card = xml.attributes().value("name").toString();
const bool sb = xml.attributes().value("zone") == "side";
append(new DecklistRow(number, card, sb));
while (!xml.atEnd())
if (xml.readNext() == QXmlStreamReader::EndElement)
break;
}
}
}
}
}
}
return true;
}
bool DeckList::saveToFile_Native(QIODevice *device)
{
QXmlStreamWriter xml(device);
xml.setAutoFormatting(true);
xml.writeStartDocument();
xml.writeStartElement("cockatrice_deck");
xml.writeAttribute("version", "1");
xml.writeTextElement("deckname", name);
xml.writeTextElement("comments", comments);
xml.writeStartElement("decklist");
for (int i = 0; i < size(); i++) {
DecklistRow *r = at(i);
xml.writeEmptyElement("card");
if (r->isSideboard())
xml.writeAttribute("zone", "side");
else
xml.writeAttribute("zone", "main");
xml.writeAttribute("number", QString::number(r->getNumber()));
xml.writeAttribute("name", r->getCard());
}
xml.writeEndElement(); // decklist
xml.writeEndElement(); // cockatrice_deck
xml.writeEndDocument();
return true;
}
bool DeckList::loadFromFile_Plain(QIODevice *device)
{
QTextStream in(device);
while (!in.atEnd()) {
QString line = in.readLine().simplified();
if (line.startsWith("//"))
continue;
bool isSideboard = false;
if (line.startsWith("SB:", Qt::CaseInsensitive)) {
line = line.mid(3).trimmed();
isSideboard = true;
}
// Filter out MWS edition symbols and basic land extras
QRegExp rx("\\[.*\\]");
line.remove(rx);
rx.setPattern("\\(.*\\)");
line.remove(rx);
line = line.simplified();
int i = line.indexOf(' ');
bool ok;
int number = line.left(i).toInt(&ok);
if (!ok)
continue;
append(new DecklistRow(number, line.mid(i + 1), isSideboard));
}
return true;
}
bool DeckList::saveToFile_Plain(QIODevice *device)
{
QTextStream out(device);
for (int i = 0; i < size(); i++) {
DecklistRow *r = at(i);
out << QString("%1%2 %3\n").arg(r->isSideboard() ? "SB: " : "").arg(r->getNumber()).arg(r->getCard());
}
return true;
}
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)
cacheCardPictures();
return result;
}
const QStringList DeckList::fileNameFilters = QStringList()
<< QObject::tr("Cockatrice decks (*.cod)")
<< QObject::tr("Plain text decks (*.dec *.mwDeck)")
<< QObject::tr("All files (*.*)");
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;
}
bool DeckList::loadDialog(QWidget *parent)
{
QFileDialog dialog(parent);
dialog.setNameFilters(fileNameFilters);
if (!dialog.exec())
return false;
QString fileName = dialog.selectedFiles().at(0);
FileFormat fmt;
switch (fileNameFilters.indexOf(dialog.selectedNameFilter())) {
case 0: fmt = CockatriceFormat; break;
case 1: fmt = PlainTextFormat; break;
default: fmt = PlainTextFormat; break;
}
if (loadFromFile(fileName, fmt)) {
lastFileName = fileName;
lastFileFormat = fmt;
return true;
}
return false;
}
bool DeckList::saveDialog(QWidget *parent)
{
QFileDialog dialog(parent);
dialog.setAcceptMode(QFileDialog::AcceptSave);
dialog.setConfirmOverwrite(true);
dialog.setDefaultSuffix("cod");
dialog.setNameFilters(fileNameFilters);
if (!dialog.exec())
return false;
QString fileName = dialog.selectedFiles().at(0);
DeckList::FileFormat fmt;
switch (fileNameFilters.indexOf(dialog.selectedNameFilter())) {
case 0: fmt = DeckList::CockatriceFormat; break;
case 1: fmt = DeckList::PlainTextFormat; break;
default: fmt = DeckList::PlainTextFormat; break;
}
if (saveToFile(fileName, fmt)) {
lastFileName = fileName;
lastFileFormat = fmt;
return true;
}
return false;
}
void DeckList::cacheCardPictures()
{
for (int i = 0; i < size(); i++)
db->getCard(at(i)->getCard())->getPixmap();
}
void DeckList::cleanList()
{
for (int i = 0; i < size(); i++)
delete at(i);
clear();
}

55
cockatrice/src/decklist.h Normal file
View file

@ -0,0 +1,55 @@
#ifndef DECKLIST_H
#define DECKLIST_H
#include <QList>
#include <QObject>
class CardDatabase;
class QIODevice;
class DecklistRow {
private:
int number;
QString card;
bool sideboard;
public:
DecklistRow(int _number, const QString &_card, bool _sideboard) : number(_number), card(_card), sideboard(_sideboard) { }
int getNumber() const { return number; }
QString getCard() const { return card; }
bool isSideboard() const { return sideboard; }
};
class DeckList : public QList<DecklistRow *> {
public:
enum FileFormat { PlainTextFormat, CockatriceFormat };
private:
static const QStringList fileNameFilters;
void cacheCardPictures();
CardDatabase *db;
QString name, comments;
QString lastFileName;
FileFormat lastFileFormat;
public:
DeckList(CardDatabase *_db);
~DeckList();
void setName(const QString &_name) { name = _name; }
QString getName() const { return name; }
void setComments(const QString &_comments) { comments = _comments; }
QString getComments() const { return comments; }
QString getLastFileName() const { return lastFileName; }
FileFormat getLastFileFormat() const { return lastFileFormat; }
bool loadFromFile_Native(QIODevice *device);
bool saveToFile_Native(QIODevice *device);
bool loadFromFile_Plain(QIODevice *device);
bool saveToFile_Plain(QIODevice *device);
bool loadFromFile(const QString &fileName, FileFormat fmt);
bool saveToFile(const QString &fileName, FileFormat fmt);
bool loadDialog(QWidget *parent = 0);
bool saveDialog(QWidget *parent = 0);
void cleanList();
};
#endif

View file

@ -6,19 +6,18 @@
DeckListModel::DeckListModel(CardDatabase *_db, QObject *parent)
: QAbstractListModel(parent), db(_db)
{
deckList = new DeckList(db);
}
DeckListModel::~DeckListModel()
{
qDebug("DeckListModel destructor");
cleanList();
delete deckList;
}
int DeckListModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return deckList.size();
return deckList->size();
}
int DeckListModel::columnCount(const QModelIndex &parent) const
@ -31,13 +30,13 @@ QVariant DeckListModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if ((index.row() >= deckList.size()) || (index.column() >= 2))
if ((index.row() >= deckList->size()) || (index.column() >= 2))
return QVariant();
if (role != Qt::DisplayRole)
return QVariant();
DecklistRow *r = deckList.at(index.row());
DecklistRow *r = deckList->at(index.row());
switch (index.column()) {
case 0: return r->getNumber();
case 1: return r->getCard();
@ -60,66 +59,13 @@ QVariant DeckListModel::headerData(int section, Qt::Orientation orientation, int
void DeckListModel::cleanList()
{
QListIterator<DecklistRow *> i(deckList);
while (i.hasNext())
delete i.next();
deckList.clear();
deckList->cleanList();
reset();
}
bool DeckListModel::loadFromFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return false;
QTextStream in(&file);
cleanList();
while (!in.atEnd()) {
QString line = in.readLine().simplified();
bool isSideboard = false;
if (line.startsWith("SB:", Qt::CaseInsensitive)) {
line = line.mid(3).trimmed();
isSideboard = true;
}
int i = line.indexOf(' ');
bool ok;
int number = line.left(i).toInt(&ok);
if (!ok)
continue;
DecklistRow *row = new DecklistRow(number, line.mid(i + 1), isSideboard);
deckList << row;
}
cacheCardPictures();
reset();
return true;
}
bool DeckListModel::saveToFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
return false;
QTextStream out(&file);
QListIterator<DecklistRow *> i(deckList);
while (i.hasNext()) {
DecklistRow *r = i.next();
out << QString("%1%2 %3\n").arg(r->isSideboard() ? "SB: " : "").arg(r->getNumber()).arg(r->getCard());
}
return true;
}
DecklistRow *DeckListModel::getRow(int row) const
{
if (row >= deckList.size())
if (row >= deckList->size())
return 0;
return deckList.at(row);
}
void DeckListModel::cacheCardPictures()
{
QListIterator<DecklistRow *> i(deckList);
while (i.hasNext()) {
DecklistRow *r = i.next();
db->getCard(r->getCard())->getPixmap();
}
return deckList->at(row);
}

View file

@ -3,21 +3,10 @@
#include <QAbstractListModel>
#include <QList>
#include "decklist.h"
class CardDatabase;
class DecklistRow {
private:
int number;
QString card;
bool sideboard;
public:
DecklistRow(int _number, const QString &_card, bool _sideboard) : number(_number), card(_card), sideboard(_sideboard) { }
int getNumber() const { return number; }
QString getCard() const { return card; }
bool isSideboard() const { return sideboard; }
};
class DeckListModel : public QAbstractListModel {
Q_OBJECT
public:
@ -27,14 +16,14 @@ public:
int columnCount(const QModelIndex &parent = QModelIndex()) const;
QVariant data(const QModelIndex &index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
bool loadFromFile(const QString &fileName);
bool saveToFile(const QString &fileName);
DecklistRow *getRow(int row) const;
void cleanList();
DeckList *getDeckList() const { return deckList; }
bool loadFromFile(const QString &fileName, DeckList::FileFormat fmt);
bool saveToFile(const QString &fileName, DeckList::FileFormat fmt);
private:
CardDatabase *db;
QList<DecklistRow *> deckList;
void cacheCardPictures();
DeckList *deckList;
};
#endif

View file

@ -35,11 +35,10 @@ DlgStartGame::DlgStartGame(CardDatabase *_db, QWidget *parent)
void DlgStartGame::actLoad()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Load deck"), QString(), tr("Deck files (*.dec)"));
if (fileName.isEmpty())
if (!tableModel->getDeckList()->loadDialog(this))
return;
tableModel->loadFromFile(fileName);
tableView->reset();
emit newDeckLoaded(getDeckList());
}

View file

@ -79,12 +79,12 @@ void WndDeckEditor::actNewDeck()
void WndDeckEditor::actLoadDeck()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Load deck"), QString(), tr("Deck files (*.dec)"));
if (fileName.isEmpty())
return;
if (deckModel->loadFromFile(fileName))
lastFileName = fileName;
DeckList *l = deckModel->getDeckList();
if (l->loadDialog(this)) {
lastFileName = l->getLastFileName();
lastFileFormat = l->getLastFileFormat();
deckView->reset();
}
}
void WndDeckEditor::actSaveDeck()
@ -92,16 +92,15 @@ void WndDeckEditor::actSaveDeck()
if (lastFileName.isEmpty())
actSaveDeckAs();
else
deckModel->saveToFile(lastFileName);
deckModel->getDeckList()->saveToFile(lastFileName, lastFileFormat);
;
}
void WndDeckEditor::actSaveDeckAs()
{
QString fileName = QFileDialog::getSaveFileName(this, tr("Save deck as"), QString(), tr("Deck files (*.dec)"));
if (fileName.isEmpty())
return;
if (!fileName.endsWith(".dec"))
fileName.append(".dec");
if (deckModel->saveToFile(fileName))
lastFileName = fileName;
DeckList *l = deckModel->getDeckList();
if (l->saveDialog(this)) {
lastFileName = l->getLastFileName();
lastFileFormat = l->getLastFileFormat();
}
}

View file

@ -3,6 +3,7 @@
#include <QMainWindow>
#include <QAbstractItemModel>
#include "decklist.h"
class CardDatabase;
class CardDatabaseModel;
@ -22,6 +23,7 @@ private slots:
void actSaveDeckAs();
private:
QString lastFileName;
DeckList::FileFormat lastFileFormat;
CardDatabase *db;
CardDatabaseModel *databaseModel;