From 1455f051e4762cf7409081f7db5cefb22d3c72bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Thu, 2 Jan 2014 23:58:53 +0100 Subject: [PATCH 01/10] Force cached updater binary to always resolve as stale --- logic/updater/DownloadUpdateTask.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/logic/updater/DownloadUpdateTask.cpp b/logic/updater/DownloadUpdateTask.cpp index 6e0a92f0..029286dd 100644 --- a/logic/updater/DownloadUpdateTask.cpp +++ b/logic/updater/DownloadUpdateTask.cpp @@ -404,11 +404,10 @@ DownloadUpdateTask::processFileLists(NetJob *job, { auto cache_entry = MMC->metacache()->resolveEntry("root", entry.path); QLOG_DEBUG() << "Updater will be in " << cache_entry->getFullPath(); - if(cache_entry->stale) - { - auto download = CacheDownload::make(QUrl(source.url), cache_entry); - job->addNetAction(download); - } + // force check. + cache_entry->stale = true; + auto download = CacheDownload::make(QUrl(source.url), cache_entry); + job->addNetAction(download); } else { From f399207ae09e2b9a34166be6dbb2a1d22dbddc99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Fri, 3 Jan 2014 02:29:05 +0100 Subject: [PATCH 02/10] Log version, work paths --- MultiMC.cpp | 96 ++++++++++++++++++++++++++++-------------------- MultiMC.h | 28 ++++++++++++++ tests/TestUtil.h | 2 +- 3 files changed, 86 insertions(+), 40 deletions(-) diff --git a/MultiMC.cpp b/MultiMC.cpp index 4e06f558..619a7e0a 100644 --- a/MultiMC.cpp +++ b/MultiMC.cpp @@ -47,7 +47,7 @@ using namespace Util::Commandline; -MultiMC::MultiMC(int &argc, char **argv, const QString &root) +MultiMC::MultiMC(int &argc, char **argv, const QString &data_dir_override) : QApplication(argc, argv), m_version{VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD, VERSION_CHANNEL, VERSION_BUILD_TYPE} { @@ -60,10 +60,6 @@ MultiMC::MultiMC(int &argc, char **argv, const QString &root) // Don't quit on hiding the last window this->setQuitOnLastWindowClosed(false); - // Print app header - std::cout << "MultiMC 5" << std::endl; - std::cout << "(c) 2013 MultiMC Contributors" << std::endl << std::endl; - // Commandline parsing QHash args; { @@ -82,16 +78,6 @@ MultiMC::MultiMC(int &argc, char **argv, const QString &root) parser.addShortOpt("dir", 'd'); parser.addDocumentation("dir", "use the supplied directory as MultiMC root instead of " "the binary location (use '.' for current)"); - // --update - parser.addOption("update"); - parser.addShortOpt("update", 'u'); - parser.addDocumentation("update", "replaces the given file with the running executable", - ""); - // --quietupdate - parser.addSwitch("quietupdate"); - parser.addShortOpt("quietupdate", 'U'); - parser.addDocumentation("quietupdate", - "doesn't restart MultiMC after installing updates"); // WARNING: disabled until further notice /* // --launch @@ -129,35 +115,67 @@ MultiMC::MultiMC(int &argc, char **argv, const QString &root) m_status = MultiMC::Succeeded; return; } - - // update - // Note: cwd is always the current executable path! - if (!args["update"].isNull()) - { - std::cout << "Performing MultiMC update: " << qPrintable(args["update"].toString()) - << std::endl; - QString cwd = QDir::currentPath(); - QDir::setCurrent(applicationDirPath()); - QFile file(applicationFilePath()); - file.copy(args["update"].toString()); - if (args["quietupdate"].toBool()) - { - m_status = MultiMC::Succeeded; - return; - } - QDir::setCurrent(cwd); - } + } + origcwdPath = QDir::currentPath(); + binPath = applicationDirPath(); + QString adjustedBy; + // change directory + QString dirParam = args["dir"].toString(); + if (!data_dir_override.isEmpty()) + { + // the override is used for tests (although dirparam would be enough...) + // TODO: remove the need for this extra logic + adjustedBy += "Test override " + data_dir_override; + dataPath = data_dir_override; + } + else if (!dirParam.isEmpty()) + { + // the dir param. it makes multimc data path point to whatever the user specified + // on command line + adjustedBy += "Command line " + dirParam; + dataPath = dirParam; + } + if(!ensureFolderPathExists(dataPath) || !QDir::setCurrent(dataPath)) + { + // BAD STUFF. WHAT DO? + initLogger(); + QLOG_ERROR() << "Failed to set work path. Will exit. NOW."; + m_status = MultiMC::Failed; + return; } - // change directory - QDir::setCurrent( - args["dir"].toString().isEmpty() - ? (root.isEmpty() ? QDir::currentPath() : QDir::current().absoluteFilePath(root)) - : args["dir"].toString()); + { + #ifdef Q_OS_LINUX + QDir foo(PathCombine(binPath, "..")); + rootPath = foo.absolutePath(); + #elif defined(Q_OS_WIN32) + QDir foo(PathCombine(binPath, "..")); + rootPath = foo.absolutePath(); + #elif defined(Q_OS_MAC) + QDir foo(PathCombine(binPath, "../..")); + rootPath = foo.absolutePath(); + #endif + } // init the logger initLogger(); + QLOG_INFO() << "MultiMC 5, (c) 2013 MultiMC Contributors"; + QLOG_INFO() << "Version : " << VERSION_STR; + QLOG_INFO() << "Git commit : " << GIT_COMMIT; + if (adjustedBy.size()) + { + QLOG_INFO() << "Work dir before adjustment : " << origcwdPath; + QLOG_INFO() << "Work dir after adjustment : " << QDir::currentPath(); + QLOG_INFO() << "Adjusted by : " << adjustedBy; + } + else + { + QLOG_INFO() << "Work dir : " << QDir::currentPath(); + } + QLOG_INFO() << "Binary path : " << binPath; + QLOG_INFO() << "Application root path : " << rootPath; + // load settings initGlobalSettings(); @@ -319,7 +337,7 @@ void MultiMC::initLogger() QsLogging::Logger &logger = QsLogging::Logger::instance(); logger.setLoggingLevel(QsLogging::TraceLevel); m_fileDestination = QsLogging::DestinationFactory::MakeFileDestination(logBase.arg(0)); - m_debugDestination = QsLogging::DestinationFactory::MakeQDebugDestination(); + m_debugDestination = QsLogging::DestinationFactory::MakeDebugOutputDestination(); logger.addDestination(m_fileDestination.get()); logger.addDestination(m_debugDestination.get()); // log all the things diff --git a/MultiMC.h b/MultiMC.h index 9ad276ff..91731afa 100644 --- a/MultiMC.h +++ b/MultiMC.h @@ -125,6 +125,29 @@ public: */ bool openJsonEditor(const QString &filename); + /// this is the root of the 'installation'. Used for automatic updates + const QString &root() + { + return rootPath; + } + /// this is the where the binary files reside + const QString &bin() + { + return binPath; + } + /// this is the work/data path. All user data is here. + const QString &data() + { + return dataPath; + } + /** + * this is the original work path before it was changed by the adjustment mechanism + */ + const QString &origcwd() + { + return origcwdPath; + } + private: void initLogger(); @@ -157,6 +180,11 @@ private: QString m_updateOnExitPath; + QString rootPath; + QString binPath; + QString dataPath; + QString origcwdPath; + Status m_status = MultiMC::Failed; MultiMCVersion m_version; }; diff --git a/tests/TestUtil.h b/tests/TestUtil.h index fd25d24f..231ce7f6 100644 --- a/tests/TestUtil.h +++ b/tests/TestUtil.h @@ -39,7 +39,7 @@ int main(int argc, char *argv[]) \ { \ char *argv_[] = { argv[0] _MMC_EXTRA_ARGV }; \ int argc_ = 1 + _MMC_EXTRA_ARGC; \ - MultiMC app(argc_, argv_, QDir::temp().absoluteFilePath("MultiMC_Test")); \ + MultiMC app(argc_, argv_/*, QDir::temp().absoluteFilePath("MultiMC_Test")*/); \ app.setAttribute(Qt::AA_Use96Dpi, true); \ TestObject tc; \ return QTest::qExec(&tc, argc, argv); \ From c35012f1a570e752051c8fcbafe628fc64aa793f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Fri, 3 Jan 2014 02:42:32 +0100 Subject: [PATCH 03/10] DEBUG: Add some logging for instance loading. --- logic/lists/InstanceList.cpp | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/logic/lists/InstanceList.cpp b/logic/lists/InstanceList.cpp index 48a2865a..bfd183d9 100644 --- a/logic/lists/InstanceList.cpp +++ b/logic/lists/InstanceList.cpp @@ -307,9 +307,10 @@ void InstanceList::loadForgeInstances(QMap groupMap) QLOG_INFO() << "The FTB directory specified does not exist. Please check your settings"; return; } - dir.cd("ModPacks"); - QFile f(dir.absoluteFilePath("modpacks.xml")); + auto fpath = dir.absoluteFilePath("modpacks.xml"); + QFile f(fpath); + QLOG_INFO() << "Discovering FTB instances -- " << fpath; if (!f.open(QFile::ReadOnly)) return; @@ -326,6 +327,9 @@ void InstanceList::loadForgeInstances(QMap groupMap) QXmlStreamAttributes attrs = reader.attributes(); FTBRecord record; record.dir = attrs.value("dir").toString(); + QDir test(dataDir.absoluteFilePath(record.dir)); + if(!test.exists()) + continue; record.name = attrs.value("name").toString(); record.logo = attrs.value("logo").toString(); record.mcVersion = attrs.value("mcVersion").toString(); @@ -343,11 +347,17 @@ void InstanceList::loadForgeInstances(QMap groupMap) } } f.close(); - + if(!records.size()) + { + QLOG_INFO() << "No FTB instances to load."; + return; + } + QLOG_INFO() << "Loading FTB instances! -- got " << records.size(); // process the records we acquired. for (auto record : records) { auto instanceDir = dataDir.absoluteFilePath(record.dir); + QLOG_INFO() << "Loading FTB instance from " << instanceDir; auto templateDir = dir.absoluteFilePath(record.dir); if (!QFileInfo(instanceDir).exists()) { @@ -361,6 +371,7 @@ void InstanceList::loadForgeInstances(QMap groupMap) if (!QFileInfo(PathCombine(instanceDir, "instance.cfg")).exists()) { + QLOG_INFO() << "Converting " << record.name << " as new."; BaseInstance *instPtr = NULL; auto &factory = InstanceFactory::get(); auto version = MMC->minecraftlist()->findVersion(record.mcVersion); @@ -386,6 +397,7 @@ void InstanceList::loadForgeInstances(QMap groupMap) } else { + QLOG_INFO() << "Loading existing " << record.name; BaseInstance *instPtr = NULL; auto error = InstanceFactory::get().loadInstance(instPtr, instanceDir); if (!instPtr || error != InstanceFactory::NoCreateError) @@ -419,7 +431,7 @@ InstanceList::InstListError InstanceList::loadList() QString subDir = iter.next(); if (!QFileInfo(PathCombine(subDir, "instance.cfg")).exists()) continue; - + QLOG_INFO() << "Loading MultiMC instance from " << subDir; BaseInstance *instPtr = NULL; auto error = InstanceFactory::get().loadInstance(instPtr, subDir); continueProcessInstance(instPtr, error, subDir, groupMap); @@ -534,7 +546,7 @@ void InstanceList::continueProcessInstance(BaseInstance *instPtr, const int erro { instPtr->setGroupInitial((*iter)); } - QLOG_INFO() << "Loaded instance " << instPtr->name(); + QLOG_INFO() << "Loaded instance " << instPtr->name() << " from " << dir.absolutePath(); instPtr->setParent(this); m_instances.append(std::shared_ptr(instPtr)); connect(instPtr, SIGNAL(propertiesChanged(BaseInstance *)), this, From b3dd1eba2146849cddd7e85b16aa3b8af9d2de23 Mon Sep 17 00:00:00 2001 From: Jan Dalheimer Date: Fri, 3 Jan 2014 19:19:27 +0100 Subject: [PATCH 04/10] Notifications system. Mainly to be used in case the updater breaks. --- CMakeLists.txt | 4 + MultiMC.cpp | 5 ++ MultiMC.h | 7 ++ config.h.in | 6 ++ gui/MainWindow.cpp | 56 +++++++++++++ gui/MainWindow.h | 2 + logic/updater/NotificationChecker.cpp | 113 ++++++++++++++++++++++++++ logic/updater/NotificationChecker.h | 54 ++++++++++++ 8 files changed, 247 insertions(+) create mode 100644 logic/updater/NotificationChecker.cpp create mode 100644 logic/updater/NotificationChecker.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c026de4d..7ac13fa0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -144,6 +144,8 @@ SET(MultiMC_CHANLIST_URL "" CACHE STRING "URL for the channel list.") # Updater enabled? SET(MultiMC_UPDATER false CACHE BOOL "Whether or not the update system is enabled. If this is enabled, you must also set MultiMC_CHANLIST_URL and MultiMC_VERSION_CHANNEL in order for it to work properly.") +# Notification URL +SET(MultiMC_NOTIFICATION_URL "" CACHE STRING "URL for checking for notifications.") # Build a version string to display in the configure logs. SET(MultiMC_VERSION_STRING "${MultiMC_VERSION_MAJOR}.${MultiMC_VERSION_MINOR}") @@ -337,6 +339,8 @@ logic/updater/UpdateChecker.h logic/updater/UpdateChecker.cpp logic/updater/DownloadUpdateTask.h logic/updater/DownloadUpdateTask.cpp +logic/updater/NotificationChecker.h +logic/updater/NotificationChecker.cpp # News System logic/news/NewsChecker.h diff --git a/MultiMC.cpp b/MultiMC.cpp index 619a7e0a..b105fd66 100644 --- a/MultiMC.cpp +++ b/MultiMC.cpp @@ -26,6 +26,7 @@ #include "logic/JavaUtils.h" #include "logic/updater/UpdateChecker.h" +#include "logic/updater/NotificationChecker.h" #include "pathutils.h" #include "cmdutils.h" @@ -182,6 +183,9 @@ MultiMC::MultiMC(int &argc, char **argv, const QString &data_dir_override) // initialize the updater m_updateChecker.reset(new UpdateChecker()); + // initialize the notification checker + m_notificationChecker.reset(new NotificationChecker()); + // initialize the news checker m_newsChecker.reset(new NewsChecker(NEWS_RSS_URL)); @@ -350,6 +354,7 @@ void MultiMC::initGlobalSettings() // Updates m_settings->registerSetting("UseDevBuilds", false); m_settings->registerSetting("AutoUpdate", true); + m_settings->registerSetting("ShownNotifications", QString()); // FTB m_settings->registerSetting("TrackFTBInstances", false); diff --git a/MultiMC.h b/MultiMC.h index 91731afa..3a25aa5e 100644 --- a/MultiMC.h +++ b/MultiMC.h @@ -17,6 +17,7 @@ class QNetworkAccessManager; class ForgeVersionList; class JavaVersionList; class UpdateChecker; +class NotificationChecker; class NewsChecker; #if defined(MMC) @@ -90,6 +91,11 @@ public: return m_updateChecker; } + std::shared_ptr notificationChecker() + { + return m_notificationChecker; + } + std::shared_ptr newsChecker() { return m_newsChecker; @@ -166,6 +172,7 @@ private: std::shared_ptr m_settings; std::shared_ptr m_instances; std::shared_ptr m_updateChecker; + std::shared_ptr m_notificationChecker; std::shared_ptr m_newsChecker; std::shared_ptr m_accounts; std::shared_ptr m_icons; diff --git a/config.h.in b/config.h.in index aa604056..9681b825 100644 --- a/config.h.in +++ b/config.h.in @@ -10,6 +10,12 @@ // URL for the updater's channel #define CHANLIST_URL "@MultiMC_CHANLIST_URL@" +// URL for notifications +#define NOTIFICATION_URL "@MultiMC_NOTIFICATION_URL@" + +// Used for matching notifications +#define FULL_VERSION_STR "@MultiMC_VERSION_MAJOR@.@MultiMC_VERSION_MINOR@.@MultiMC_VERSION_BUILD@" + // The commit hash of this build #define GIT_COMMIT "@MultiMC_GIT_COMMIT@" diff --git a/gui/MainWindow.cpp b/gui/MainWindow.cpp index 2b911b2c..cf34a46b 100644 --- a/gui/MainWindow.cpp +++ b/gui/MainWindow.cpp @@ -92,6 +92,7 @@ #include "logic/assets/AssetsUtils.h" #include "logic/assets/AssetsMigrateTask.h" #include +#include #include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) @@ -279,6 +280,9 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi // if automatic update checks are allowed, start one. if (MMC->settings()->get("AutoUpdate").toBool()) on_actionCheckUpdate_triggered(); + + connect(MMC->notificationChecker().get(), &NotificationChecker::notificationCheckFinished, + this, &MainWindow::notificationsChanged); } const QString currentInstanceId = MMC->settings()->get("SelectedInstance").toString(); @@ -495,6 +499,58 @@ void MainWindow::updateAvailable(QString repo, QString versionName, int versionI } } +QList stringToIntList(const QString &string) +{ + QStringList split = string.split(',', QString::SkipEmptyParts); + QList out; + for (int i = 0; i < split.size(); ++i) + { + out.append(split.at(i).toInt()); + } + return out; +} +QString intListToString(const QList &list) +{ + QStringList slist; + for (int i = 0; i < list.size(); ++i) + { + slist.append(QString::number(list.at(i))); + } + return slist.join(','); +} +void MainWindow::notificationsChanged() +{ + QList entries = + MMC->notificationChecker()->notificationEntries(); + QList shownNotifications = + stringToIntList(MMC->settings()->get("ShownNotifications").toString()); + for (auto it = entries.begin(); it != entries.end(); ++it) + { + NotificationChecker::NotificationEntry entry = *it; + if (!shownNotifications.contains(entry.id) && entry.applies()) + { + QMessageBox::Icon icon; + switch (entry.type) + { + case NotificationChecker::NotificationEntry::Critical: + icon = QMessageBox::Critical; + break; + case NotificationChecker::NotificationEntry::Warning: + icon = QMessageBox::Warning; + break; + case NotificationChecker::NotificationEntry::Information: + icon = QMessageBox::Information; + break; + } + + QMessageBox box(icon, tr("Notification"), entry.message, QMessageBox::Ok, this); + box.exec(); + shownNotifications.append(entry.id); + } + } + MMC->settings()->set("ShownNotifications", intListToString(shownNotifications)); +} + void MainWindow::downloadUpdates(QString repo, int versionId, bool installOnExit) { QLOG_INFO() << "Downloading updates."; diff --git a/gui/MainWindow.h b/gui/MainWindow.h index f2315ee6..7089b98b 100644 --- a/gui/MainWindow.h +++ b/gui/MainWindow.h @@ -157,6 +157,8 @@ slots: void updateAvailable(QString repo, QString versionName, int versionId); + void notificationsChanged(); + void activeAccountChanged(); void changeActiveAccount(); diff --git a/logic/updater/NotificationChecker.cpp b/logic/updater/NotificationChecker.cpp new file mode 100644 index 00000000..a3d7a945 --- /dev/null +++ b/logic/updater/NotificationChecker.cpp @@ -0,0 +1,113 @@ +#include "NotificationChecker.h" + +#include +#include +#include + +#include "MultiMC.h" +#include "logic/net/CacheDownload.h" +#include "config.h" + +NotificationChecker::NotificationChecker(QObject *parent) + : QObject(parent), m_notificationsUrl(QUrl(NOTIFICATION_URL)) +{ + // this will call checkForNotifications once the event loop is running + QMetaObject::invokeMethod(this, "checkForNotifications", Qt::QueuedConnection); +} + +QUrl NotificationChecker::notificationsUrl() const +{ + return m_notificationsUrl; +} +void NotificationChecker::setNotificationsUrl(const QUrl ¬ificationsUrl) +{ + m_notificationsUrl = notificationsUrl; +} + +QList NotificationChecker::notificationEntries() const +{ + return m_entries; +} + +void NotificationChecker::checkForNotifications() +{ + if (m_checkJob) + { + return; + } + m_checkJob.reset(new NetJob("Checking for notifications")); + auto entry = MMC->metacache()->resolveEntry("root", "notifications.json"); + entry->stale = true; + m_checkJob->addNetAction(m_download = CacheDownload::make(m_notificationsUrl, entry)); + connect(m_download.get(), &CacheDownload::succeeded, this, + &NotificationChecker::downloadSucceeded); + m_checkJob->start(); +} + +void NotificationChecker::downloadSucceeded(int) +{ + m_entries.clear(); + + QFile file(m_download->m_output_file.fileName()); + if (file.open(QFile::ReadOnly)) + { + QJsonArray root = QJsonDocument::fromJson(file.readAll()).array(); + for (auto it = root.begin(); it != root.end(); ++it) + { + QJsonObject obj = (*it).toObject(); + NotificationEntry entry; + entry.id = obj.value("id").toInt(); + entry.message = obj.value("message").toString(); + entry.channel = obj.value("channel").toString(); + entry.buildtype = obj.value("buildtype").toString(); + entry.from = obj.value("from").toString(); + entry.to = obj.value("to").toString(); + const QString type = obj.value("type").toString("critical"); + if (type == "critical") + { + entry.type = NotificationEntry::Critical; + } + else if (type == "warning") + { + entry.type = NotificationEntry::Warning; + } + else if (type == "information") + { + entry.type = NotificationEntry::Information; + } + m_entries.append(entry); + } + } + + m_checkJob.reset(); + + emit notificationCheckFinished(); +} + +bool NotificationChecker::NotificationEntry::applies() const +{ + bool channelApplies = channel.isEmpty() || channel == VERSION_CHANNEL; + bool buildtypeApplies = buildtype.isEmpty() || buildtype == VERSION_BUILD_TYPE; + bool fromApplies = + from.isEmpty() || from == FULL_VERSION_STR || !versionLessThan(FULL_VERSION_STR, from); + bool toApplies = + to.isEmpty() || to == FULL_VERSION_STR || !versionLessThan(to, FULL_VERSION_STR); + return channelApplies && buildtypeApplies && fromApplies && toApplies; +} + +bool NotificationChecker::NotificationEntry::versionLessThan(const QString &v1, + const QString &v2) +{ + QStringList l1 = v1.split('.'); + QStringList l2 = v2.split('.'); + while (!l1.isEmpty() && !l2.isEmpty()) + { + int one = l1.isEmpty() ? 0 : l1.takeFirst().toInt(); + int two = l2.isEmpty() ? 0 : l2.takeFirst().toInt(); + if (one != two) + { + return one < two; + } + } + return false; +} diff --git a/logic/updater/NotificationChecker.h b/logic/updater/NotificationChecker.h new file mode 100644 index 00000000..20541757 --- /dev/null +++ b/logic/updater/NotificationChecker.h @@ -0,0 +1,54 @@ +#pragma once + +#include + +#include "logic/net/NetJob.h" +#include "logic/net/CacheDownload.h" + +class NotificationChecker : public QObject +{ + Q_OBJECT + +public: + explicit NotificationChecker(QObject *parent = 0); + + QUrl notificationsUrl() const; + void setNotificationsUrl(const QUrl ¬ificationsUrl); + + struct NotificationEntry + { + int id; + QString message; + enum + { + Critical, + Warning, + Information + } type; + QString channel; + QString buildtype; + QString from; + QString to; + bool applies() const; + static bool versionLessThan(const QString &v1, const QString &v2); + }; + + QList notificationEntries() const; + +public +slots: + void checkForNotifications(); + +private +slots: + void downloadSucceeded(int); + +signals: + void notificationCheckFinished(); + +private: + QList m_entries; + QUrl m_notificationsUrl; + NetJobPtr m_checkJob; + CacheDownloadPtr m_download; +}; From df9f9a34ef325b55c34293cf4e3367c50084416b Mon Sep 17 00:00:00 2001 From: Jan Dalheimer Date: Fri, 3 Jan 2014 20:12:37 +0100 Subject: [PATCH 05/10] Fix for pre-Qt5.2 --- logic/updater/NotificationChecker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logic/updater/NotificationChecker.cpp b/logic/updater/NotificationChecker.cpp index a3d7a945..8540b5a1 100644 --- a/logic/updater/NotificationChecker.cpp +++ b/logic/updater/NotificationChecker.cpp @@ -56,7 +56,7 @@ void NotificationChecker::downloadSucceeded(int) { QJsonObject obj = (*it).toObject(); NotificationEntry entry; - entry.id = obj.value("id").toInt(); + entry.id = obj.value("id").toDouble(); entry.message = obj.value("message").toString(); entry.channel = obj.value("channel").toString(); entry.buildtype = obj.value("buildtype").toString(); From 71e1410b9fd785b62ece869f3d5448c14fdcba83 Mon Sep 17 00:00:00 2001 From: Jan Dalheimer Date: Fri, 3 Jan 2014 20:39:21 +0100 Subject: [PATCH 06/10] Don't try to check for notifications if we don't have a URL for it --- logic/updater/NotificationChecker.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/logic/updater/NotificationChecker.cpp b/logic/updater/NotificationChecker.cpp index 8540b5a1..40367eac 100644 --- a/logic/updater/NotificationChecker.cpp +++ b/logic/updater/NotificationChecker.cpp @@ -31,6 +31,13 @@ QList NotificationChecker::notificationE void NotificationChecker::checkForNotifications() { + if (!m_notificationsUrl.isValid()) + { + QLOG_ERROR() << "Failed to check for notifications. No notifications URL set." + << "If you'd like to use MultiMC's notification system, please pass the " + "URL to CMake at compile time."; + return; + } if (m_checkJob) { return; From df1186e0212efc99fb0125380f2da0a3ac85fe5a Mon Sep 17 00:00:00 2001 From: Jan Dalheimer Date: Fri, 3 Jan 2014 21:05:03 +0100 Subject: [PATCH 07/10] Add the option to disable a certain message --- gui/MainWindow.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gui/MainWindow.cpp b/gui/MainWindow.cpp index cf34a46b..826cbc04 100644 --- a/gui/MainWindow.cpp +++ b/gui/MainWindow.cpp @@ -543,9 +543,13 @@ void MainWindow::notificationsChanged() break; } - QMessageBox box(icon, tr("Notification"), entry.message, QMessageBox::Ok, this); + QMessageBox box(icon, tr("Notification"), entry.message, QMessageBox::Close, this); + QPushButton *dontShowAgainButton = box.addButton(tr("Don't show again"), QMessageBox::AcceptRole); box.exec(); - shownNotifications.append(entry.id); + if (box.clickedButton() == dontShowAgainButton) + { + shownNotifications.append(entry.id); + } } } MMC->settings()->set("ShownNotifications", intListToString(shownNotifications)); From 116a6458b5ba35c87f6a22783d509a1fe8672f24 Mon Sep 17 00:00:00 2001 From: Jan Dalheimer Date: Fri, 3 Jan 2014 21:11:33 +0100 Subject: [PATCH 08/10] Explicitly set the close button to be the default button --- gui/MainWindow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/gui/MainWindow.cpp b/gui/MainWindow.cpp index 826cbc04..cb9171f1 100644 --- a/gui/MainWindow.cpp +++ b/gui/MainWindow.cpp @@ -545,6 +545,7 @@ void MainWindow::notificationsChanged() QMessageBox box(icon, tr("Notification"), entry.message, QMessageBox::Close, this); QPushButton *dontShowAgainButton = box.addButton(tr("Don't show again"), QMessageBox::AcceptRole); + box.setDefaultButton(QMessageBox::Close); box.exec(); if (box.clickedButton() == dontShowAgainButton) { From 8fa69307d2d6fb19d157c134691834fc72659ebe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Fri, 3 Jan 2014 22:29:30 +0100 Subject: [PATCH 09/10] Fix mod list checkboxes --- logic/ModList.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logic/ModList.cpp b/logic/ModList.cpp index fd41bcf7..499623bf 100644 --- a/logic/ModList.cpp +++ b/logic/ModList.cpp @@ -416,7 +416,7 @@ QVariant ModList::data(const QModelIndex &index, int role) const switch (index.column()) { case ActiveColumn: - return mods[row].enabled(); + return mods[row].enabled() ? Qt::Checked: Qt::Unchecked; default: return QVariant(); } From e558584af0e6a168d76868e89d132aeebd0aa36a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Fri, 3 Jan 2014 23:26:21 +0100 Subject: [PATCH 10/10] Fix library column stretching --- gui/widgets/ModListView.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/gui/widgets/ModListView.cpp b/gui/widgets/ModListView.cpp index 9d5950c3..358e6331 100644 --- a/gui/widgets/ModListView.cpp +++ b/gui/widgets/ModListView.cpp @@ -44,9 +44,19 @@ void ModListView::setModel ( QAbstractItemModel* model ) QTreeView::setModel ( model ); auto head = header(); head->setStretchLastSection(false); - head->setSectionResizeMode(0, QHeaderView::ResizeToContents); - head->setSectionResizeMode(1, QHeaderView::Stretch); - for(int i = 2; i < head->count(); i++) - head->setSectionResizeMode(i, QHeaderView::ResizeToContents); - dropIndicatorPosition(); + // HACK: this is true for the checkbox column of mod lists + auto string = model->headerData(0,head->orientation()).toString(); + if(!string.size()) + { + head->setSectionResizeMode(0, QHeaderView::ResizeToContents); + head->setSectionResizeMode(1, QHeaderView::Stretch); + for(int i = 2; i < head->count(); i++) + head->setSectionResizeMode(i, QHeaderView::ResizeToContents); + } + else + { + head->setSectionResizeMode(0, QHeaderView::Stretch); + for(int i = 1; i < head->count(); i++) + head->setSectionResizeMode(i, QHeaderView::ResizeToContents); + } }