Rewrite oracle as a wizard
This commit is contained in:
parent
f3a57d5506
commit
40f9536224
8 changed files with 518 additions and 323 deletions
|
@ -9,8 +9,8 @@ set(DESKTOPDIR share/applications CACHE STRING "path to .desktop files")
|
||||||
|
|
||||||
SET(oracle_SOURCES
|
SET(oracle_SOURCES
|
||||||
src/main.cpp
|
src/main.cpp
|
||||||
|
src/oraclewizard.cpp
|
||||||
src/oracleimporter.cpp
|
src/oracleimporter.cpp
|
||||||
src/window_main.cpp
|
|
||||||
../cockatrice/src/carddatabase.cpp
|
../cockatrice/src/carddatabase.cpp
|
||||||
../cockatrice/src/settingscache.cpp
|
../cockatrice/src/settingscache.cpp
|
||||||
../cockatrice/src/qt-json/json.cpp
|
../cockatrice/src/qt-json/json.cpp
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QTextCodec>
|
#include <QTextCodec>
|
||||||
#include "window_main.h"
|
#include "oraclewizard.h"
|
||||||
#include "settingscache.h"
|
#include "settingscache.h"
|
||||||
|
|
||||||
SettingsCache *settingsCache;
|
SettingsCache *settingsCache;
|
||||||
|
@ -12,13 +12,14 @@ int main(int argc, char *argv[])
|
||||||
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
|
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
|
||||||
|
|
||||||
QCoreApplication::setOrganizationName("Cockatrice");
|
QCoreApplication::setOrganizationName("Cockatrice");
|
||||||
QCoreApplication::setOrganizationDomain("cockatrice.de");
|
QCoreApplication::setOrganizationDomain("cockatrice");
|
||||||
|
// this can't be changed, as it influences the default savepath for cards.xml
|
||||||
QCoreApplication::setApplicationName("Cockatrice");
|
QCoreApplication::setApplicationName("Cockatrice");
|
||||||
|
|
||||||
settingsCache = new SettingsCache;
|
settingsCache = new SettingsCache;
|
||||||
|
|
||||||
WindowMain wnd;
|
OracleWizard wizard;
|
||||||
wnd.show();
|
wizard.show();
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,17 +9,6 @@ OracleImporter::OracleImporter(const QString &_dataDir, QObject *parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OracleImporter::readSetsFromFile(const QString &fileName)
|
|
||||||
{
|
|
||||||
QFile setsFile(fileName);
|
|
||||||
if (!setsFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
|
||||||
QMessageBox::critical(0, tr("Error"), tr("Cannot open file '%1'.").arg(fileName));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return readSetsFromByteArray(setsFile.readAll());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool OracleImporter::readSetsFromByteArray(const QByteArray &data)
|
bool OracleImporter::readSetsFromByteArray(const QByteArray &data)
|
||||||
{
|
{
|
||||||
QList<SetToDownload> newSetList;
|
QList<SetToDownload> newSetList;
|
||||||
|
@ -51,6 +40,9 @@ bool OracleImporter::readSetsFromByteArray(const QByteArray &data)
|
||||||
|
|
||||||
newSetList.append(SetToDownload(edition, editionLong, editionCards, import));
|
newSetList.append(SetToDownload(edition, editionLong, editionCards, import));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qSort(newSetList);
|
||||||
|
|
||||||
if (newSetList.isEmpty())
|
if (newSetList.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
allSets = newSetList;
|
allSets = newSetList;
|
||||||
|
@ -243,8 +235,8 @@ int OracleImporter::startImport()
|
||||||
while (it.hasNext())
|
while (it.hasNext())
|
||||||
{
|
{
|
||||||
curSet = & it.next();
|
curSet = & it.next();
|
||||||
|
if(!curSet->getImport())
|
||||||
emit setIndexChanged(0, 0, curSet->getLongName());
|
continue;
|
||||||
|
|
||||||
CardSet *set = new CardSet(curSet->getShortName(), curSet->getLongName());
|
CardSet *set = new CardSet(curSet->getShortName(), curSet->getLongName());
|
||||||
if (!setHash.contains(set->getShortName()))
|
if (!setHash.contains(set->getShortName()))
|
||||||
|
|
|
@ -18,6 +18,7 @@ public:
|
||||||
void setImport(bool _import) { import = _import; }
|
void setImport(bool _import) { import = _import; }
|
||||||
SetToDownload(const QString &_shortName, const QString &_longName, const QVariant &_cards, bool _import)
|
SetToDownload(const QString &_shortName, const QString &_longName, const QVariant &_cards, bool _import)
|
||||||
: shortName(_shortName), longName(_longName), cards(_cards), import(_import) { }
|
: shortName(_shortName), longName(_longName), cards(_cards), import(_import) { }
|
||||||
|
bool operator<(const SetToDownload &set) const { return longName < set.longName; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class OracleImporter : public CardDatabase {
|
class OracleImporter : public CardDatabase {
|
||||||
|
@ -27,15 +28,13 @@ private:
|
||||||
QVariantMap setsMap;
|
QVariantMap setsMap;
|
||||||
QString dataDir;
|
QString dataDir;
|
||||||
|
|
||||||
void downloadNextFile();
|
|
||||||
CardInfo *addCard(const QString &setName, QString cardName, bool isToken, int cardId, const QString &cardCost, const QString &cardType, const QString &cardPT, int cardLoyalty, const QStringList &cardText);
|
CardInfo *addCard(const QString &setName, QString cardName, bool isToken, int cardId, const QString &cardCost, const QString &cardType, const QString &cardPT, int cardLoyalty, const QStringList &cardText);
|
||||||
signals:
|
signals:
|
||||||
void setIndexChanged(int cardsImported, int setIndex, const QString &nextSetName);
|
void setIndexChanged(int cardsImported, int setIndex, const QString &setName);
|
||||||
void dataReadProgress(int bytesRead, int totalBytes);
|
void dataReadProgress(int bytesRead, int totalBytes);
|
||||||
public:
|
public:
|
||||||
OracleImporter(const QString &_dataDir, QObject *parent = 0);
|
OracleImporter(const QString &_dataDir, QObject *parent = 0);
|
||||||
bool readSetsFromByteArray(const QByteArray &data);
|
bool readSetsFromByteArray(const QByteArray &data);
|
||||||
bool readSetsFromFile(const QString &fileName);
|
|
||||||
int startImport();
|
int startImport();
|
||||||
int importTextSpoiler(CardSet *set, const QVariant &data);
|
int importTextSpoiler(CardSet *set, const QVariant &data);
|
||||||
QList<SetToDownload> &getSets() { return allSets; }
|
QList<SetToDownload> &getSets() { return allSets; }
|
||||||
|
|
392
oracle/src/oraclewizard.cpp
Normal file
392
oracle/src/oraclewizard.cpp
Normal file
|
@ -0,0 +1,392 @@
|
||||||
|
#include <QtGui>
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <QDesktopServices>
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
|
||||||
|
#include "oraclewizard.h"
|
||||||
|
#include "oracleimporter.h"
|
||||||
|
|
||||||
|
#define ALLSETS_URL "http://mtgjson.com/json/AllSets.json"
|
||||||
|
|
||||||
|
OracleWizard::OracleWizard(QWidget *parent)
|
||||||
|
: QWizard(parent)
|
||||||
|
{
|
||||||
|
importer = new OracleImporter(QDesktopServices::storageLocation(QDesktopServices::DataLocation), this);
|
||||||
|
|
||||||
|
addPage(new IntroPage);
|
||||||
|
addPage(new LoadSetsPage);
|
||||||
|
addPage(new ChooseSetsPage);
|
||||||
|
addPage(new SaveSetsPage);
|
||||||
|
|
||||||
|
/*
|
||||||
|
setPixmap(QWizard::BannerPixmap, QPixmap(":/images/banner.png"));
|
||||||
|
setPixmap(QWizard::BackgroundPixmap, QPixmap(":/images/background.png"));
|
||||||
|
*/
|
||||||
|
setWindowTitle(tr("Oracle Importer"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void OracleWizard::accept()
|
||||||
|
{
|
||||||
|
QDialog::accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OracleWizard::enableButtons()
|
||||||
|
{
|
||||||
|
button(QWizard::NextButton)->setDisabled(false);
|
||||||
|
button(QWizard::BackButton)->setDisabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OracleWizard::disableButtons()
|
||||||
|
{
|
||||||
|
button(QWizard::NextButton)->setDisabled(true);
|
||||||
|
button(QWizard::BackButton)->setDisabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
IntroPage::IntroPage(QWidget *parent)
|
||||||
|
: OracleWizardPage(parent)
|
||||||
|
{
|
||||||
|
setTitle(tr("Introduction"));
|
||||||
|
//setPixmap(QWizard::WatermarkPixmap, QPixmap(":/images/watermark1.png"));
|
||||||
|
|
||||||
|
label = new QLabel(tr("This wizard will import the list of sets and cards "
|
||||||
|
"that will be used by Cockatrice. You will need to "
|
||||||
|
"specify an url or a filename that will be used as a "
|
||||||
|
"source, and then choose the wanted sets from the list "
|
||||||
|
"of the available ones."),
|
||||||
|
this);
|
||||||
|
label->setWordWrap(true);
|
||||||
|
|
||||||
|
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||||
|
layout->addWidget(label);
|
||||||
|
setLayout(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadSetsPage::LoadSetsPage(QWidget *parent)
|
||||||
|
: OracleWizardPage(parent), nam(0)
|
||||||
|
{
|
||||||
|
setTitle(tr("Source selection"));
|
||||||
|
setSubTitle(tr("Please specify a source for the list of sets and cards. "
|
||||||
|
"You can specify an url address that will be download or "
|
||||||
|
"use an existing file from your computer."));
|
||||||
|
//setPixmap(QWizard::LogoPixmap, QPixmap(":/images/logo1.png"));
|
||||||
|
|
||||||
|
urlRadioButton = new QRadioButton(tr("Download url:"), this);
|
||||||
|
fileRadioButton = new QRadioButton(tr("Local file:"), this);
|
||||||
|
|
||||||
|
urlLineEdit = new QLineEdit(this);
|
||||||
|
fileLineEdit = new QLineEdit(this);
|
||||||
|
|
||||||
|
progressLabel = new QLabel(this);
|
||||||
|
progressBar = new QProgressBar(this);
|
||||||
|
|
||||||
|
urlRadioButton->setChecked(true);
|
||||||
|
urlLineEdit->setText(ALLSETS_URL);
|
||||||
|
|
||||||
|
fileButton = new QPushButton(tr("Choose file..."), this);
|
||||||
|
connect(fileButton, SIGNAL(clicked()), this, SLOT(actLoadSetsFile()));
|
||||||
|
|
||||||
|
QGridLayout *layout = new QGridLayout(this);
|
||||||
|
layout->addWidget(urlRadioButton, 0, 0);
|
||||||
|
layout->addWidget(urlLineEdit, 0, 1);
|
||||||
|
layout->addWidget(fileRadioButton, 1, 0);
|
||||||
|
layout->addWidget(fileLineEdit, 1, 1);
|
||||||
|
layout->addWidget(fileButton, 2, 1, Qt::AlignRight);
|
||||||
|
layout->addWidget(progressLabel, 3, 0);
|
||||||
|
layout->addWidget(progressBar, 3, 1);
|
||||||
|
|
||||||
|
connect(&watcher, SIGNAL(finished()), this, SLOT(importFinished()));
|
||||||
|
|
||||||
|
setLayout(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadSetsPage::initializePage()
|
||||||
|
{
|
||||||
|
progressLabel->hide();
|
||||||
|
progressBar->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadSetsPage::actLoadSetsFile()
|
||||||
|
{
|
||||||
|
QFileDialog dialog(this, tr("Load sets file"));
|
||||||
|
dialog.setFileMode(QFileDialog::ExistingFile);
|
||||||
|
dialog.setNameFilter("Sets JSON file (*.json)");
|
||||||
|
|
||||||
|
if(!fileLineEdit->text().isEmpty() && QFile::exists(fileLineEdit->text()))
|
||||||
|
dialog.selectFile(fileLineEdit->text());
|
||||||
|
|
||||||
|
if (!dialog.exec())
|
||||||
|
return;
|
||||||
|
|
||||||
|
fileLineEdit->setText(dialog.selectedFiles().at(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LoadSetsPage::validatePage()
|
||||||
|
{
|
||||||
|
// once the import is finished, we call next(); skip validation
|
||||||
|
if(wizard()->importer->getSets().count() > 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// else, try to import sets
|
||||||
|
if(urlRadioButton->isChecked())
|
||||||
|
{
|
||||||
|
QUrl url = QUrl::fromUserInput(urlLineEdit->text());
|
||||||
|
if(!url.isValid())
|
||||||
|
{
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("The provided url is not valid."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
progressLabel->setText(tr("Downloading (0MB)"));
|
||||||
|
// show an infinite progressbar
|
||||||
|
progressBar->setMaximum(0);
|
||||||
|
progressBar->setMinimum(0);
|
||||||
|
progressBar->setValue(0);
|
||||||
|
progressLabel->show();
|
||||||
|
progressBar->show();
|
||||||
|
|
||||||
|
wizard()->disableButtons();
|
||||||
|
setEnabled(false);
|
||||||
|
|
||||||
|
if(!nam)
|
||||||
|
nam = new QNetworkAccessManager(this);
|
||||||
|
QNetworkReply *reply = nam->get(QNetworkRequest(url));
|
||||||
|
|
||||||
|
connect(reply, SIGNAL(finished()), this, SLOT(actDownloadFinishedSetsFile()));
|
||||||
|
connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(actDownloadProgressSetsFile(qint64, qint64)));
|
||||||
|
|
||||||
|
} else if(fileRadioButton->isChecked()) {
|
||||||
|
QFile setsFile(fileLineEdit->text());
|
||||||
|
if(!setsFile.exists())
|
||||||
|
{
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("Please choose a file."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!setsFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
|
QMessageBox::critical(0, tr("Error"), tr("Cannot open file '%1'.").arg(fileLineEdit->text()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
wizard()->disableButtons();
|
||||||
|
setEnabled(false);
|
||||||
|
|
||||||
|
readSetsFromByteArray(setsFile.readAll());
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadSetsPage::actDownloadProgressSetsFile(qint64 received, qint64 total)
|
||||||
|
{
|
||||||
|
if(total > 0 && progressBar->maximum()==0)
|
||||||
|
{
|
||||||
|
progressBar->setMaximum(total);
|
||||||
|
progressBar->setValue(received);
|
||||||
|
}
|
||||||
|
progressLabel->setText(tr("Downloading (%1MB)").arg((int) received / 1048576));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadSetsPage::actDownloadFinishedSetsFile()
|
||||||
|
{
|
||||||
|
progressLabel->hide();
|
||||||
|
progressBar->hide();
|
||||||
|
|
||||||
|
// check for a reply
|
||||||
|
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
|
||||||
|
QNetworkReply::NetworkError errorCode = reply->error();
|
||||||
|
if (errorCode != QNetworkReply::NoError) {
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("Network error: %1.").arg(reply->errorString()));
|
||||||
|
|
||||||
|
wizard()->enableButtons();
|
||||||
|
setEnabled(true);
|
||||||
|
|
||||||
|
reply->deleteLater();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->readSetsFromByteArray(reply->readAll());
|
||||||
|
reply->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadSetsPage::readSetsFromByteArray(QByteArray data)
|
||||||
|
{
|
||||||
|
// show an infinite progressbar
|
||||||
|
progressBar->setMaximum(0);
|
||||||
|
progressBar->setMinimum(0);
|
||||||
|
progressBar->setValue(0);
|
||||||
|
progressLabel->setText(tr("Parsing file"));
|
||||||
|
progressLabel->show();
|
||||||
|
progressBar->show();
|
||||||
|
|
||||||
|
// Start the computation.
|
||||||
|
future = QtConcurrent::run(wizard()->importer, &OracleImporter::readSetsFromByteArray, data);
|
||||||
|
watcher.setFuture(future);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoadSetsPage::importFinished()
|
||||||
|
{
|
||||||
|
if(watcher.future().result())
|
||||||
|
{
|
||||||
|
wizard()->enableButtons();
|
||||||
|
setEnabled(true);
|
||||||
|
progressLabel->hide();
|
||||||
|
progressBar->hide();
|
||||||
|
|
||||||
|
wizard()->next();
|
||||||
|
} else {
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("The file was retrieved successfully, but it does not contain any sets data."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ChooseSetsPage::ChooseSetsPage(QWidget *parent)
|
||||||
|
: OracleWizardPage(parent)
|
||||||
|
{
|
||||||
|
setTitle(tr("Sets selection"));
|
||||||
|
setSubTitle(tr("The following sets has been found in the source file. "
|
||||||
|
"Please mark the sets that will be imported."));
|
||||||
|
|
||||||
|
checkBoxLayout = new QVBoxLayout;
|
||||||
|
|
||||||
|
QWidget *checkboxFrame = new QWidget(this);
|
||||||
|
checkboxFrame->setLayout(checkBoxLayout);
|
||||||
|
|
||||||
|
QScrollArea *checkboxArea = new QScrollArea(this);
|
||||||
|
checkboxArea->setWidget(checkboxFrame);
|
||||||
|
checkboxArea->setWidgetResizable(true);
|
||||||
|
|
||||||
|
checkAllButton = new QPushButton(tr("&Check all"));
|
||||||
|
connect(checkAllButton, SIGNAL(clicked()), this, SLOT(actCheckAll()));
|
||||||
|
uncheckAllButton = new QPushButton(tr("&Uncheck all"));
|
||||||
|
connect(uncheckAllButton, SIGNAL(clicked()), this, SLOT(actUncheckAll()));
|
||||||
|
|
||||||
|
QGridLayout *layout = new QGridLayout(this);
|
||||||
|
layout->addWidget(checkboxArea, 0, 0, 1, 2);
|
||||||
|
layout->addWidget(checkAllButton, 1, 0);
|
||||||
|
layout->addWidget(uncheckAllButton, 1, 1);
|
||||||
|
|
||||||
|
setLayout(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChooseSetsPage::initializePage()
|
||||||
|
{
|
||||||
|
// populate checkbox list
|
||||||
|
for (int i = 0; i < checkBoxList.size(); ++i)
|
||||||
|
delete checkBoxList[i];
|
||||||
|
checkBoxList.clear();
|
||||||
|
|
||||||
|
QList<SetToDownload> &sets = wizard()->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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChooseSetsPage::checkBoxChanged(int state)
|
||||||
|
{
|
||||||
|
QCheckBox *checkBox = qobject_cast<QCheckBox *>(sender());
|
||||||
|
QList<SetToDownload> &sets = wizard()->importer->getSets();
|
||||||
|
for (int i = 0; i < sets.size(); ++i)
|
||||||
|
if (sets[i].getLongName() == checkBox->text()) {
|
||||||
|
sets[i].setImport(state);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChooseSetsPage::actCheckAll()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < checkBoxList.size(); ++i)
|
||||||
|
checkBoxList[i]->setChecked(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChooseSetsPage::actUncheckAll()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < checkBoxList.size(); ++i)
|
||||||
|
checkBoxList[i]->setChecked(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ChooseSetsPage::validatePage()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < checkBoxList.size(); ++i)
|
||||||
|
{
|
||||||
|
if(checkBoxList[i]->isChecked())
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("Please mark at least one set."));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SaveSetsPage::SaveSetsPage(QWidget *parent)
|
||||||
|
: OracleWizardPage(parent)
|
||||||
|
{
|
||||||
|
setTitle(tr("Sets imported"));
|
||||||
|
setSubTitle(tr("The following sets has been imported. "
|
||||||
|
"Press \"Done\" to save the imported cards to the Cockatrice database."));
|
||||||
|
|
||||||
|
// setPixmap(QWizard::LogoPixmap, QPixmap(":/images/logo3.png"));
|
||||||
|
|
||||||
|
messageLog = new QTextEdit(this);
|
||||||
|
messageLog->setReadOnly(true);
|
||||||
|
|
||||||
|
QGridLayout *layout = new QGridLayout(this);
|
||||||
|
layout->addWidget(messageLog, 0, 0);
|
||||||
|
|
||||||
|
setLayout(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SaveSetsPage::cleanupPage()
|
||||||
|
{
|
||||||
|
disconnect(wizard()->importer, SIGNAL(setIndexChanged(int, int, const QString &)), 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SaveSetsPage::initializePage()
|
||||||
|
{
|
||||||
|
messageLog->clear();
|
||||||
|
|
||||||
|
connect(wizard()->importer, SIGNAL(setIndexChanged(int, int, const QString &)), this, SLOT(updateTotalProgress(int, int, const QString &)));
|
||||||
|
|
||||||
|
if (!wizard()->importer->startImport())
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("No set has been imported."));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SaveSetsPage::updateTotalProgress(int cardsImported, int setIndex, const QString &setName)
|
||||||
|
{
|
||||||
|
if (setName.isEmpty()) {
|
||||||
|
messageLog->append("<b>" + tr("Import finished: %1 cards.").arg(wizard()->importer->getCardList().size()) + "</b>");
|
||||||
|
} else {
|
||||||
|
messageLog->append(tr("%1: %2 cards imported").arg(setName).arg(cardsImported));
|
||||||
|
}
|
||||||
|
messageLog->verticalScrollBar()->setValue(messageLog->verticalScrollBar()->maximum());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SaveSetsPage::validatePage()
|
||||||
|
{
|
||||||
|
bool ok = false;
|
||||||
|
const QString dataDir = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
|
||||||
|
QDir dir(dataDir);
|
||||||
|
if (!dir.exists())
|
||||||
|
dir.mkpath(dataDir);
|
||||||
|
QString savePath = dataDir + "/cards.xml";
|
||||||
|
do {
|
||||||
|
QString fileName;
|
||||||
|
if (savePath.isEmpty())
|
||||||
|
fileName = QFileDialog::getSaveFileName(this, tr("Save card database"), dataDir + "/cards.xml", tr("XML card database (*.xml)"));
|
||||||
|
else {
|
||||||
|
fileName = savePath;
|
||||||
|
savePath.clear();
|
||||||
|
}
|
||||||
|
if (fileName.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (wizard()->importer->saveToFile(fileName))
|
||||||
|
ok = true;
|
||||||
|
else
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("The file could not be saved to the desired location."));
|
||||||
|
} while (!ok);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
111
oracle/src/oraclewizard.h
Normal file
111
oracle/src/oraclewizard.h
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
#ifndef ORACLEWIZARD_H
|
||||||
|
#define ORACLEWIZARD_H
|
||||||
|
|
||||||
|
#include <QWizard>
|
||||||
|
#include <QFutureWatcher>
|
||||||
|
#include <QFuture>
|
||||||
|
|
||||||
|
class QCheckBox;
|
||||||
|
class QGroupBox;
|
||||||
|
class QLabel;
|
||||||
|
class QLineEdit;
|
||||||
|
class QRadioButton;
|
||||||
|
class QProgressBar;
|
||||||
|
class QNetworkAccessManager;
|
||||||
|
class QTextEdit;
|
||||||
|
class QVBoxLayout;
|
||||||
|
class OracleImporter;
|
||||||
|
|
||||||
|
class OracleWizard : public QWizard
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
OracleWizard(QWidget *parent = 0);
|
||||||
|
void accept();
|
||||||
|
void enableButtons();
|
||||||
|
void disableButtons();
|
||||||
|
public:
|
||||||
|
OracleImporter *importer;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class OracleWizardPage : public QWizardPage
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
OracleWizardPage(QWidget *parent = 0): QWizardPage(parent) {};
|
||||||
|
protected:
|
||||||
|
inline OracleWizard *wizard() { return (OracleWizard*) QWizardPage::wizard(); };
|
||||||
|
};
|
||||||
|
|
||||||
|
class IntroPage : public OracleWizardPage
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
IntroPage(QWidget *parent = 0);
|
||||||
|
private:
|
||||||
|
QLabel *label;
|
||||||
|
};
|
||||||
|
|
||||||
|
class LoadSetsPage : public OracleWizardPage
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
LoadSetsPage(QWidget *parent = 0);
|
||||||
|
protected:
|
||||||
|
void initializePage();
|
||||||
|
bool validatePage();
|
||||||
|
void readSetsFromByteArray(QByteArray data);
|
||||||
|
private:
|
||||||
|
QRadioButton *urlRadioButton;
|
||||||
|
QRadioButton *fileRadioButton;
|
||||||
|
QLineEdit *urlLineEdit;
|
||||||
|
QLineEdit *fileLineEdit;
|
||||||
|
QPushButton *fileButton;
|
||||||
|
QLabel *progressLabel;
|
||||||
|
QProgressBar * progressBar;
|
||||||
|
|
||||||
|
QNetworkAccessManager *nam;
|
||||||
|
QFutureWatcher<bool> watcher;
|
||||||
|
QFuture<bool> future;
|
||||||
|
private slots:
|
||||||
|
void actLoadSetsFile();
|
||||||
|
void actDownloadProgressSetsFile(qint64 received, qint64 total);
|
||||||
|
void actDownloadFinishedSetsFile();
|
||||||
|
void importFinished();
|
||||||
|
};
|
||||||
|
|
||||||
|
class ChooseSetsPage : public OracleWizardPage
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ChooseSetsPage(QWidget *parent = 0);
|
||||||
|
protected:
|
||||||
|
void initializePage();
|
||||||
|
bool validatePage();
|
||||||
|
private:
|
||||||
|
QPushButton *checkAllButton, *uncheckAllButton;
|
||||||
|
QVBoxLayout *checkBoxLayout;
|
||||||
|
QList<QCheckBox *> checkBoxList;
|
||||||
|
private slots:
|
||||||
|
void actCheckAll();
|
||||||
|
void actUncheckAll();
|
||||||
|
void checkBoxChanged(int state);
|
||||||
|
};
|
||||||
|
|
||||||
|
class SaveSetsPage : public OracleWizardPage
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
SaveSetsPage(QWidget *parent = 0);
|
||||||
|
private:
|
||||||
|
QTextEdit *messageLog;
|
||||||
|
protected:
|
||||||
|
void initializePage();
|
||||||
|
void cleanupPage();
|
||||||
|
bool validatePage();
|
||||||
|
private slots:
|
||||||
|
void updateTotalProgress(int cardsImported, int setIndex, const QString &setName);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,248 +0,0 @@
|
||||||
#include <QApplication>
|
|
||||||
#include <QMenu>
|
|
||||||
#include <QMenuBar>
|
|
||||||
#include <QStatusBar>
|
|
||||||
#include <QLineEdit>
|
|
||||||
#include <QFileDialog>
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QScrollArea>
|
|
||||||
#include <QTextEdit>
|
|
||||||
#include <QInputDialog>
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QPushButton>
|
|
||||||
#include <QCheckBox>
|
|
||||||
#include <QProgressBar>
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
#include <QDesktopServices>
|
|
||||||
#include <QNetworkAccessManager>
|
|
||||||
#include <QNetworkReply>
|
|
||||||
#include "window_main.h"
|
|
||||||
#include "oracleimporter.h"
|
|
||||||
|
|
||||||
const QString WindowMain::defaultSetsUrl = QString("http://mtgjson.com/json/AllSets.json");
|
|
||||||
|
|
||||||
WindowMain::WindowMain(QWidget *parent)
|
|
||||||
: QMainWindow(parent)
|
|
||||||
{
|
|
||||||
importer = new OracleImporter(QDesktopServices::storageLocation(QDesktopServices::DataLocation), this);
|
|
||||||
nam = new QNetworkAccessManager(this);
|
|
||||||
|
|
||||||
checkBoxLayout = new QVBoxLayout;
|
|
||||||
|
|
||||||
QWidget *checkboxFrame = new QWidget;
|
|
||||||
checkboxFrame->setLayout(checkBoxLayout);
|
|
||||||
|
|
||||||
QScrollArea *checkboxArea = new QScrollArea;
|
|
||||||
checkboxArea->setWidget(checkboxFrame);
|
|
||||||
checkboxArea->setWidgetResizable(true);
|
|
||||||
|
|
||||||
checkAllButton = new QPushButton(tr("&Check all"));
|
|
||||||
connect(checkAllButton, SIGNAL(clicked()), this, SLOT(actCheckAll()));
|
|
||||||
uncheckAllButton = new QPushButton(tr("&Uncheck all"));
|
|
||||||
connect(uncheckAllButton, SIGNAL(clicked()), this, SLOT(actUncheckAll()));
|
|
||||||
|
|
||||||
QHBoxLayout *checkAllButtonLayout = new QHBoxLayout;
|
|
||||||
checkAllButtonLayout->addWidget(checkAllButton);
|
|
||||||
checkAllButtonLayout->addWidget(uncheckAllButton);
|
|
||||||
|
|
||||||
startButton = new QPushButton(tr("&Start import"));
|
|
||||||
connect(startButton, SIGNAL(clicked()), this, SLOT(actStart()));
|
|
||||||
|
|
||||||
QVBoxLayout *settingsLayout = new QVBoxLayout;
|
|
||||||
settingsLayout->addWidget(checkboxArea);
|
|
||||||
settingsLayout->addLayout(checkAllButtonLayout);
|
|
||||||
settingsLayout->addWidget(startButton);
|
|
||||||
|
|
||||||
totalLabel = new QLabel(tr("Total progress:"));
|
|
||||||
totalProgressBar = new QProgressBar;
|
|
||||||
nextSetLabel1 = new QLabel(tr("Current file:"));
|
|
||||||
nextSetLabel2 = new QLabel;
|
|
||||||
fileLabel = new QLabel(tr("Progress:"));
|
|
||||||
fileProgressBar = new QProgressBar;
|
|
||||||
|
|
||||||
messageLog = new QTextEdit;
|
|
||||||
messageLog->setReadOnly(true);
|
|
||||||
|
|
||||||
QGridLayout *grid = new QGridLayout;
|
|
||||||
grid->addWidget(totalLabel, 0, 0);
|
|
||||||
grid->addWidget(totalProgressBar, 0, 1);
|
|
||||||
grid->addWidget(nextSetLabel1, 1, 0);
|
|
||||||
grid->addWidget(nextSetLabel2, 1, 1);
|
|
||||||
grid->addWidget(fileLabel, 2, 0);
|
|
||||||
grid->addWidget(fileProgressBar, 2, 1);
|
|
||||||
grid->addWidget(messageLog, 3, 0, 1, 2);
|
|
||||||
|
|
||||||
QHBoxLayout *mainLayout = new QHBoxLayout;
|
|
||||||
mainLayout->addLayout(settingsLayout, 6);
|
|
||||||
mainLayout->addSpacing(10);
|
|
||||||
mainLayout->addLayout(grid, 10);
|
|
||||||
|
|
||||||
QWidget *centralWidget = new QWidget;
|
|
||||||
centralWidget->setLayout(mainLayout);
|
|
||||||
setCentralWidget(centralWidget);
|
|
||||||
|
|
||||||
connect(importer, SIGNAL(setIndexChanged(int, int, const QString &)), this, SLOT(updateTotalProgress(int, int, const QString &)));
|
|
||||||
connect(importer, SIGNAL(dataReadProgress(int, int)), this, SLOT(updateFileProgress(int, int)));
|
|
||||||
|
|
||||||
aLoadSetsFile = new QAction(tr("Load sets information from &file..."), this);
|
|
||||||
connect(aLoadSetsFile, SIGNAL(triggered()), this, SLOT(actLoadSetsFile()));
|
|
||||||
aDownloadSetsFile = new QAction(tr("&Download sets information..."), this);
|
|
||||||
connect(aDownloadSetsFile, SIGNAL(triggered()), this, SLOT(actDownloadSetsFile()));
|
|
||||||
aExit = new QAction(tr("E&xit"), this);
|
|
||||||
connect(aExit, SIGNAL(triggered()), this, SLOT(close()));
|
|
||||||
|
|
||||||
fileMenu = menuBar()->addMenu(tr("&File"));
|
|
||||||
fileMenu->addAction(aLoadSetsFile);
|
|
||||||
fileMenu->addAction(aDownloadSetsFile);
|
|
||||||
fileMenu->addSeparator();
|
|
||||||
fileMenu->addAction(aExit);
|
|
||||||
|
|
||||||
setWindowTitle(tr("Oracle importer"));
|
|
||||||
setMinimumSize(750, 500);
|
|
||||||
|
|
||||||
QStringList args = qApp->arguments();
|
|
||||||
if (args.contains("-dlsets"))
|
|
||||||
downloadSetsFile(defaultSetsUrl);
|
|
||||||
|
|
||||||
statusLabel = new QLabel;
|
|
||||||
statusBar()->addWidget(statusLabel);
|
|
||||||
statusLabel->setText(tr("Sets data not loaded."));
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowMain::updateSetList()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < checkBoxList.size(); ++i)
|
|
||||||
delete checkBoxList[i];
|
|
||||||
checkBoxList.clear();
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
statusLabel->setText(tr("Ready."));
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowMain::actLoadSetsFile()
|
|
||||||
{
|
|
||||||
QFileDialog dialog(this, tr("Load sets file"));
|
|
||||||
dialog.setFileMode(QFileDialog::ExistingFile);
|
|
||||||
dialog.setNameFilter("Sets JSON file (*.json)");
|
|
||||||
if (!dialog.exec())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QString fileName = dialog.selectedFiles().at(0);
|
|
||||||
if (importer->readSetsFromFile(fileName))
|
|
||||||
updateSetList();
|
|
||||||
else
|
|
||||||
QMessageBox::critical(this, tr("Error"), tr("This file does not contain any sets data."));
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowMain::actDownloadSetsFile()
|
|
||||||
{
|
|
||||||
QString url = QInputDialog::getText(this, tr("Load sets from URL"), tr("Please enter the URL of the sets file:"), QLineEdit::Normal, defaultSetsUrl);
|
|
||||||
if (!url.isEmpty())
|
|
||||||
downloadSetsFile(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowMain::downloadSetsFile(const QString &url)
|
|
||||||
{
|
|
||||||
QNetworkReply *reply = nam->get(QNetworkRequest(url));
|
|
||||||
connect(reply, SIGNAL(finished()), this, SLOT(setsDownloadFinished()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowMain::setsDownloadFinished()
|
|
||||||
{
|
|
||||||
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
|
|
||||||
QNetworkReply::NetworkError errorCode = reply->error();
|
|
||||||
if (errorCode == QNetworkReply::NoError) {
|
|
||||||
if (importer->readSetsFromByteArray(reply->readAll()))
|
|
||||||
updateSetList();
|
|
||||||
else
|
|
||||||
QMessageBox::critical(this, tr("Error"), tr("The file was retrieved successfully, but it does not contain any sets data."));
|
|
||||||
} else
|
|
||||||
QMessageBox::critical(this, tr("Error"), tr("Network error: %1.").arg(reply->errorString()));
|
|
||||||
reply->deleteLater();
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowMain::updateTotalProgress(int cardsImported, int setIndex, const QString &nextSetName)
|
|
||||||
{
|
|
||||||
if (setIndex != 0)
|
|
||||||
messageLog->append(QString("%1: %2 cards imported").arg(nextSetLabel2->text()).arg(cardsImported));
|
|
||||||
totalProgressBar->setValue(setIndex);
|
|
||||||
if (nextSetName.isEmpty()) {
|
|
||||||
QMessageBox::information(this, tr("Oracle importer"), tr("Import finished: %1 cards.").arg(importer->getCardList().size()));
|
|
||||||
bool ok = false;
|
|
||||||
const QString dataDir = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
|
|
||||||
QDir dir(dataDir);
|
|
||||||
if (!dir.exists())
|
|
||||||
dir.mkpath(dataDir);
|
|
||||||
QString savePath = dataDir + "/cards.xml";
|
|
||||||
do {
|
|
||||||
QString fileName;
|
|
||||||
if (savePath.isEmpty())
|
|
||||||
fileName = QFileDialog::getSaveFileName(this, tr("Save card database"), dataDir + "/cards.xml", tr("XML card database (*.xml)"));
|
|
||||||
else {
|
|
||||||
fileName = savePath;
|
|
||||||
savePath.clear();
|
|
||||||
}
|
|
||||||
if (fileName.isEmpty()) {
|
|
||||||
qApp->quit();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (importer->saveToFile(fileName))
|
|
||||||
ok = true;
|
|
||||||
else
|
|
||||||
QMessageBox::critical(this, tr("Error"), tr("The file could not be saved to the desired location."));
|
|
||||||
} while (!ok);
|
|
||||||
qApp->quit();
|
|
||||||
} else {
|
|
||||||
nextSetLabel2->setText(nextSetName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowMain::updateFileProgress(int bytesRead, int totalBytes)
|
|
||||||
{
|
|
||||||
fileProgressBar->setMaximum(totalBytes);
|
|
||||||
fileProgressBar->setValue(bytesRead);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowMain::actCheckAll()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < checkBoxList.size(); ++i)
|
|
||||||
checkBoxList[i]->setChecked(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowMain::actUncheckAll()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < checkBoxList.size(); ++i)
|
|
||||||
checkBoxList[i]->setChecked(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowMain::actStart()
|
|
||||||
{
|
|
||||||
int setsCount = importer->startImport();
|
|
||||||
if (!setsCount) {
|
|
||||||
QMessageBox::critical(this, tr("Error"), tr("No sets to download selected."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < checkBoxList.size(); ++i)
|
|
||||||
checkBoxList[i]->setEnabled(false);
|
|
||||||
startButton->setEnabled(false);
|
|
||||||
totalProgressBar->setMaximum(setsCount);
|
|
||||||
statusLabel->setText(tr("Downloading card data..."));
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
#ifndef WINDOW_MAIN_H
|
|
||||||
#define WINDOW_MAIN_H
|
|
||||||
|
|
||||||
#include <QMainWindow>
|
|
||||||
#include <QList>
|
|
||||||
|
|
||||||
class OracleImporter;
|
|
||||||
class QLabel;
|
|
||||||
class QProgressBar;
|
|
||||||
class QTextEdit;
|
|
||||||
class QPushButton;
|
|
||||||
class QCheckBox;
|
|
||||||
class QVBoxLayout;
|
|
||||||
class QMenu;
|
|
||||||
class QAction;
|
|
||||||
class QNetworkAccessManager;
|
|
||||||
|
|
||||||
class WindowMain : public QMainWindow {
|
|
||||||
Q_OBJECT
|
|
||||||
private:
|
|
||||||
static const QString defaultSetsUrl;
|
|
||||||
|
|
||||||
OracleImporter *importer;
|
|
||||||
QNetworkAccessManager *nam;
|
|
||||||
|
|
||||||
QMenu *fileMenu;
|
|
||||||
QAction *aLoadSetsFile, *aDownloadSetsFile, *aExit;
|
|
||||||
QPushButton *checkAllButton, *uncheckAllButton, *startButton;
|
|
||||||
QLabel *totalLabel, *fileLabel, *nextSetLabel1, *nextSetLabel2;
|
|
||||||
QProgressBar *totalProgressBar, *fileProgressBar;
|
|
||||||
QTextEdit *messageLog;
|
|
||||||
QVBoxLayout *checkBoxLayout;
|
|
||||||
QList<QCheckBox *> checkBoxList;
|
|
||||||
QLabel *statusLabel;
|
|
||||||
|
|
||||||
void downloadSetsFile(const QString &url);
|
|
||||||
private slots:
|
|
||||||
void updateTotalProgress(int cardsImported, int setIndex, const QString &nextSetName);
|
|
||||||
void updateFileProgress(int bytesRead, int totalBytes);
|
|
||||||
void updateSetList();
|
|
||||||
void actCheckAll();
|
|
||||||
void actUncheckAll();
|
|
||||||
void actStart();
|
|
||||||
void actLoadSetsFile();
|
|
||||||
void actDownloadSetsFile();
|
|
||||||
void setsDownloadFinished();
|
|
||||||
void checkBoxChanged(int state);
|
|
||||||
public:
|
|
||||||
WindowMain(QWidget *parent = 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
Loading…
Reference in a new issue