From f273334212274b1f1c7da376ef186314de8c4428 Mon Sep 17 00:00:00 2001 From: Jan Dalheimer Date: Sat, 14 Dec 2013 19:19:14 +0100 Subject: More tests for the UpdateChecker class. It should be done for now. --- MultiMC.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'MultiMC.h') diff --git a/MultiMC.h b/MultiMC.h index 7bfa0023..5723b2b0 100644 --- a/MultiMC.h +++ b/MultiMC.h @@ -124,6 +124,8 @@ private: void initTranslations(); private: + friend class UpdateCheckerTest; + std::shared_ptr m_qt_translator; std::shared_ptr m_mmc_translator; std::shared_ptr m_settings; -- cgit From 3e8bcc1cf6f3400fff9aa361ddc109bafe16d646 Mon Sep 17 00:00:00 2001 From: Jan Dalheimer Date: Sun, 15 Dec 2013 12:18:42 +0100 Subject: Unit tests for the DownloadUpdateTask class --- MultiMC.h | 1 + logic/updater/DownloadUpdateTask.cpp | 112 +++++++++-------- logic/updater/DownloadUpdateTask.h | 22 +++- tests/CMakeLists.txt | 1 + tests/TestUtil.h | 5 + tests/data/1.json | 43 +++++++ tests/data/2.json | 31 +++++ tests/data/channels.json | 2 +- tests/data/fileOneA | 1 + tests/data/fileOneB | 3 + tests/data/fileThree | 1 + tests/data/fileTwo | 1 + ..._DownloadUpdateTask-test_writeInstallScript.xml | 17 +++ tests/tst_DownloadUpdateTask.cpp | 136 +++++++++++++++++++++ 14 files changed, 321 insertions(+), 55 deletions(-) create mode 100644 tests/data/1.json create mode 100644 tests/data/2.json create mode 100644 tests/data/fileOneA create mode 100644 tests/data/fileOneB create mode 100644 tests/data/fileThree create mode 100644 tests/data/fileTwo create mode 100644 tests/data/tst_DownloadUpdateTask-test_writeInstallScript.xml create mode 100644 tests/tst_DownloadUpdateTask.cpp (limited to 'MultiMC.h') diff --git a/MultiMC.h b/MultiMC.h index 5723b2b0..4a33fb69 100644 --- a/MultiMC.h +++ b/MultiMC.h @@ -125,6 +125,7 @@ private: private: friend class UpdateCheckerTest; + friend class DownloadUpdateTaskTest; std::shared_ptr m_qt_translator; std::shared_ptr m_mmc_translator; diff --git a/logic/updater/DownloadUpdateTask.cpp b/logic/updater/DownloadUpdateTask.cpp index d9aab826..ed5bfd02 100644 --- a/logic/updater/DownloadUpdateTask.cpp +++ b/logic/updater/DownloadUpdateTask.cpp @@ -45,55 +45,54 @@ void DownloadUpdateTask::executeTask() findCurrentVersionInfo(); } -void DownloadUpdateTask::findCurrentVersionInfo() +void DownloadUpdateTask::processChannels() { - setStatus(tr("Finding information about the current version.")); - auto checker = MMC->updateChecker(); - // This runs after we've tried loading the channel list. - // If the channel list doesn't need to be loaded, this will be called immediately. - // If the channel list does need to be loaded, this will be called when it's done. - auto processFunc = [this, &checker] () -> void + // Now, check the channel list again. + if (!checker->hasChannels()) { - // Now, check the channel list again. - if (checker->hasChannels()) - { - // We still couldn't load the channel list. Give up. Call loadVersionInfo and return. - QLOG_INFO() << "Reloading the channel list didn't work. Giving up."; - loadVersionInfo(); - return; - } + // We still couldn't load the channel list. Give up. Call loadVersionInfo and return. + QLOG_INFO() << "Reloading the channel list didn't work. Giving up."; + loadVersionInfo(); + return; + } - QList channels = checker->getChannelList(); - QString channelId = MMC->version().channel; + QList channels = checker->getChannelList(); + QString channelId = MMC->version().channel; - // Search through the channel list for a channel with the correct ID. - for (auto channel : channels) + // Search through the channel list for a channel with the correct ID. + for (auto channel : channels) + { + if (channel.id == channelId) { - if (channel.id == channelId) - { - QLOG_INFO() << "Found matching channel."; - m_cRepoUrl = channel.url; - break; - } + QLOG_INFO() << "Found matching channel."; + m_cRepoUrl = preparePath(channel.url); + break; } + } - // Now that we've done that, load version info. - loadVersionInfo(); - }; + // Now that we've done that, load version info. + loadVersionInfo(); +} + +void DownloadUpdateTask::findCurrentVersionInfo() +{ + setStatus(tr("Finding information about the current version.")); + + auto checker = MMC->updateChecker(); - if (checker->hasChannels()) + if (!checker->hasChannels()) { // Load the channel list and wait for it to finish loading. QLOG_INFO() << "No channel list entries found. Will try reloading it."; - QObject::connect(checker.get(), &UpdateChecker::channelListLoaded, processFunc); + QObject::connect(checker.get(), &UpdateChecker::channelListLoaded, this, &DownloadUpdateTask::processChannels); checker->updateChanList(); } else { - processFunc(); + processChannels(); } } @@ -152,12 +151,24 @@ void DownloadUpdateTask::parseDownloadedVersionInfo() { setStatus(tr("Reading file lists.")); - parseVersionInfo(NEW_VERSION, &m_nVersionFileList); + setStatus(tr("Reading file list for new version.")); + QLOG_DEBUG() << "Reading file list for new version."; + QString error; + if (!parseVersionInfo(std::dynamic_pointer_cast( + m_vinfoNetJob->first())->m_data, &m_nVersionFileList, &error)) + { + emitFailed(error); + return; + } // If there is a second entry in the network job's list, load it as the current version's info. if (m_vinfoNetJob->size() >= 2 && m_vinfoNetJob->operator[](1)->m_status != Job_Failed) { - parseVersionInfo(CURRENT_VERSION, &m_cVersionFileList); + setStatus(tr("Reading file list for current version.")); + QLOG_DEBUG() << "Reading file list for current version."; + QString error; + parseVersionInfo(std::dynamic_pointer_cast( + m_vinfoNetJob->operator[](1))->m_data, &m_cVersionFileList, &error); } // We don't need this any more. @@ -167,26 +178,15 @@ void DownloadUpdateTask::parseDownloadedVersionInfo() processFileLists(); } -void DownloadUpdateTask::parseVersionInfo(VersionInfoFileEnum vfile, VersionFileList* list) +bool DownloadUpdateTask::parseVersionInfo(const QByteArray &data, VersionFileList* list, QString *error) { - if (vfile == CURRENT_VERSION) setStatus(tr("Reading file list for current version.")); - else if (vfile == NEW_VERSION) setStatus(tr("Reading file list for new version.")); - - QLOG_DEBUG() << "Reading file list for" << (vfile == NEW_VERSION ? "new" : "current") << "version."; - - QByteArray data; - { - ByteArrayDownloadPtr dl = std::dynamic_pointer_cast( - vfile == NEW_VERSION ? m_vinfoNetJob->first() : m_vinfoNetJob->operator[](1)); - data = dl->m_data; - } - QJsonParseError jsonError; QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError); if (jsonError.error != QJsonParseError::NoError) { - QLOG_ERROR() << "Failed to parse version info JSON:" << jsonError.errorString() << "at" << jsonError.offset; - return; + *error = QString("Failed to parse version info JSON: %1 at %2").arg(jsonError.errorString()).arg(jsonError.offset); + QLOG_ERROR() << error; + return false; } QJsonObject json = jsonDoc.object(); @@ -213,11 +213,11 @@ void DownloadUpdateTask::parseVersionInfo(VersionInfoFileEnum vfile, VersionFile QString type = sourceObj.value("SourceType").toString(); if (type == "http") { - file.sources.append(FileSource("http", sourceObj.value("Url").toString())); + file.sources.append(FileSource("http", preparePath(sourceObj.value("Url").toString()))); } else if (type == "httpc") { - file.sources.append(FileSource("httpc", sourceObj.value("Url").toString(), sourceObj.value("CompressionType").toString())); + file.sources.append(FileSource("httpc", preparePath(sourceObj.value("Url").toString()), sourceObj.value("CompressionType").toString())); } else { @@ -229,6 +229,8 @@ void DownloadUpdateTask::parseVersionInfo(VersionInfoFileEnum vfile, VersionFile list->append(file); } + + return true; } void DownloadUpdateTask::processFileLists() @@ -312,7 +314,7 @@ void DownloadUpdateTask::processFileLists() writeInstallScript(m_operationList, PathCombine(m_updateFilesDir.path(), "file_list.xml")); } -void DownloadUpdateTask::writeInstallScript(UpdateOperationList& opsList, QString scriptFile) +bool DownloadUpdateTask::writeInstallScript(UpdateOperationList& opsList, QString scriptFile) { // Build the base structure of the XML document. QDomDocument doc; @@ -377,7 +379,15 @@ void DownloadUpdateTask::writeInstallScript(UpdateOperationList& opsList, QStrin else { emitFailed(tr("Failed to write update script file.")); + return false; } + + return true; +} + +QString DownloadUpdateTask::preparePath(const QString &path) +{ + return QString(path).replace("$PWD", qApp->applicationDirPath()); } void DownloadUpdateTask::fileDownloadFinished() diff --git a/logic/updater/DownloadUpdateTask.h b/logic/updater/DownloadUpdateTask.h index f5b23d12..1d1fc7bf 100644 --- a/logic/updater/DownloadUpdateTask.h +++ b/logic/updater/DownloadUpdateTask.h @@ -34,7 +34,8 @@ public: */ QString updateFilesDir(); -protected: +public: + // TODO: We should probably put these data structures into a separate header... /*! @@ -59,6 +60,7 @@ protected: /*! * Structure that describes an entry in a GoUpdate version's `Files` list. */ + struct VersionFileEntry { QString path; @@ -69,6 +71,8 @@ protected: typedef QList VersionFileList; +protected: + friend class DownloadUpdateTaskTest; /*! * Structure that describes an operation to perform when installing updates. @@ -119,6 +123,13 @@ protected: */ virtual void findCurrentVersionInfo(); + /*! + * This runs after we've tried loading the channel list. + * If the channel list doesn't need to be loaded, this will be called immediately. + * If the channel list does need to be loaded, this will be called when it's done. + */ + void processChannels(); + /*! * Downloads the version info files from the repository. * The files for both the current build, and the build that we're updating to need to be downloaded. @@ -142,7 +153,7 @@ protected: /*! * Loads the file list from the given version info JSON object into the given list. */ - virtual void parseVersionInfo(VersionInfoFileEnum vfile, VersionFileList* list); + virtual bool parseVersionInfo(const QByteArray &data, VersionFileList* list, QString *error); /*! * Takes a list of file entries for the current version's files and the new version's files @@ -153,7 +164,7 @@ protected: /*! * Takes the operations list and writes an install script for the updater to the update files directory. */ - virtual void writeInstallScript(UpdateOperationList& opsList, QString scriptFile); + virtual bool writeInstallScript(UpdateOperationList& opsList, QString scriptFile); VersionFileList m_downloadList; UpdateOperationList m_operationList; @@ -181,6 +192,11 @@ protected: */ QTemporaryDir m_updateFilesDir; + /*! + * Substitutes $PWD for the application directory + */ + static QString preparePath(const QString &path); + protected slots: void vinfoDownloadFinished(); void vinfoDownloadFailed(); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 79939312..14670fbd 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -21,6 +21,7 @@ endmacro() add_unit_test(pathutils tst_pathutils.cpp) add_unit_test(userutils tst_userutils.cpp) add_unit_test(UpdateChecker tst_UpdateChecker.cpp) +add_unit_test(DownloadUpdateTask tst_DownloadUpdateTask.cpp) # Tests END # diff --git a/tests/TestUtil.h b/tests/TestUtil.h index 64ee1675..865fcf87 100644 --- a/tests/TestUtil.h +++ b/tests/TestUtil.h @@ -15,9 +15,14 @@ struct TestsInternal f.open(QFile::ReadOnly); return f.readAll(); } + static QString readFileUtf8(const QString &fileName) + { + return QString::fromUtf8(readFile(fileName)); + } }; #define MULTIMC_GET_TEST_FILE(file) TestsInternal::readFile(QFINDTESTDATA( file )) +#define MULTIMC_GET_TEST_FILE_UTF8(file) TestsInternal::readFileUtf8(QFINDTESTDATA( file )) #define QTEST_GUILESS_MAIN_MULTIMC(TestObject) \ int main(int argc, char *argv[]) \ diff --git a/tests/data/1.json b/tests/data/1.json new file mode 100644 index 00000000..d5261d2c --- /dev/null +++ b/tests/data/1.json @@ -0,0 +1,43 @@ +{ + "ApiVersion": 0, + "Id": 1, + "Name": "1.0.1", + "Files": [ + { + "Path": "fileOne", + "Sources": [ + { + "SourceType": "http", + "Url": "file://$PWD/tests/data/fileOneA" + } + ], + "Executable": true, + "Perms": 493, + "MD5": "9eb84090956c484e32cb6c08455a667b" + }, + { + "Path": "fileTwo", + "Sources": [ + { + "SourceType": "http", + "Url": "file://$PWD/tests/data/fileTwo" + } + ], + "Executable": false, + "Perms": 644, + "MD5": "38f94f54fa3eb72b0ea836538c10b043" + }, + { + "Path": "fileThree", + "Sources": [ + { + "SourceType": "http", + "Url": "file://$PWD/tests/data/fileThree" + } + ], + "Executable": false, + "Perms": "750", + "MD5": "f12df554b21e320be6471d7154130e70" + } + ] +} diff --git a/tests/data/2.json b/tests/data/2.json new file mode 100644 index 00000000..a96aff79 --- /dev/null +++ b/tests/data/2.json @@ -0,0 +1,31 @@ +{ + "ApiVersion": 0, + "Id": 1, + "Name": "1.0.1", + "Files": [ + { + "Path": "fileOne", + "Sources": [ + { + "SourceType": "http", + "Url": "file://$PWD/tests/data/fileOneB" + } + ], + "Executable": true, + "Perms": 493, + "MD5": "42915a71277c9016668cce7b82c6b577" + }, + { + "Path": "fileTwo", + "Sources": [ + { + "SourceType": "http", + "Url": "file://$PWD/tests/data/fileTwo" + } + ], + "Executable": false, + "Perms": 644, + "MD5": "38f94f54fa3eb72b0ea836538c10b043" + } + ] +} diff --git a/tests/data/channels.json b/tests/data/channels.json index dd99fd27..e4f04bff 100644 --- a/tests/data/channels.json +++ b/tests/data/channels.json @@ -5,7 +5,7 @@ "id": "develop", "name": "Develop", "description": "The channel called \"develop\"", - "url": "http://example.org/stuff" + "url": "file://$PWD/tests/data/" }, { "id": "stable", diff --git a/tests/data/fileOneA b/tests/data/fileOneA new file mode 100644 index 00000000..f2e41136 --- /dev/null +++ b/tests/data/fileOneA @@ -0,0 +1 @@ +stuff diff --git a/tests/data/fileOneB b/tests/data/fileOneB new file mode 100644 index 00000000..f9aba922 --- /dev/null +++ b/tests/data/fileOneB @@ -0,0 +1,3 @@ +stuff + +more stuff that came in the new version diff --git a/tests/data/fileThree b/tests/data/fileThree new file mode 100644 index 00000000..6353ff16 --- /dev/null +++ b/tests/data/fileThree @@ -0,0 +1 @@ +this is yet another file diff --git a/tests/data/fileTwo b/tests/data/fileTwo new file mode 100644 index 00000000..aad9a93a --- /dev/null +++ b/tests/data/fileTwo @@ -0,0 +1 @@ +some other stuff diff --git a/tests/data/tst_DownloadUpdateTask-test_writeInstallScript.xml b/tests/data/tst_DownloadUpdateTask-test_writeInstallScript.xml new file mode 100644 index 00000000..09c162ca --- /dev/null +++ b/tests/data/tst_DownloadUpdateTask-test_writeInstallScript.xml @@ -0,0 +1,17 @@ + + + + sourceOne + destOne + 0777 + + + MultiMC.exe + M/u/l/t/i/M/C/e/x/e + 0644 + + + + toDelete.abc + + diff --git a/tests/tst_DownloadUpdateTask.cpp b/tests/tst_DownloadUpdateTask.cpp new file mode 100644 index 00000000..69391466 --- /dev/null +++ b/tests/tst_DownloadUpdateTask.cpp @@ -0,0 +1,136 @@ +#include +#include + +#include "TestUtil.h" + +#include "logic/updater/DownloadUpdateTask.h" +#include "logic/updater/UpdateChecker.h" + +Q_DECLARE_METATYPE(DownloadUpdateTask::VersionFileList) + +bool operator==(const DownloadUpdateTask::FileSource &f1, const DownloadUpdateTask::FileSource &f2) +{ + return f1.type == f2.type && + f1.url == f2.url && + f1.compressionType == f2.compressionType; +} +bool operator==(const DownloadUpdateTask::VersionFileEntry &v1, const DownloadUpdateTask::VersionFileEntry &v2) +{ + return v1.path == v2.path && + v1.mode == v2.mode && + v1.sources == v2.sources && + v1.md5 == v2.md5; +} + +QDebug operator<<(QDebug dbg, const DownloadUpdateTask::FileSource &f) +{ + dbg.nospace() << "FileSource(type=" << f.type << " url=" << f.url << " comp=" << f.compressionType << ")"; + return dbg.maybeSpace(); +} +QDebug operator<<(QDebug dbg, const DownloadUpdateTask::VersionFileEntry &v) +{ + dbg.nospace() << "VersionFileEntry(path=" << v.path << " mode=" << v.mode << " md5=" << v.md5 << " sources=" << v.sources << ")"; + return dbg.maybeSpace(); +} + +class DownloadUpdateTaskTest : public QObject +{ + Q_OBJECT +private +slots: + void initTestCase() + { + + } + void cleanupTestCase() + { + + } + + void test_writeInstallScript() + { + DownloadUpdateTask task(QUrl::fromLocalFile(QDir::current().absoluteFilePath("tests/data/")).toString(), 0); + + DownloadUpdateTask::UpdateOperationList ops; + + ops << DownloadUpdateTask::UpdateOperation::CopyOp("sourceOne", "destOne", 0777) + << DownloadUpdateTask::UpdateOperation::CopyOp("MultiMC.exe", "M/u/l/t/i/M/C/e/x/e") + << DownloadUpdateTask::UpdateOperation::DeleteOp("toDelete.abc"); + + const QString script = QDir::temp().absoluteFilePath("MultiMCUpdateScript.xml"); + QVERIFY(task.writeInstallScript(ops, script)); + QCOMPARE(TestsInternal::readFileUtf8(script), MULTIMC_GET_TEST_FILE_UTF8("tests/data/tst_DownloadUpdateTask-test_writeInstallScript.xml")); + } + + void test_parseVersionInfo_data() + { + QTest::addColumn("data"); + QTest::addColumn("list"); + QTest::addColumn("error"); + QTest::addColumn("ret"); + + QTest::newRow("one") << MULTIMC_GET_TEST_FILE("tests/data/1.json") + << (DownloadUpdateTask::VersionFileList() + << DownloadUpdateTask::VersionFileEntry{"fileOne", 493, + (DownloadUpdateTask::FileSourceList() << DownloadUpdateTask::FileSource("http", "file://" + qApp->applicationDirPath() + "/tests/data/fileOneA")), + "9eb84090956c484e32cb6c08455a667b"} + << DownloadUpdateTask::VersionFileEntry{"fileTwo", 644, + (DownloadUpdateTask::FileSourceList() << DownloadUpdateTask::FileSource("http", "file://" + qApp->applicationDirPath() + "/tests/data/fileTwo")), + "38f94f54fa3eb72b0ea836538c10b043"} + << DownloadUpdateTask::VersionFileEntry{"fileThree", 750, + (DownloadUpdateTask::FileSourceList() << DownloadUpdateTask::FileSource("http", "file://" + qApp->applicationDirPath() + "/tests/data/fileThree")), + "f12df554b21e320be6471d7154130e70"}) + << QString() + << true; + QTest::newRow("two") << MULTIMC_GET_TEST_FILE("tests/data/2.json") + << (DownloadUpdateTask::VersionFileList() + << DownloadUpdateTask::VersionFileEntry{"fileOne", 493, + (DownloadUpdateTask::FileSourceList() << DownloadUpdateTask::FileSource("http", "file://" + qApp->applicationDirPath() + "/tests/data/fileOneB")), + "42915a71277c9016668cce7b82c6b577"} + << DownloadUpdateTask::VersionFileEntry{"fileTwo", 644, + (DownloadUpdateTask::FileSourceList() << DownloadUpdateTask::FileSource("http", "file://" + qApp->applicationDirPath() + "/tests/data/fileTwo")), + "38f94f54fa3eb72b0ea836538c10b043"}) + << QString() + << true; + } + void test_parseVersionInfo() + { + QFETCH(QByteArray, data); + QFETCH(DownloadUpdateTask::VersionFileList, list); + QFETCH(QString, error); + QFETCH(bool, ret); + + DownloadUpdateTask::VersionFileList outList; + QString outError; + bool outRet = DownloadUpdateTask("", 0).parseVersionInfo(data, &outList, &outError); + QCOMPARE(outRet, ret); + QCOMPARE(outList, list); + QCOMPARE(outError, error); + } + + void test_processFileLists() + { + // TODO create unit test for this + } + + void test_masterTest() + { + QLOG_INFO() << "#####################"; + MMC->m_version.build = 1; + MMC->m_version.channel = "develop"; + MMC->updateChecker()->setChannelListUrl(QUrl::fromLocalFile(QDir::current().absoluteFilePath("tests/data/channels.json")).toString()); + MMC->updateChecker()->setCurrentChannel("develop"); + + DownloadUpdateTask task(QUrl::fromLocalFile(QDir::current().absoluteFilePath("tests/data/")).toString(), 2); + + QSignalSpy succeededSpy(&task, SIGNAL(succeeded())); + + task.start(); + + QVERIFY(succeededSpy.wait()); + } +}; + +QTEST_GUILESS_MAIN_MULTIMC(DownloadUpdateTaskTest) + +#include "tst_DownloadUpdateTask.moc" -- cgit From 3380bc75633c63e8569b76981ac29528c58943ce Mon Sep 17 00:00:00 2001 From: Jan Dalheimer Date: Sun, 29 Dec 2013 17:51:16 +0100 Subject: Launch an editor for the custom.json file. Also allow overriding of the system default editor --- MultiMC.cpp | 18 ++++++++++++++++++ MultiMC.h | 11 ++++++++--- gui/dialogs/OneSixModEditDialog.cpp | 10 ++++++++++ gui/dialogs/OneSixModEditDialog.h | 1 + gui/dialogs/OneSixModEditDialog.ui | 14 ++++++++++++++ gui/dialogs/SettingsDialog.cpp | 32 ++++++++++++++++++++++++++++++++ gui/dialogs/SettingsDialog.h | 2 ++ gui/dialogs/SettingsDialog.ui | 34 ++++++++++++++++++++++++++++++++-- 8 files changed, 117 insertions(+), 5 deletions(-) (limited to 'MultiMC.h') diff --git a/MultiMC.cpp b/MultiMC.cpp index 71d0e5a7..24cdd077 100644 --- a/MultiMC.cpp +++ b/MultiMC.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "gui/dialogs/VersionSelectDialog.h" #include "logic/lists/InstanceList.h" @@ -382,6 +383,9 @@ void MultiMC::initGlobalSettings() m_settings->registerSetting(new Setting("CentralModsDir", "mods")); m_settings->registerSetting(new Setting("LWJGLDir", "lwjgl")); + // Editors + m_settings->registerSetting(new Setting("JsonEditor", QString())); + // Console m_settings->registerSetting(new Setting("ShowConsole", true)); m_settings->registerSetting(new Setting("AutoCloseConsole", true)); @@ -550,4 +554,18 @@ QString MultiMC::getExitUpdatePath() const return m_updateOnExitPath; } +void MultiMC::openJsonEditor(const QString &filename) +{ + const QString file = QDir::current().absoluteFilePath(filename); + if (m_settings->get("JsonEditor").toString().isEmpty()) + { + QDesktopServices::openUrl(QUrl::fromLocalFile(file)); + } + else + { + QProcess::startDetached(m_settings->get("JsonEditor").toString(), + QStringList() << file); + } +} + #include "MultiMC.moc" diff --git a/MultiMC.h b/MultiMC.h index 4a33fb69..17113181 100644 --- a/MultiMC.h +++ b/MultiMC.h @@ -6,7 +6,6 @@ #include "logger/QsLog.h" #include "logger/QsLogDest.h" - class MinecraftVersionList; class LWJGLVersionList; class HttpMetaCache; @@ -101,12 +100,12 @@ public: /*! * Installs update from the given update files directory. */ - void installUpdates(const QString& updateFilesDir, bool restartOnFinish=false); + void installUpdates(const QString &updateFilesDir, bool restartOnFinish = false); /*! * Sets MultiMC to install updates from the given directory when it exits. */ - void setUpdateOnExit(const QString& updateFilesDir); + void setUpdateOnExit(const QString &updateFilesDir); /*! * Gets the path to install updates from on exit. @@ -114,6 +113,12 @@ public: */ QString getExitUpdatePath() const; + /*! + * Opens a json file using either a system default editor, or, if note empty, the editor + * specified in the settings + */ + void openJsonEditor(const QString &filename); + private: void initLogger(); diff --git a/gui/dialogs/OneSixModEditDialog.cpp b/gui/dialogs/OneSixModEditDialog.cpp index d8b84d3e..e575c868 100644 --- a/gui/dialogs/OneSixModEditDialog.cpp +++ b/gui/dialogs/OneSixModEditDialog.cpp @@ -97,6 +97,7 @@ void OneSixModEditDialog::updateVersionControls() ui->revertBtn->setEnabled(customVersion); ui->forgeBtn->setEnabled(true); ui->liteloaderBtn->setEnabled(LiteLoaderInstaller(m_inst->intendedVersionId()).canApply()); + ui->customEditorBtn->setEnabled(customVersion); } void OneSixModEditDialog::disableVersionControls() @@ -105,6 +106,7 @@ void OneSixModEditDialog::disableVersionControls() ui->revertBtn->setEnabled(false); ui->forgeBtn->setEnabled(false); ui->liteloaderBtn->setEnabled(false); + ui->customEditorBtn->setEnabled(false); } void OneSixModEditDialog::on_customizeBtn_clicked() @@ -134,6 +136,14 @@ void OneSixModEditDialog::on_revertBtn_clicked() } } +void OneSixModEditDialog::on_customEditorBtn_clicked() +{ + if (m_inst->versionIsCustom()) + { + MMC->openJsonEditor(m_inst->instanceRoot() + "/custom.json"); + } +} + void OneSixModEditDialog::on_forgeBtn_clicked() { VersionSelectDialog vselect(MMC->forgelist().get(), tr("Select Forge version"), this); diff --git a/gui/dialogs/OneSixModEditDialog.h b/gui/dialogs/OneSixModEditDialog.h index 09bd7946..2510c59c 100644 --- a/gui/dialogs/OneSixModEditDialog.h +++ b/gui/dialogs/OneSixModEditDialog.h @@ -47,6 +47,7 @@ slots: void on_liteloaderBtn_clicked(); void on_customizeBtn_clicked(); void on_revertBtn_clicked(); + void on_customEditorBtn_clicked(); void updateVersionControls(); void disableVersionControls(); diff --git a/gui/dialogs/OneSixModEditDialog.ui b/gui/dialogs/OneSixModEditDialog.ui index ad20cd73..899e0cbf 100644 --- a/gui/dialogs/OneSixModEditDialog.ui +++ b/gui/dialogs/OneSixModEditDialog.ui @@ -143,6 +143,20 @@ + + + + Qt::Horizontal + + + + + + + Open custom.json + + + diff --git a/gui/dialogs/SettingsDialog.cpp b/gui/dialogs/SettingsDialog.cpp index 131cb5c3..a95a8e83 100644 --- a/gui/dialogs/SettingsDialog.cpp +++ b/gui/dialogs/SettingsDialog.cpp @@ -125,6 +125,23 @@ void SettingsDialog::on_lwjglDirBrowseBtn_clicked() } } +void SettingsDialog::on_jsonEditorBrowseBtn_clicked() +{ + QString raw_file = QFileDialog::getOpenFileName( + this, tr("JSON Editor"), + ui->jsonEditorTextBox->text().isEmpty() + ? QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation).first() + : ui->jsonEditorTextBox->text()); + QString cooked_file = NormalizePath(raw_file); + + // it has to exist and be an executable + if (!cooked_file.isEmpty() && QFileInfo(cooked_file).exists() && + QFileInfo(cooked_file).isExecutable()) + { + ui->jsonEditorTextBox->setText(cooked_file); + } +} + void SettingsDialog::on_maximizedCheckBox_clicked(bool checked) { Q_UNUSED(checked); @@ -172,6 +189,18 @@ void SettingsDialog::applySettings(SettingsObject *s) s->set("CentralModsDir", ui->modsDirTextBox->text()); s->set("LWJGLDir", ui->lwjglDirTextBox->text()); + // Editors + QString jsonEditor = ui->jsonEditorTextBox->text(); + if (!jsonEditor.isEmpty() && (!QFileInfo(jsonEditor).exists() || !QFileInfo(jsonEditor).isExecutable())) + { + QString found = QStandardPaths::findExecutable(jsonEditor); + if (!found.isEmpty()) + { + jsonEditor = found; + } + } + s->set("JsonEditor", jsonEditor); + // Console s->set("ShowConsole", ui->showConsoleCheck->isChecked()); s->set("AutoCloseConsole", ui->autoCloseConsoleCheck->isChecked()); @@ -226,6 +255,9 @@ void SettingsDialog::loadSettings(SettingsObject *s) ui->modsDirTextBox->setText(s->get("CentralModsDir").toString()); ui->lwjglDirTextBox->setText(s->get("LWJGLDir").toString()); + // Editors + ui->jsonEditorTextBox->setText(s->get("JsonEditor").toString()); + // Console ui->showConsoleCheck->setChecked(s->get("ShowConsole").toBool()); ui->autoCloseConsoleCheck->setChecked(s->get("AutoCloseConsole").toBool()); diff --git a/gui/dialogs/SettingsDialog.h b/gui/dialogs/SettingsDialog.h index 36fc4797..01357c91 100644 --- a/gui/dialogs/SettingsDialog.h +++ b/gui/dialogs/SettingsDialog.h @@ -55,6 +55,8 @@ slots: void on_lwjglDirBrowseBtn_clicked(); + void on_jsonEditorBrowseBtn_clicked(); + void on_maximizedCheckBox_clicked(bool checked); void on_buttonBox_accepted(); diff --git a/gui/dialogs/SettingsDialog.ui b/gui/dialogs/SettingsDialog.ui index 4d06d1f8..ca8c7391 100644 --- a/gui/dialogs/SettingsDialog.ui +++ b/gui/dialogs/SettingsDialog.ui @@ -7,7 +7,7 @@ 0 0 526 - 599 + 628 @@ -39,7 +39,7 @@ General - + @@ -236,6 +236,36 @@ + + + + External Editors (leave empty for system default) + + + + + + true + + + + + + + JSON Editor: + + + + + + + ... + + + + + + -- cgit From 5d0868a056e3de295deaa94717b4023d07772c54 Mon Sep 17 00:00:00 2001 From: Jan Dalheimer Date: Mon, 30 Dec 2013 14:45:59 +0100 Subject: Notify the user of any errors --- MultiMC.cpp | 8 ++++---- MultiMC.h | 2 +- gui/dialogs/OneSixModEditDialog.cpp | 5 ++++- gui/dialogs/SettingsDialog.cpp | 11 ++++++++++- 4 files changed, 19 insertions(+), 7 deletions(-) (limited to 'MultiMC.h') diff --git a/MultiMC.cpp b/MultiMC.cpp index 24cdd077..865d0cf1 100644 --- a/MultiMC.cpp +++ b/MultiMC.cpp @@ -554,17 +554,17 @@ QString MultiMC::getExitUpdatePath() const return m_updateOnExitPath; } -void MultiMC::openJsonEditor(const QString &filename) +bool MultiMC::openJsonEditor(const QString &filename) { const QString file = QDir::current().absoluteFilePath(filename); if (m_settings->get("JsonEditor").toString().isEmpty()) { - QDesktopServices::openUrl(QUrl::fromLocalFile(file)); + return QDesktopServices::openUrl(QUrl::fromLocalFile(file)); } else { - QProcess::startDetached(m_settings->get("JsonEditor").toString(), - QStringList() << file); + return QProcess::startDetached(m_settings->get("JsonEditor").toString(), + QStringList() << file); } } diff --git a/MultiMC.h b/MultiMC.h index 17113181..602a4673 100644 --- a/MultiMC.h +++ b/MultiMC.h @@ -117,7 +117,7 @@ public: * Opens a json file using either a system default editor, or, if note empty, the editor * specified in the settings */ - void openJsonEditor(const QString &filename); + bool openJsonEditor(const QString &filename); private: void initLogger(); diff --git a/gui/dialogs/OneSixModEditDialog.cpp b/gui/dialogs/OneSixModEditDialog.cpp index e575c868..3982f17d 100644 --- a/gui/dialogs/OneSixModEditDialog.cpp +++ b/gui/dialogs/OneSixModEditDialog.cpp @@ -140,7 +140,10 @@ void OneSixModEditDialog::on_customEditorBtn_clicked() { if (m_inst->versionIsCustom()) { - MMC->openJsonEditor(m_inst->instanceRoot() + "/custom.json"); + if (!MMC->openJsonEditor(m_inst->instanceRoot() + "/custom.json")) + { + QMessageBox::warning(this, tr("Error"), tr("Unable to open custom.json, check the settings")); + } } } diff --git a/gui/dialogs/SettingsDialog.cpp b/gui/dialogs/SettingsDialog.cpp index 2797fe4e..0d97a5a5 100644 --- a/gui/dialogs/SettingsDialog.cpp +++ b/gui/dialogs/SettingsDialog.cpp @@ -142,12 +142,21 @@ void SettingsDialog::on_jsonEditorBrowseBtn_clicked() : ui->jsonEditorTextBox->text()); QString cooked_file = NormalizePath(raw_file); + if (cooked_file.isEmpty()) + { + return; + } + // it has to exist and be an executable - if (!cooked_file.isEmpty() && QFileInfo(cooked_file).exists() && + if (QFileInfo(cooked_file).exists() && QFileInfo(cooked_file).isExecutable()) { ui->jsonEditorTextBox->setText(cooked_file); } + else + { + QMessageBox::warning(this, tr("Invalid"), tr("The file choosen does not seem to be an executable")); + } } void SettingsDialog::on_maximizedCheckBox_clicked(bool checked) -- cgit