mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-04-27 07:48:01 -07:00
deck editor
This commit is contained in:
parent
3502ec80e4
commit
1da5c63726
9 changed files with 349 additions and 256 deletions
|
|
@ -4,6 +4,7 @@
|
|||
#include <QXmlStreamReader>
|
||||
#include <QXmlStreamWriter>
|
||||
#include <QProgressDialog>
|
||||
#include <QVariant>
|
||||
#include "decklist.h"
|
||||
#include "carddatabase.h"
|
||||
|
||||
|
|
@ -14,6 +15,14 @@ AbstractDecklistNode::AbstractDecklistNode(InnerDecklistNode *_parent)
|
|||
parent->append(this);
|
||||
}
|
||||
|
||||
int AbstractDecklistNode::depth() const
|
||||
{
|
||||
if (parent)
|
||||
return parent->depth() + 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
InnerDecklistNode::~InnerDecklistNode()
|
||||
{
|
||||
clearTree();
|
||||
|
|
@ -26,33 +35,83 @@ QString InnerDecklistNode::getVisibleName() const
|
|||
else if (name == "side")
|
||||
return QObject::tr("Sideboard");
|
||||
else
|
||||
return QString();
|
||||
return getName();
|
||||
}
|
||||
|
||||
void InnerDecklistNode::clearTree()
|
||||
{
|
||||
for (int i = 0; i < size(); i++)
|
||||
delete at(i);
|
||||
clear();
|
||||
}
|
||||
|
||||
int InnerDecklistNode::recursiveCount() const
|
||||
AbstractDecklistNode *InnerDecklistNode::findChild(const QString &name)
|
||||
{
|
||||
for (int i = 0; i < size(); i++)
|
||||
if (at(i)->getName() == name)
|
||||
return at(i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int InnerDecklistNode::recursiveCount(bool countTotalCards) const
|
||||
{
|
||||
int result = 0;
|
||||
for (int i = 0; i < size(); i++) {
|
||||
InnerDecklistNode *node = dynamic_cast<InnerDecklistNode *>(at(i));
|
||||
if (node)
|
||||
result += node->recursiveCount();
|
||||
result += node->recursiveCount(countTotalCards);
|
||||
else if (countTotalCards)
|
||||
result += dynamic_cast<AbstractDecklistCardNode *>(at(i))->getNumber();
|
||||
else
|
||||
result += 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool InnerDecklistNode::compare(AbstractDecklistNode *other) const
|
||||
{
|
||||
InnerDecklistNode *other2 = dynamic_cast<InnerDecklistNode *>(other);
|
||||
if (other2)
|
||||
return (getName() > other->getName());
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AbstractDecklistCardNode::compare(AbstractDecklistNode *other) const
|
||||
{
|
||||
AbstractDecklistCardNode *other2 = dynamic_cast<AbstractDecklistCardNode *>(other);
|
||||
if (other2)
|
||||
return (getName() > other->getName());
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
class InnerDecklistNode::compareFunctor {
|
||||
private:
|
||||
Qt::SortOrder order;
|
||||
public:
|
||||
compareFunctor(Qt::SortOrder _order) : order(_order) { }
|
||||
inline bool operator()(AbstractDecklistNode *a, AbstractDecklistNode *b) const
|
||||
{
|
||||
return (order == Qt::AscendingOrder) ^ (a->compare(b));
|
||||
}
|
||||
};
|
||||
|
||||
void InnerDecklistNode::sort(Qt::SortOrder order)
|
||||
{
|
||||
compareFunctor cmp(order);
|
||||
qSort(begin(), end(), cmp);
|
||||
for (int i = 0; i < size(); i++) {
|
||||
InnerDecklistNode *node = dynamic_cast<InnerDecklistNode *>(at(i));
|
||||
if (node)
|
||||
node->sort(order);
|
||||
}
|
||||
}
|
||||
|
||||
DeckList::DeckList(CardDatabase *_db, QObject *parent)
|
||||
: QObject(parent), db(_db)
|
||||
{
|
||||
root = new InnerDecklistNode;
|
||||
initZones();
|
||||
}
|
||||
|
||||
DeckList::~DeckList()
|
||||
|
|
@ -60,6 +119,25 @@ DeckList::~DeckList()
|
|||
delete root;
|
||||
}
|
||||
|
||||
QXmlStreamReader &operator>>(QXmlStreamReader &xml, InnerDecklistNode *node)
|
||||
{
|
||||
while (!xml.atEnd()) {
|
||||
if (xml.readNext() == QXmlStreamReader::EndElement)
|
||||
break;
|
||||
if (xml.name() == "zone")
|
||||
xml >> new InnerDecklistNode(xml.attributes().value("name").toString(), node);
|
||||
else if (xml.name() == "card") {
|
||||
const int number = xml.attributes().value("number").toString().toInt();
|
||||
const QString card = xml.attributes().value("name").toString();
|
||||
new DecklistCardNode(card, number, node);
|
||||
while (!xml.atEnd())
|
||||
if (xml.readNext() == QXmlStreamReader::EndElement)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return xml;
|
||||
}
|
||||
|
||||
bool DeckList::loadFromFile_Native(QIODevice *device)
|
||||
{
|
||||
QXmlStreamReader xml(device);
|
||||
|
|
@ -74,30 +152,35 @@ bool DeckList::loadFromFile_Native(QIODevice *device)
|
|||
name = xml.readElementText();
|
||||
else if (xml.name() == "comments")
|
||||
comments = xml.readElementText();
|
||||
else if (xml.name() == "zone") {
|
||||
InnerDecklistNode *node = new InnerDecklistNode(xml.attributes().value("name").toString(), root);
|
||||
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();
|
||||
new DecklistCardNode(card, number, node);
|
||||
while (!xml.atEnd())
|
||||
if (xml.readNext() == QXmlStreamReader::EndElement)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (xml.name() == "zone")
|
||||
xml >> new InnerDecklistNode(xml.attributes().value("name").toString(), root);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const AbstractDecklistNode *node)
|
||||
{
|
||||
const InnerDecklistNode *inner = dynamic_cast<const InnerDecklistNode *>(node);
|
||||
if (inner) {
|
||||
xml.writeStartElement("zone");
|
||||
xml.writeAttribute("name", inner->getName());
|
||||
for (int i = 0; i < inner->size(); i++)
|
||||
xml << inner->at(i);
|
||||
xml.writeEndElement(); // zone
|
||||
} else {
|
||||
const AbstractDecklistCardNode *card = dynamic_cast<const AbstractDecklistCardNode *>(node);
|
||||
xml.writeEmptyElement("card");
|
||||
xml.writeAttribute("number", QString::number(card->getNumber()));
|
||||
xml.writeAttribute("name", card->getName());
|
||||
}
|
||||
return xml;
|
||||
}
|
||||
|
||||
bool DeckList::saveToFile_Native(QIODevice *device)
|
||||
{
|
||||
/* QXmlStreamWriter xml(device);
|
||||
QXmlStreamWriter xml(device);
|
||||
xml.setAutoFormatting(true);
|
||||
xml.writeStartDocument();
|
||||
|
||||
|
|
@ -106,27 +189,18 @@ bool DeckList::saveToFile_Native(QIODevice *device)
|
|||
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
|
||||
}
|
||||
for (int i = 0; i < root->size(); i++)
|
||||
xml << root->at(i);
|
||||
|
||||
xml.writeEndElement(); // cockatrice_deck
|
||||
|
||||
xml.writeEndDocument();
|
||||
return true;
|
||||
*/}
|
||||
}
|
||||
|
||||
bool DeckList::loadFromFile_Plain(QIODevice *device)
|
||||
{
|
||||
/* initZones();
|
||||
InnerDecklistNode *main = 0, *side = 0;
|
||||
|
||||
QTextStream in(device);
|
||||
while (!in.atEnd()) {
|
||||
|
|
@ -134,12 +208,17 @@ bool DeckList::loadFromFile_Plain(QIODevice *device)
|
|||
if (line.startsWith("//"))
|
||||
continue;
|
||||
|
||||
DecklistZone *zone;
|
||||
InnerDecklistNode *zone;
|
||||
if (line.startsWith("SB:", Qt::CaseInsensitive)) {
|
||||
line = line.mid(3).trimmed();
|
||||
zone = zones[1];
|
||||
} else
|
||||
zone = zones[0];
|
||||
if (!side)
|
||||
side = new InnerDecklistNode("side", root);
|
||||
zone = side;
|
||||
} else {
|
||||
if (!main)
|
||||
main = new InnerDecklistNode("main", root);
|
||||
zone = main;
|
||||
}
|
||||
|
||||
// Filter out MWS edition symbols and basic land extras
|
||||
QRegExp rx("\\[.*\\]");
|
||||
|
|
@ -153,21 +232,24 @@ bool DeckList::loadFromFile_Plain(QIODevice *device)
|
|||
int number = line.left(i).toInt(&ok);
|
||||
if (!ok)
|
||||
continue;
|
||||
zone->append(new DecklistRow(number, line.mid(i + 1)));
|
||||
new DecklistCardNode(line.mid(i + 1), number, zone);
|
||||
}
|
||||
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());
|
||||
// Support for this is only possible if the internal structure doesn't get more complicated.
|
||||
QTextStream out(device);
|
||||
for (int i = 0; i < root->size(); i++) {
|
||||
InnerDecklistNode *node = dynamic_cast<InnerDecklistNode *>(root->at(i));
|
||||
for (int j = 0; j < node->size(); j++) {
|
||||
DecklistCardNode *card = dynamic_cast<DecklistCardNode *>(node->at(j));
|
||||
out << QString("%1%2 %3\n").arg(node->getName() == "side" ? "SB: " : "").arg(card->getNumber()).arg(card->getName());
|
||||
}
|
||||
}
|
||||
return true;
|
||||
*/}
|
||||
}
|
||||
|
||||
bool DeckList::loadFromFile(const QString &fileName, FileFormat fmt, QWidget *parent)
|
||||
{
|
||||
|
|
@ -286,9 +368,34 @@ void DeckList::cleanList()
|
|||
setComments();
|
||||
}
|
||||
|
||||
void DeckList::initZones()
|
||||
DecklistCardNode *DeckList::addCard(const QString &cardName, const QString &zoneName)
|
||||
{
|
||||
/* // possibly Magic specific
|
||||
zones.append(new DecklistZone("main"));
|
||||
zones.append(new DecklistZone("side"));
|
||||
*/}
|
||||
InnerDecklistNode *zoneNode = dynamic_cast<InnerDecklistNode *>(root->findChild(zoneName));
|
||||
if (!zoneNode)
|
||||
zoneNode = new InnerDecklistNode(zoneName, root);
|
||||
|
||||
return new DecklistCardNode(cardName, 1, zoneNode);
|
||||
}
|
||||
|
||||
bool DeckList::deleteNode(AbstractDecklistNode *node, InnerDecklistNode *rootNode)
|
||||
{
|
||||
if (node == root)
|
||||
return true;
|
||||
if (!rootNode)
|
||||
rootNode = root;
|
||||
|
||||
int index = rootNode->indexOf(node);
|
||||
if (index != -1) {
|
||||
delete rootNode->takeAt(index);
|
||||
if (!rootNode->size())
|
||||
deleteNode(rootNode, rootNode->getParent());
|
||||
return true;
|
||||
}
|
||||
for (int i = 0; i < rootNode->size(); i++) {
|
||||
InnerDecklistNode *inner = dynamic_cast<InnerDecklistNode *>(rootNode->at(i));
|
||||
if (inner)
|
||||
if (deleteNode(node, inner))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue