From bc05ad30aa7c3da5d76947e82012f50466bb5d39 Mon Sep 17 00:00:00 2001 From: Petr Mrázek Date: Sun, 20 Jul 2014 23:47:46 +0200 Subject: Rework the settings dialog. Rework all of it. Thoroughly. Also introduces the ColumnResizer from: https://github.com/agateau/columnresizer/ --- CMakeLists.txt | 29 +- gui/ColumnResizer.cpp | 202 +++++++ gui/ColumnResizer.h | 38 ++ gui/MainWindow.cpp | 12 +- gui/dialogs/AboutDialog.ui | 39 +- gui/pages/global/AccountListPage.cpp | 3 +- gui/pages/global/AccountListPage.h | 2 +- gui/pages/global/AccountListPage.ui | 142 +++-- gui/pages/global/BaseSettingsPage.cpp | 28 - gui/pages/global/BaseSettingsPage.h | 35 -- gui/pages/global/ExternalToolsPage.cpp | 77 ++- gui/pages/global/ExternalToolsPage.h | 12 +- gui/pages/global/ExternalToolsPage.ui | 296 ++++++---- gui/pages/global/JavaPage.cpp | 146 +++++ gui/pages/global/JavaPage.h | 72 +++ gui/pages/global/JavaPage.ui | 303 ++++++++++ gui/pages/global/MinecraftPage.cpp | 104 ++++ gui/pages/global/MinecraftPage.h | 69 +++ gui/pages/global/MinecraftPage.ui | 184 ++++++ gui/pages/global/MultiMCPage.cpp | 340 +++++++++++ gui/pages/global/MultiMCPage.h | 90 +++ gui/pages/global/MultiMCPage.ui | 399 +++++++++++++ gui/pages/global/ProxyPage.cpp | 95 +++ gui/pages/global/ProxyPage.h | 66 +++ gui/pages/global/ProxyPage.ui | 197 +++++++ gui/pages/global/SettingsPage.cpp | 547 ------------------ gui/pages/global/SettingsPage.h | 105 ---- gui/pages/global/SettingsPage.ui | 985 -------------------------------- gui/widgets/PageContainer.cpp | 3 + resources/multimc/16x16/minecraft.png | Bin 0 -> 782 bytes resources/multimc/24x24/minecraft.png | Bin 0 -> 1500 bytes resources/multimc/256x256/minecraft.png | Bin 0 -> 49869 bytes resources/multimc/32x32/minecraft.png | Bin 0 -> 2495 bytes resources/multimc/48x48/minecraft.png | Bin 0 -> 5077 bytes resources/multimc/index.theme | 3 + resources/multimc/multimc.qrc | 13 + resources/multimc/scalable/java.svg | 773 +++++++++++++++++++++++++ resources/multimc/scalable/proxy.svg | 260 +++++++++ 38 files changed, 3746 insertions(+), 1923 deletions(-) create mode 100644 gui/ColumnResizer.cpp create mode 100644 gui/ColumnResizer.h delete mode 100644 gui/pages/global/BaseSettingsPage.cpp delete mode 100644 gui/pages/global/BaseSettingsPage.h create mode 100644 gui/pages/global/JavaPage.cpp create mode 100644 gui/pages/global/JavaPage.h create mode 100644 gui/pages/global/JavaPage.ui create mode 100644 gui/pages/global/MinecraftPage.cpp create mode 100644 gui/pages/global/MinecraftPage.h create mode 100644 gui/pages/global/MinecraftPage.ui create mode 100644 gui/pages/global/MultiMCPage.cpp create mode 100644 gui/pages/global/MultiMCPage.h create mode 100644 gui/pages/global/MultiMCPage.ui create mode 100644 gui/pages/global/ProxyPage.cpp create mode 100644 gui/pages/global/ProxyPage.h create mode 100644 gui/pages/global/ProxyPage.ui delete mode 100644 gui/pages/global/SettingsPage.cpp delete mode 100644 gui/pages/global/SettingsPage.h delete mode 100644 gui/pages/global/SettingsPage.ui create mode 100644 resources/multimc/16x16/minecraft.png create mode 100644 resources/multimc/24x24/minecraft.png create mode 100644 resources/multimc/256x256/minecraft.png create mode 100644 resources/multimc/32x32/minecraft.png create mode 100644 resources/multimc/48x48/minecraft.png create mode 100644 resources/multimc/scalable/java.svg create mode 100644 resources/multimc/scalable/proxy.svg diff --git a/CMakeLists.txt b/CMakeLists.txt index 7cae21dd..7efd42e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -283,6 +283,8 @@ SET(MULTIMC_SOURCES # GUI - general utilities gui/GuiUtil.h gui/GuiUtil.cpp + gui/ColumnResizer.h + gui/ColumnResizer.cpp # GUI - windows gui/MainWindow.h @@ -312,14 +314,20 @@ SET(MULTIMC_SOURCES gui/pages/ScreenshotsPage.h gui/pages/OtherLogsPage.cpp gui/pages/OtherLogsPage.h - gui/pages/global/SettingsPage.cpp - gui/pages/global/SettingsPage.h - gui/pages/global/ExternalToolsPage.cpp - gui/pages/global/ExternalToolsPage.h - gui/pages/global/BaseSettingsPage.cpp - gui/pages/global/BaseSettingsPage.h + + # GUI - global settings pages gui/pages/global/AccountListPage.cpp gui/pages/global/AccountListPage.h + gui/pages/global/ExternalToolsPage.cpp + gui/pages/global/ExternalToolsPage.h + gui/pages/global/JavaPage.cpp + gui/pages/global/JavaPage.h + gui/pages/global/MinecraftPage.cpp + gui/pages/global/MinecraftPage.h + gui/pages/global/MultiMCPage.cpp + gui/pages/global/MultiMCPage.h + gui/pages/global/ProxyPage.cpp + gui/pages/global/ProxyPage.h # GUI - dialogs gui/dialogs/AboutDialog.cpp @@ -648,9 +656,14 @@ SET(MULTIMC_UIS gui/pages/NotesPage.ui gui/pages/ScreenshotsPage.ui gui/pages/OtherLogsPage.ui - gui/pages/global/SettingsPage.ui - gui/pages/global/ExternalToolsPage.ui + + # Global settings pages gui/pages/global/AccountListPage.ui + gui/pages/global/ExternalToolsPage.ui + gui/pages/global/JavaPage.ui + gui/pages/global/MinecraftPage.ui + gui/pages/global/MultiMCPage.ui + gui/pages/global/ProxyPage.ui # Dialogs gui/dialogs/CopyInstanceDialog.ui diff --git a/gui/ColumnResizer.cpp b/gui/ColumnResizer.cpp new file mode 100644 index 00000000..1c5597aa --- /dev/null +++ b/gui/ColumnResizer.cpp @@ -0,0 +1,202 @@ +/* + * Copyright 2011 Aurélien Gâteau + * License: LGPL v2.1 or later (see COPYING) + */ +#include "ColumnResizer.h" + +#include +#include +#include +#include +#include +#include + +class FormLayoutWidgetItem : public QWidgetItem +{ +public: + FormLayoutWidgetItem(QWidget* widget, QFormLayout* formLayout, QFormLayout::ItemRole itemRole) + : QWidgetItem(widget) + , m_width(-1) + , m_formLayout(formLayout) + , m_itemRole(itemRole) + {} + + QSize sizeHint() const + { + QSize size = QWidgetItem::sizeHint(); + if (m_width != -1) { + size.setWidth(m_width); + } + return size; + } + + QSize minimumSize() const + { + QSize size = QWidgetItem::minimumSize(); + if (m_width != -1) { + size.setWidth(m_width); + } + return size; + } + + QSize maximumSize() const + { + QSize size = QWidgetItem::maximumSize(); + if (m_width != -1) { + size.setWidth(m_width); + } + return size; + } + + void setWidth(int width) + { + if (width != m_width) { + m_width = width; + invalidate(); + } + } + + void setGeometry(const QRect& _rect) + { + QRect rect = _rect; + int width = widget()->sizeHint().width(); + if (m_itemRole == QFormLayout::LabelRole && m_formLayout->labelAlignment() & Qt::AlignRight) { + rect.setLeft(rect.right() - width); + } + QWidgetItem::setGeometry(rect); + } + + QFormLayout* formLayout() const + { + return m_formLayout; + } + +private: + int m_width; + QFormLayout* m_formLayout; + QFormLayout::ItemRole m_itemRole; +}; + +typedef QPair GridColumnInfo; + +class ColumnResizerPrivate +{ +public: + ColumnResizerPrivate(ColumnResizer* q_ptr) + : q(q_ptr) + , m_updateTimer(new QTimer(q)) + { + m_updateTimer->setSingleShot(true); + m_updateTimer->setInterval(0); + QObject::connect(m_updateTimer, SIGNAL(timeout()), q, SLOT(updateWidth())); + } + + void scheduleWidthUpdate() + { + m_updateTimer->start(); + } + + ColumnResizer* q; + QTimer* m_updateTimer; + QList m_widgets; + QList m_wrWidgetItemList; + QList m_gridColumnInfoList; +}; + +ColumnResizer::ColumnResizer(QObject* parent) +: QObject(parent) +, d(new ColumnResizerPrivate(this)) +{} + +ColumnResizer::~ColumnResizer() +{ + delete d; +} + +void ColumnResizer::addWidget(QWidget* widget) +{ + d->m_widgets.append(widget); + widget->installEventFilter(this); + d->scheduleWidthUpdate(); +} + +void ColumnResizer::updateWidth() +{ + int width = 0; + Q_FOREACH(QWidget* widget, d->m_widgets) { + width = qMax(widget->sizeHint().width(), width); + } + Q_FOREACH(FormLayoutWidgetItem* item, d->m_wrWidgetItemList) { + item->setWidth(width); + item->formLayout()->update(); + } + Q_FOREACH(GridColumnInfo info, d->m_gridColumnInfoList) { + info.first->setColumnMinimumWidth(info.second, width); + } +} + +bool ColumnResizer::eventFilter(QObject*, QEvent* event) +{ + if (event->type() == QEvent::Resize) { + d->scheduleWidthUpdate(); + } + return false; +} + +void ColumnResizer::addWidgetsFromLayout(QLayout* layout, int column) +{ + Q_ASSERT(column >= 0); + QGridLayout* gridLayout = qobject_cast(layout); + QFormLayout* formLayout = qobject_cast(layout); + if (gridLayout) { + addWidgetsFromGridLayout(gridLayout, column); + } else if (formLayout) { + if (column > QFormLayout::SpanningRole) { + qCritical() << "column should not be more than" << QFormLayout::SpanningRole << "for QFormLayout"; + return; + } + QFormLayout::ItemRole role = static_cast(column); + addWidgetsFromFormLayout(formLayout, role); + } else { + qCritical() << "Don't know how to handle layout" << layout; + } +} + +void ColumnResizer::addWidgetsFromGridLayout(QGridLayout* layout, int column) +{ + for (int row = 0; row < layout->rowCount(); ++row) { + QLayoutItem* item = layout->itemAtPosition(row, column); + if (!item) { + continue; + } + QWidget* widget = item->widget(); + if (!widget) { + continue; + } + addWidget(widget); + } + d->m_gridColumnInfoList << GridColumnInfo(layout, column); +} + +void ColumnResizer::addWidgetsFromFormLayout(QFormLayout* layout, QFormLayout::ItemRole role) +{ + for (int row = 0; row < layout->rowCount(); ++row) { + QLayoutItem* item = layout->itemAt(row, role); + if (!item) { + continue; + } + QWidget* widget = item->widget(); + if (!widget) { + continue; + } + layout->removeItem(item); + delete item; + FormLayoutWidgetItem* newItem = new FormLayoutWidgetItem(widget, layout, role); + layout->setItem(row, role, newItem); + addWidget(widget); + d->m_wrWidgetItemList << newItem; + } +} + +#include +// vi: ts=4 sw=4 et diff --git a/gui/ColumnResizer.h b/gui/ColumnResizer.h new file mode 100644 index 00000000..4bbac383 --- /dev/null +++ b/gui/ColumnResizer.h @@ -0,0 +1,38 @@ +/* + * Copyright 2011 Aurélien Gâteau + * License: LGPL v2.1 or later (see COPYING) + */ +#pragma once + +#include + +#include +#include + +class QEvent; +class QGridLayout; +class QLayout; +class QWidget; + +class ColumnResizerPrivate; +class ColumnResizer : public QObject +{ + Q_OBJECT +public: + ColumnResizer(QObject* parent = 0); + ~ColumnResizer(); + + void addWidget(QWidget* widget); + void addWidgetsFromLayout(QLayout*, int column); + void addWidgetsFromGridLayout(QGridLayout*, int column); + void addWidgetsFromFormLayout(QFormLayout*, QFormLayout::ItemRole role); + +private Q_SLOTS: + void updateWidth(); + +protected: + bool eventFilter(QObject*, QEvent* event); + +private: + ColumnResizerPrivate* const d; +}; diff --git a/gui/MainWindow.cpp b/gui/MainWindow.cpp index 81ee466b..ce03d7b9 100644 --- a/gui/MainWindow.cpp +++ b/gui/MainWindow.cpp @@ -62,9 +62,12 @@ #include "gui/dialogs/EditAccountDialog.h" #include "gui/dialogs/NotificationDialog.h" -#include "gui/pages/global/SettingsPage.h" +#include "gui/pages/global/MultiMCPage.h" #include "gui/pages/global/ExternalToolsPage.h" #include "gui/pages/global/AccountListPage.h" +#include "pages/global/ProxyPage.h" +#include "pages/global/JavaPage.h" +#include "pages/global/MinecraftPage.h" #include "gui/ConsoleWindow.h" #include "pagedialog/PageDialog.h" @@ -250,9 +253,12 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi // set up global pages dialog { m_globalSettingsProvider = std::make_shared(tr("Settings")); - m_globalSettingsProvider->addPage(); - m_globalSettingsProvider->addPage(); + m_globalSettingsProvider->addPage(); + m_globalSettingsProvider->addPage(); + m_globalSettingsProvider->addPage(); + m_globalSettingsProvider->addPage(); m_globalSettingsProvider->addPage(); + m_globalSettingsProvider->addPage(); } // Update the menu when the active account changes. diff --git a/gui/dialogs/AboutDialog.ui b/gui/dialogs/AboutDialog.ui index 04983299..93fa8963 100644 --- a/gui/dialogs/AboutDialog.ui +++ b/gui/dialogs/AboutDialog.ui @@ -96,7 +96,7 @@ - 1 + 0 @@ -104,7 +104,7 @@ 0 0 689 - 331 + 311 @@ -229,7 +229,7 @@ 0 0 689 - 331 + 311 @@ -245,8 +245,8 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> +</style></head><body style=" font-family:'Bitstream Vera Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html> Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse @@ -271,7 +271,7 @@ p, li { white-space: pre-wrap; } 0 0 689 - 331 + 311 @@ -298,7 +298,7 @@ p, li { white-space: pre-wrap; } <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'DejaVu Sans Mono'; font-size:9pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'DejaVu Sans Mono'; font-size:11pt; font-weight:400; font-style:normal;"> <p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Bitstream Vera Sans'; font-size:18pt; font-weight:600;">MultiMC</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Copyright 2012-2014 MultiMC Contributors</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:10pt;">Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span></p> @@ -422,7 +422,7 @@ p, li { white-space: pre-wrap; } <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> */</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> <p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Bitstream Vera Sans'; font-size:18pt; font-weight:600;">Java IconLoader class</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><br /></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Copyright (c) 2011, Chris Molini</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">All rights reserved.</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> @@ -447,8 +447,13 @@ p, li { white-space: pre-wrap; } <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</span></p> +<p align="center" style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> +<p align="center" style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Bitstream Vera Sans'; font-size:18pt; font-weight:600;">ColumnResizer</span></p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"><br /></p></body></html> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">/*</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * Copyright 2011 Aurélien Gâteau &lt;agateau@kde.org&gt;</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> * License: LGPL v2.1 or later (see COPYING)</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;"> */</span></p></body></html> @@ -459,8 +464,8 @@ p, li { white-space: pre-wrap; } 0 0 - 689 - 331 + 98 + 88 @@ -473,12 +478,12 @@ p, li { white-space: pre-wrap; } <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Bitstream Vera Sans'; font-size:11pt;">We keep MultiMC open source because we think it's important to be able to see the source code for a project like this, and we do so using the Apache license.</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Bitstream Vera Sans'; font-size:11pt;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Bitstream Vera Sans'; font-size:11pt;">Part of the reason for using the Apache license is we don't want people using the &quot;MultiMC&quot; name when redistributing the project. This means people must take the time to go through the source code and remove all references to &quot;MultiMC&quot;, including but not limited to the project icon and the title of windows, (no *MultiMC-fork* in the title).</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Bitstream Vera Sans'; font-size:11pt;"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Bitstream Vera Sans'; font-size:11pt;">The Apache license covers reasonable use for the name - a mention of the project's origins in the About dialog and the license is acceptable. However, it should be abundantly clear that the project is a fork </span><span style=" font-family:'Bitstream Vera Sans'; font-size:11pt; font-weight:600;">without</span><span style=" font-family:'Bitstream Vera Sans'; font-size:11pt;"> implying that you have our blessing.</span></p></body></html> +</style></head><body style=" font-family:'Bitstream Vera Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">We keep MultiMC open source because we think it's important to be able to see the source code for a project like this, and we do so using the Apache license.</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Part of the reason for using the Apache license is we don't want people using the &quot;MultiMC&quot; name when redistributing the project. This means people must take the time to go through the source code and remove all references to &quot;MultiMC&quot;, including but not limited to the project icon and the title of windows, (no *MultiMC-fork* in the title).</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">The Apache license covers reasonable use for the name - a mention of the project's origins in the About dialog and the license is acceptable. However, it should be abundantly clear that the project is a fork <span style=" font-weight:600;">without</span> implying that you have our blessing.</p></body></html> Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse diff --git a/gui/pages/global/AccountListPage.cpp b/gui/pages/global/AccountListPage.cpp index cad7d5bc..00487d57 100644 --- a/gui/pages/global/AccountListPage.cpp +++ b/gui/pages/global/AccountListPage.cpp @@ -34,9 +34,10 @@ #include AccountListPage::AccountListPage(QWidget *parent) - : QDialog(parent), ui(new Ui::AccountListPage) + : QWidget(parent), ui(new Ui::AccountListPage) { ui->setupUi(this); + ui->tabWidget->tabBar()->hide(); m_accounts = MMC->accounts(); diff --git a/gui/pages/global/AccountListPage.h b/gui/pages/global/AccountListPage.h index fd4724d1..fd2c96e3 100644 --- a/gui/pages/global/AccountListPage.h +++ b/gui/pages/global/AccountListPage.h @@ -29,7 +29,7 @@ class AccountListPage; class AuthenticateTask; -class AccountListPage : public QDialog, public BasePage +class AccountListPage : public QWidget, public BasePage { Q_OBJECT public: diff --git a/gui/pages/global/AccountListPage.ui b/gui/pages/global/AccountListPage.ui index 1e5b07eb..8ad78cf4 100644 --- a/gui/pages/global/AccountListPage.ui +++ b/gui/pages/global/AccountListPage.ui @@ -6,81 +6,107 @@ 0 0 - 400 - 300 + 694 + 609 Manage Accounts + + 0 + + + 0 + + + 0 + + + 0 + - - - <html><head/><body><p>Welcome! If you're new here, you can click the &quot;Add&quot; button to add your Mojang or Minecraft account.</p></body></html> + + + 0 - - true - - - - - - - - - - + + + Tab 1 + + - + - &Add + <html><head/><body><p>Welcome! If you're new here, you can click the &quot;Add&quot; button to add your Mojang or Minecraft account.</p></body></html> - - - - - - &Remove + + true - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - <html><head/><body><p>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).</p></body></html> - - - &Set Default - - - - - - - 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. - - - &No Default - - + + + + + + + + + + &Add + + + + + + + &Remove + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + <html><head/><body><p>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).</p></body></html> + + + &Set Default + + + + + + + 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. + + + &No Default + + + + + + - - + + diff --git a/gui/pages/global/BaseSettingsPage.cpp b/gui/pages/global/BaseSettingsPage.cpp deleted file mode 100644 index 167b23c0..00000000 --- a/gui/pages/global/BaseSettingsPage.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* 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 "BaseSettingsPage.h" - -#include "MultiMC.h" - -void BaseSettingsPage::opened() -{ - loadSettings(MMC->settings().get()); -} -bool BaseSettingsPage::apply() -{ - applySettings(MMC->settings().get()); - return true; -} diff --git a/gui/pages/global/BaseSettingsPage.h b/gui/pages/global/BaseSettingsPage.h deleted file mode 100644 index 55e5f2a4..00000000 --- a/gui/pages/global/BaseSettingsPage.h +++ /dev/null @@ -1,35 +0,0 @@ -/* 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 "gui/pages/BasePage.h" - -class SettingsObject; - -class BaseSettingsPage : public BasePage -{ -public: - virtual ~BaseSettingsPage() - { - } - - void opened() override; - bool apply() override; - -protected: - virtual void loadSettings(SettingsObject *object) = 0; - virtual void applySettings(SettingsObject *object) = 0; -}; diff --git a/gui/pages/global/ExternalToolsPage.cpp b/gui/pages/global/ExternalToolsPage.cpp index e0312ee5..417a13e3 100644 --- a/gui/pages/global/ExternalToolsPage.cpp +++ b/gui/pages/global/ExternalToolsPage.cpp @@ -18,6 +18,7 @@ #include #include +#include #include @@ -30,10 +31,16 @@ ExternalToolsPage::ExternalToolsPage(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() @@ -41,17 +48,35 @@ ExternalToolsPage::~ExternalToolsPage() delete ui; } -void ExternalToolsPage::loadSettings(SettingsObject *object) +void ExternalToolsPage::loadSettings() { - ui->jprofilerPathEdit->setText(object->get("JProfilerPath").toString()); - ui->jvisualvmPathEdit->setText(object->get("JVisualVMPath").toString()); - ui->mceditPathEdit->setText(object->get("MCEditPath").toString()); + 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(SettingsObject *object) +void ExternalToolsPage::applySettings() { - object->set("JProfilerPath", ui->jprofilerPathEdit->text()); - object->set("JVisualVMPath", ui->jvisualvmPathEdit->text()); - object->set("MCEditPath", ui->mceditPathEdit->text()); + 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() @@ -175,3 +200,39 @@ void ExternalToolsPage::on_mceditCheckBtn_clicked() 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 index 1b35a92b..027e164e 100644 --- a/gui/pages/global/ExternalToolsPage.h +++ b/gui/pages/global/ExternalToolsPage.h @@ -17,13 +17,13 @@ #include -#include "BaseSettingsPage.h" +#include "gui/pages/BasePage.h" namespace Ui { class ExternalToolsPage; } -class ExternalToolsPage : public QWidget, public BaseSettingsPage +class ExternalToolsPage : public QWidget, public BasePage { Q_OBJECT @@ -47,10 +47,11 @@ public: { return "External-tools"; } + virtual bool apply(); -protected: - void loadSettings(SettingsObject *object) override; - void applySettings(SettingsObject *object) override; +private: + void loadSettings(); + void applySettings(); private: Ui::ExternalToolsPage *ui; @@ -63,4 +64,5 @@ slots: 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 index 96650f0f..ba1b6f01 100644 --- a/gui/pages/global/ExternalToolsPage.ui +++ b/gui/pages/global/ExternalToolsPage.ui @@ -6,138 +6,190 @@ 0 0 - 494 - 562 + 673 + 751 Form + + 0 + + + 0 + + + 0 + + + 0 + - - - JProfiler + + + 0 - - - - - - - - - - ... - - - - - - - - - Check - - - - - - - <html><head/><body><p><a href="http://www.ej-technologies.com/products/jprofiler/overview.html"><span style=" text-decoration: underline; color:#0000ff;">http://www.ej-technologies.com/products/jprofiler/overview.html</span></a></p></body></html> - - - - + + + Tab 1 + + + + + + JProfiler + + + + + + + + + + + ... + + + + + + + + + Check + + + + + + + <html><head/><body><p><a href="http://www.ej-technologies.com/products/jprofiler/overview.html"><span style=" text-decoration: underline; color:#0000ff;">http://www.ej-technologies.com/products/jprofiler/overview.html</span></a></p></body></html> + + + + + + + + + + JVisualVM + + + + + + + + + + + ... + + + + + + + + + Check + + + + + + + <html><head/><body><p><a href="http://visualvm.java.net/"><span style=" text-decoration: underline; color:#0000ff;">http://visualvm.java.net/</span></a></p></body></html> + + + + + + + + + + MCEdit + + + + + + + + + + + ... + + + + + + + + + Check + + + + + + + <html><head/><body><p><a href="http://www.mcedit.net/"><span style=" text-decoration: underline; color:#0000ff;">http://www.mcedit.net/</span></a></p></body></html> + + + + + + + + + + External Editors (leave empty for system default) + + + + + + + + + Text Editor: + + + + + + + ... + + + + + + + + + + Qt::Vertical + + + + 20 + 216 + + + + + + - - - - JVisualVM - - - - - - - - - - - ... - - - - - - - - - Check - - - - - - - <html><head/><body><p><a href="http://visualvm.java.net/"><span style=" text-decoration: underline; color:#0000ff;">http://visualvm.java.net/</span></a></p></body></html> - - - - - - - - - - MCEdit - - - - - - - - - - - ... - - - - - - - - - Check - - - - - - - <html><head/><body><p><a href="http://www.mcedit.net/"><span style=" text-decoration: underline; color:#0000ff;">http://www.mcedit.net/</span></a></p></body></html> - - - - - - - - - - Qt::Vertical - - - - 20 - 160 - - - - 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 +#include +#include + +#include + +#include "logic/NagUtils.h" + +#include "gui/Platform.h" +#include "gui/dialogs/VersionSelectDialog.h" +#include + +#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(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 +#include + +#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 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 @@ + + + JavaPage + + + + 0 + 0 + 545 + 609 + + + + + 0 + 0 + + + + Settings + + + + :/icons/toolbar/settings:/icons/toolbar/settings + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0 + + + + Tab 1 + + + + + + Memory + + + + + + The maximum amount of memory Minecraft is allowed to use. + + + MB + + + 512 + + + 65536 + + + 128 + + + 1024 + + + + + + + Minimum memory allocation: + + + + + + + Maximum memory allocation: + + + + + + + The amount of memory Minecraft is started with. + + + MB + + + 256 + + + 65536 + + + 128 + + + 256 + + + + + + + PermGen: + + + + + + + The amount of memory available to store loaded Java classes. + + + MB + + + 64 + + + 999999999 + + + 8 + + + 64 + + + + + + + + + + Java Runtime + + + + + + + 0 + 0 + + + + Java path: + + + + + + + + 0 + 0 + + + + Auto-detect... + + + + + + + + 0 + 0 + + + + Test + + + + + + + + 0 + 0 + + + + JVM arguments: + + + + + + +