servatrice/cockatrice/src/decklist.cpp
Max-Wilhelm Bruker d9e51e58a3 deck editor...
2009-05-24 01:41:25 +02:00

263 lines
6.5 KiB
C++

#include <QFile>
#include <QFileDialog>
#include <QTextStream>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
#include <QProgressDialog>
#include "decklist.h"
#include "carddatabase.h"
QString DecklistZone::getVisibleName() const
{
if (name == "main")
return QObject::tr("Maindeck");
else if (name == "side")
return QObject::tr("Sideboard");
else
return QString();
}
DeckList::DeckList(CardDatabase *_db, QObject *parent)
: QObject(parent), db(_db)
{
initZones();
}
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() == "zone") {
DecklistZone *zone = new DecklistZone(xml.attributes().value("name").toString());
zones.append(zone);
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();
zone->append(new DecklistRow(number, card));
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);
for (int i = 0; i < zones.size(); i++) {
xml.writeStartElement("zone");
xml.writeAttribute("name", zones[i]->getName());
for (int j = 0; j < zones[i]->size(); j++) {
DecklistRow *r = zones[i]->at(j);
xml.writeEmptyElement("card");
xml.writeAttribute("number", QString::number(r->getNumber()));
xml.writeAttribute("name", r->getCard());
}
xml.writeEndElement(); // zone
}
xml.writeEndElement(); // cockatrice_deck
xml.writeEndDocument();
return true;
}
bool DeckList::loadFromFile_Plain(QIODevice *device)
{
initZones();
QTextStream in(device);
while (!in.atEnd()) {
QString line = in.readLine().simplified();
if (line.startsWith("//"))
continue;
DecklistZone *zone;
if (line.startsWith("SB:", Qt::CaseInsensitive)) {
line = line.mid(3).trimmed();
zone = zones[1];
} else
zone = zones[0];
// 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;
zone->append(new DecklistRow(number, line.mid(i + 1)));
}
return true;
}
bool DeckList::saveToFile_Plain(QIODevice *device)
{
QTextStream out(device);
for (int i = 0; i < zones.size(); i++)
for (int j = 0; j < zones[i]->size(); j++) {
DecklistRow *r = zones[i]->at(j);
out << QString("%1%2 %3\n").arg(zones[i]->getName() == "side" ? "SB: " : "").arg(r->getNumber()).arg(r->getCard());
}
return true;
}
bool DeckList::loadFromFile(const QString &fileName, FileFormat fmt, QWidget *parent)
{
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(parent);
emit deckLoaded();
}
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, tr("Load deck"));
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, parent)) {
lastFileName = fileName;
lastFileFormat = fmt;
return true;
}
return false;
}
bool DeckList::saveDialog(QWidget *parent)
{
QFileDialog dialog(parent, tr("Save deck"));
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(QWidget *parent)
{
int totalCards = 0;
for (int i = 0; i < zones.size(); i++)
totalCards += zones[i]->size();
QProgressDialog progress(tr("Caching card pictures..."), QString(), 0, totalCards, parent);
progress.setMinimumDuration(1000);
progress.setWindowModality(Qt::WindowModal);
for (int i = 0; i < zones.size(); i++)
for (int j = 0; j < zones[i]->size(); j++) {
db->getCard(zones[i]->at(j)->getCard())->getPixmap();
progress.setValue(progress.value() + 1);
}
}
void DeckList::cleanList()
{
for (int i = 0; i < zones.size(); i++) {
for (int j = 0; j < zones[i]->size(); j++)
delete zones[i]->at(j);
zones[i]->clear();
delete zones[i];
}
zones.clear();
setName();
setComments();
}
void DeckList::initZones()
{
// possibly Magic specific
zones.append(new DecklistZone("main"));
zones.append(new DecklistZone("side"));
}