improved importer

This commit is contained in:
Max-Wilhelm Bruker 2009-10-17 17:13:55 +02:00
parent aae2c437d6
commit 3c8f2b878b
9 changed files with 160 additions and 93 deletions

View file

@ -98,8 +98,9 @@ QString CardInfo::getMainCardType() const
QString CardInfo::getCorrectedName() const QString CardInfo::getCorrectedName() const
{ {
QString result = name;
// Fire // Ice, Circle of Protection: Red // Fire // Ice, Circle of Protection: Red
return getName().remove(" // ").remove(":"); return result.remove(" // ").remove(":");
} }
void CardInfo::addToSet(CardSet *set) void CardInfo::addToSet(CardSet *set)
@ -204,10 +205,10 @@ QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfo *info)
xml.writeStartElement("card"); xml.writeStartElement("card");
xml.writeTextElement("name", info->getName()); xml.writeTextElement("name", info->getName());
SetList sets = info->getSets(); const SetList &sets = info->getSets();
for (int i = 0; i < sets.size(); i++) for (int i = 0; i < sets.size(); i++)
xml.writeTextElement("set", sets[i]->getShortName()); xml.writeTextElement("set", sets[i]->getShortName());
QStringList colors = info->getColors(); const QStringList &colors = info->getColors();
for (int i = 0; i < colors.size(); i++) for (int i = 0; i < colors.size(); i++)
xml.writeTextElement("color", colors[i]); xml.writeTextElement("color", colors[i]);

View file

@ -61,15 +61,15 @@ public:
const SetList &_sets = SetList(), const SetList &_sets = SetList(),
const QString &_picURL = QString()); const QString &_picURL = QString());
~CardInfo(); ~CardInfo();
QString getName() const { return name; } const QString &getName() const { return name; }
SetList getSets() const { return sets; } const SetList &getSets() const { return sets; }
QString getManaCost() const { return manacost; } const QString &getManaCost() const { return manacost; }
QString getCardType() const { return cardtype; } const QString &getCardType() const { return cardtype; }
QString getPowTough() const { return powtough; } const QString &getPowTough() const { return powtough; }
QString getText() const { return text; } const QString &getText() const { return text; }
void setText(const QString &_text) { text = _text; } void setText(const QString &_text) { text = _text; }
QStringList getColors() const { return colors; } const QStringList &getColors() const { return colors; }
QString getPicURL() const { return picURL; } const QString &getPicURL() const { return picURL; }
QString getMainCardType() const; QString getMainCardType() const;
QString getCorrectedName() const; QString getCorrectedName() const;
int getTableRow() const { return tableRow; } int getTableRow() const { return tableRow; }

View file

@ -35,7 +35,7 @@ QVariant CardDatabaseModel::data(const QModelIndex &index, int role) const
case 0: return card->getName(); case 0: return card->getName();
case 1: { case 1: {
QStringList setList; QStringList setList;
QList<CardSet *> sets = card->getSets(); const QList<CardSet *> &sets = card->getSets();
for (int i = 0; i < sets.size(); i++) for (int i = 0; i < sets.size(); i++)
setList << sets[i]->getShortName(); setList << sets[i]->getShortName();
return setList.join(", "); return setList.join(", ");

View file

@ -33,6 +33,7 @@ WndDeckEditor::WndDeckEditor(CardDatabase *_db, QWidget *parent)
databaseView = new QTreeView(); databaseView = new QTreeView();
databaseView->setModel(databaseDisplayModel); databaseView->setModel(databaseDisplayModel);
databaseView->setUniformRowHeights(true); databaseView->setUniformRowHeights(true);
databaseView->setAlternatingRowColors(true);
databaseView->setSortingEnabled(true); databaseView->setSortingEnabled(true);
databaseView->sortByColumn(0, Qt::AscendingOrder); databaseView->sortByColumn(0, Qt::AscendingOrder);
databaseView->resizeColumnToContents(0); databaseView->resizeColumnToContents(0);
@ -194,7 +195,7 @@ void WndDeckEditor::updateCardInfoRight(const QModelIndex &current, const QModel
void WndDeckEditor::updateSearch(const QString &search) void WndDeckEditor::updateSearch(const QString &search)
{ {
databaseDisplayModel->setFilterRegExp(search); databaseDisplayModel->setFilterFixedString(search);
} }
bool WndDeckEditor::confirmClose() bool WndDeckEditor::confirmClose()

View file

@ -1,292 +1,292 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<cockatrice_setdatabase version="20090811"> <cockatrice_setdatabase version="20091017">
<picture_url>http://www.wizards.com/global/images/magic/general/%1.jpg</picture_url> <picture_url>http://www.wizards.com/global/images/magic/general/%1.jpg</picture_url>
<set_url>http://gatherer.wizards.com/Pages/Search/Default.aspx?output=spoiler&amp;method=text&amp;set=[&quot;!longname!&quot;]</set_url> <set_url>http://gatherer.wizards.com/Pages/Search/Default.aspx?output=spoiler&amp;method=text&amp;set=[&quot;!longname!&quot;]</set_url>
<set> <set import="1">
<name>ARB</name> <name>ARB</name>
<longname>Alara Reborn</longname> <longname>Alara Reborn</longname>
</set> </set>
<set> <set import="1">
<name>AL</name> <name>AL</name>
<longname>Alliances</longname> <longname>Alliances</longname>
</set> </set>
<set> <set import="1">
<name>AQ</name> <name>AQ</name>
<longname>Antiquities</longname> <longname>Antiquities</longname>
</set> </set>
<set> <set import="1">
<name>AP</name> <name>AP</name>
<longname>Apocalypse</longname> <longname>Apocalypse</longname>
</set> </set>
<set> <set import="1">
<name>AN</name> <name>AN</name>
<longname>Arabian Nights</longname> <longname>Arabian Nights</longname>
</set> </set>
<set> <set import="1">
<name>BOK</name> <name>BOK</name>
<longname>Betrayers of Kamigawa</longname> <longname>Betrayers of Kamigawa</longname>
</set> </set>
<set> <set import="1">
<name>CHK</name> <name>CHK</name>
<longname>Champions of Kamigawa</longname> <longname>Champions of Kamigawa</longname>
</set> </set>
<set> <set import="1">
<name>CH</name> <name>CH</name>
<longname>Chronicles</longname> <longname>Chronicles</longname>
</set> </set>
<set> <set import="1">
<name>6E</name> <name>6E</name>
<longname>Classic Sixth Edition</longname> <longname>Classic Sixth Edition</longname>
</set> </set>
<set> <set import="1">
<name>CS</name> <name>CS</name>
<longname>Coldsnap</longname> <longname>Coldsnap</longname>
</set> </set>
<set> <set import="1">
<name>CFX</name> <name>CFX</name>
<longname>Conflux</longname> <longname>Conflux</longname>
</set> </set>
<set> <set import="1">
<name>DS</name> <name>DS</name>
<longname>Darksteel</longname> <longname>Darksteel</longname>
</set> </set>
<set> <set import="1">
<name>DIS</name> <name>DIS</name>
<longname>Dissension</longname> <longname>Dissension</longname>
</set> </set>
<set> <set import="1">
<name>8E</name> <name>8E</name>
<longname>Eighth Edition</longname> <longname>Eighth Edition</longname>
</set> </set>
<set> <set import="1">
<name>EVE</name> <name>EVE</name>
<longname>Eventide</longname> <longname>Eventide</longname>
</set> </set>
<set> <set import="1">
<name>EX</name> <name>EX</name>
<longname>Exodus</longname> <longname>Exodus</longname>
</set> </set>
<set> <set import="1">
<name>FE</name> <name>FE</name>
<longname>Fallen Empires</longname> <longname>Fallen Empires</longname>
</set> </set>
<set> <set import="1">
<name>FD</name> <name>FD</name>
<longname>Fifth Dawn</longname> <longname>Fifth Dawn</longname>
</set> </set>
<set> <set import="1">
<name>5E</name> <name>5E</name>
<longname>Fifth Edition</longname> <longname>Fifth Edition</longname>
</set> </set>
<set> <set import="1">
<name>4E</name> <name>4E</name>
<longname>Fourth Edition</longname> <longname>Fourth Edition</longname>
</set> </set>
<set> <set import="1">
<name>FUT</name> <name>FUT</name>
<longname>Future Sight</longname> <longname>Future Sight</longname>
</set> </set>
<set> <set import="1">
<name>GP</name> <name>GP</name>
<longname>Guildpact</longname> <longname>Guildpact</longname>
</set> </set>
<set> <set import="1">
<name>HL</name> <name>HL</name>
<longname>Homelands</longname> <longname>Homelands</longname>
</set> </set>
<set> <set import="1">
<name>IA</name> <name>IA</name>
<longname>Ice Age</longname> <longname>Ice Age</longname>
</set> </set>
<set> <set import="1">
<name>IN</name> <name>IN</name>
<longname>Invasion</longname> <longname>Invasion</longname>
</set> </set>
<set> <set import="1">
<name>JU</name> <name>JU</name>
<longname>Judgment</longname> <longname>Judgment</longname>
</set> </set>
<set> <set import="1">
<name>LG</name> <name>LG</name>
<longname>Legends</longname> <longname>Legends</longname>
</set> </set>
<set> <set import="1">
<name>LE</name> <name>LE</name>
<longname>Legions</longname> <longname>Legions</longname>
</set> </set>
<set> <set import="1">
<name>A</name> <name>A</name>
<longname>Limited Edition Alpha</longname> <longname>Limited Edition Alpha</longname>
</set> </set>
<set> <set import="1">
<name>B</name> <name>B</name>
<longname>Limited Edition Beta</longname> <longname>Limited Edition Beta</longname>
</set> </set>
<set> <set import="1">
<name>LRW</name> <name>LRW</name>
<longname>Lorwyn</longname> <longname>Lorwyn</longname>
</set> </set>
<set> <set import="1">
<name>M10</name> <name>M10</name>
<longname>Magic 2010</longname> <longname>Magic 2010</longname>
</set> </set>
<set> <set import="1">
<name>MM</name> <name>MM</name>
<longname>Mercadian Masques</longname> <longname>Mercadian Masques</longname>
</set> </set>
<set> <set import="1">
<name>MI</name> <name>MI</name>
<longname>Mirage</longname> <longname>Mirage</longname>
</set> </set>
<set> <set import="1">
<name>MR</name> <name>MR</name>
<longname>Mirrodin</longname> <longname>Mirrodin</longname>
</set> </set>
<set> <set import="1">
<name>MOR</name> <name>MOR</name>
<longname>Morningtide</longname> <longname>Morningtide</longname>
</set> </set>
<set> <set import="1">
<name>NE</name> <name>NE</name>
<longname>Nemesis</longname> <longname>Nemesis</longname>
</set> </set>
<set> <set import="1">
<name>9E</name> <name>9E</name>
<longname>Ninth Edition</longname> <longname>Ninth Edition</longname>
</set> </set>
<set> <set import="1">
<name>OD</name> <name>OD</name>
<longname>Odyssey</longname> <longname>Odyssey</longname>
</set> </set>
<set> <set import="1">
<name>ON</name> <name>ON</name>
<longname>Onslaught</longname> <longname>Onslaught</longname>
</set> </set>
<set> <set import="1">
<name>PLC</name> <name>PLC</name>
<longname>Planar Chaos</longname> <longname>Planar Chaos</longname>
</set> </set>
<set> <set import="1">
<name>PS</name> <name>PS</name>
<longname>Planeshift</longname> <longname>Planeshift</longname>
</set> </set>
<set> <set import="1">
<name>PT</name> <name>PT</name>
<longname>Portal</longname> <longname>Portal</longname>
</set> </set>
<set> <set import="1">
<name>P2</name> <name>P2</name>
<longname>Portal Second Age</longname> <longname>Portal Second Age</longname>
</set> </set>
<set> <set import="1">
<name>P3</name> <name>P3</name>
<longname>Portal Three Kingdoms</longname> <longname>Portal Three Kingdoms</longname>
</set> </set>
<set> <set import="1">
<name>PR</name> <name>PR</name>
<longname>Promo set for Gatherer</longname> <longname>Promo set for Gatherer</longname>
</set> </set>
<set> <set import="1">
<name>PY</name> <name>PY</name>
<longname>Prophecy</longname> <longname>Prophecy</longname>
</set> </set>
<set> <set import="1">
<name>RAV</name> <name>RAV</name>
<longname>Ravnica: City of Guilds</longname> <longname>Ravnica: City of Guilds</longname>
</set> </set>
<set> <set import="1">
<name>R</name> <name>R</name>
<longname>Revised Edition</longname> <longname>Revised Edition</longname>
</set> </set>
<set> <set import="1">
<name>SOK</name> <name>SOK</name>
<longname>Saviors of Kamigawa</longname> <longname>Saviors of Kamigawa</longname>
</set> </set>
<set> <set import="1">
<name>SC</name> <name>SC</name>
<longname>Scourge</longname> <longname>Scourge</longname>
</set> </set>
<set> <set import="1">
<name>7E</name> <name>7E</name>
<longname>Seventh Edition</longname> <longname>Seventh Edition</longname>
</set> </set>
<set> <set import="1">
<name>SHM</name> <name>SHM</name>
<longname>Shadowmoor</longname> <longname>Shadowmoor</longname>
</set> </set>
<set> <set import="1">
<name>ALA</name> <name>ALA</name>
<longname>Shards of Alara</longname> <longname>Shards of Alara</longname>
</set> </set>
<set> <set import="1">
<name>ST</name> <name>ST</name>
<longname>Starter 1999</longname> <longname>Starter 1999</longname>
</set> </set>
<set> <set import="1">
<name>ST2K</name> <name>ST2K</name>
<longname>Starter 2000</longname> <longname>Starter 2000</longname>
</set> </set>
<set> <set import="1">
<name>SH</name> <name>SH</name>
<longname>Stronghold</longname> <longname>Stronghold</longname>
</set> </set>
<set> <set import="1">
<name>TE</name> <name>TE</name>
<longname>Tempest</longname> <longname>Tempest</longname>
</set> </set>
<set> <set import="1">
<name>10E</name> <name>10E</name>
<longname>Tenth Edition</longname> <longname>Tenth Edition</longname>
</set> </set>
<set> <set import="1">
<name>DK</name> <name>DK</name>
<longname>The Dark</longname> <longname>The Dark</longname>
</set> </set>
<set> <set import="1">
<name>TSP</name> <name>TSP</name>
<longname>Time Spiral</longname> <longname>Time Spiral</longname>
</set> </set>
<set> <set import="1">
<name>TSB</name> <name>TSB</name>
<longname>Time Spiral "Timeshifted"</longname> <longname>Time Spiral "Timeshifted"</longname>
</set> </set>
<set> <set import="1">
<name>TO</name> <name>TO</name>
<longname>Torment</longname> <longname>Torment</longname>
</set> </set>
<set> <set import="0">
<name>UG</name> <name>UG</name>
<longname>Unglued</longname> <longname>Unglued</longname>
</set> </set>
<set> <set import="0">
<name>UNH</name> <name>UNH</name>
<longname>Unhinged</longname> <longname>Unhinged</longname>
</set> </set>
<set> <set import="1">
<name>U</name> <name>U</name>
<longname>Unlimited Edition</longname> <longname>Unlimited Edition</longname>
</set> </set>
<set> <set import="1">
<name>UD</name> <name>UD</name>
<longname>Urza's Destiny</longname> <longname>Urza's Destiny</longname>
</set> </set>
<set> <set import="1">
<name>UL</name> <name>UL</name>
<longname>Urza's Legacy</longname> <longname>Urza's Legacy</longname>
</set> </set>
<set> <set import="1">
<name>US</name> <name>US</name>
<longname>Urza's Saga</longname> <longname>Urza's Saga</longname>
</set> </set>
<set> <set import="1">
<name>VI</name> <name>VI</name>
<longname>Visions</longname> <longname>Visions</longname>
</set> </set>
<set> <set import="1">
<name>WL</name> <name>WL</name>
<longname>Weatherlight</longname> <longname>Weatherlight</longname>
</set> </set>
<set> <set import="1">
<name>ZEN</name> <name>ZEN</name>
<longname>Zendikar</longname> <longname>Zendikar</longname>
</set> </set>

View file

@ -18,6 +18,7 @@ OracleImporter::OracleImporter(const QString &_dataDir, QObject *parent)
break; break;
if (xml.name() == "set") { if (xml.name() == "set") {
QString shortName, longName; QString shortName, longName;
bool import = xml.attributes().value("import").toString().toInt();
while (!xml.atEnd()) { while (!xml.atEnd()) {
if (xml.readNext() == QXmlStreamReader::EndElement) if (xml.readNext() == QXmlStreamReader::EndElement)
break; break;
@ -28,7 +29,7 @@ OracleImporter::OracleImporter(const QString &_dataDir, QObject *parent)
else if (xml.name() == "url") else if (xml.name() == "url")
editionURL = xml.readElementText(); editionURL = xml.readElementText();
} }
setsToDownload << SetToDownload(edition, editionLong, editionURL); setsToDownload << SetToDownload(edition, editionLong, editionURL, import);
edition = editionLong = editionURL = QString(); edition = editionLong = editionURL = QString();
} else if (xml.name() == "picture_url") } else if (xml.name() == "picture_url")
pictureUrl = xml.readElementText(); pictureUrl = xml.readElementText();
@ -182,6 +183,13 @@ QString OracleImporter::getURLFromName(QString name) const
void OracleImporter::downloadNextFile() void OracleImporter::downloadNextFile()
{ {
if (setIndex == -1) { if (setIndex == -1) {
for (int i = 0; i < setsToDownload.size(); ++i)
if (!setsToDownload[i].getImport()) {
setsToDownload.removeAt(i);
--i;
}
if (setsToDownload.isEmpty())
return;
setIndex = 0; setIndex = 0;
emit setIndexChanged(0, 0, setsToDownload[0].getLongName()); emit setIndexChanged(0, 0, setsToDownload[0].getLongName());
} }

View file

@ -9,12 +9,15 @@ class QBuffer;
class SetToDownload { class SetToDownload {
private: private:
QString shortName, longName, url; QString shortName, longName, url;
bool import;
public: public:
const QString &getShortName() const { return shortName; } const QString &getShortName() const { return shortName; }
const QString &getLongName() const { return longName; } const QString &getLongName() const { return longName; }
const QString &getUrl() const { return url; } const QString &getUrl() const { return url; }
SetToDownload(const QString &_shortName, const QString &_longName, const QString &_url) bool getImport() const { return import; }
: shortName(_shortName), longName(_longName), url(_url) { } void setImport(bool _import) { qDebug(QString("%1: setting import to %2").arg(getShortName()).arg(_import).toUtf8()); import = _import; }
SetToDownload(const QString &_shortName, const QString &_longName, const QString &_url, bool _import)
: shortName(_shortName), longName(_longName), url(_url), import(_import) { }
}; };
class OracleImporter : public CardDatabase { class OracleImporter : public CardDatabase {
@ -41,6 +44,7 @@ public:
int importTextSpoiler(CardSet *set, const QByteArray &data); int importTextSpoiler(CardSet *set, const QByteArray &data);
void downloadNextFile(); void downloadNextFile();
int getSetsCount() const { return setsToDownload.size(); } int getSetsCount() const { return setsToDownload.size(); }
QList<SetToDownload> &getSets() { return setsToDownload; }
}; };
#endif #endif

View file

@ -7,6 +7,30 @@ WindowMain::WindowMain(QWidget *parent)
{ {
importer = new OracleImporter("../oracle", this); importer = new OracleImporter("../oracle", this);
QVBoxLayout *checkboxLayout = new QVBoxLayout;
QList<SetToDownload> &sets = importer->getSets();
for (int i = 0; i < sets.size(); ++i) {
QCheckBox *checkBox = new QCheckBox(sets[i].getLongName());
checkBox->setChecked(sets[i].getImport());
connect(checkBox, SIGNAL(stateChanged(int)), this, SLOT(checkBoxChanged(int)));
checkboxLayout->addWidget(checkBox);
checkBoxList << checkBox;
}
QWidget *checkboxFrame = new QWidget;
checkboxFrame->setLayout(checkboxLayout);
QScrollArea *checkboxArea = new QScrollArea;
checkboxArea->setWidget(checkboxFrame);
checkboxArea->setWidgetResizable(true);
startButton = new QPushButton(tr("&Start download"));
connect(startButton, SIGNAL(clicked()), this, SLOT(actStart()));
QVBoxLayout *settingsLayout = new QVBoxLayout;
settingsLayout->addWidget(checkboxArea);
settingsLayout->addWidget(startButton);
totalLabel = new QLabel(tr("Total progress:")); totalLabel = new QLabel(tr("Total progress:"));
totalProgressBar = new QProgressBar; totalProgressBar = new QProgressBar;
nextSetLabel1 = new QLabel(tr("Current file:")); nextSetLabel1 = new QLabel(tr("Current file:"));
@ -26,8 +50,13 @@ WindowMain::WindowMain(QWidget *parent)
grid->addWidget(fileProgressBar, 2, 1); grid->addWidget(fileProgressBar, 2, 1);
grid->addWidget(messageLog, 3, 0, 1, 2); grid->addWidget(messageLog, 3, 0, 1, 2);
QHBoxLayout *mainLayout = new QHBoxLayout;
mainLayout->addLayout(settingsLayout);
mainLayout->addSpacing(10);
mainLayout->addLayout(grid);
QWidget *centralWidget = new QWidget; QWidget *centralWidget = new QWidget;
centralWidget->setLayout(grid); centralWidget->setLayout(mainLayout);
setCentralWidget(centralWidget); setCentralWidget(centralWidget);
connect(importer, SIGNAL(setIndexChanged(int, int, const QString &)), this, SLOT(updateTotalProgress(int, int, const QString &))); connect(importer, SIGNAL(setIndexChanged(int, int, const QString &)), this, SLOT(updateTotalProgress(int, int, const QString &)));
@ -35,9 +64,7 @@ WindowMain::WindowMain(QWidget *parent)
totalProgressBar->setMaximum(importer->getSetsCount()); totalProgressBar->setMaximum(importer->getSetsCount());
setWindowTitle(tr("Oracle importer")); setWindowTitle(tr("Oracle importer"));
setFixedSize(300, 300); setFixedSize(500, 300);
importer->downloadNextFile();
} }
void WindowMain::updateTotalProgress(int cardsImported, int setIndex, const QString &nextSetName) void WindowMain::updateTotalProgress(int cardsImported, int setIndex, const QString &nextSetName)
@ -58,3 +85,22 @@ void WindowMain::updateFileProgress(int bytesRead, int totalBytes)
fileProgressBar->setMaximum(totalBytes); fileProgressBar->setMaximum(totalBytes);
fileProgressBar->setValue(bytesRead); fileProgressBar->setValue(bytesRead);
} }
void WindowMain::actStart()
{
startButton->setEnabled(false);
for (int i = 0; i < checkBoxList.size(); ++i)
checkBoxList[i]->setEnabled(false);
importer->downloadNextFile();
}
void WindowMain::checkBoxChanged(int state)
{
QCheckBox *checkBox = qobject_cast<QCheckBox *>(sender());
QList<SetToDownload> &sets = importer->getSets();
for (int i = 0; i < sets.size(); ++i)
if (sets[i].getLongName() == checkBox->text()) {
sets[i].setImport(state);
break;
}
}

View file

@ -2,23 +2,30 @@
#define WINDOW_MAIN_H #define WINDOW_MAIN_H
#include <QMainWindow> #include <QMainWindow>
#include <QList>
class OracleImporter; class OracleImporter;
class QLabel; class QLabel;
class QProgressBar; class QProgressBar;
class QTextEdit; class QTextEdit;
class QPushButton;
class QCheckBox;
class WindowMain : public QMainWindow { class WindowMain : public QMainWindow {
Q_OBJECT Q_OBJECT
private: private:
OracleImporter *importer; OracleImporter *importer;
QPushButton *startButton;
QLabel *totalLabel, *fileLabel, *nextSetLabel1, *nextSetLabel2; QLabel *totalLabel, *fileLabel, *nextSetLabel1, *nextSetLabel2;
QProgressBar *totalProgressBar, *fileProgressBar; QProgressBar *totalProgressBar, *fileProgressBar;
QTextEdit *messageLog; QTextEdit *messageLog;
QList<QCheckBox *> checkBoxList;
private slots: private slots:
void updateTotalProgress(int cardsImported, int setIndex, const QString &nextSetName); void updateTotalProgress(int cardsImported, int setIndex, const QString &nextSetName);
void updateFileProgress(int bytesRead, int totalBytes); void updateFileProgress(int bytesRead, int totalBytes);
void actStart();
void checkBoxChanged(int state);
public: public:
WindowMain(QWidget *parent = 0); WindowMain(QWidget *parent = 0);
}; };