diff options
| -rw-r--r-- | CMakeLists.txt | 26 | ||||
| -rw-r--r-- | MultiMC.cpp | 36 | ||||
| -rw-r--r-- | MultiMC.h | 7 | ||||
| -rw-r--r-- | changelog.yaml | 17 | ||||
| -rw-r--r-- | generated.qrc.in | 8 | ||||
| -rw-r--r-- | gui/MainWindow.cpp | 96 | ||||
| -rw-r--r-- | gui/MainWindow.h | 11 | ||||
| -rw-r--r-- | gui/dialogs/AboutDialog.cpp | 2 | ||||
| -rw-r--r-- | gui/dialogs/InstanceSettings.ui | 18 | ||||
| -rw-r--r-- | gui/dialogs/ModEditDialogCommon.cpp | 4 | ||||
| -rw-r--r-- | gui/dialogs/SettingsDialog.cpp | 16 | ||||
| -rw-r--r-- | gui/dialogs/SettingsDialog.ui | 503 | ||||
| -rw-r--r-- | logic/MinecraftProcess.cpp | 8 | ||||
| -rw-r--r-- | logic/NagUtils.cpp | 18 | ||||
| -rw-r--r-- | logic/net/CacheDownload.cpp | 100 | ||||
| -rw-r--r-- | logic/net/CacheDownload.h | 8 | ||||
| -rw-r--r-- | logic/net/URLConstants.h | 2 | ||||
| -rw-r--r-- | logic/status/StatusChecker.cpp | 137 | ||||
| -rw-r--r-- | logic/status/StatusChecker.h | 57 | ||||
| -rw-r--r-- | main.cpp | 1 | ||||
| -rw-r--r-- | translations/mmc_de.ts | 1828 |
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); @@ -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 |
