aboutsummaryrefslogtreecommitdiff
path: root/gui/pages
diff options
context:
space:
mode:
Diffstat (limited to 'gui/pages')
-rw-r--r--gui/pages/BasePageProvider.h41
-rw-r--r--gui/pages/LegacyJarModPage.cpp2
-rw-r--r--gui/pages/LegacyJarModPage.ui200
-rw-r--r--gui/pages/LogPage.cpp1
-rw-r--r--gui/pages/LogPage.ui222
-rw-r--r--gui/pages/ModFolderPage.cpp1
-rw-r--r--gui/pages/ModFolderPage.ui106
-rw-r--r--gui/pages/NotesPage.cpp1
-rw-r--r--gui/pages/NotesPage.ui38
-rw-r--r--gui/pages/OtherLogsPage.cpp1
-rw-r--r--gui/pages/OtherLogsPage.ui142
-rw-r--r--gui/pages/ScreenshotsPage.cpp1
-rw-r--r--gui/pages/ScreenshotsPage.ui104
-rw-r--r--gui/pages/VersionPage.cpp2
-rw-r--r--gui/pages/VersionPage.ui311
-rw-r--r--gui/pages/global/AccountListPage.cpp141
-rw-r--r--gui/pages/global/AccountListPage.h80
-rw-r--r--gui/pages/global/AccountListPage.ui115
-rw-r--r--gui/pages/global/ExternalToolsPage.cpp238
-rw-r--r--gui/pages/global/ExternalToolsPage.h68
-rw-r--r--gui/pages/global/ExternalToolsPage.ui197
-rw-r--r--gui/pages/global/JavaPage.cpp146
-rw-r--r--gui/pages/global/JavaPage.h72
-rw-r--r--gui/pages/global/JavaPage.ui303
-rw-r--r--gui/pages/global/MinecraftPage.cpp104
-rw-r--r--gui/pages/global/MinecraftPage.h69
-rw-r--r--gui/pages/global/MinecraftPage.ui184
-rw-r--r--gui/pages/global/MultiMCPage.cpp340
-rw-r--r--gui/pages/global/MultiMCPage.h90
-rw-r--r--gui/pages/global/MultiMCPage.ui399
-rw-r--r--gui/pages/global/ProxyPage.cpp95
-rw-r--r--gui/pages/global/ProxyPage.h66
-rw-r--r--gui/pages/global/ProxyPage.ui197
33 files changed, 3552 insertions, 525 deletions
diff --git a/gui/pages/BasePageProvider.h b/gui/pages/BasePageProvider.h
index cff9c8e7..5e5a11fb 100644
--- a/gui/pages/BasePageProvider.h
+++ b/gui/pages/BasePageProvider.h
@@ -17,6 +17,7 @@
#include "BasePage.h"
#include <memory>
+#include <functional>
class BasePageProvider
{
@@ -25,4 +26,44 @@ public:
virtual QString dialogTitle() = 0;
};
+class GenericPageProvider : public BasePageProvider
+{
+ typedef std::function<BasePage *()> PageCreator;
+public:
+ explicit GenericPageProvider(const QString &dialogTitle)
+ : m_dialogTitle(dialogTitle)
+ {
+ }
+
+ QList<BasePage *> getPages() override
+ {
+ QList<BasePage *> pages;
+ for (PageCreator creator : m_creators)
+ {
+ pages.append(creator());
+ }
+ return pages;
+ }
+ QString dialogTitle() override { return m_dialogTitle; }
+
+ void setDialogTitle(const QString &title)
+ {
+ m_dialogTitle = title;
+ }
+ void addPageCreator(PageCreator page)
+ {
+ m_creators.append(page);
+ }
+
+ template<typename PageClass>
+ void addPage()
+ {
+ addPageCreator([](){return new PageClass();});
+ }
+
+private:
+ QList<PageCreator> m_creators;
+ QString m_dialogTitle;
+};
+
typedef std::shared_ptr<BasePageProvider> BasePageProviderPtr;
diff --git a/gui/pages/LegacyJarModPage.cpp b/gui/pages/LegacyJarModPage.cpp
index 16a2ff66..8ff23ae2 100644
--- a/gui/pages/LegacyJarModPage.cpp
+++ b/gui/pages/LegacyJarModPage.cpp
@@ -35,6 +35,8 @@ LegacyJarModPage::LegacyJarModPage(LegacyInstance *inst, QWidget *parent)
: QWidget(parent), ui(new Ui::LegacyJarModPage), m_inst(inst)
{
ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
+
m_jarmods = m_inst->jarModList();
ui->jarModsTreeView->setModel(m_jarmods.get());
ui->jarModsTreeView->setDragDropMode(QAbstractItemView::DragDrop);
diff --git a/gui/pages/LegacyJarModPage.ui b/gui/pages/LegacyJarModPage.ui
index a1da2b20..50edfc8e 100644
--- a/gui/pages/LegacyJarModPage.ui
+++ b/gui/pages/LegacyJarModPage.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>378</width>
- <height>324</height>
+ <width>659</width>
+ <height>593</height>
</rect>
</property>
<property name="windowTitle">
@@ -27,100 +27,114 @@
<number>0</number>
</property>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="ModListView" name="jarModsTreeView">
- <property name="verticalScrollBarPolicy">
- <enum>Qt::ScrollBarAlwaysOn</enum>
- </property>
- <property name="horizontalScrollBarPolicy">
- <enum>Qt::ScrollBarAlwaysOff</enum>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QVBoxLayout" name="jarModsButtonBox">
- <item>
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Selection</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="rmJarBtn">
- <property name="text">
- <string>&amp;Remove</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="moveJarUpBtn">
- <property name="text">
- <string>Move &amp;Up</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="moveJarDownBtn">
- <property name="text">
- <string>Move &amp;Down</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="LineSeparator" name="separator" native="true"/>
- </item>
- <item>
- <widget class="QLabel" name="label_2">
- <property name="text">
- <string>Install</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="addJarBtn">
- <property name="text">
- <string>&amp;Add jar mod</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="addForgeBtn">
- <property name="text">
- <string>Install Forge</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab">
+ <attribute name="title">
+ <string>Tab 1</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout">
<item>
- <widget class="QPushButton" name="viewJarBtn">
- <property name="text">
- <string>&amp;View Folder</string>
- </property>
- </widget>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="ModListView" name="jarModsTreeView">
+ <property name="verticalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOn</enum>
+ </property>
+ <property name="horizontalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="jarModsButtonBox">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Selection</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="rmJarBtn">
+ <property name="text">
+ <string>&amp;Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="moveJarUpBtn">
+ <property name="text">
+ <string>Move &amp;Up</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="moveJarDownBtn">
+ <property name="text">
+ <string>Move &amp;Down</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="LineSeparator" name="separator" native="true"/>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Install</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="addJarBtn">
+ <property name="text">
+ <string>&amp;Add jar mod</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="addForgeBtn">
+ <property name="text">
+ <string>Install Forge</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="viewJarBtn">
+ <property name="text">
+ <string>&amp;View Folder</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
</item>
</layout>
- </item>
- </layout>
+ </widget>
+ </widget>
</item>
<item>
<widget class="MCModInfoFrame" name="jarMIFrame">
diff --git a/gui/pages/LogPage.cpp b/gui/pages/LogPage.cpp
index 601c738f..7fbf5929 100644
--- a/gui/pages/LogPage.cpp
+++ b/gui/pages/LogPage.cpp
@@ -11,6 +11,7 @@ LogPage::LogPage(MinecraftProcess *proc, QWidget *parent)
: QWidget(parent), ui(new Ui::LogPage), m_process(proc)
{
ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
connect(m_process, SIGNAL(log(QString, MessageLevel::Enum)), this,
SLOT(write(QString, MessageLevel::Enum)));
}
diff --git a/gui/pages/LogPage.ui b/gui/pages/LogPage.ui
index d6b0a0c0..b87a7522 100644
--- a/gui/pages/LogPage.ui
+++ b/gui/pages/LogPage.ui
@@ -13,7 +13,7 @@
<property name="windowTitle">
<string>Log</string>
</property>
- <layout class="QGridLayout" name="gridLayout">
+ <layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
@@ -26,112 +26,126 @@
<property name="bottomMargin">
<number>0</number>
</property>
- <item row="2" column="1">
- <widget class="QLineEdit" name="lineEdit">
- <property name="enabled">
- <bool>false</bool>
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
</property>
+ <widget class="QWidget" name="tab">
+ <attribute name="title">
+ <string>Tab 1</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="2" column="0">
+ <widget class="QLabel" name="label">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Search:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="lineEdit">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QPushButton" name="pushButton">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Find next</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="3">
+ <widget class="QPlainTextEdit" name="text">
+ <property name="undoRedoEnabled">
+ <bool>false</bool>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ <property name="plainText">
+ <string notr="true"/>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ <property name="centerOnScroll">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" colspan="3">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QCheckBox" name="checkBox">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Keep updating</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnCopy">
+ <property name="toolTip">
+ <string>Copy the whole log into the clipboard</string>
+ </property>
+ <property name="text">
+ <string>&amp;Copy</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnPaste">
+ <property name="toolTip">
+ <string>Upload the log to paste.ee - it will stay online for a month</string>
+ </property>
+ <property name="text">
+ <string>Upload</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnClear">
+ <property name="toolTip">
+ <string>Clear the log</string>
+ </property>
+ <property name="text">
+ <string>Clear</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
</widget>
</item>
- <item row="2" column="0">
- <widget class="QLabel" name="label">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Search:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="2">
- <widget class="QPushButton" name="pushButton">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Find next</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0" colspan="3">
- <widget class="QPlainTextEdit" name="text">
- <property name="undoRedoEnabled">
- <bool>false</bool>
- </property>
- <property name="readOnly">
- <bool>true</bool>
- </property>
- <property name="plainText">
- <string notr="true"/>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
- </property>
- <property name="centerOnScroll">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="0" colspan="3">
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="QCheckBox" name="checkBox">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Keep updating</string>
- </property>
- <property name="checked">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="btnCopy">
- <property name="toolTip">
- <string>Copy the whole log into the clipboard</string>
- </property>
- <property name="text">
- <string>&amp;Copy</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="btnPaste">
- <property name="toolTip">
- <string>Upload the log to paste.ee - it will stay online for a month</string>
- </property>
- <property name="text">
- <string>Upload</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="btnClear">
- <property name="toolTip">
- <string>Clear the log</string>
- </property>
- <property name="text">
- <string>Clear</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
</layout>
</widget>
<resources/>
diff --git a/gui/pages/ModFolderPage.cpp b/gui/pages/ModFolderPage.cpp
index d94696ec..24421e55 100644
--- a/gui/pages/ModFolderPage.cpp
+++ b/gui/pages/ModFolderPage.cpp
@@ -38,6 +38,7 @@ ModFolderPage::ModFolderPage(BaseInstance *inst, std::shared_ptr<ModList> mods,
: QWidget(parent), ui(new Ui::ModFolderPage)
{
ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
m_inst = inst;
m_mods = mods;
m_id = id;
diff --git a/gui/pages/ModFolderPage.ui b/gui/pages/ModFolderPage.ui
index eb29a2c0..019b8faf 100644
--- a/gui/pages/ModFolderPage.ui
+++ b/gui/pages/ModFolderPage.ui
@@ -13,7 +13,7 @@
<property name="windowTitle">
<string>Mods</string>
</property>
- <layout class="QVBoxLayout" name="verticalLayout_3">
+ <layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
@@ -27,10 +27,16 @@
<number>0</number>
</property>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab">
+ <attribute name="title">
+ <string>Tab 1</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
<widget class="ModListView" name="modTreeView">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
@@ -46,56 +52,56 @@
</property>
</widget>
</item>
- </layout>
- </item>
- <item>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
- <widget class="QPushButton" name="addModBtn">
- <property name="text">
- <string>&amp;Add</string>
- </property>
- </widget>
+ <item row="0" column="1">
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QPushButton" name="addModBtn">
+ <property name="text">
+ <string>&amp;Add</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="rmModBtn">
+ <property name="text">
+ <string>&amp;Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="viewModBtn">
+ <property name="text">
+ <string>&amp;View Folder</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
- <item>
- <widget class="QPushButton" name="rmModBtn">
- <property name="text">
- <string>&amp;Remove</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="viewModBtn">
- <property name="text">
- <string>&amp;View Folder</string>
+ <item row="1" column="0" colspan="2">
+ <widget class="MCModInfoFrame" name="frame">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
</property>
</widget>
</item>
</layout>
- </item>
- </layout>
- </item>
- <item>
- <widget class="MCModInfoFrame" name="frame">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
+ </widget>
</widget>
</item>
</layout>
diff --git a/gui/pages/NotesPage.cpp b/gui/pages/NotesPage.cpp
index a2558e3c..48bb468c 100644
--- a/gui/pages/NotesPage.cpp
+++ b/gui/pages/NotesPage.cpp
@@ -5,6 +5,7 @@ NotesPage::NotesPage(BaseInstance *inst, QWidget *parent)
: QWidget(parent), ui(new Ui::NotesPage), m_inst(inst)
{
ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
ui->noteEditor->setText(m_inst->notes());
}
diff --git a/gui/pages/NotesPage.ui b/gui/pages/NotesPage.ui
index ab33ffd3..8da01c8b 100644
--- a/gui/pages/NotesPage.ui
+++ b/gui/pages/NotesPage.ui
@@ -6,14 +6,14 @@
<rect>
<x>0</x>
<y>0</y>
- <width>400</width>
- <height>300</height>
+ <width>731</width>
+ <height>538</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
- <layout class="QHBoxLayout" name="horizontalLayout">
+ <layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
@@ -27,16 +27,30 @@
<number>0</number>
</property>
<item>
- <widget class="QTextEdit" name="noteEditor">
- <property name="verticalScrollBarPolicy">
- <enum>Qt::ScrollBarAlwaysOn</enum>
- </property>
- <property name="acceptRichText">
- <bool>false</bool>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextEditable|Qt::TextEditorInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
</property>
+ <widget class="QWidget" name="tab">
+ <attribute name="title">
+ <string>Tab 1</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTextEdit" name="noteEditor">
+ <property name="verticalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOn</enum>
+ </property>
+ <property name="acceptRichText">
+ <bool>false</bool>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextEditable|Qt::TextEditorInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
</widget>
</item>
</layout>
diff --git a/gui/pages/OtherLogsPage.cpp b/gui/pages/OtherLogsPage.cpp
index 555075e3..55c632fd 100644
--- a/gui/pages/OtherLogsPage.cpp
+++ b/gui/pages/OtherLogsPage.cpp
@@ -28,6 +28,7 @@ OtherLogsPage::OtherLogsPage(BaseInstance *instance, QWidget *parent)
m_watcher(new RecursiveFileSystemWatcher(this))
{
ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
m_watcher->setFileExpression("(.*\\.log(\\.[0-9]*)?$)|(crash-.*\\.txt)");
m_watcher->setRootDir(QDir::current().absoluteFilePath(m_instance->minecraftRoot()));
diff --git a/gui/pages/OtherLogsPage.ui b/gui/pages/OtherLogsPage.ui
index 1083ebcb..08200684 100644
--- a/gui/pages/OtherLogsPage.ui
+++ b/gui/pages/OtherLogsPage.ui
@@ -13,7 +13,7 @@
<property name="windowTitle">
<string>Form</string>
</property>
- <layout class="QVBoxLayout" name="verticalLayout">
+ <layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
@@ -27,70 +27,84 @@
<number>0</number>
</property>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="QComboBox" name="selectLogBox">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="btnReload">
- <property name="text">
- <string>Reload</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="btnCopy">
- <property name="toolTip">
- <string>Copy the whole log into the clipboard</string>
- </property>
- <property name="text">
- <string>&amp;Copy</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="btnPaste">
- <property name="toolTip">
- <string>Upload the log to paste.ee - it will stay online for a month</string>
- </property>
- <property name="text">
- <string>Upload</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="btnDelete">
- <property name="toolTip">
- <string>Clear the log</string>
- </property>
- <property name="text">
- <string>Delete</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QPlainTextEdit" name="text">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="verticalScrollBarPolicy">
- <enum>Qt::ScrollBarAlwaysOn</enum>
- </property>
- <property name="readOnly">
- <bool>true</bool>
- </property>
- <property name="textInteractionFlags">
- <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
</property>
+ <widget class="QWidget" name="tab">
+ <attribute name="title">
+ <string>Tab 1</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QComboBox" name="selectLogBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnReload">
+ <property name="text">
+ <string>Reload</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnCopy">
+ <property name="toolTip">
+ <string>Copy the whole log into the clipboard</string>
+ </property>
+ <property name="text">
+ <string>&amp;Copy</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnPaste">
+ <property name="toolTip">
+ <string>Upload the log to paste.ee - it will stay online for a month</string>
+ </property>
+ <property name="text">
+ <string>Upload</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="btnDelete">
+ <property name="toolTip">
+ <string>Clear the log</string>
+ </property>
+ <property name="text">
+ <string>Delete</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QPlainTextEdit" name="text">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="verticalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOn</enum>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
</widget>
</item>
</layout>
diff --git a/gui/pages/ScreenshotsPage.cpp b/gui/pages/ScreenshotsPage.cpp
index 004f797b..d47a2897 100644
--- a/gui/pages/ScreenshotsPage.cpp
+++ b/gui/pages/ScreenshotsPage.cpp
@@ -222,6 +222,7 @@ ScreenshotsPage::ScreenshotsPage(BaseInstance *instance, QWidget *parent)
m_valid = ensureFolderPathExists(m_folder);
ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
ui->listView->setModel(m_filterModel.get());
ui->listView->setIconSize(QSize(128, 128));
ui->listView->setGridSize(QSize(192, 160));
diff --git a/gui/pages/ScreenshotsPage.ui b/gui/pages/ScreenshotsPage.ui
index 5951ab02..30b55092 100644
--- a/gui/pages/ScreenshotsPage.ui
+++ b/gui/pages/ScreenshotsPage.ui
@@ -13,7 +13,7 @@
<property name="windowTitle">
<string>Mods</string>
</property>
- <layout class="QVBoxLayout" name="verticalLayout_3">
+ <layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
@@ -27,9 +27,15 @@
<number>0</number>
</property>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <layout class="QVBoxLayout" name="verticalLayout">
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab">
+ <attribute name="title">
+ <string>Tab 1</string>
+ </attribute>
+ <layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QListView" name="listView">
<property name="selectionMode">
@@ -40,54 +46,54 @@
</property>
</widget>
</item>
- </layout>
- </item>
- <item>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
- <widget class="QPushButton" name="uploadBtn">
- <property name="text">
- <string>&amp;Upload</string>
- </property>
- </widget>
- </item>
<item>
- <widget class="QPushButton" name="deleteBtn">
- <property name="text">
- <string>&amp;Delete</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="renameBtn">
- <property name="text">
- <string>&amp;Rename</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="viewFolderBtn">
- <property name="text">
- <string>&amp;View Folder</string>
- </property>
- </widget>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QPushButton" name="uploadBtn">
+ <property name="text">
+ <string>&amp;Upload</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="deleteBtn">
+ <property name="text">
+ <string>&amp;Delete</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="renameBtn">
+ <property name="text">
+ <string>&amp;Rename</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="viewFolderBtn">
+ <property name="text">
+ <string>&amp;View Folder</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
</layout>
- </item>
- </layout>
+ </widget>
+ </widget>
</item>
</layout>
</widget>
diff --git a/gui/pages/VersionPage.cpp b/gui/pages/VersionPage.cpp
index 6e29dd41..e19cf7cc 100644
--- a/gui/pages/VersionPage.cpp
+++ b/gui/pages/VersionPage.cpp
@@ -63,7 +63,7 @@ VersionPage::VersionPage(OneSixInstance *inst, QWidget *parent)
: QWidget(parent), ui(new Ui::VersionPage), m_inst(inst)
{
ui->setupUi(this);
- // libraries!
+ ui->tabWidget->tabBar()->hide();
m_version = m_inst->getFullVersion();
if (m_version)
diff --git a/gui/pages/VersionPage.ui b/gui/pages/VersionPage.ui
index f770df55..9b270d01 100644
--- a/gui/pages/VersionPage.ui
+++ b/gui/pages/VersionPage.ui
@@ -6,17 +6,14 @@
<rect>
<x>0</x>
<y>0</y>
- <width>400</width>
- <height>475</height>
+ <width>693</width>
+ <height>575</height>
</rect>
</property>
<property name="windowTitle">
<string>Version</string>
</property>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <property name="spacing">
- <number>6</number>
- </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
@@ -30,152 +27,162 @@
<number>0</number>
</property>
<item>
- <layout class="QVBoxLayout" name="verticalLayout_10">
- <item>
- <widget class="ModListView" name="libraryTreeView">
- <property name="verticalScrollBarPolicy">
- <enum>Qt::ScrollBarAlwaysOn</enum>
- </property>
- <property name="horizontalScrollBarPolicy">
- <enum>Qt::ScrollBarAlwaysOff</enum>
- </property>
- <property name="headerHidden">
- <bool>false</bool>
- </property>
- <attribute name="headerVisible">
- <bool>true</bool>
- </attribute>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QVBoxLayout" name="verticalLayout_4">
- <item>
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Selection</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="changeMCVersionBtn">
- <property name="text">
- <string>Change version</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="moveLibraryUpBtn">
- <property name="toolTip">
- <string>This isn't implemented yet.</string>
- </property>
- <property name="text">
- <string>Move up</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="moveLibraryDownBtn">
- <property name="toolTip">
- <string>This isn't implemented yet.</string>
- </property>
- <property name="text">
- <string>Move down</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="removeLibraryBtn">
- <property name="text">
- <string>Remove</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="LineSeparator" name="separator" native="true"/>
- </item>
- <item>
- <widget class="QLabel" name="label_2">
- <property name="text">
- <string>Install</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="forgeBtn">
- <property name="toolTip">
- <string>Replace any current custom version with Minecraft Forge</string>
- </property>
- <property name="text">
- <string>Install Forge</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="liteloaderBtn">
- <property name="text">
- <string>Install LiteLoader</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="jarmodBtn">
- <property name="text">
- <string>Add jar mod</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="LineSeparator" name="widget" native="true"/>
- </item>
- <item>
- <widget class="QLabel" name="label_5">
- <property name="text">
- <string>List</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="resetLibraryOrderBtn">
- <property name="toolTip">
- <string>This isn't implemented yet.</string>
- </property>
- <property name="text">
- <string>Reset order</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="reloadLibrariesBtn">
- <property name="text">
- <string>Reload</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer_7">
- <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 class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab">
+ <attribute name="title">
+ <string>Tab 1</string>
+ </attribute>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="ModListView" name="libraryTreeView">
+ <property name="verticalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOn</enum>
+ </property>
+ <property name="horizontalScrollBarPolicy">
+ <enum>Qt::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="headerHidden">
+ <bool>false</bool>
+ </property>
+ <attribute name="headerVisible">
+ <bool>true</bool>
+ </attribute>
+ </widget>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Selection</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="changeMCVersionBtn">
+ <property name="text">
+ <string>Change version</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="moveLibraryUpBtn">
+ <property name="toolTip">
+ <string>This isn't implemented yet.</string>
+ </property>
+ <property name="text">
+ <string>Move up</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="moveLibraryDownBtn">
+ <property name="toolTip">
+ <string>This isn't implemented yet.</string>
+ </property>
+ <property name="text">
+ <string>Move down</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="removeLibraryBtn">
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="LineSeparator" name="separator" native="true"/>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Install</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="forgeBtn">
+ <property name="toolTip">
+ <string>Replace any current custom version with Minecraft Forge</string>
+ </property>
+ <property name="text">
+ <string>Install Forge</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="liteloaderBtn">
+ <property name="text">
+ <string>Install LiteLoader</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="jarmodBtn">
+ <property name="text">
+ <string>Add jar mod</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="LineSeparator" name="widget" native="true"/>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>List</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="resetLibraryOrderBtn">
+ <property name="toolTip">
+ <string>This isn't implemented yet.</string>
+ </property>
+ <property name="text">
+ <string>Reset order</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="reloadLibrariesBtn">
+ <property name="text">
+ <string>Reload</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_7">
+ <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>
+ </item>
+ </layout>
+ </widget>
+ </widget>
</item>
</layout>
</widget>
diff --git a/gui/pages/global/AccountListPage.cpp b/gui/pages/global/AccountListPage.cpp
new file mode 100644
index 00000000..00487d57
--- /dev/null
+++ b/gui/pages/global/AccountListPage.cpp
@@ -0,0 +1,141 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "AccountListPage.h"
+#include "ui_AccountListPage.h"
+
+#include <QItemSelectionModel>
+
+#include <logger/QsLog.h>
+
+#include "logic/net/NetJob.h"
+#include "logic/net/URLConstants.h"
+
+#include "gui/dialogs/EditAccountDialog.h"
+#include "gui/dialogs/ProgressDialog.h"
+#include "gui/dialogs/AccountSelectDialog.h"
+#include "gui/dialogs/LoginDialog.h"
+#include "gui/dialogs/CustomMessageBox.h"
+#include "logic/tasks/Task.h"
+#include "logic/auth/YggdrasilTask.h"
+
+#include <MultiMC.h>
+
+AccountListPage::AccountListPage(QWidget *parent)
+ : QWidget(parent), ui(new Ui::AccountListPage)
+{
+ ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
+
+ m_accounts = MMC->accounts();
+
+ ui->listView->setModel(m_accounts.get());
+ ui->listView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
+
+ // Expand the account column
+ ui->listView->header()->setSectionResizeMode(1, QHeaderView::Stretch);
+
+ QItemSelectionModel *selectionModel = ui->listView->selectionModel();
+
+ connect(selectionModel, &QItemSelectionModel::selectionChanged,
+ [this](const QItemSelection &sel, const QItemSelection &dsel)
+ { updateButtonStates(); });
+
+ connect(m_accounts.get(), SIGNAL(listChanged()), SLOT(listChanged()));
+ connect(m_accounts.get(), SIGNAL(activeAccountChanged()), SLOT(listChanged()));
+
+ updateButtonStates();
+}
+
+AccountListPage::~AccountListPage()
+{
+ delete ui;
+}
+
+void AccountListPage::listChanged()
+{
+ updateButtonStates();
+}
+
+void AccountListPage::on_addAccountBtn_clicked()
+{
+ addAccount(tr("Please enter your Mojang or Minecraft account username and password to add "
+ "your account."));
+}
+
+void AccountListPage::on_rmAccountBtn_clicked()
+{
+ QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes();
+ if (selection.size() > 0)
+ {
+ QModelIndex selected = selection.first();
+ m_accounts->removeAccount(selected);
+ }
+}
+
+void AccountListPage::on_setDefaultBtn_clicked()
+{
+ QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes();
+ if (selection.size() > 0)
+ {
+ QModelIndex selected = selection.first();
+ MojangAccountPtr account =
+ selected.data(MojangAccountList::PointerRole).value<MojangAccountPtr>();
+ m_accounts->setActiveAccount(account->username());
+ }
+}
+
+void AccountListPage::on_noDefaultBtn_clicked()
+{
+ m_accounts->setActiveAccount("");
+}
+
+void AccountListPage::updateButtonStates()
+{
+ // If there is no selection, disable buttons that require something selected.
+ QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes();
+
+ ui->rmAccountBtn->setEnabled(selection.size() > 0);
+ ui->setDefaultBtn->setEnabled(selection.size() > 0);
+
+ ui->noDefaultBtn->setDown(m_accounts->activeAccount().get() == nullptr);
+}
+
+void AccountListPage::addAccount(const QString &errMsg)
+{
+ // TODO: The login dialog isn't quite done yet
+ MojangAccountPtr account = LoginDialog::newAccount(this, errMsg);
+
+ if (account != nullptr)
+ {
+ m_accounts->addAccount(account);
+ if (m_accounts->count() == 1)
+ m_accounts->setActiveAccount(account->username());
+
+ // Grab associated player skins
+ auto job = new NetJob("Player skins: " + account->username());
+
+ for (AccountProfile profile : account->profiles())
+ {
+ auto meta = MMC->metacache()->resolveEntry("skins", profile.name + ".png");
+ auto action = CacheDownload::make(
+ QUrl("http://" + URLConstants::SKINS_BASE + profile.name + ".png"), meta);
+ job->addNetAction(action);
+ meta->stale = true;
+ }
+
+ job->start();
+ }
+}
diff --git a/gui/pages/global/AccountListPage.h b/gui/pages/global/AccountListPage.h
new file mode 100644
index 00000000..fd2c96e3
--- /dev/null
+++ b/gui/pages/global/AccountListPage.h
@@ -0,0 +1,80 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <QDialog>
+#include <memory>
+
+#include "gui/pages/BasePage.h"
+
+#include "logic/auth/MojangAccountList.h"
+
+namespace Ui
+{
+class AccountListPage;
+}
+
+class AuthenticateTask;
+
+class AccountListPage : public QWidget, public BasePage
+{
+ Q_OBJECT
+public:
+ explicit AccountListPage(QWidget *parent = 0);
+ ~AccountListPage();
+
+ QString displayName() const override
+ {
+ return tr("Accounts");
+ }
+ QIcon icon() const override
+ {
+ return QIcon::fromTheme("noaccount");
+ }
+ QString id() const override
+ {
+ return "accounts";
+ }
+ QString helpPage() const override
+ {
+ return "Accounts";
+ }
+
+public
+slots:
+ void on_addAccountBtn_clicked();
+
+ void on_rmAccountBtn_clicked();
+
+ void on_setDefaultBtn_clicked();
+
+ void on_noDefaultBtn_clicked();
+
+ void listChanged();
+
+ //! Updates the states of the dialog's buttons.
+ void updateButtonStates();
+
+protected:
+ std::shared_ptr<MojangAccountList> m_accounts;
+
+protected
+slots:
+ void addAccount(const QString& errMsg="");
+
+private:
+ Ui::AccountListPage *ui;
+};
diff --git a/gui/pages/global/AccountListPage.ui b/gui/pages/global/AccountListPage.ui
new file mode 100644
index 00000000..8ad78cf4
--- /dev/null
+++ b/gui/pages/global/AccountListPage.ui
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>AccountListPage</class>
+ <widget class="QWidget" name="AccountListPage">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>694</width>
+ <height>609</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Manage Accounts</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab">
+ <attribute name="title">
+ <string>Tab 1</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="welcomeLabel">
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Welcome! If you're new here, you can click the &amp;quot;Add&amp;quot; button to add your Mojang or Minecraft account.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QTreeView" name="listView"/>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="manageAcctsBtnBox">
+ <item>
+ <widget class="QPushButton" name="addAccountBtn">
+ <property name="text">
+ <string>&amp;Add</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="rmAccountBtn">
+ <property name="text">
+ <string>&amp;Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="buttonSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="setDefaultBtn">
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Set the currently selected account as the active account. The active account is the account that is used to log in (unless it is overridden in an instance-specific setting).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string>&amp;Set Default</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="noDefaultBtn">
+ <property name="toolTip">
+ <string>Set no default account. This will cause MultiMC to prompt you to select an account every time you launch an instance that doesn't have its own default set.</string>
+ </property>
+ <property name="text">
+ <string>&amp;No Default</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/gui/pages/global/ExternalToolsPage.cpp b/gui/pages/global/ExternalToolsPage.cpp
new file mode 100644
index 00000000..417a13e3
--- /dev/null
+++ b/gui/pages/global/ExternalToolsPage.cpp
@@ -0,0 +1,238 @@
+/* Copyright 2014 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ExternalToolsPage.h"
+#include "ui_ExternalToolsPage.h"
+
+#include <QMessageBox>
+#include <QFileDialog>
+#include <QStandardPaths>
+
+#include <pathutils.h>
+
+#include "logic/settings/SettingsObject.h"
+#include "logic/tools/BaseProfiler.h"
+#include "MultiMC.h"
+
+ExternalToolsPage::ExternalToolsPage(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::ExternalToolsPage)
+{
+ ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
+
+ #if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
+ ui->jsonEditorTextBox->setClearButtonEnabled(true);
+ #endif
+
+ ui->mceditLink->setOpenExternalLinks(true);
+ ui->jvisualvmLink->setOpenExternalLinks(true);
+ ui->jprofilerLink->setOpenExternalLinks(true);
+ loadSettings();
+}
+
+ExternalToolsPage::~ExternalToolsPage()
+{
+ delete ui;
+}
+
+void ExternalToolsPage::loadSettings()
+{
+ auto s = MMC->settings();
+ ui->jprofilerPathEdit->setText(s->get("JProfilerPath").toString());
+ ui->jvisualvmPathEdit->setText(s->get("JVisualVMPath").toString());
+ ui->mceditPathEdit->setText(s->get("MCEditPath").toString());
+
+ // Editors
+ ui->jsonEditorTextBox->setText(s->get("JsonEditor").toString());
+}
+void ExternalToolsPage::applySettings()
+{
+ auto s = MMC->settings();
+ s->set("JProfilerPath", ui->jprofilerPathEdit->text());
+ s->set("JVisualVMPath", ui->jvisualvmPathEdit->text());
+ s->set("MCEditPath", ui->mceditPathEdit->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);
+}
+
+void ExternalToolsPage::on_jprofilerPathBtn_clicked()
+{
+ QString raw_dir = ui->jprofilerPathEdit->text();
+ QString error;
+ do
+ {
+ raw_dir = QFileDialog::getExistingDirectory(this, tr("JProfiler Directory"), raw_dir);
+ if (raw_dir.isEmpty())
+ {
+ break;
+ }
+ QString cooked_dir = NormalizePath(raw_dir);
+ if (!MMC->profilers()["jprofiler"]->check(cooked_dir, &error))
+ {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Error while checking JProfiler install:\n%1").arg(error));
+ continue;
+ }
+ else
+ {
+ ui->jprofilerPathEdit->setText(cooked_dir);
+ break;
+ }
+ } while (1);
+}
+void ExternalToolsPage::on_jprofilerCheckBtn_clicked()
+{
+ QString error;
+ if (!MMC->profilers()["jprofiler"]->check(ui->jprofilerPathEdit->text(), &error))
+ {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Error while checking JProfiler install:\n%1").arg(error));
+ }
+ else
+ {
+ QMessageBox::information(this, tr("OK"), tr("JProfiler setup seems to be OK"));
+ }
+}
+
+void ExternalToolsPage::on_jvisualvmPathBtn_clicked()
+{
+ QString raw_dir = ui->jvisualvmPathEdit->text();
+ QString error;
+ do
+ {
+ raw_dir = QFileDialog::getOpenFileName(this, tr("JVisualVM Executable"), raw_dir);
+ if (raw_dir.isEmpty())
+ {
+ break;
+ }
+ QString cooked_dir = NormalizePath(raw_dir);
+ if (!MMC->profilers()["jvisualvm"]->check(cooked_dir, &error))
+ {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Error while checking JVisualVM install:\n%1").arg(error));
+ continue;
+ }
+ else
+ {
+ ui->jvisualvmPathEdit->setText(cooked_dir);
+ break;
+ }
+ } while (1);
+}
+void ExternalToolsPage::on_jvisualvmCheckBtn_clicked()
+{
+ QString error;
+ if (!MMC->profilers()["jvisualvm"]->check(ui->jvisualvmPathEdit->text(), &error))
+ {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Error while checking JVisualVM install:\n%1").arg(error));
+ }
+ else
+ {
+ QMessageBox::information(this, tr("OK"), tr("JVisualVM setup seems to be OK"));
+ }
+}
+
+void ExternalToolsPage::on_mceditPathBtn_clicked()
+{
+ QString raw_dir = ui->mceditPathEdit->text();
+ QString error;
+ do
+ {
+#ifdef Q_OS_OSX
+#warning stuff
+ raw_dir = QFileDialog::getOpenFileName(this, tr("MCEdit Application"), raw_dir);
+#else
+ raw_dir = QFileDialog::getExistingDirectory(this, tr("MCEdit Directory"), raw_dir);
+#endif
+ if (raw_dir.isEmpty())
+ {
+ break;
+ }
+ QString cooked_dir = NormalizePath(raw_dir);
+ if (!MMC->tools()["mcedit"]->check(cooked_dir, &error))
+ {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Error while checking MCEdit install:\n%1").arg(error));
+ continue;
+ }
+ else
+ {
+ ui->mceditPathEdit->setText(cooked_dir);
+ break;
+ }
+ } while (1);
+}
+void ExternalToolsPage::on_mceditCheckBtn_clicked()
+{
+ QString error;
+ if (!MMC->tools()["mcedit"]->check(ui->mceditPathEdit->text(), &error))
+ {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Error while checking MCEdit install:\n%1").arg(error));
+ }
+ else
+ {
+ QMessageBox::information(this, tr("OK"), tr("MCEdit setup seems to be OK"));
+ }
+}
+
+void ExternalToolsPage::on_jsonEditorBrowseBtn_clicked()
+{
+ QString raw_file = QFileDialog::getOpenFileName(
+ this, tr("JSON Editor"),
+ ui->jsonEditorTextBox->text().isEmpty()
+#if defined(Q_OS_LINUX)
+ ? QString("/usr/bin")
+#else
+ ? QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation).first()
+#endif
+ : ui->jsonEditorTextBox->text());
+ QString cooked_file = NormalizePath(raw_file);
+
+ if (cooked_file.isEmpty())
+ {
+ return;
+ }
+
+ // it has to exist and be an executable
+ if (QFileInfo(cooked_file).exists() && QFileInfo(cooked_file).isExecutable())
+ {
+ ui->jsonEditorTextBox->setText(cooked_file);
+ }
+ else
+ {
+ QMessageBox::warning(this, tr("Invalid"),
+ tr("The file chosen does not seem to be an executable"));
+ }
+}
+
+bool ExternalToolsPage::apply()
+{
+ applySettings();
+ return true;
+}
diff --git a/gui/pages/global/ExternalToolsPage.h b/gui/pages/global/ExternalToolsPage.h
new file mode 100644
index 00000000..027e164e
--- /dev/null
+++ b/gui/pages/global/ExternalToolsPage.h
@@ -0,0 +1,68 @@
+/* Copyright 2014 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <QWidget>
+
+#include "gui/pages/BasePage.h"
+
+namespace Ui {
+class ExternalToolsPage;
+}
+
+class ExternalToolsPage : public QWidget, public BasePage
+{
+ Q_OBJECT
+
+public:
+ explicit ExternalToolsPage(QWidget *parent = 0);
+ ~ExternalToolsPage();
+
+ QString displayName() const override
+ {
+ return tr("External Tools");
+ }
+ QIcon icon() const override
+ {
+ return QIcon::fromTheme("plugin-blue");
+ }
+ QString id() const override
+ {
+ return "external-tools";
+ }
+ QString helpPage() const override
+ {
+ return "External-tools";
+ }
+ virtual bool apply();
+
+private:
+ void loadSettings();
+ void applySettings();
+
+private:
+ Ui::ExternalToolsPage *ui;
+
+private
+slots:
+ void on_jprofilerPathBtn_clicked();
+ void on_jprofilerCheckBtn_clicked();
+ void on_jvisualvmPathBtn_clicked();
+ void on_jvisualvmCheckBtn_clicked();
+ void on_mceditPathBtn_clicked();
+ void on_mceditCheckBtn_clicked();
+ void on_jsonEditorBrowseBtn_clicked();
+};
diff --git a/gui/pages/global/ExternalToolsPage.ui b/gui/pages/global/ExternalToolsPage.ui
new file mode 100644
index 00000000..ba1b6f01
--- /dev/null
+++ b/gui/pages/global/ExternalToolsPage.ui
@@ -0,0 +1,197 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ExternalToolsPage</class>
+ <widget class="QWidget" name="ExternalToolsPage">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>673</width>
+ <height>751</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab">
+ <attribute name="title">
+ <string>Tab 1</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QGroupBox" name="groupBox_2">
+ <property name="title">
+ <string>JProfiler</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_10">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <widget class="QLineEdit" name="jprofilerPathEdit"/>
+ </item>
+ <item>
+ <widget class="QPushButton" name="jprofilerPathBtn">
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QPushButton" name="jprofilerCheckBtn">
+ <property name="text">
+ <string>Check</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="jprofilerLink">
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;http://www.ej-technologies.com/products/jprofiler/overview.html&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;http://www.ej-technologies.com/products/jprofiler/overview.html&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_3">
+ <property name="title">
+ <string>JVisualVM</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_11">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <item>
+ <widget class="QLineEdit" name="jvisualvmPathEdit"/>
+ </item>
+ <item>
+ <widget class="QPushButton" name="jvisualvmPathBtn">
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QPushButton" name="jvisualvmCheckBtn">
+ <property name="text">
+ <string>Check</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="jvisualvmLink">
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;http://visualvm.java.net/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;http://visualvm.java.net/&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_4">
+ <property name="title">
+ <string>MCEdit</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_12">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_6">
+ <item>
+ <widget class="QLineEdit" name="mceditPathEdit"/>
+ </item>
+ <item>
+ <widget class="QPushButton" name="mceditPathBtn">
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QPushButton" name="mceditCheckBtn">
+ <property name="text">
+ <string>Check</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="mceditLink">
+ <property name="text">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;http://www.mcedit.net/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;http://www.mcedit.net/&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="editorsBox">
+ <property name="title">
+ <string>External Editors (leave empty for system default)</string>
+ </property>
+ <layout class="QGridLayout" name="foldersBoxLayout_2">
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="jsonEditorTextBox"/>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelJsonEditor">
+ <property name="text">
+ <string>Text Editor:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QToolButton" name="jsonEditorBrowseBtn">
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>216</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/gui/pages/global/JavaPage.cpp b/gui/pages/global/JavaPage.cpp
new file mode 100644
index 00000000..86451411
--- /dev/null
+++ b/gui/pages/global/JavaPage.cpp
@@ -0,0 +1,146 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "JavaPage.h"
+#include "ui_JavaPage.h"
+
+#include <QFileDialog>
+#include <QMessageBox>
+#include <QDir>
+
+#include <pathutils.h>
+
+#include "logic/NagUtils.h"
+
+#include "gui/Platform.h"
+#include "gui/dialogs/VersionSelectDialog.h"
+#include <gui/ColumnResizer.h>
+
+#include "logic/java/JavaUtils.h"
+#include "logic/java/JavaVersionList.h"
+#include "logic/java/JavaChecker.h"
+
+#include "logic/settings/SettingsObject.h"
+#include "MultiMC.h"
+
+JavaPage::JavaPage(QWidget *parent) : QWidget(parent), ui(new Ui::JavaPage)
+{
+ ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
+
+ auto resizer = new ColumnResizer(this);
+ resizer->addWidgetsFromLayout(ui->javaSettingsGroupBox->layout(), 0);
+ resizer->addWidgetsFromLayout(ui->customCommandsGroupBox->layout(), 0);
+
+ loadSettings();
+}
+
+JavaPage::~JavaPage()
+{
+ delete ui;
+}
+
+bool JavaPage::apply()
+{
+ applySettings();
+ return true;
+}
+
+void JavaPage::applySettings()
+{
+ auto s = MMC->settings();
+ // Memory
+ s->set("MinMemAlloc", ui->minMemSpinBox->value());
+ s->set("MaxMemAlloc", ui->maxMemSpinBox->value());
+ s->set("PermGen", ui->permGenSpinBox->value());
+
+ // Java Settings
+ s->set("JavaPath", ui->javaPathTextBox->text());
+ s->set("JvmArgs", ui->jvmArgsTextBox->text());
+ NagUtils::checkJVMArgs(s->get("JvmArgs").toString(), this->parentWidget());
+
+ // Custom Commands
+ s->set("PreLaunchCommand", ui->preLaunchCmdTextBox->text());
+ s->set("PostExitCommand", ui->postExitCmdTextBox->text());
+}
+void JavaPage::loadSettings()
+{
+ auto s = MMC->settings();
+ // Memory
+ ui->minMemSpinBox->setValue(s->get("MinMemAlloc").toInt());
+ ui->maxMemSpinBox->setValue(s->get("MaxMemAlloc").toInt());
+ ui->permGenSpinBox->setValue(s->get("PermGen").toInt());
+
+ // Java Settings
+ ui->javaPathTextBox->setText(s->get("JavaPath").toString());
+ ui->jvmArgsTextBox->setText(s->get("JvmArgs").toString());
+
+ // Custom Commands
+ ui->preLaunchCmdTextBox->setText(s->get("PreLaunchCommand").toString());
+ ui->postExitCmdTextBox->setText(s->get("PostExitCommand").toString());
+}
+
+void JavaPage::on_javaDetectBtn_clicked()
+{
+ JavaVersionPtr java;
+
+ VersionSelectDialog vselect(MMC->javalist().get(), tr("Select a Java version"), this, true);
+ vselect.setResizeOn(2);
+ vselect.exec();
+
+ if (vselect.result() == QDialog::Accepted && vselect.selectedVersion())
+ {
+ java = std::dynamic_pointer_cast<JavaVersion>(vselect.selectedVersion());
+ ui->javaPathTextBox->setText(java->path);
+ }
+}
+void JavaPage::on_javaBrowseBtn_clicked()
+{
+ QString dir = QFileDialog::getOpenFileName(this, tr("Find Java executable"));
+ if (!dir.isNull())
+ {
+ ui->javaPathTextBox->setText(dir);
+ }
+}
+void JavaPage::on_javaTestBtn_clicked()
+{
+ checker.reset(new JavaChecker());
+ connect(checker.get(), SIGNAL(checkFinished(JavaCheckResult)), this,
+ SLOT(checkFinished(JavaCheckResult)));
+ checker->path = ui->javaPathTextBox->text();
+ checker->performCheck();
+}
+
+void JavaPage::checkFinished(JavaCheckResult result)
+{
+ if (result.valid)
+ {
+ QString text;
+ text += "Java test succeeded!\n";
+ if (result.is_64bit)
+ text += "Using 64bit java.\n";
+ text += "\n";
+ text += "Platform reported: " + result.realPlatform + "\n";
+ text += "Java version reported: " + result.javaVersion;
+ QMessageBox::information(this, tr("Java test success"), text);
+ }
+ else
+ {
+ QMessageBox::warning(
+ this, tr("Java test failure"),
+ tr("The specified java binary didn't work. You should use the auto-detect feature, "
+ "or set the path to the java executable."));
+ }
+}
diff --git a/gui/pages/global/JavaPage.h b/gui/pages/global/JavaPage.h
new file mode 100644
index 00000000..d0228bd2
--- /dev/null
+++ b/gui/pages/global/JavaPage.h
@@ -0,0 +1,72 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <memory>
+#include <QDialog>
+
+#include "logic/java/JavaChecker.h"
+#include "gui/pages/BasePage.h"
+
+class SettingsObject;
+
+namespace Ui
+{
+class JavaPage;
+}
+
+class JavaPage : public QWidget, public BasePage
+{
+ Q_OBJECT
+
+public:
+ explicit JavaPage(QWidget *parent = 0);
+ ~JavaPage();
+
+ QString displayName() const override
+ {
+ return tr("Java");
+ }
+ QIcon icon() const override
+ {
+ return QIcon::fromTheme("java");
+ }
+ QString id() const override
+ {
+ return "java-settings";
+ }
+ QString helpPage() const override
+ {
+ return "Java-settings";
+ }
+ bool apply() override;
+
+private:
+ void applySettings();
+ void loadSettings();
+
+private
+slots:
+ void on_javaDetectBtn_clicked();
+ void on_javaTestBtn_clicked();
+ void on_javaBrowseBtn_clicked();
+
+ void checkFinished(JavaCheckResult result);
+
+private:
+ Ui::JavaPage *ui;
+ std::shared_ptr<JavaChecker> checker;
+};
diff --git a/gui/pages/global/JavaPage.ui b/gui/pages/global/JavaPage.ui
new file mode 100644
index 00000000..6ae41a49
--- /dev/null
+++ b/gui/pages/global/JavaPage.ui
@@ -0,0 +1,303 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>JavaPage</class>
+ <widget class="QWidget" name="JavaPage">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>545</width>
+ <height>609</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Settings</string>
+ </property>
+ <property name="windowIcon">
+ <iconset>
+ <normaloff>:/icons/toolbar/settings</normaloff>:/icons/toolbar/settings</iconset>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab">
+ <attribute name="title">
+ <string>Tab 1</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QGroupBox" name="memoryGroupBox">
+ <property name="title">
+ <string>Memory</string>
+ </property>
+ <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>
+ <property name="maximum">
+ <number>65536</number>
+ </property>
+ <property name="singleStep">
+ <number>128</number>
+ </property>
+ <property name="value">
+ <number>1024</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelMinMem">
+ <property name="text">
+ <string>Minimum memory allocation:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelMaxMem">
+ <property name="text">
+ <string>Maximum memory allocation:</string>
+ </property>
+ </widget>
+ </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>
+ <property name="maximum">
+ <number>65536</number>
+ </property>
+ <property name="singleStep">
+ <number>128</number>
+ </property>
+ <property name="value">
+ <number>256</number>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="labelPermGen">
+ <property name="text">
+ <string>PermGen:</string>
+ </property>
+ </widget>
+ </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>
+ <property name="maximum">
+ <number>999999999</number>
+ </property>
+ <property name="singleStep">
+ <number>8</number>
+ </property>
+ <property name="value">
+ <number>64</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="javaSettingsGroupBox">
+ <property name="title">
+ <string>Java Runtime</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelJavaPath">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Java path:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QPushButton" name="javaDetectBtn">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Auto-detect...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QPushButton" name="javaTestBtn">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Test</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="labelJVMArgs">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>JVM arguments:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="2">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLineEdit" name="javaPathTextBox"/>
+ </item>
+ <item>
+ <widget class="QPushButton" name="javaBrowseBtn">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>28</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="2" column="1" colspan="2">
+ <widget class="QLineEdit" name="jvmArgsTextBox"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="customCommandsGroupBox">
+ <property name="title">
+ <string>Custom Commands</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_4">
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelPostExitCmd">
+ <property name="text">
+ <string>Post-exit command:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelPreLaunchCmd">
+ <property name="text">
+ <string>Pre-launch command:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="preLaunchCmdTextBox"/>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="postExitCmdTextBox"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="labelCustomCmdsDescription">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Pre-launch command runs before the instance launches and post-exit command runs after it exits. Both will be run in MultiMC's working directory with INST_ID, INST_DIR, and INST_NAME as environment variables.</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>minMemSpinBox</tabstop>
+ <tabstop>maxMemSpinBox</tabstop>
+ <tabstop>permGenSpinBox</tabstop>
+ <tabstop>javaPathTextBox</tabstop>
+ <tabstop>javaBrowseBtn</tabstop>
+ <tabstop>javaDetectBtn</tabstop>
+ <tabstop>javaTestBtn</tabstop>
+ <tabstop>jvmArgsTextBox</tabstop>
+ <tabstop>preLaunchCmdTextBox</tabstop>
+ <tabstop>postExitCmdTextBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/gui/pages/global/MinecraftPage.cpp b/gui/pages/global/MinecraftPage.cpp
new file mode 100644
index 00000000..0fe56fde
--- /dev/null
+++ b/gui/pages/global/MinecraftPage.cpp
@@ -0,0 +1,104 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "MinecraftPage.h"
+#include "ui_MinecraftPage.h"
+
+#include <QFileDialog>
+#include <QMessageBox>
+#include <QDir>
+
+#include <pathutils.h>
+
+#include "gui/Platform.h"
+#include "gui/dialogs/VersionSelectDialog.h"
+#include "gui/dialogs/CustomMessageBox.h"
+
+#include "logic/NagUtils.h"
+
+#include "logic/java/JavaUtils.h"
+#include "logic/java/JavaVersionList.h"
+#include "logic/java/JavaChecker.h"
+
+#include "logic/updater/UpdateChecker.h"
+
+#include "logic/tools/BaseProfiler.h"
+
+#include "logic/settings/SettingsObject.h"
+#include "MultiMC.h"
+
+MinecraftPage::MinecraftPage(QWidget *parent) : QWidget(parent), ui(new Ui::MinecraftPage)
+{
+ ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
+ loadSettings();
+ updateCheckboxStuff();
+}
+
+MinecraftPage::~MinecraftPage()
+{
+ delete ui;
+}
+
+bool MinecraftPage::apply()
+{
+ applySettings();
+ return true;
+}
+
+void MinecraftPage::updateCheckboxStuff()
+{
+ ui->windowWidthSpinBox->setEnabled(!ui->maximizedCheckBox->isChecked());
+ ui->windowHeightSpinBox->setEnabled(!ui->maximizedCheckBox->isChecked());
+}
+
+void MinecraftPage::on_maximizedCheckBox_clicked(bool checked)
+{
+ Q_UNUSED(checked);
+ updateCheckboxStuff();
+}
+
+
+void MinecraftPage::applySettings()
+{
+ auto s = MMC->settings();
+ // Minecraft version updates
+ s->set("AutoUpdateMinecraftVersions", ui->autoupdateMinecraft->isChecked());
+
+ // Console
+ s->set("ShowConsole", ui->showConsoleCheck->isChecked());
+ s->set("AutoCloseConsole", ui->autoCloseConsoleCheck->isChecked());
+
+ // Window Size
+ s->set("LaunchMaximized", ui->maximizedCheckBox->isChecked());
+ s->set("MinecraftWinWidth", ui->windowWidthSpinBox->value());
+ s->set("MinecraftWinHeight", ui->windowHeightSpinBox->value());
+}
+
+void MinecraftPage::loadSettings()
+{
+ auto s = MMC->settings();
+ // Minecraft version updates
+ ui->autoupdateMinecraft->setChecked(s->get("AutoUpdateMinecraftVersions").toBool());
+
+ // Console
+ ui->showConsoleCheck->setChecked(s->get("ShowConsole").toBool());
+ ui->autoCloseConsoleCheck->setChecked(s->get("AutoCloseConsole").toBool());
+
+ // Window Size
+ ui->maximizedCheckBox->setChecked(s->get("LaunchMaximized").toBool());
+ ui->windowWidthSpinBox->setValue(s->get("MinecraftWinWidth").toInt());
+ ui->windowHeightSpinBox->setValue(s->get("MinecraftWinHeight").toInt());
+}
diff --git a/gui/pages/global/MinecraftPage.h b/gui/pages/global/MinecraftPage.h
new file mode 100644
index 00000000..90299020
--- /dev/null
+++ b/gui/pages/global/MinecraftPage.h
@@ -0,0 +1,69 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <memory>
+#include <QDialog>
+
+#include "logic/java/JavaChecker.h"
+#include "gui/pages/BasePage.h"
+
+class SettingsObject;
+
+namespace Ui
+{
+class MinecraftPage;
+}
+
+class MinecraftPage : public QWidget, public BasePage
+{
+ Q_OBJECT
+
+public:
+ explicit MinecraftPage(QWidget *parent = 0);
+ ~MinecraftPage();
+
+ QString displayName() const override
+ {
+ return tr("Minecraft");
+ }
+ QIcon icon() const override
+ {
+ return QIcon::fromTheme("minecraft");
+ }
+ QString id() const override
+ {
+ return "minecraft-settings";
+ }
+ QString helpPage() const override
+ {
+ return "Minecraft-settings";
+ }
+ bool apply() override;
+
+private:
+ void updateCheckboxStuff();
+ void applySettings();
+ void loadSettings();
+
+private
+slots:
+ void on_maximizedCheckBox_clicked(bool checked);
+
+private:
+ Ui::MinecraftPage *ui;
+
+};
diff --git a/gui/pages/global/MinecraftPage.ui b/gui/pages/global/MinecraftPage.ui
new file mode 100644
index 00000000..e938d09d
--- /dev/null
+++ b/gui/pages/global/MinecraftPage.ui
@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MinecraftPage</class>
+ <widget class="QWidget" name="MinecraftPage">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>545</width>
+ <height>609</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Settings</string>
+ </property>
+ <property name="windowIcon">
+ <iconset>
+ <normaloff>:/icons/toolbar/settings</normaloff>:/icons/toolbar/settings</iconset>
+ </property>
+ <layout class="QVBoxLayout" name="mainLayout">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="tabShape">
+ <enum>QTabWidget::Rounded</enum>
+ </property>
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="minecraftTab">
+ <attribute name="title">
+ <string>Minecraft</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QGroupBox" name="groupBox_5">
+ <property name="title">
+ <string>Minecraft Version Updates</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_14">
+ <item>
+ <widget class="QCheckBox" name="autoupdateMinecraft">
+ <property name="text">
+ <string>Automatically update to latest version revision</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="windowSizeGroupBox">
+ <property name="title">
+ <string>Window Size</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <widget class="QCheckBox" name="maximizedCheckBox">
+ <property name="text">
+ <string>Start Minecraft maximized?</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QGridLayout" name="gridLayoutWindowSize">
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelWindowHeight">
+ <property name="text">
+ <string>Window height:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelWindowWidth">
+ <property name="text">
+ <string>Window width:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QSpinBox" name="windowWidthSpinBox">
+ <property name="minimum">
+ <number>854</number>
+ </property>
+ <property name="maximum">
+ <number>65536</number>
+ </property>
+ <property name="singleStep">
+ <number>1</number>
+ </property>
+ <property name="value">
+ <number>854</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QSpinBox" name="windowHeightSpinBox">
+ <property name="minimum">
+ <number>480</number>
+ </property>
+ <property name="maximum">
+ <number>65536</number>
+ </property>
+ <property name="value">
+ <number>480</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="consoleSettingsBox">
+ <property name="title">
+ <string>Console Settings</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QCheckBox" name="showConsoleCheck">
+ <property name="text">
+ <string>Show console while the game is running?</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="autoCloseConsoleCheck">
+ <property name="text">
+ <string>Automatically close console when the game quits?</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacerMinecraft">
+ <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>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>tabWidget</tabstop>
+ <tabstop>autoupdateMinecraft</tabstop>
+ <tabstop>maximizedCheckBox</tabstop>
+ <tabstop>windowWidthSpinBox</tabstop>
+ <tabstop>windowHeightSpinBox</tabstop>
+ <tabstop>showConsoleCheck</tabstop>
+ <tabstop>autoCloseConsoleCheck</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/gui/pages/global/MultiMCPage.cpp b/gui/pages/global/MultiMCPage.cpp
new file mode 100644
index 00000000..2d6eb7d5
--- /dev/null
+++ b/gui/pages/global/MultiMCPage.cpp
@@ -0,0 +1,340 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "MultiMCPage.h"
+#include "ui_MultiMCPage.h"
+
+#include <QFileDialog>
+#include <QMessageBox>
+#include <QDir>
+
+#include <pathutils.h>
+
+#include "gui/Platform.h"
+#include "gui/dialogs/VersionSelectDialog.h"
+#include "gui/dialogs/CustomMessageBox.h"
+#include <gui/ColumnResizer.h>
+
+#include "logic/NagUtils.h"
+
+#include "logic/java/JavaUtils.h"
+#include "logic/java/JavaVersionList.h"
+#include "logic/java/JavaChecker.h"
+
+#include "logic/updater/UpdateChecker.h"
+
+#include "logic/tools/BaseProfiler.h"
+
+#include "logic/settings/SettingsObject.h"
+#include "MultiMC.h"
+
+// FIXME: possibly move elsewhere
+enum InstSortMode
+{
+ // Sort alphabetically by name.
+ Sort_Name,
+ // Sort by which instance was launched most recently.
+ Sort_LastLaunch
+};
+
+MultiMCPage::MultiMCPage(QWidget *parent) : QWidget(parent), ui(new Ui::MultiMCPage)
+{
+ ui->setupUi(this);
+ ui->sortingModeGroup->setId(ui->sortByNameBtn, Sort_Name);
+ ui->sortingModeGroup->setId(ui->sortLastLaunchedBtn, Sort_LastLaunch);
+
+ auto resizer = new ColumnResizer(this);
+ resizer->addWidgetsFromLayout(ui->groupBox->layout(), 1);
+ resizer->addWidgetsFromLayout(ui->foldersBox->layout(), 1);
+
+ loadSettings();
+
+ QObject::connect(MMC->updateChecker().get(), &UpdateChecker::channelListLoaded, this,
+ &MultiMCPage::refreshUpdateChannelList);
+
+ if (MMC->updateChecker()->hasChannels())
+ {
+ refreshUpdateChannelList();
+ }
+ else
+ {
+ MMC->updateChecker()->updateChanList(false);
+ }
+}
+
+MultiMCPage::~MultiMCPage()
+{
+ delete ui;
+}
+
+bool MultiMCPage::apply()
+{
+ applySettings();
+ return true;
+}
+
+void MultiMCPage::on_ftbLauncherBrowseBtn_clicked()
+{
+ QString raw_dir = QFileDialog::getExistingDirectory(this, tr("FTB Launcher Directory"),
+ ui->ftbLauncherBox->text());
+ QString cooked_dir = NormalizePath(raw_dir);
+
+ // do not allow current dir - it's dirty. Do not allow dirs that don't exist
+ if (!cooked_dir.isEmpty() && QDir(cooked_dir).exists())
+ {
+ ui->ftbLauncherBox->setText(cooked_dir);
+ }
+}
+void MultiMCPage::on_ftbBrowseBtn_clicked()
+{
+ QString raw_dir =
+ QFileDialog::getExistingDirectory(this, tr("FTB Directory"), ui->ftbBox->text());
+ QString cooked_dir = NormalizePath(raw_dir);
+
+ // do not allow current dir - it's dirty. Do not allow dirs that don't exist
+ if (!cooked_dir.isEmpty() && QDir(cooked_dir).exists())
+ {
+ ui->ftbBox->setText(cooked_dir);
+ }
+}
+
+void MultiMCPage::on_instDirBrowseBtn_clicked()
+{
+ QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Instance Directory"),
+ ui->instDirTextBox->text());
+ QString cooked_dir = NormalizePath(raw_dir);
+
+ // do not allow current dir - it's dirty. Do not allow dirs that don't exist
+ if (!cooked_dir.isEmpty() && QDir(cooked_dir).exists())
+ {
+ ui->instDirTextBox->setText(cooked_dir);
+ }
+}
+void MultiMCPage::on_iconsDirBrowseBtn_clicked()
+{
+ QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Icons Directory"),
+ ui->iconsDirTextBox->text());
+ QString cooked_dir = NormalizePath(raw_dir);
+
+ // do not allow current dir - it's dirty. Do not allow dirs that don't exist
+ if (!cooked_dir.isEmpty() && QDir(cooked_dir).exists())
+ {
+ ui->iconsDirTextBox->setText(cooked_dir);
+ }
+}
+void MultiMCPage::on_modsDirBrowseBtn_clicked()
+{
+ QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Mods Directory"),
+ ui->modsDirTextBox->text());
+ QString cooked_dir = NormalizePath(raw_dir);
+
+ // do not allow current dir - it's dirty. Do not allow dirs that don't exist
+ if (!cooked_dir.isEmpty() && QDir(cooked_dir).exists())
+ {
+ ui->modsDirTextBox->setText(cooked_dir);
+ }
+}
+void MultiMCPage::on_lwjglDirBrowseBtn_clicked()
+{
+ QString raw_dir = QFileDialog::getExistingDirectory(this, tr("LWJGL Directory"),
+ ui->lwjglDirTextBox->text());
+ QString cooked_dir = NormalizePath(raw_dir);
+
+ // do not allow current dir - it's dirty. Do not allow dirs that don't exist
+ if (!cooked_dir.isEmpty() && QDir(cooked_dir).exists())
+ {
+ ui->lwjglDirTextBox->setText(cooked_dir);
+ }
+}
+
+void MultiMCPage::refreshUpdateChannelList()
+{
+ // Stop listening for selection changes. It's going to change a lot while we update it and
+ // we don't need to update the
+ // description label constantly.
+ QObject::disconnect(ui->updateChannelComboBox, SIGNAL(currentIndexChanged(int)), this,
+ SLOT(updateChannelSelectionChanged(int)));
+
+ QList<UpdateChecker::ChannelListEntry> channelList = MMC->updateChecker()->getChannelList();
+ ui->updateChannelComboBox->clear();
+ int selection = -1;
+ for (int i = 0; i < channelList.count(); i++)
+ {
+ UpdateChecker::ChannelListEntry entry = channelList.at(i);
+
+ // When it comes to selection, we'll rely on the indexes of a channel entry being the
+ // same in the
+ // combo box as it is in the update checker's channel list.
+ // This probably isn't very safe, but the channel list doesn't change often enough (or
+ // at all) for
+ // this to be a big deal. Hope it doesn't break...
+ ui->updateChannelComboBox->addItem(entry.name);
+
+ // If the update channel we just added was the selected one, set the current index in
+ // the combo box to it.
+ if (entry.id == m_currentUpdateChannel)
+ {
+ QLOG_DEBUG() << "Selected index" << i << "channel id" << m_currentUpdateChannel;
+ selection = i;
+ }
+ }
+
+ ui->updateChannelComboBox->setCurrentIndex(selection);
+
+ // Start listening for selection changes again and update the description label.
+ QObject::connect(ui->updateChannelComboBox, SIGNAL(currentIndexChanged(int)), this,
+ SLOT(updateChannelSelectionChanged(int)));
+ refreshUpdateChannelDesc();
+
+ // Now that we've updated the channel list, we can enable the combo box.
+ // It starts off disabled so that if the channel list hasn't been loaded, it will be
+ // disabled.
+ ui->updateChannelComboBox->setEnabled(true);
+}
+
+void MultiMCPage::updateChannelSelectionChanged(int index)
+{
+ refreshUpdateChannelDesc();
+}
+
+void MultiMCPage::refreshUpdateChannelDesc()
+{
+ // Get the channel list.
+ QList<UpdateChecker::ChannelListEntry> channelList = MMC->updateChecker()->getChannelList();
+ int selectedIndex = ui->updateChannelComboBox->currentIndex();
+ if (selectedIndex < 0)
+ {
+ return;
+ }
+ if (selectedIndex < channelList.count())
+ {
+ // Find the channel list entry with the given index.
+ UpdateChecker::ChannelListEntry selected = channelList.at(selectedIndex);
+
+ // Set the description text.
+ ui->updateChannelDescLabel->setText(selected.description);
+
+ // Set the currently selected channel ID.
+ m_currentUpdateChannel = selected.id;
+ }
+}
+
+void MultiMCPage::applySettings()
+{
+ auto s = MMC->settings();
+ // Language
+ s->set("Language",
+ ui->languageBox->itemData(ui->languageBox->currentIndex()).toLocale().bcp47Name());
+
+ if (ui->resetNotificationsBtn->isChecked())
+ {
+ s->set("ShownNotifications", QString());
+ }
+
+ // Updates
+ s->set("AutoUpdate", ui->autoUpdateCheckBox->isChecked());
+ s->set("UpdateChannel", m_currentUpdateChannel);
+ //FIXME: make generic
+ switch (ui->themeComboBox->currentIndex())
+ {
+ case 1:
+ s->set("IconTheme", "pe_dark");
+ break;
+ case 2:
+ s->set("IconTheme", "pe_light");
+ break;
+ case 0:
+ default:
+ s->set("IconTheme", "multimc");
+ break;
+ }
+ // FTB
+ s->set("TrackFTBInstances", ui->trackFtbBox->isChecked());
+ s->set("FTBLauncherRoot", ui->ftbLauncherBox->text());
+ s->set("FTBRoot", ui->ftbBox->text());
+
+ // Folders
+ // TODO: Offer to move instances to new instance folder.
+ s->set("InstanceDir", ui->instDirTextBox->text());
+ s->set("CentralModsDir", ui->modsDirTextBox->text());
+ s->set("LWJGLDir", ui->lwjglDirTextBox->text());
+ s->set("IconsDir", ui->iconsDirTextBox->text());
+
+ auto sortMode = (InstSortMode)ui->sortingModeGroup->checkedId();
+ switch (sortMode)
+ {
+ case Sort_LastLaunch:
+ s->set("InstSortMode", "LastLaunch");
+ break;
+ case Sort_Name:
+ default:
+ s->set("InstSortMode", "Name");
+ break;
+ }
+}
+void MultiMCPage::loadSettings()
+{
+ auto s = MMC->settings();
+ // Language
+ ui->languageBox->clear();
+ ui->languageBox->addItem(tr("English"), QLocale(QLocale::English));
+ foreach(const QString & lang, QDir(MMC->staticData() + "/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();
+ //FIXME: make generic
+ auto theme = s->get("IconTheme").toString();
+ if (theme == "pe_dark")
+ {
+ ui->themeComboBox->setCurrentIndex(1);
+ }
+ else if (theme == "pe_light")
+ {
+ ui->themeComboBox->setCurrentIndex(2);
+ }
+ else
+ {
+ ui->themeComboBox->setCurrentIndex(0);
+ }
+ // FTB
+ ui->trackFtbBox->setChecked(s->get("TrackFTBInstances").toBool());
+ ui->ftbLauncherBox->setText(s->get("FTBLauncherRoot").toString());
+ ui->ftbBox->setText(s->get("FTBRoot").toString());
+
+ // Folders
+ ui->instDirTextBox->setText(s->get("InstanceDir").toString());
+ ui->modsDirTextBox->setText(s->get("CentralModsDir").toString());
+ ui->lwjglDirTextBox->setText(s->get("LWJGLDir").toString());
+ ui->iconsDirTextBox->setText(s->get("IconsDir").toString());
+
+ QString sortMode = s->get("InstSortMode").toString();
+
+ if (sortMode == "LastLaunch")
+ {
+ ui->sortLastLaunchedBtn->setChecked(true);
+ }
+ else
+ {
+ ui->sortByNameBtn->setChecked(true);
+ }
+}
diff --git a/gui/pages/global/MultiMCPage.h b/gui/pages/global/MultiMCPage.h
new file mode 100644
index 00000000..b465355f
--- /dev/null
+++ b/gui/pages/global/MultiMCPage.h
@@ -0,0 +1,90 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <memory>
+#include <QDialog>
+
+#include "logic/java/JavaChecker.h"
+#include "gui/pages/BasePage.h"
+
+class SettingsObject;
+
+namespace Ui
+{
+class MultiMCPage;
+}
+
+class MultiMCPage : public QWidget, public BasePage
+{
+ Q_OBJECT
+
+public:
+ explicit MultiMCPage(QWidget *parent = 0);
+ ~MultiMCPage();
+
+ QString displayName() const override
+ {
+ return tr("MultiMC");
+ }
+ QIcon icon() const override
+ {
+ return QIcon::fromTheme("multimc");
+ }
+ QString id() const override
+ {
+ return "multimc-settings";
+ }
+ QString helpPage() const override
+ {
+ return "MultiMC-settings";
+ }
+ bool apply() override;
+
+private:
+ void applySettings();
+ void loadSettings();
+
+private
+slots:
+ void on_ftbLauncherBrowseBtn_clicked();
+ void on_ftbBrowseBtn_clicked();
+
+ void on_instDirBrowseBtn_clicked();
+ void on_modsDirBrowseBtn_clicked();
+ void on_lwjglDirBrowseBtn_clicked();
+ void on_iconsDirBrowseBtn_clicked();
+
+ /*!
+ * Updates the list of update channels in the combo box.
+ */
+ void refreshUpdateChannelList();
+
+ /*!
+ * Updates the channel description label.
+ */
+ void refreshUpdateChannelDesc();
+
+ void updateChannelSelectionChanged(int index);
+
+private:
+ Ui::MultiMCPage *ui;
+
+ /*!
+ * Stores the currently selected update channel.
+ */
+ QString m_currentUpdateChannel;
+};
diff --git a/gui/pages/global/MultiMCPage.ui b/gui/pages/global/MultiMCPage.ui
new file mode 100644
index 00000000..f456ebc1
--- /dev/null
+++ b/gui/pages/global/MultiMCPage.ui
@@ -0,0 +1,399 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MultiMCPage</class>
+ <widget class="QWidget" name="MultiMCPage">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>545</width>
+ <height>609</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Settings</string>
+ </property>
+ <property name="windowIcon">
+ <iconset>
+ <normaloff>:/icons/toolbar/settings</normaloff>:/icons/toolbar/settings</iconset>
+ </property>
+ <layout class="QVBoxLayout" name="mainLayout">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="tabShape">
+ <enum>QTabWidget::Rounded</enum>
+ </property>
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="featuresTab">
+ <attribute name="title">
+ <string>Features</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_9">
+ <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>
+ </property>
+ </widget>
+ </item>
+ <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>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>FTB</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="2" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Launcher:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="ftbLauncherBox">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLineEdit" name="ftbBox"/>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Files:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2">
+ <widget class="QToolButton" name="ftbBrowseBtn">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QToolButton" name="ftbLauncherBrowseBtn">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::TabFocus</enum>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" colspan="3">
+ <widget class="QCheckBox" name="trackFtbBox">
+ <property name="text">
+ <string>Track FTB instances</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="foldersBox">
+ <property name="title">
+ <string>Folders</string>
+ </property>
+ <layout class="QGridLayout" name="foldersBoxLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="labelInstDir">
+ <property name="text">
+ <string>Instances:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="instDirTextBox"/>
+ </item>
+ <item row="0" column="2">
+ <widget class="QToolButton" name="instDirBrowseBtn">
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="labelModsDir">
+ <property name="text">
+ <string>Mods:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="modsDirTextBox"/>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="lwjglDirTextBox"/>
+ </item>
+ <item row="1" column="2">
+ <widget class="QToolButton" name="modsDirBrowseBtn">
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="labelLWJGLDir">
+ <property name="text">
+ <string>LWJGL:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="2">
+ <widget class="QToolButton" name="lwjglDirBrowseBtn">
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLineEdit" name="iconsDirTextBox"/>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="labelIconsDir">
+ <property name="text">
+ <string>Icons:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2">
+ <widget class="QToolButton" name="iconsDirBrowseBtn">
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </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_6">
+ <item>
+ <widget class="QGroupBox" name="groupBox_3">
+ <property name="title">
+ <string>MultiMC notifications</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <item>
+ <widget class="QPushButton" name="resetNotificationsBtn">
+ <property name="text">
+ <string>Reset hidden notifications</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="sortingModeBox">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="title">
+ <string>Instance view 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="groupBox_2">
+ <property name="title">
+ <string>Language (needs restart):</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QComboBox" name="languageBox"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="themeBox">
+ <property name="title">
+ <string>Icon Theme (needs restart, work in progress)</string>
+ </property>
+ <layout class="QHBoxLayout" name="themeBoxLayout">
+ <item>
+ <widget class="QComboBox" name="themeComboBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="focusPolicy">
+ <enum>Qt::StrongFocus</enum>
+ </property>
+ <item>
+ <property name="text">
+ <string>Default</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Simple</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Simple (Light Icons)</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="generalTabSpacer">
+ <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>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>tabWidget</tabstop>
+ <tabstop>autoUpdateCheckBox</tabstop>
+ <tabstop>updateChannelComboBox</tabstop>
+ <tabstop>trackFtbBox</tabstop>
+ <tabstop>ftbLauncherBox</tabstop>
+ <tabstop>ftbLauncherBrowseBtn</tabstop>
+ <tabstop>ftbBox</tabstop>
+ <tabstop>ftbBrowseBtn</tabstop>
+ <tabstop>instDirTextBox</tabstop>
+ <tabstop>instDirBrowseBtn</tabstop>
+ <tabstop>modsDirTextBox</tabstop>
+ <tabstop>modsDirBrowseBtn</tabstop>
+ <tabstop>lwjglDirTextBox</tabstop>
+ <tabstop>lwjglDirBrowseBtn</tabstop>
+ <tabstop>iconsDirTextBox</tabstop>
+ <tabstop>iconsDirBrowseBtn</tabstop>
+ <tabstop>resetNotificationsBtn</tabstop>
+ <tabstop>sortLastLaunchedBtn</tabstop>
+ <tabstop>sortByNameBtn</tabstop>
+ <tabstop>languageBox</tabstop>
+ <tabstop>themeComboBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+ <buttongroups>
+ <buttongroup name="sortingModeGroup"/>
+ </buttongroups>
+</ui>
diff --git a/gui/pages/global/ProxyPage.cpp b/gui/pages/global/ProxyPage.cpp
new file mode 100644
index 00000000..5578fbb7
--- /dev/null
+++ b/gui/pages/global/ProxyPage.cpp
@@ -0,0 +1,95 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ProxyPage.h"
+#include "ui_ProxyPage.h"
+
+#include "logic/settings/SettingsObject.h"
+#include "MultiMC.h"
+
+ProxyPage::ProxyPage(QWidget *parent) : QWidget(parent), ui(new Ui::ProxyPage)
+{
+ ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
+ loadSettings();
+ updateCheckboxStuff();
+
+ connect(ui->proxyGroup, SIGNAL(buttonClicked(int)), SLOT(proxyChanged(int)));
+}
+
+ProxyPage::~ProxyPage()
+{
+ delete ui;
+}
+
+bool ProxyPage::apply()
+{
+ applySettings();
+ return true;
+}
+
+void ProxyPage::updateCheckboxStuff()
+{
+ ui->proxyAddrBox->setEnabled(!ui->proxyNoneBtn->isChecked() &&
+ !ui->proxyDefaultBtn->isChecked());
+ ui->proxyAuthBox->setEnabled(!ui->proxyNoneBtn->isChecked() &&
+ !ui->proxyDefaultBtn->isChecked());
+}
+
+void ProxyPage::proxyChanged(int)
+{
+ updateCheckboxStuff();
+}
+
+void ProxyPage::applySettings()
+{
+ auto s = MMC->settings();
+
+ // Proxy
+ QString proxyType = "None";
+ if (ui->proxyDefaultBtn->isChecked())
+ proxyType = "Default";
+ else if (ui->proxyNoneBtn->isChecked())
+ proxyType = "None";
+ else if (ui->proxySOCKS5Btn->isChecked())
+ proxyType = "SOCKS5";
+ else if (ui->proxyHTTPBtn->isChecked())
+ proxyType = "HTTP";
+
+ s->set("ProxyType", proxyType);
+ s->set("ProxyAddr", ui->proxyAddrEdit->text());
+ s->set("ProxyPort", ui->proxyPortEdit->value());
+ s->set("ProxyUser", ui->proxyUserEdit->text());
+ s->set("ProxyPass", ui->proxyPassEdit->text());
+}
+void ProxyPage::loadSettings()
+{
+ auto s = MMC->settings();
+ // Proxy
+ QString proxyType = s->get("ProxyType").toString();
+ if (proxyType == "Default")
+ ui->proxyDefaultBtn->setChecked(true);
+ else if (proxyType == "None")
+ ui->proxyNoneBtn->setChecked(true);
+ else if (proxyType == "SOCKS5")
+ ui->proxySOCKS5Btn->setChecked(true);
+ else if (proxyType == "HTTP")
+ ui->proxyHTTPBtn->setChecked(true);
+
+ ui->proxyAddrEdit->setText(s->get("ProxyAddr").toString());
+ ui->proxyPortEdit->setValue(s->get("ProxyPort").value<qint16>());
+ ui->proxyUserEdit->setText(s->get("ProxyUser").toString());
+ ui->proxyPassEdit->setText(s->get("ProxyPass").toString());
+}
diff --git a/gui/pages/global/ProxyPage.h b/gui/pages/global/ProxyPage.h
new file mode 100644
index 00000000..700a3af0
--- /dev/null
+++ b/gui/pages/global/ProxyPage.h
@@ -0,0 +1,66 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <memory>
+#include <QDialog>
+
+#include "logic/java/JavaChecker.h"
+#include "gui/pages/BasePage.h"
+
+namespace Ui
+{
+class ProxyPage;
+}
+
+class ProxyPage : public QWidget, public BasePage
+{
+ Q_OBJECT
+
+public:
+ explicit ProxyPage(QWidget *parent = 0);
+ ~ProxyPage();
+
+ QString displayName() const override
+ {
+ return tr("Proxy");
+ }
+ QIcon icon() const override
+ {
+ return QIcon::fromTheme("proxy");
+ }
+ QString id() const override
+ {
+ return "proxy-settings";
+ }
+ QString helpPage() const override
+ {
+ return "Proxy-settings";
+ }
+ bool apply() override;
+
+private:
+ void updateCheckboxStuff();
+ void applySettings();
+ void loadSettings();
+
+private
+slots:
+ void proxyChanged(int);
+
+private:
+ Ui::ProxyPage *ui;
+};
diff --git a/gui/pages/global/ProxyPage.ui b/gui/pages/global/ProxyPage.ui
new file mode 100644
index 00000000..7cddd66d
--- /dev/null
+++ b/gui/pages/global/ProxyPage.ui
@@ -0,0 +1,197 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ProxyPage</class>
+ <widget class="QWidget" name="ProxyPage">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>607</width>
+ <height>632</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="windowTitle">
+ <string>Settings</string>
+ </property>
+ <property name="windowIcon">
+ <iconset>
+ <normaloff>:/icons/toolbar/settings</normaloff>:/icons/toolbar/settings</iconset>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <widget class="QWidget" name="tabWidgetPage1" native="true">
+ <attribute name="title">
+ <string/>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <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="buttonGroup">
+ <string notr="true">proxyGroup</string>
+ </attribute>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="proxyAddrBox">
+ <property name="title">
+ <string>Address and Port</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLineEdit" name="proxyAddrEdit">
+ <property name="placeholderText">
+ <string>127.0.0.1</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="proxyPortEdit">
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="buttonSymbols">
+ <enum>QAbstractSpinBox::PlusMinus</enum>
+ </property>
+ <property name="maximum">
+ <number>65535</number>
+ </property>
+ <property name="value">
+ <number>8080</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="proxyAuthBox">
+ <property name="title">
+ <string>Authentication</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_5">
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="proxyUserEdit"/>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="proxyUsernameLabel">
+ <property name="text">
+ <string>Username:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="proxyPasswordLabel">
+ <property name="text">
+ <string>Password:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="proxyPassEdit">
+ <property name="echoMode">
+ <enum>QLineEdit::Password</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="2">
+ <widget class="QLabel" name="proxyPlainTextWarningLabel">
+ <property name="text">
+ <string>Note: Proxy username and password are stored in plain text inside MultiMC's configuration file!</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <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>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+ <buttongroups>
+ <buttongroup name="proxyGroup"/>
+ </buttongroups>
+</ui>