diff --git a/cockatrice/cockatrice.pro b/cockatrice/cockatrice.pro index 6348efed..6faeeff7 100644 --- a/cockatrice/cockatrice.pro +++ b/cockatrice/cockatrice.pro @@ -112,4 +112,10 @@ SOURCES += src/counter.cpp \ ../common/protocol_datastructures.cpp TRANSLATIONS += translations/cockatrice_de.ts translations/cockatrice_en.ts -CONFIG += qt debug +win32 { + RC_FILE = cockatrice.rc +} +macx { + ICON = resources/appicon.icns + CONFIG += x86 ppc +} diff --git a/cockatrice/cockatrice.qrc b/cockatrice/cockatrice.qrc index 052b8289..38910b7e 100644 --- a/cockatrice/cockatrice.qrc +++ b/cockatrice/cockatrice.qrc @@ -24,7 +24,7 @@ resources/hr.jpg translations/cockatrice_de.qm translations/cockatrice_en.qm - resources/icon.svg + resources/appicon.svg resources/add_to_sideboard.svg resources/decrement.svg resources/increment.svg diff --git a/cockatrice/cockatrice.rc b/cockatrice/cockatrice.rc new file mode 100644 index 00000000..d7108130 --- /dev/null +++ b/cockatrice/cockatrice.rc @@ -0,0 +1 @@ +ID1_ICON1 ICON DISCARDABLE "resources/appicon.ico" diff --git a/cockatrice/resources/appicon.icns b/cockatrice/resources/appicon.icns new file mode 100644 index 00000000..4bd00ffc Binary files /dev/null and b/cockatrice/resources/appicon.icns differ diff --git a/cockatrice/resources/appicon.ico b/cockatrice/resources/appicon.ico new file mode 100644 index 00000000..9a4885f4 Binary files /dev/null and b/cockatrice/resources/appicon.ico differ diff --git a/cockatrice/resources/icon.svg b/cockatrice/resources/appicon.svg similarity index 100% rename from cockatrice/resources/icon.svg rename to cockatrice/resources/appicon.svg diff --git a/cockatrice/resources/icon_phase_combat_blockers.svg b/cockatrice/resources/icon_phase_combat_blockers.svg index 0d10be6f..6344ef6b 100644 --- a/cockatrice/resources/icon_phase_combat_blockers.svg +++ b/cockatrice/resources/icon_phase_combat_blockers.svg @@ -1,5 +1,6 @@ + + enable-background="new" + version="1.1"> + + + + - - - + + + inkscape:window-x="51" + inkscape:window-y="25" + inkscape:window-maximized="0" /> @@ -157,13 +173,9 @@ id="rect2577" sodipodi:nodetypes="ccscsc" /> - diff --git a/cockatrice/resources/icon_phase_combat_end.svg b/cockatrice/resources/icon_phase_combat_end.svg index 59cc8bde..9e7b8950 100644 --- a/cockatrice/resources/icon_phase_combat_end.svg +++ b/cockatrice/resources/icon_phase_combat_end.svg @@ -1,5 +1,6 @@ + + enable-background="new" + version="1.1"> + + + + - - - + + inkscape:window-x="51" + inkscape:window-y="25" + inkscape:window-maximized="0" /> @@ -217,24 +226,16 @@ inkscape:label="Layer 1" inkscape:groupmode="layer" style="display:inline;"> - - - - - + + diff --git a/cockatrice/resources/icon_phase_combat_start.svg b/cockatrice/resources/icon_phase_combat_start.svg index 3de8c3cf..996571d7 100644 --- a/cockatrice/resources/icon_phase_combat_start.svg +++ b/cockatrice/resources/icon_phase_combat_start.svg @@ -1,5 +1,6 @@ + + enable-background="new" + version="1.1"> + + + + - - - + + inkscape:window-x="51" + inkscape:window-y="25" + inkscape:window-maximized="0" /> @@ -223,14 +232,10 @@ id="rect2577" sodipodi:nodetypes="ccscsc" /> - diff --git a/cockatrice/src/carddatabase.cpp b/cockatrice/src/carddatabase.cpp index 8a2065bb..4d162883 100644 --- a/cockatrice/src/carddatabase.cpp +++ b/cockatrice/src/carddatabase.cpp @@ -232,7 +232,7 @@ QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfo *info) } CardDatabase::CardDatabase(QObject *parent) - : QObject(parent), noCard(0) + : QObject(parent), downloadRunning(false), loadSuccess(false), noCard(0) { connect(settingsCache, SIGNAL(picsPathChanged()), this, SLOT(clearPixmapCache())); connect(settingsCache, SIGNAL(cardDatabasePathChanged()), this, SLOT(loadCardDatabase())); @@ -331,22 +331,20 @@ void CardDatabase::startPicDownload(CardInfo *card) void CardDatabase::startNextPicDownload() { if (cardsToDownload.isEmpty()) { + cardBeingDownloaded = 0; downloadRunning = false; return; } downloadRunning = true; - CardInfo *card = cardsToDownload.takeFirst(); - QNetworkRequest req(QUrl(card->getPicURL())); - req.setOriginatingObject(card); + cardBeingDownloaded = cardsToDownload.takeFirst(); + QNetworkRequest req(QUrl(cardBeingDownloaded->getPicURL())); networkManager->get(req); } void CardDatabase::picDownloadFinished(QNetworkReply *reply) { - CardInfo *card = static_cast(reply->request().originatingObject()); - QString picsPath = settingsCache->getPicsPath(); const QByteArray &picData = reply->readAll(); QPixmap testPixmap; @@ -357,13 +355,13 @@ void CardDatabase::picDownloadFinished(QNetworkReply *reply) return; dir.mkdir("downloadedPics"); } - QFile newPic(picsPath + "/downloadedPics/" + card->getCorrectedName() + ".full.jpg"); + QFile newPic(picsPath + "/downloadedPics/" + cardBeingDownloaded->getCorrectedName() + ".full.jpg"); if (!newPic.open(QIODevice::WriteOnly)) return; newPic.write(picData); newPic.close(); - card->updatePixmapCache(); + cardBeingDownloaded->updatePixmapCache(); } reply->deleteLater(); @@ -430,12 +428,12 @@ void CardDatabase::loadCardsFromXml(QXmlStreamReader &xml) } } -int CardDatabase::loadFromFile(const QString &fileName) +bool CardDatabase::loadFromFile(const QString &fileName) { QFile file(fileName); file.open(QIODevice::ReadOnly); if (!file.isOpen()) - return -1; + return false; QXmlStreamReader xml(&file); clear(); while (!xml.atEnd()) { @@ -453,7 +451,7 @@ int CardDatabase::loadFromFile(const QString &fileName) } } qDebug(QString("%1 cards in %2 sets loaded").arg(cardHash.size()).arg(setHash.size()).toLatin1()); - return cardHash.size(); + return true; } bool CardDatabase::saveToFile(const QString &fileName) @@ -494,11 +492,13 @@ void CardDatabase::picDownloadChanged() } } -void CardDatabase::loadCardDatabase() +bool CardDatabase::loadCardDatabase() { QString cardDatabasePath = settingsCache->getCardDatabasePath(); if (!cardDatabasePath.isEmpty()) - loadFromFile(cardDatabasePath); + loadSuccess = loadFromFile(cardDatabasePath); + else loadSuccess = false; + return loadSuccess; } QStringList CardDatabase::getAllColors() const diff --git a/cockatrice/src/carddatabase.h b/cockatrice/src/carddatabase.h index a544b7e4..65fa44cd 100644 --- a/cockatrice/src/carddatabase.h +++ b/cockatrice/src/carddatabase.h @@ -7,6 +7,7 @@ #include #include #include +#include class CardDatabase; class CardInfo; @@ -96,7 +97,9 @@ protected: QHash setHash; QNetworkAccessManager *networkManager; QList cardsToDownload; + CardInfo *cardBeingDownloaded; bool downloadRunning; + bool loadSuccess; CardInfo *noCard; private: void loadCardsFromXml(QXmlStreamReader &xml); @@ -110,16 +113,17 @@ public: CardSet *getSet(const QString &setName); QList getCardList() const { return cardHash.values(); } SetList getSetList() const; - int loadFromFile(const QString &fileName); + bool loadFromFile(const QString &fileName); bool saveToFile(const QString &fileName); void startPicDownload(CardInfo *card); QStringList getAllColors() const; QStringList getAllMainCardTypes() const; + bool getLoadSuccess() const { return loadSuccess; } public slots: void clearPixmapCache(); private slots: void picDownloadFinished(QNetworkReply *reply); - void loadCardDatabase(); + bool loadCardDatabase(); void picDownloadChanged(); }; diff --git a/cockatrice/src/dlg_settings.cpp b/cockatrice/src/dlg_settings.cpp index 638c1141..4e99921c 100644 --- a/cockatrice/src/dlg_settings.cpp +++ b/cockatrice/src/dlg_settings.cpp @@ -454,6 +454,21 @@ void DlgSettings::changeEvent(QEvent *event) QDialog::changeEvent(event); } +void DlgSettings::closeEvent(QCloseEvent *event) +{ + if (!db->getLoadSuccess()) { + QMessageBox::critical(this, tr("Error"), tr("Your card database is invalid. Please check if the path is set correctly.")); + event->ignore(); + } else if (!QDir(settingsCache->getDeckPath()).exists()) { + QMessageBox::critical(this, tr("Error"), tr("The path to your deck directory is invalid.")); + event->ignore(); + } else if (!QDir(settingsCache->getPicsPath()).exists()) { + QMessageBox::critical(this, tr("Error"), tr("The path to your card pictures directory is invalid.")); + event->ignore(); + } else + event->accept(); +} + void DlgSettings::retranslateUi() { setWindowTitle(tr("Settings")); diff --git a/cockatrice/src/dlg_settings.h b/cockatrice/src/dlg_settings.h index 6d17f065..ae06b9e2 100644 --- a/cockatrice/src/dlg_settings.h +++ b/cockatrice/src/dlg_settings.h @@ -13,6 +13,7 @@ class QComboBox; class QGroupBox; class QCheckBox; class QLabel; +class QCloseEvent; class AbstractSettingsPage : public QWidget { public: @@ -107,6 +108,7 @@ private: void retranslateUi(); protected: void changeEvent(QEvent *event); + void closeEvent(QCloseEvent *event); }; #endif diff --git a/cockatrice/src/main.cpp b/cockatrice/src/main.cpp index 1c3c43e9..2cb0e3f1 100644 --- a/cockatrice/src/main.cpp +++ b/cockatrice/src/main.cpp @@ -26,10 +26,12 @@ #include #include #include +#include #include #include "main.h" #include "window_main.h" +#include "dlg_settings.h" #include "carddatabase.h" #include "settingscache.h" #include "pingpixmapgenerator.h" @@ -80,20 +82,30 @@ int main(int argc, char *argv[]) qsrand(QDateTime::currentDateTime().toTime_t()); - MainWindow ui; - qDebug("main(): MainWindow constructor finished"); + bool startMainProgram = true; + if (!db->getLoadSuccess() || !QDir(settingsCache->getDeckPath()).exists() || !QDir(settingsCache->getPicsPath()).exists()) { + DlgSettings dlgSettings; + dlgSettings.show(); + app.exec(); + startMainProgram = (db->getLoadSuccess() && QDir(settingsCache->getDeckPath()).exists() && QDir(settingsCache->getPicsPath()).exists()); + } - QIcon icon(":/resources/icon.svg"); - ui.setWindowIcon(icon); - - ui.show(); - qDebug("main(): ui.show() finished"); - - int retval = app.exec(); + if (startMainProgram) { + MainWindow ui; + qDebug("main(): MainWindow constructor finished"); + + QIcon icon(":/resources/appicon.svg"); + ui.setWindowIcon(icon); + + ui.show(); + qDebug("main(): ui.show() finished"); + + app.exec(); + } delete pingPixmapGenerator; delete db; delete settingsCache; - return retval; + return 0; } diff --git a/cockatrice/translations/cockatrice_de.ts b/cockatrice/translations/cockatrice_de.ts index 244bba3c..020549b4 100644 --- a/cockatrice/translations/cockatrice_de.ts +++ b/cockatrice/translations/cockatrice_de.ts @@ -564,32 +564,54 @@ DlgSettings - + + + + Error + Fehler + + + + Your card database is invalid. Please check if the path is set correctly. + Ihre Kartendatenbank ist ungültig. Bitte überprüfen Sie, ob der Pfad korrekt gesetzt ist. + + + + The path to your deck directory is invalid. + Der Pfad zum Deckverzeichnis ist ungültig. + + + + The path to your card pictures directory is invalid. + Der Pfad zum Kartenbilderverzeichnis ist ungültig. + + + Settings Einstellungen - + General Allgemeines - + Appearance Erscheinungsbild - + User interface Bedienung - + Messages Nachrichten - + &Close S&chließen @@ -2237,17 +2259,17 @@ Deck - + no deck kein Deck - + local deck lokales Deck - + ID #%1 ID #%1 @@ -2770,17 +2792,17 @@ Willst du die Änderungen speichern? alphabetisch sortieren - + sort by name nach Namen sortieren - + sort by type nach Kartentypen sortieren - + shuffle when closing beim Schließen mischen diff --git a/cockatrice/translations/cockatrice_en.ts b/cockatrice/translations/cockatrice_en.ts index de83275a..c0b2a4a3 100644 --- a/cockatrice/translations/cockatrice_en.ts +++ b/cockatrice/translations/cockatrice_en.ts @@ -453,32 +453,54 @@ DlgSettings - - Settings + + + + Error - - General - - - - - Appearance + + Your card database is invalid. Please check if the path is set correctly. - User interface - - - - - Messages + The path to your deck directory is invalid. + The path to your card pictures directory is invalid. + + + + + Settings + + + + + General + + + + + Appearance + + + + + User interface + + + + + Messages + + + + &Close @@ -1516,17 +1538,17 @@ - + no deck - + local deck - + ID #%1 @@ -1992,17 +2014,17 @@ Do you want to save the changes? ZoneViewWidget - + sort by name - + sort by type - + shuffle when closing diff --git a/nsis/cockatrice.nsi b/nsis/cockatrice.nsi new file mode 100644 index 00000000..1518f993 --- /dev/null +++ b/nsis/cockatrice.nsi @@ -0,0 +1,68 @@ +!include "MUI2.nsh" + +Name "Cockatrice" +OutFile "cockatrice_win32.exe" +SetCompressor lzma +InstallDir "$PROGRAMFILES\Cockatrice" + +!define MUI_ABORTWARNING +!define MUI_WELCOMEFINISHPAGE_BITMAP "leftimage.bmp" +!define MUI_HEADERIMAGE +!define MUI_HEADERIMAGE_BITMAP "headerimage.bmp" +!define MUI_WELCOMEPAGE_TEXT "This wizard will guide you through the installation of Cockatrice.$\r$\n$\r$\nClick Next to continue." +!define MUI_FINISHPAGE_RUN "$INSTDIR/oracle.exe" +!define MUI_FINISHPAGE_RUN_TEXT "Run card database downloader now" +!define MUI_FINISHPAGE_RUN_PARAMETERS "-dlsets" + +!insertmacro MUI_PAGE_WELCOME +!insertmacro MUI_PAGE_COMPONENTS +!insertmacro MUI_PAGE_DIRECTORY +!insertmacro MUI_PAGE_INSTFILES +!insertmacro MUI_PAGE_FINISH + +!insertmacro MUI_LANGUAGE "English" + +Section "Application" SecApplication + SetOutPath "$INSTDIR" + File ..\cockatrice\release\cockatrice.exe + File ..\oracle\release\oracle.exe + File data\libgcc_s_dw2-1.dll + File data\mingwm10.dll + File data\QtCore4.dll + File data\QtGui4.dll + File data\QtNetwork4.dll + File data\QtSvg4.dll + File data\QtXml4.dll + + SetOutPath "$INSTDIR\zonebg" + File /r ..\zonebg\*.* + + SetOutPath "$INSTDIR\plugins" + File /r data\plugins\*.* + + SetOutPath "$INSTDIR\pics" + SetOutPath "$INSTDIR\decks" + +SectionEnd + +Section "Update configuration" SecUpdateConfig + WriteRegStr HKCU "Software\Cockatrice\Cockatrice\paths" "carddatabase" "$INSTDIR\cards.xml" + WriteRegStr HKCU "Software\Cockatrice\Cockatrice\paths" "decks" "$INSTDIR\decks" + WriteRegStr HKCU "Software\Cockatrice\Cockatrice\paths" "pics" "$INSTDIR\pics" +SectionEnd + +Section "Start menu item" SecStartMenu + createDirectory "$SMPROGRAMS\Cockatrice" + createShortCut "$SMPROGRAMS\Cockatrice\Cockatrice.lnk" "$INSTDIR\cockatrice.exe" + createShortCut "$SMPROGRAMS\Cockatrice\Oracle.lnk" "$INSTDIR\oracle.exe" +SectionEnd + +LangString DESC_SecApplication ${LANG_ENGLISH} "Cockatrice program files" +LangString DESC_SecUpdateConfig ${LANG_ENGLISH} "Update the paths in the application settings according to the installation paths." +LangString DESC_SecStartMenu ${LANG_ENGLISH} "Create start menu items for Cockatrice and Oracle." +!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN + !insertmacro MUI_DESCRIPTION_TEXT ${SecApplication} $(DESC_SecApplication) + !insertmacro MUI_DESCRIPTION_TEXT ${SecUpdateConfig} $(DESC_SecUpdateConfig) + !insertmacro MUI_DESCRIPTION_TEXT ${SecStartMenu} $(DESC_SecStartMenu) +!insertmacro MUI_FUNCTION_DESCRIPTION_END + diff --git a/nsis/headerimage.bmp b/nsis/headerimage.bmp new file mode 100644 index 00000000..73c88d6d Binary files /dev/null and b/nsis/headerimage.bmp differ diff --git a/nsis/leftimage.bmp b/nsis/leftimage.bmp new file mode 100644 index 00000000..e89fdd95 Binary files /dev/null and b/nsis/leftimage.bmp differ diff --git a/oracle/src/oracleimporter.cpp b/oracle/src/oracleimporter.cpp index 476b894c..63c025d5 100644 --- a/oracle/src/oracleimporter.cpp +++ b/oracle/src/oracleimporter.cpp @@ -7,7 +7,15 @@ OracleImporter::OracleImporter(const QString &_dataDir, QObject *parent) : CardDatabase(parent), dataDir(_dataDir), setIndex(-1) { - QString fileName = dataDir + "/sets.xml"; + buffer = new QBuffer(this); + http = new QHttp(this); + connect(http, SIGNAL(requestFinished(int, bool)), this, SLOT(httpRequestFinished(int, bool))); + connect(http, SIGNAL(responseHeaderReceived(const QHttpResponseHeader &)), this, SLOT(readResponseHeader(const QHttpResponseHeader &))); + connect(http, SIGNAL(dataReadProgress(int, int)), this, SIGNAL(dataReadProgress(int, int))); +} + +void 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)); @@ -15,6 +23,19 @@ OracleImporter::OracleImporter(const QString &_dataDir, QObject *parent) } QXmlStreamReader xml(&setsFile); + readSetsFromXml(xml); +} + +void OracleImporter::readSetsFromByteArray(const QByteArray &data) +{ + QXmlStreamReader xml(data); + readSetsFromXml(xml); +} + +void OracleImporter::readSetsFromXml(QXmlStreamReader &xml) +{ + allSets.clear(); + QString edition; QString editionLong; QString editionURL; @@ -34,19 +55,13 @@ OracleImporter::OracleImporter(const QString &_dataDir, QObject *parent) else if (xml.name() == "url") editionURL = xml.readElementText(); } - setsToDownload << SetToDownload(edition, editionLong, editionURL, import); + allSets << SetToDownload(edition, editionLong, editionURL, import); edition = editionLong = editionURL = QString(); } else if (xml.name() == "picture_url") pictureUrl = xml.readElementText(); else if (xml.name() == "set_url") setUrl = xml.readElementText(); } - - buffer = new QBuffer(this); - http = new QHttp(this); - connect(http, SIGNAL(requestFinished(int, bool)), this, SLOT(httpRequestFinished(int, bool))); - connect(http, SIGNAL(responseHeaderReceived(const QHttpResponseHeader &)), this, SLOT(readResponseHeader(const QHttpResponseHeader &))); - connect(http, SIGNAL(dataReadProgress(int, int)), this, SIGNAL(dataReadProgress(int, int))); } CardInfo *OracleImporter::addCard(QString cardName, const QString &cardCost, const QString &cardType, const QString &cardPT, const QStringList &cardText) @@ -188,19 +203,24 @@ QString OracleImporter::getURLFromName(QString name) const ); } +int OracleImporter::startDownload() +{ + setsToDownload.clear(); + for (int i = 0; i < allSets.size(); ++i) + if (allSets[i].getImport()) + setsToDownload.append(allSets[i]); + + if (setsToDownload.isEmpty()) + return 0; + setIndex = 0; + emit setIndexChanged(0, 0, setsToDownload[0].getLongName()); + + downloadNextFile(); + return setsToDownload.size(); +} + void OracleImporter::downloadNextFile() { - 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; - emit setIndexChanged(0, 0, setsToDownload[0].getLongName()); - } QString urlString = setsToDownload[setIndex].getUrl(); if (urlString.isEmpty()) urlString = setUrl; @@ -245,9 +265,9 @@ void OracleImporter::httpRequestFinished(int requestId, bool error) ++setIndex; if (setIndex == setsToDownload.size()) { - setIndex = -1; saveToFile(dataDir + "/cards.xml"); emit setIndexChanged(cards, setIndex, QString()); + setIndex = -1; } else { downloadNextFile(); emit setIndexChanged(cards, setIndex, setsToDownload[setIndex].getLongName()); diff --git a/oracle/src/oracleimporter.h b/oracle/src/oracleimporter.h index 897cfcef..59f620ef 100644 --- a/oracle/src/oracleimporter.h +++ b/oracle/src/oracleimporter.h @@ -5,6 +5,7 @@ #include class QBuffer; +class QXmlStreamReader; class SetToDownload { private: @@ -15,7 +16,7 @@ public: const QString &getLongName() const { return longName; } const QString &getUrl() const { return url; } bool getImport() const { return import; } - void setImport(bool _import) { qDebug(QString("%1: setting import to %2").arg(getShortName()).arg(_import).toUtf8()); import = _import; } + void setImport(bool _import) { import = _import; } SetToDownload(const QString &_shortName, const QString &_longName, const QString &_url, bool _import) : shortName(_shortName), longName(_longName), url(_url), import(_import) { } }; @@ -23,7 +24,7 @@ public: class OracleImporter : public CardDatabase { Q_OBJECT private: - QList setsToDownload; + QList allSets, setsToDownload; QString pictureUrl, setUrl; QString dataDir; int setIndex; @@ -32,6 +33,8 @@ private: QHttp *http; QString getURLFromName(QString name) const; + void downloadNextFile(); + void readSetsFromXml(QXmlStreamReader &xml); CardInfo *addCard(QString cardName, const QString &cardCost, const QString &cardType, const QString &cardPT, const QStringList &cardText); private slots: void httpRequestFinished(int requestId, bool error); @@ -41,10 +44,11 @@ signals: void dataReadProgress(int bytesRead, int totalBytes); public: OracleImporter(const QString &_dataDir, QObject *parent = 0); + void readSetsFromByteArray(const QByteArray &data); + void readSetsFromFile(const QString &fileName); + int startDownload(); int importTextSpoiler(CardSet *set, const QByteArray &data); - void downloadNextFile(); - int getSetsCount() const { return setsToDownload.size(); } - QList &getSets() { return setsToDownload; } + QList &getSets() { return allSets; } }; #endif diff --git a/oracle/src/window_main.cpp b/oracle/src/window_main.cpp index 79324c48..de792192 100644 --- a/oracle/src/window_main.cpp +++ b/oracle/src/window_main.cpp @@ -1,24 +1,21 @@ #include +#include +#include #include "window_main.h" #include "oracleimporter.h" +const QString WindowMain::defaultSetsUrl = QString("http://www.cockatrice.de/files/sets.xml"); + WindowMain::WindowMain(QWidget *parent) : QMainWindow(parent) { - importer = new OracleImporter(qApp->applicationDirPath() + "/../oracle", this); + importer = new OracleImporter(qApp->applicationDirPath(), this); + nam = new QNetworkAccessManager(this); - QVBoxLayout *checkboxLayout = new QVBoxLayout; - QList &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; - } + checkBoxLayout = new QVBoxLayout; QWidget *checkboxFrame = new QWidget; - checkboxFrame->setLayout(checkboxLayout); + checkboxFrame->setLayout(checkBoxLayout); QScrollArea *checkboxArea = new QScrollArea; checkboxArea->setWidget(checkboxFrame); @@ -61,10 +58,76 @@ WindowMain::WindowMain(QWidget *parent) 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))); - totalProgressBar->setMaximum(importer->getSetsCount()); + + 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")); - setFixedSize(500, 300); + setFixedSize(600, 500); + + QStringList args = qApp->arguments(); + if (args.contains("-dlsets")) + downloadSetsFile(defaultSetsUrl); +} + +void WindowMain::updateSetList() +{ + for (int i = 0; i < checkBoxList.size(); ++i) + delete checkBoxList[i]; + checkBoxList.clear(); + + QList &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; + } +} + +void WindowMain::actLoadSetsFile() +{ + QFileDialog dialog(this, tr("Load sets file")); + dialog.setFileMode(QFileDialog::ExistingFile); + dialog.setNameFilter("Sets XML file (*.xml)"); + if (!dialog.exec()) + return; + + QString fileName = dialog.selectedFiles().at(0); + importer->readSetsFromFile(fileName); + updateSetList(); +} + +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(sender()); + importer->readSetsFromByteArray(reply->readAll()); + reply->deleteLater(); + updateSetList(); } void WindowMain::updateTotalProgress(int cardsImported, int setIndex, const QString &nextSetName) @@ -91,7 +154,8 @@ void WindowMain::actStart() startButton->setEnabled(false); for (int i = 0; i < checkBoxList.size(); ++i) checkBoxList[i]->setEnabled(false); - importer->downloadNextFile(); + int setsCount = importer->startDownload(); + totalProgressBar->setMaximum(setsCount); } void WindowMain::checkBoxChanged(int state) diff --git a/oracle/src/window_main.h b/oracle/src/window_main.h index 3c1391eb..61ae7110 100644 --- a/oracle/src/window_main.h +++ b/oracle/src/window_main.h @@ -10,21 +10,37 @@ class QProgressBar; class QTextEdit; class QPushButton; class QCheckBox; +class QVBoxLayout; +class QMenu; +class QAction; +class QNetworkAccessManager; class WindowMain : public QMainWindow { Q_OBJECT private: - OracleImporter *importer; + static const QString defaultSetsUrl; + OracleImporter *importer; + QNetworkAccessManager *nam; + + QMenu *fileMenu; + QAction *aLoadSetsFile, *aDownloadSetsFile, *aExit; QPushButton *startButton; QLabel *totalLabel, *fileLabel, *nextSetLabel1, *nextSetLabel2; QProgressBar *totalProgressBar, *fileProgressBar; QTextEdit *messageLog; + QVBoxLayout *checkBoxLayout; QList checkBoxList; + + 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 actStart(); + void actLoadSetsFile(); + void actDownloadSetsFile(); + void setsDownloadFinished(); void checkBoxChanged(int state); public: WindowMain(QWidget *parent = 0);