aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt26
-rw-r--r--MultiMC.cpp36
-rw-r--r--MultiMC.h7
-rw-r--r--changelog.yaml17
-rw-r--r--generated.qrc.in8
-rw-r--r--gui/MainWindow.cpp96
-rw-r--r--gui/MainWindow.h11
-rw-r--r--gui/dialogs/AboutDialog.cpp2
-rw-r--r--gui/dialogs/InstanceSettings.ui18
-rw-r--r--gui/dialogs/ModEditDialogCommon.cpp4
-rw-r--r--gui/dialogs/SettingsDialog.cpp16
-rw-r--r--gui/dialogs/SettingsDialog.ui503
-rw-r--r--logic/MinecraftProcess.cpp8
-rw-r--r--logic/NagUtils.cpp18
-rw-r--r--logic/net/CacheDownload.cpp100
-rw-r--r--logic/net/CacheDownload.h8
-rw-r--r--logic/net/URLConstants.h2
-rw-r--r--logic/status/StatusChecker.cpp137
-rw-r--r--logic/status/StatusChecker.h57
-rw-r--r--main.cpp1
-rw-r--r--translations/mmc_de.ts1828
21 files changed, 2226 insertions, 677 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c5c23235..c0a4439b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -25,6 +25,8 @@ IF(UNIX)
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
ENDIF()
+set(CMAKE_JAVA_TARGET_OUTPUT_DIR ${PROJECT_BINARY_DIR}/jars)
+
######## Set compiler flags ########
IF(APPLE)
message(STATUS "Using APPLE CMAKE_CXX_FLAGS")
@@ -90,8 +92,8 @@ SET(MultiMC_NEWS_RSS_URL "http://multimc.org/rss.xml" CACHE STRING "URL to fetch
######## Set version numbers ########
SET(MultiMC_VERSION_MAJOR 0)
-SET(MultiMC_VERSION_MINOR 0)
-SET(MultiMC_VERSION_HOTFIX 0)
+SET(MultiMC_VERSION_MINOR 1)
+SET(MultiMC_VERSION_HOTFIX 1)
# Build number
SET(MultiMC_VERSION_BUILD -1 CACHE STRING "Build number. -1 for no build number.")
@@ -120,17 +122,23 @@ IF (MultiMC_VERSION_HOTFIX GREATER 0)
ENDIF()
# Build a version string to display in the configure logs.
-IF (MultiMC_VERSION_TYPE STREQUAL "Custom" OR MultiMC_VERSION_TYPE STREQUAL "Release")
+IF (MultiMC_VERSION_TYPE STREQUAL "Custom")
+ MESSAGE(STATUS "Version Type: Custom")
+ SET(MultiMC_VERSION_STRING "${MultiMC_RELEASE_VERSION_NAME}")
+ELSEIF (MultiMC_VERSION_TYPE STREQUAL "Release")
+ MESSAGE(STATUS "Version Type: Stable Release")
SET(MultiMC_VERSION_STRING "${MultiMC_RELEASE_VERSION_NAME}")
ELSEIF (MultiMC_VERSION_TYPE STREQUAL "ReleaseCandidate")
+ MESSAGE(STATUS "Version Type: Release Candidate")
SET(MultiMC_VERSION_STRING "${MultiMC_RELEASE_VERSION_NAME}-rc${MultiMC_VERSION_BUILD}")
ELSEIF (MultiMC_VERSION_TYPE STREQUAL "Development")
+ MESSAGE(STATUS "Version Type: Development")
SET(MultiMC_VERSION_STRING "${MultiMC_RELEASE_VERSION_NAME}-dev${MultiMC_VERSION_BUILD}")
ELSE ()
MESSAGE(ERROR "Invalid build type.")
ENDIF ()
-MESSAGE(STATUS "MultiMC 5 version ${MultiMC_VERSION_STRING}")
+MESSAGE(STATUS "MultiMC 5 Version: ${MultiMC_VERSION_STRING}")
# If the update system is enabled, make sure MultiMC_CHANLIST_URL and MultiMC_VERSION_CHANNEL are set.
IF (MultiMC_UPDATER)
@@ -274,7 +282,6 @@ gui/dialogs/SettingsDialog.h
gui/dialogs/SettingsDialog.cpp
gui/dialogs/CopyInstanceDialog.h
gui/dialogs/CopyInstanceDialog.cpp
-gui/dialogs/dialogs/
gui/dialogs/NewInstanceDialog.cpp
gui/dialogs/ProgressDialog.h
gui/dialogs/ProgressDialog.cpp
@@ -385,6 +392,10 @@ logic/news/NewsChecker.cpp
logic/news/NewsEntry.h
logic/news/NewsEntry.cpp
+# Status system
+logic/status/StatusChecker.h
+logic/status/StatusChecker.cpp
+
# legacy instances
logic/LegacyInstance.h
logic/LegacyInstance.cpp
@@ -551,12 +562,10 @@ ENDIF(MultiMC_CODE_COVERAGE)
# Qt 5 stuff
QT5_WRAP_UI(MULTIMC_UI ${MULTIMC_UIS})
-CONFIGURE_FILE(generated.qrc.in generated.qrc)
-QT5_ADD_RESOURCES(GENERATED_QRC ${CMAKE_CURRENT_BINARY_DIR}/generated.qrc)
QT5_ADD_RESOURCES(GRAPHICS_QRC graphics.qrc)
# Add common library
-ADD_LIBRARY(MultiMC_common STATIC ${MULTIMC_SOURCES} ${MULTIMC_UI} ${GENERATED_QRC} ${GRAPHICS_QRC})
+ADD_LIBRARY(MultiMC_common STATIC ${MULTIMC_SOURCES} ${MULTIMC_UI} ${GRAPHICS_QRC})
# Add executable
ADD_EXECUTABLE(MultiMC MACOSX_BUNDLE WIN32 main.cpp ${MULTIMC_RCS})
@@ -566,7 +575,6 @@ TARGET_LINK_LIBRARIES(MultiMC MultiMC_common)
TARGET_LINK_LIBRARIES(MultiMC_common xz-embedded unpack200 quazip libUtil libSettings libGroupView ${MultiMC_LINK_ADDITIONAL_LIBS})
QT5_USE_MODULES(MultiMC Core Widgets Network Xml Concurrent ${MultiMC_QT_ADDITIONAL_MODULES})
QT5_USE_MODULES(MultiMC_common Core Widgets Network Xml Concurrent ${MultiMC_QT_ADDITIONAL_MODULES})
-ADD_DEPENDENCIES(MultiMC_common MultiMCLauncher JavaCheck)
################################ INSTALLATION AND PACKAGING ################################
diff --git a/MultiMC.cpp b/MultiMC.cpp
index 17fc2e0a..7a82c642 100644
--- a/MultiMC.cpp
+++ b/MultiMC.cpp
@@ -20,8 +20,11 @@
#include "logic/news/NewsChecker.h"
+#include "logic/status/StatusChecker.h"
+
#include "logic/InstanceLauncher.h"
#include "logic/net/HttpMetaCache.h"
+#include "logic/net/URLConstants.h"
#include "logic/JavaUtils.h"
@@ -44,8 +47,6 @@ MultiMC::MultiMC(int &argc, char **argv, bool root_override)
setOrganizationName("MultiMC");
setApplicationName("MultiMC5");
- initTranslations();
-
setAttribute(Qt::AA_UseHighDpiPixmaps);
// Don't quit on hiding the last window
this->setQuitOnLastWindowClosed(false);
@@ -172,6 +173,9 @@ MultiMC::MultiMC(int &argc, char **argv, bool root_override)
// load settings
initGlobalSettings();
+ // load translations
+ initTranslations();
+
// initialize the updater
m_updateChecker.reset(new UpdateChecker());
@@ -181,6 +185,9 @@ MultiMC::MultiMC(int &argc, char **argv, bool root_override)
// initialize the news checker
m_newsChecker.reset(new NewsChecker(NEWS_RSS_URL));
+ // initialize the status checker
+ m_statusChecker.reset(new StatusChecker());
+
// and instances
auto InstDirSetting = m_settings->getSetting("InstanceDir");
m_instances.reset(new InstanceList(InstDirSetting->get().toString(), this));
@@ -234,18 +241,20 @@ MultiMC::~MultiMC()
void MultiMC::initTranslations()
{
+ QLocale locale(m_settings->get("Language").toString());
+ QLocale::setDefault(locale);
+ QLOG_INFO() << "Your language is" << locale.bcp47Name();
m_qt_translator.reset(new QTranslator());
- if (m_qt_translator->load("qt_" + QLocale::system().name(),
+ if (m_qt_translator->load("qt_" + locale.bcp47Name(),
QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
{
- std::cout << "Loading Qt Language File for "
- << QLocale::system().name().toLocal8Bit().constData() << "...";
+ QLOG_DEBUG() << "Loading Qt Language File for"
+ << locale.bcp47Name().toLocal8Bit().constData() << "...";
if (!installTranslator(m_qt_translator.get()))
{
- std::cout << " failed.";
+ QLOG_ERROR() << "Loading Qt Language File failed.";
m_qt_translator.reset();
}
- std::cout << std::endl;
}
else
{
@@ -253,17 +262,15 @@ void MultiMC::initTranslations()
}
m_mmc_translator.reset(new QTranslator());
- if (m_mmc_translator->load("mmc_" + QLocale::system().name(),
- QDir("translations").absolutePath()))
+ if (m_mmc_translator->load("mmc_" + locale.bcp47Name(), MMC->root() + "/translations"))
{
- std::cout << "Loading MMC Language File for "
- << QLocale::system().name().toLocal8Bit().constData() << "...";
+ QLOG_DEBUG() << "Loading MMC Language File for"
+ << locale.bcp47Name().toLocal8Bit().constData() << "...";
if (!installTranslator(m_mmc_translator.get()))
{
- std::cout << " failed.";
+ QLOG_ERROR() << "Loading MMC Language File failed.";
m_mmc_translator.reset();
}
- std::cout << std::endl;
}
else
{
@@ -366,6 +373,9 @@ void MultiMC::initGlobalSettings()
// Editors
m_settings->registerSetting("JsonEditor", QString());
+ // Language
+ m_settings->registerSetting("Language", QLocale(QLocale::system().language()).bcp47Name());
+
// Console
m_settings->registerSetting("ShowConsole", true);
m_settings->registerSetting("AutoCloseConsole", true);
diff --git a/MultiMC.h b/MultiMC.h
index 18c7aab7..638a442f 100644
--- a/MultiMC.h
+++ b/MultiMC.h
@@ -21,6 +21,7 @@ class JavaVersionList;
class UpdateChecker;
class NotificationChecker;
class NewsChecker;
+class StatusChecker;
#if defined(MMC)
#undef MMC
@@ -113,6 +114,11 @@ public:
return m_newsChecker;
}
+ std::shared_ptr<StatusChecker> statusChecker()
+ {
+ return m_statusChecker;
+ }
+
std::shared_ptr<LWJGLVersionList> lwjgllist();
std::shared_ptr<ForgeVersionList> forgelist();
@@ -183,6 +189,7 @@ private:
std::shared_ptr<UpdateChecker> m_updateChecker;
std::shared_ptr<NotificationChecker> m_notificationChecker;
std::shared_ptr<NewsChecker> m_newsChecker;
+ std::shared_ptr<StatusChecker> m_statusChecker;
std::shared_ptr<MojangAccountList> m_accounts;
std::shared_ptr<IconList> m_icons;
std::shared_ptr<QNetworkAccessManager> m_qnam;
diff --git a/changelog.yaml b/changelog.yaml
index 63c4b4b1..82dccd69 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -1,2 +1,19 @@
+#
+# This is MultiMC's changelog. It is formatted in YAML.
+#
+# Each key below represents a release version name. Each release key has several string entries under it, each containing information about a single change. Each of these entries may contain Markdown for formatting.
+#
+
0.0:
- Initial release.
+0.1:
+ - Reworked the version numbering system to support our [new Git workflow](http://nvie.com/posts/a-successful-git-branching-model/).
+ - Added a tray icon for the console window.
+ - Fixed instances getting deselected after FTB instances are loaded (or whenever the model is reset).
+ - Implemented proxy settings.
+ - Fixed sorting of Java installations in the Java list.
+ - Jar files are now distributed separately, rather than being extracted from the binary at runtime.
+ - Added additional information to the about dialog.
+0.1.1:
+ - Hotfix - Changed the issue tracker URL to [GitHub issues](https://github.com/MultiMC/MultiMC5/issues).
+
diff --git a/generated.qrc.in b/generated.qrc.in
deleted file mode 100644
index 794943eb..00000000
--- a/generated.qrc.in
+++ /dev/null
@@ -1,8 +0,0 @@
-<RCC>
-<!--
- <qresource prefix="/java">
- <file alias="launcher.jar">@MMC_BIN@/depends/launcher/MultiMCLauncher.jar</file>
- <file alias="checker.jar">@MMC_BIN@/depends/javacheck/JavaCheck.jar</file>
- </qresource>
--->
-</RCC>
diff --git a/gui/MainWindow.cpp b/gui/MainWindow.cpp
index 905d14cf..d5cc1d44 100644
--- a/gui/MainWindow.cpp
+++ b/gui/MainWindow.cpp
@@ -77,6 +77,8 @@
#include "logic/news/NewsChecker.h"
+#include "logic/status/StatusChecker.h"
+
#include "logic/net/URLConstants.h"
#include "logic/BaseInstance.h"
@@ -99,7 +101,11 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
{
MultiMCPlatform::fixWM_CLASS(this);
ui->setupUi(this);
- setWindowTitle(QString("MultiMC %1").arg(MMC->version().toString()));
+
+ QString winTitle = QString("MultiMC 5 - Version %1").arg(MMC->version().toString());
+ if (!MMC->version().platform.isEmpty())
+ winTitle += " on " + MMC->version().platform;
+ setWindowTitle(winTitle);
// OSX magic.
// setUnifiedTitleAndToolBarOnMac(true);
@@ -195,7 +201,27 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
connect(MMC->instances().get(), SIGNAL(dataIsInvalid()), SLOT(selectionBad()));
m_statusLeft = new QLabel(tr("No instance selected"), this);
+ m_statusRight = new QLabel(tr("No status available"), this);
+ m_statusRefresh = new QToolButton(this);
+ m_statusRefresh->setToolButtonStyle(Qt::ToolButtonIconOnly);
+ m_statusRefresh->setIcon(
+ QPixmap(":/icons/toolbar/refresh").scaled(16, 16, Qt::KeepAspectRatio));
+
statusBar()->addPermanentWidget(m_statusLeft, 1);
+ statusBar()->addPermanentWidget(m_statusRight, 0);
+ statusBar()->addPermanentWidget(m_statusRefresh, 0);
+
+ // Start status checker
+ {
+ connect(MMC->statusChecker().get(), &StatusChecker::statusLoaded, this, &MainWindow::updateStatusUI);
+ connect(MMC->statusChecker().get(), &StatusChecker::statusLoadingFailed, this, &MainWindow::updateStatusFailedUI);
+
+ connect(m_statusRefresh, &QAbstractButton::clicked, this, &MainWindow::reloadStatus);
+ connect(&statusTimer, &QTimer::timeout, this, &MainWindow::reloadStatus);
+ statusTimer.setSingleShot(true);
+
+ reloadStatus();
+ }
// Add "manage accounts" button, right align
QWidget *spacer = new QWidget();
@@ -231,17 +257,20 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi
connect(MMC->accounts().get(), &MojangAccountList::listChanged, [this]
{ repopulateAccountsMenu(); });
- std::shared_ptr<MojangAccountList> accounts = MMC->accounts();
+ // Show initial account
+ activeAccountChanged();
+
+ auto accounts = MMC->accounts();
// TODO: Nicer way to iterate?
for (int i = 0; i < accounts->count(); i++)
{
- MojangAccountPtr account = accounts->at(i);
+ auto account = accounts->at(i);
if (account != nullptr)
{
auto job = new NetJob("Startup player skins: " + account->username());
- for (AccountProfile profile : account->profiles())
+ for (auto profile : account->profiles())
{
auto meta = MMC->metacache()->resolveEntry("skins", profile.name + ".png");
auto action = CacheDownload::make(
@@ -491,6 +520,63 @@ void MainWindow::updateNewsLabel()
}
}
+static QString convertStatus(const QString &status)
+{
+ if(status == "green") return "↑";
+ else if(status == "yellow") return "-";
+ else if(status == "red") return "↓";
+ else return "?";
+}
+
+void MainWindow::reloadStatus()
+{
+ MMC->statusChecker()->reloadStatus();
+ updateStatusUI();
+}
+
+static QString makeStatusString(const QMap<QString, QString> statuses)
+{
+ QString status = "";
+ status += "Web: " + convertStatus(statuses["minecraft.net"]);
+ status += " Account: " + convertStatus(statuses["account.mojang.com"]);
+ status += " Skins: " + convertStatus(statuses["skins.minecraft.net"]);
+ status += " Auth: " + convertStatus(statuses["authserver.mojang.com"]);
+ status += " Session: " + convertStatus(statuses["sessionserver.mojang.com"]);
+
+ return status;
+}
+
+void MainWindow::updateStatusUI()
+{
+ auto statusChecker = MMC->statusChecker();
+ auto statuses = statusChecker->getStatusEntries();
+
+ QString status = makeStatusString(statuses);
+ if(statusChecker->isLoadingStatus())
+ {
+ m_statusRefresh->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ m_statusRefresh->setText(tr("Loading..."));
+ }
+ else
+ {
+ m_statusRefresh->setToolButtonStyle(Qt::ToolButtonIconOnly);
+ m_statusRefresh->setText(tr(""));
+ }
+
+ m_statusRight->setText(status);
+
+ statusTimer.start(60 * 1000);
+}
+
+void MainWindow::updateStatusFailedUI()
+{
+ m_statusRight->setText(makeStatusString(QMap<QString, QString>()));
+ m_statusRefresh->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ m_statusRefresh->setText(tr("Failed."));
+
+ statusTimer.start(60 * 1000);
+}
+
void MainWindow::updateAvailable(QString repo, QString versionName, int versionId)
{
UpdateDialog dlg;
@@ -853,7 +939,7 @@ void MainWindow::on_actionManageAccounts_triggered()
void MainWindow::on_actionReportBug_triggered()
{
- openWebPage(QUrl("http://multimc.myjetbrains.com/youtrack/dashboard#newissue=yes"));
+ openWebPage(QUrl("https://github.com/MultiMC/MultiMC5/issues"));
}
void MainWindow::on_actionMoreNews_triggered()
diff --git a/gui/MainWindow.h b/gui/MainWindow.h
index 12d76da4..eb478776 100644
--- a/gui/MainWindow.h
+++ b/gui/MainWindow.h
@@ -17,6 +17,7 @@
#include <QMainWindow>
#include <QProcess>
+#include <QTimer>
#include "logic/lists/InstanceList.h"
#include "logic/BaseInstance.h"
@@ -168,6 +169,12 @@ slots:
void repopulateAccountsMenu();
void updateNewsLabel();
+
+ void updateStatusUI();
+
+ void updateStatusFailedUI();
+
+ void reloadStatus();
/*!
* Runs the DownloadUpdateTask and installs updates.
@@ -198,8 +205,12 @@ private:
Task *m_versionLoadTask;
QLabel *m_statusLeft;
+ QLabel *m_statusRight;
+ QToolButton *m_statusRefresh;
QMenu *accountMenu;
QToolButton *accountMenuButton;
QAction *manageAccountsAction;
+
+ QTimer statusTimer;
};
diff --git a/gui/dialogs/AboutDialog.cpp b/gui/dialogs/AboutDialog.cpp
index efeea6f2..35c85815 100644
--- a/gui/dialogs/AboutDialog.cpp
+++ b/gui/dialogs/AboutDialog.cpp
@@ -24,6 +24,8 @@ AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AboutDia
MultiMCPlatform::fixWM_CLASS(this);
ui->setupUi(this);
+ ui->urlLabel->setOpenExternalLinks(true);
+
ui->icon->setPixmap(QIcon(":/icons/multimc/scalable/apps/multimc.svg").pixmap(64));
ui->title->setText("MultiMC 5 " + MMC->version().toString());
diff --git a/gui/dialogs/InstanceSettings.ui b/gui/dialogs/InstanceSettings.ui
index 9260caea..9c7e1757 100644
--- a/gui/dialogs/InstanceSettings.ui
+++ b/gui/dialogs/InstanceSettings.ui
@@ -168,6 +168,12 @@
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="1">
<widget class="QSpinBox" name="maxMemSpinBox">
+ <property name="toolTip">
+ <string>The maximum amount of memory Minecraft is allowed to use.</string>
+ </property>
+ <property name="suffix">
+ <string> MB</string>
+ </property>
<property name="minimum">
<number>512</number>
</property>
@@ -198,6 +204,12 @@
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="minMemSpinBox">
+ <property name="toolTip">
+ <string>The amount of memory Minecraft is started with.</string>
+ </property>
+ <property name="suffix">
+ <string> MB</string>
+ </property>
<property name="minimum">
<number>256</number>
</property>
@@ -214,6 +226,12 @@
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="permGenSpinBox">
+ <property name="toolTip">
+ <string>The amount of memory available to store loaded Java classes.</string>
+ </property>
+ <property name="suffix">
+ <string> MB</string>
+ </property>
<property name="minimum">
<number>64</number>
</property>
diff --git a/gui/dialogs/ModEditDialogCommon.cpp b/gui/dialogs/ModEditDialogCommon.cpp
index 9a15d92d..eee42e5e 100644
--- a/gui/dialogs/ModEditDialogCommon.cpp
+++ b/gui/dialogs/ModEditDialogCommon.cpp
@@ -50,8 +50,8 @@ void showWebsiteForMod(QWidget *parentDlg, Mod &m)
else
{
CustomMessageBox::selectable(
- parentDlg, parentDlg->tr("How sad!"),
- parentDlg->tr("The mod author didn't provide a website link for this mod."),
+ parentDlg, QObject::tr("How sad!"),
+ QObject::tr("The mod author didn't provide a website link for this mod."),
QMessageBox::Warning);
}
}
diff --git a/gui/dialogs/SettingsDialog.cpp b/gui/dialogs/SettingsDialog.cpp
index 00b3b1fd..b90434b0 100644
--- a/gui/dialogs/SettingsDialog.cpp
+++ b/gui/dialogs/SettingsDialog.cpp
@@ -284,6 +284,9 @@ void SettingsDialog::refreshUpdateChannelDesc()
void SettingsDialog::applySettings(SettingsObject *s)
{
+ // Language
+ s->set("Language", ui->languageBox->itemData(ui->languageBox->currentIndex()).toLocale().bcp47Name());
+
// Updates
s->set("AutoUpdate", ui->autoUpdateCheckBox->isChecked());
s->set("UpdateChannel", m_currentUpdateChannel);
@@ -365,6 +368,19 @@ void SettingsDialog::applySettings(SettingsObject *s)
void SettingsDialog::loadSettings(SettingsObject *s)
{
+ // Language
+ ui->languageBox->clear();
+ ui->languageBox->addItem(tr("English"), QLocale(QLocale::English));
+ foreach(const QString & lang,
+ QDir(MMC->root() + "/translations").entryList(QStringList() << "*.qm", QDir::Files))
+ {
+ QLocale locale(lang.section(QRegExp("[_\.]"), 1));
+ ui->languageBox->addItem(
+ QLocale::languageToString(locale.language()),
+ locale);
+ }
+ ui->languageBox->setCurrentIndex(ui->languageBox->findData(QLocale(s->get("Language").toString())));
+
// Updates
ui->autoUpdateCheckBox->setChecked(s->get("AutoUpdate").toBool());
m_currentUpdateChannel = s->get("UpdateChannel").toString();
diff --git a/gui/dialogs/SettingsDialog.ui b/gui/dialogs/SettingsDialog.ui
index e7671cce..54e7db7a 100644
--- a/gui/dialogs/SettingsDialog.ui
+++ b/gui/dialogs/SettingsDialog.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>526</width>
- <height>723</height>
+ <width>545</width>
+ <height>609</height>
</rect>
</property>
<property name="sizePolicy">
@@ -35,80 +35,47 @@
<property name="currentIndex">
<number>0</number>
</property>
- <widget class="QWidget" name="generalTab">
+ <widget class="QWidget" name="featuresTab">
<attribute name="title">
- <string>General</string>
+ <string>Features</string>
</attribute>
- <layout class="QVBoxLayout" name="verticalLayout">
+ <layout class="QVBoxLayout" name="verticalLayout_9">
<item>
- <widget class="QGroupBox" name="sortingModeBox">
- <property name="enabled">
- <bool>true</bool>
- </property>
+ <widget class="QGroupBox" name="updateSettingsBox">
<property name="title">
- <string>Sorting Mode</string>
+ <string>Update Settings</string>
</property>
- <layout class="QHBoxLayout" name="sortingModeBoxLayout">
+ <layout class="QVBoxLayout" name="verticalLayout_7">
<item>
- <widget class="QRadioButton" name="sortLastLaunchedBtn">
+ <widget class="QCheckBox" name="autoUpdateCheckBox">
<property name="text">
- <string>By last launched</string>
+ <string>Check for updates when MultiMC starts?</string>
</property>
- <attribute name="buttonGroup">
- <string notr="true">sortingModeGroup</string>
- </attribute>
</widget>
</item>
<item>
- <widget class="QRadioButton" name="sortByNameBtn">
+ <widget class="QLabel" name="updateChannelLabel">
<property name="text">
- <string>By name</string>
+ <string>Update Channel:</string>
</property>
- <attribute name="buttonGroup">
- <string notr="true">sortingModeGroup</string>
- </attribute>
</widget>
</item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="updateSettingsBox">
- <property name="title">
- <string>Update Settings</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_7">
<item>
- <widget class="QCheckBox" name="autoUpdateCheckBox">
- <property name="text">
- <string>Check for updates when MultiMC starts?</string>
+ <widget class="QComboBox" name="updateChannelComboBox">
+ <property name="enabled">
+ <bool>false</bool>
</property>
</widget>
</item>
<item>
- <layout class="QVBoxLayout" name="channelVerticalLayout">
- <item>
- <widget class="QLabel" name="updateChannelLabel">
- <property name="text">
- <string>Update Channel:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QComboBox" name="updateChannelComboBox">
- <property name="enabled">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="updateChannelDescLabel">
- <property name="text">
- <string>No channel selected.</string>
- </property>
- </widget>
- </item>
- </layout>
+ <widget class="QLabel" name="updateChannelDescLabel">
+ <property name="text">
+ <string>No channel selected.</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
</item>
</layout>
</widget>
@@ -278,6 +245,78 @@
</widget>
</item>
<item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="generalTab">
+ <attribute name="title">
+ <string>User Interface</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QGridLayout" name="_2">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Language (needs restart):</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="languageBox"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="sortingModeBox">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="title">
+ <string>Sorting Mode</string>
+ </property>
+ <layout class="QHBoxLayout" name="sortingModeBoxLayout">
+ <item>
+ <widget class="QRadioButton" name="sortLastLaunchedBtn">
+ <property name="text">
+ <string>By last launched</string>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">sortingModeGroup</string>
+ </attribute>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="sortByNameBtn">
+ <property name="text">
+ <string>By name</string>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">sortingModeGroup</string>
+ </attribute>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
<widget class="QGroupBox" name="editorsBox">
<property name="title">
<string>External Editors (leave empty for system default)</string>
@@ -424,165 +463,6 @@
</item>
</layout>
</widget>
- <widget class="QWidget" name="networkTab">
- <property name="toolTip">
- <string>Network settings.</string>
- </property>
- <attribute name="title">
- <string>Network</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_6">
- <item>
- <widget class="QGroupBox" name="proxySettingsBox">
- <property name="title">
- <string>Proxy</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_8">
- <item>
- <widget class="QGroupBox" name="proxyTypeBox">
- <property name="title">
- <string>Type</string>
- </property>
- <layout class="QHBoxLayout" name="horizontalLayout_3">
- <item>
- <widget class="QRadioButton" name="proxyDefaultBtn">
- <property name="toolTip">
- <string>Uses your system's default proxy settings.</string>
- </property>
- <property name="text">
- <string>Default</string>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">proxyGroup</string>
- </attribute>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="proxyNoneBtn">
- <property name="text">
- <string>None</string>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">proxyGroup</string>
- </attribute>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="proxySOCKS5Btn">
- <property name="text">
- <string>SOCKS5</string>
- </property>
- <attribute name="buttonGroup">
- <string notr="true">proxyGroup</string>
- </attribute>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="proxyHTTPBtn">
- <property name="text">
- <string>HTTP</string>
- </property>
- <attribute name="buttonGrou