summaryrefslogtreecommitdiffstats
path: root/application/setupwizard
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2017-01-05 04:05:08 +0100
committerPetr Mrázek <peterix@gmail.com>2017-01-05 04:05:08 +0100
commite1bd1c614519974d7bfc0efc8dcbfafa9418e2fa (patch)
tree2592a85455ff45925eaa19e8023061a5089be89a /application/setupwizard
parent4c0db2b99decf407b1f5cf0afc6f29db87ac03ca (diff)
downloadMultiMC-e1bd1c614519974d7bfc0efc8dcbfafa9418e2fa.tar
MultiMC-e1bd1c614519974d7bfc0efc8dcbfafa9418e2fa.tar.gz
MultiMC-e1bd1c614519974d7bfc0efc8dcbfafa9418e2fa.tar.lz
MultiMC-e1bd1c614519974d7bfc0efc8dcbfafa9418e2fa.tar.xz
MultiMC-e1bd1c614519974d7bfc0efc8dcbfafa9418e2fa.zip
NOISSUE feature complete setup wizard
Diffstat (limited to 'application/setupwizard')
-rw-r--r--application/setupwizard/AnalyticsWizardPage.cpp79
-rw-r--r--application/setupwizard/AnalyticsWizardPage.h26
-rw-r--r--application/setupwizard/BaseWizardPage.h33
-rw-r--r--application/setupwizard/JavaWizardPage.cpp327
-rw-r--r--application/setupwizard/JavaWizardPage.h79
-rw-r--r--application/setupwizard/LanguageWizardPage.cpp74
-rw-r--r--application/setupwizard/LanguageWizardPage.h33
-rw-r--r--application/setupwizard/SetupWizard.cpp353
-rw-r--r--application/setupwizard/SetupWizard.h7
9 files changed, 715 insertions, 296 deletions
diff --git a/application/setupwizard/AnalyticsWizardPage.cpp b/application/setupwizard/AnalyticsWizardPage.cpp
new file mode 100644
index 00000000..40fb0b88
--- /dev/null
+++ b/application/setupwizard/AnalyticsWizardPage.cpp
@@ -0,0 +1,79 @@
+#include "AnalyticsWizardPage.h"
+#include <MultiMC.h>
+
+#include <QVBoxLayout>
+#include <QTextBrowser>
+#include <QCheckBox>
+
+#include <ganalytics.h>
+
+AnalyticsWizardPage::AnalyticsWizardPage(QWidget *parent)
+ : BaseWizardPage(parent)
+{
+ setObjectName(QStringLiteral("analyticsPage"));
+ verticalLayout_3 = new QVBoxLayout(this);
+ verticalLayout_3->setObjectName(QStringLiteral("verticalLayout_3"));
+ textBrowser = new QTextBrowser(this);
+ textBrowser->setObjectName(QStringLiteral("textBrowser"));
+ textBrowser->setAcceptRichText(false);
+ textBrowser->setOpenExternalLinks(true);
+ verticalLayout_3->addWidget(textBrowser);
+
+ checkBox = new QCheckBox(this);
+ checkBox->setObjectName(QStringLiteral("checkBox"));
+ checkBox->setChecked(true);
+ verticalLayout_3->addWidget(checkBox);
+ retranslate();
+}
+
+AnalyticsWizardPage::~AnalyticsWizardPage()
+{
+}
+
+bool AnalyticsWizardPage::validatePage()
+{
+ auto settings = MMC->settings();
+ auto analytics = MMC->analytics();
+ auto status = checkBox->isChecked();
+ settings->set("AnalyticsSeen", analytics->version());
+ settings->set("Analytics", status);
+ return true;
+}
+
+bool AnalyticsWizardPage::isRequired()
+{
+ auto settings = MMC->settings();
+ auto analytics = MMC->analytics();
+ if (!settings->get("Analytics").toBool())
+ {
+ return false;
+ }
+ if (settings->get("AnalyticsSeen").toInt() < analytics->version())
+ {
+ return true;
+ }
+ return false;
+}
+
+void AnalyticsWizardPage::retranslate()
+{
+ setTitle(QApplication::translate("AnalyticsWizardPage", "Analytics", Q_NULLPTR));
+ setSubTitle(QApplication::translate("AnalyticsWizardPage", "We track some anonymous statistics about users.", Q_NULLPTR));
+ textBrowser->setHtml(QApplication::translate(
+ "AnalyticsWizardPage",
+ "<html><body>"
+ "<p>MultiMC sends anonymous usage statistics on every start of the application. This helps us decide what platforms and issues to focus on.</p>"
+ "<p>The data is processed by Google Analytics, see their <a href=\"https://support.google.com/analytics/answer/6004245?hl=en\">article on the "
+ "matter</a>.</p>"
+ "<p>The following data is collected:</p>"
+ "<ul><li>A random unique ID of the MultiMC installation.<br />It is stored in the application settings (multimc.cfg).</li>"
+ "<li>Anonymized (partial) IP address.</li>"
+ "<li>MultiMC version.</li>"
+ "<li>Operating system name, version and architecture.</li>"
+ "<li>CPU architecture (kernel architecture on linux).</li>"
+ "<li>Size of system memory.</li>"
+ "<li>Java version, architecture and memory settings.</li></ul>"
+ "<p>If we change the tracked information, you will see this page again.</p></body></html>",
+ Q_NULLPTR));
+ checkBox->setText(QApplication::translate("AnalyticsWizardPage", "Enable Analytics", Q_NULLPTR));
+}
diff --git a/application/setupwizard/AnalyticsWizardPage.h b/application/setupwizard/AnalyticsWizardPage.h
new file mode 100644
index 00000000..88fbed01
--- /dev/null
+++ b/application/setupwizard/AnalyticsWizardPage.h
@@ -0,0 +1,26 @@
+#pragma once
+
+#include "BaseWizardPage.h"
+
+class QVBoxLayout;
+class QTextBrowser;
+class QCheckBox;
+
+class AnalyticsWizardPage : public BaseWizardPage
+{
+ Q_OBJECT;
+public:
+ explicit AnalyticsWizardPage(QWidget *parent = Q_NULLPTR);
+ virtual ~AnalyticsWizardPage();
+
+ bool validatePage() override;
+ static bool isRequired();
+
+protected:
+ void retranslate() override;
+
+private:
+ QVBoxLayout *verticalLayout_3 = nullptr;
+ QTextBrowser *textBrowser = nullptr;
+ QCheckBox *checkBox = nullptr;
+}; \ No newline at end of file
diff --git a/application/setupwizard/BaseWizardPage.h b/application/setupwizard/BaseWizardPage.h
new file mode 100644
index 00000000..9ad54e09
--- /dev/null
+++ b/application/setupwizard/BaseWizardPage.h
@@ -0,0 +1,33 @@
+#pragma once
+
+#include <QWizardPage>
+#include <QEvent>
+
+class BaseWizardPage : public QWizardPage
+{
+public:
+ explicit BaseWizardPage(QWidget *parent = Q_NULLPTR)
+ : QWizardPage(parent)
+ {
+ }
+ virtual ~BaseWizardPage() {};
+
+ virtual bool wantsRefreshButton()
+ {
+ return false;
+ }
+ virtual void refresh()
+ {
+ }
+
+protected:
+ virtual void retranslate() = 0;
+ void changeEvent(QEvent * event) override
+ {
+ if (event->type() == QEvent::LanguageChange)
+ {
+ retranslate();
+ }
+ QWizardPage::changeEvent(event);
+ }
+};
diff --git a/application/setupwizard/JavaWizardPage.cpp b/application/setupwizard/JavaWizardPage.cpp
new file mode 100644
index 00000000..31b8ff71
--- /dev/null
+++ b/application/setupwizard/JavaWizardPage.cpp
@@ -0,0 +1,327 @@
+#include "JavaWizardPage.h"
+#include <MultiMC.h>
+
+#include <QVBoxLayout>
+#include <QGroupBox>
+#include <QSpinBox>
+#include <QLabel>
+#include <QLineEdit>
+#include <QPushButton>
+#include <widgets/VersionSelectWidget.h>
+#include <widgets/IconLabel.h>
+#include <FileSystem.h>
+
+#include <java/JavaInstall.h>
+#include <dialogs/CustomMessageBox.h>
+#include <java/JavaUtils.h>
+#include <sys.h>
+#include <QFileDialog>
+
+
+JavaWizardPage::JavaWizardPage(QWidget *parent)
+ :BaseWizardPage(parent)
+{
+ m_availableMemory = Sys::getSystemRam() / (1024ull * 1024ull);
+
+ goodIcon = MMC->getThemedIcon("status-good");
+ yellowIcon = MMC->getThemedIcon("status-yellow");
+ badIcon = MMC->getThemedIcon("status-bad");
+ setupUi();
+
+ connect(m_minMemSpinBox, SIGNAL(valueChanged(int)), this, SLOT(memoryValueChanged(int)));
+ connect(m_maxMemSpinBox, SIGNAL(valueChanged(int)), this, SLOT(memoryValueChanged(int)));
+ connect(m_permGenSpinBox, SIGNAL(valueChanged(int)), this, SLOT(memoryValueChanged(int)));
+ connect(m_versionWidget, &VersionSelectWidget::selectedVersionChanged, this, &JavaWizardPage::javaVersionSelected);
+ connect(m_javaBrowseBtn, &QPushButton::clicked, this, &JavaWizardPage::on_javaBrowseBtn_clicked);
+ connect(m_javaPathTextBox, &QLineEdit::textEdited, this, &JavaWizardPage::checkJavaPath);
+}
+
+void JavaWizardPage::setupUi()
+{
+ setObjectName(QStringLiteral("javaPage"));
+ m_verticalLayout = new QVBoxLayout(this);
+ m_verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
+
+ m_versionWidget = new VersionSelectWidget(MMC->javalist().get(), this);
+ m_versionWidget->setResizeOn(2);
+ m_verticalLayout->addWidget(m_versionWidget);
+
+ m_horizontalLayout = new QHBoxLayout();
+ m_horizontalLayout->setObjectName(QStringLiteral("horizontalLayout"));
+ m_javaPathTextBox = new QLineEdit(this);
+ m_javaPathTextBox->setObjectName(QStringLiteral("javaPathTextBox"));
+
+ m_horizontalLayout->addWidget(m_javaPathTextBox);
+
+ m_javaBrowseBtn = new QPushButton(this);
+ m_javaBrowseBtn->setObjectName(QStringLiteral("javaBrowseBtn"));
+ /*
+ QSizePolicy sizePolicy2(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ sizePolicy2.setHorizontalStretch(0);
+ sizePolicy2.setVerticalStretch(0);
+ sizePolicy2.setHeightForWidth(m_javaBrowseBtn->sizePolicy().hasHeightForWidth());
+ m_javaBrowseBtn->setSizePolicy(sizePolicy2);
+ m_javaBrowseBtn->setMaximumSize(QSize(28, 16777215));
+ */
+ m_javaBrowseBtn->setText(QStringLiteral("..."));
+ m_horizontalLayout->addWidget(m_javaBrowseBtn);
+
+ m_javaStatusLabel = new IconLabel(this, badIcon, QSize(16, 16));
+ m_horizontalLayout->addWidget(m_javaStatusLabel);
+
+ m_verticalLayout->addLayout(m_horizontalLayout);
+
+ m_memoryGroupBox = new QGroupBox(this);
+ m_memoryGroupBox->setObjectName(QStringLiteral("memoryGroupBox"));
+ m_gridLayout_2 = new QGridLayout(m_memoryGroupBox);
+ m_gridLayout_2->setObjectName(QStringLiteral("gridLayout_2"));
+
+ m_labelMinMem = new QLabel(m_memoryGroupBox);
+ m_labelMinMem->setObjectName(QStringLiteral("labelMinMem"));
+ m_gridLayout_2->addWidget(m_labelMinMem, 0, 0, 1, 1);
+
+ m_minMemSpinBox = new QSpinBox(m_memoryGroupBox);
+ m_minMemSpinBox->setObjectName(QStringLiteral("minMemSpinBox"));
+ m_minMemSpinBox->setSuffix(QStringLiteral(" MB"));
+ m_minMemSpinBox->setMinimum(256);
+ m_minMemSpinBox->setMaximum(m_availableMemory);
+ m_minMemSpinBox->setSingleStep(128);
+ m_minMemSpinBox->setValue(256);
+ m_gridLayout_2->addWidget(m_minMemSpinBox, 0, 1, 1, 1);
+
+ m_labelMaxMem = new QLabel(m_memoryGroupBox);
+ m_labelMaxMem->setObjectName(QStringLiteral("labelMaxMem"));
+ m_gridLayout_2->addWidget(m_labelMaxMem, 1, 0, 1, 1);
+
+ m_maxMemSpinBox = new QSpinBox(m_memoryGroupBox);
+ m_maxMemSpinBox->setObjectName(QStringLiteral("maxMemSpinBox"));
+ m_maxMemSpinBox->setSuffix(QStringLiteral(" MB"));
+ m_maxMemSpinBox->setMinimum(512);
+ m_maxMemSpinBox->setMaximum(m_availableMemory);
+ m_maxMemSpinBox->setSingleStep(128);
+ m_maxMemSpinBox->setValue(1024);
+ m_gridLayout_2->addWidget(m_maxMemSpinBox, 1, 1, 1, 1);
+
+ m_labelPermGen = new QLabel(m_memoryGroupBox);
+ m_labelPermGen->setObjectName(QStringLiteral("labelPermGen"));
+ m_labelPermGen->setText(QStringLiteral("PermGen:"));
+ m_gridLayout_2->addWidget(m_labelPermGen, 2, 0, 1, 1);
+ m_labelPermGen->setVisible(false);
+
+ m_permGenSpinBox = new QSpinBox(m_memoryGroupBox);
+ m_permGenSpinBox->setObjectName(QStringLiteral("permGenSpinBox"));
+ m_permGenSpinBox->setSuffix(QStringLiteral(" MB"));
+ m_permGenSpinBox->setMinimum(64);
+ m_permGenSpinBox->setMaximum(m_availableMemory);
+ m_permGenSpinBox->setSingleStep(8);
+ m_permGenSpinBox->setValue(128);
+ m_gridLayout_2->addWidget(m_permGenSpinBox, 2, 1, 1, 1);
+ m_permGenSpinBox->setVisible(false);
+
+ m_verticalLayout->addWidget(m_memoryGroupBox);
+
+ retranslate();
+}
+
+void JavaWizardPage::refresh()
+{
+ m_versionWidget->loadList();
+}
+
+void JavaWizardPage::initializePage()
+{
+ m_versionWidget->initialize();
+ auto s = MMC->settings();
+ // Memory
+ m_minMemSpinBox->setValue(s->get("MinMemAlloc").toInt());
+ m_maxMemSpinBox->setValue(s->get("MaxMemAlloc").toInt());
+ m_permGenSpinBox->setValue(s->get("PermGen").toInt());
+}
+
+bool JavaWizardPage::validatePage()
+{
+ auto settings = MMC->settings();
+ auto path = m_javaPathTextBox->text();
+ switch(javaStatus)
+ {
+ case JavaStatus::Bad:
+ {
+ int button = CustomMessageBox::selectable(
+ this,
+ tr("No Java version selected"),
+ tr("You didn't select a Java version or selected something that doesn't work.\n"
+ "MultiMC will not be able to start Minecraft.\n"
+ "Do you wish to proceed without any Java?"
+ "\n\n"
+ "You can change the Java version in the settings later.\n"
+ ),
+ QMessageBox::Warning,
+ QMessageBox::Yes | QMessageBox::No,
+ QMessageBox::NoButton
+ )->exec();
+ if(button == QMessageBox::No)
+ {
+ return false;
+ }
+ }
+ break;
+ case JavaStatus::Pending:
+ {
+ return false;
+ }
+ case JavaStatus::Good:
+ {
+ settings->set("JavaPath", path);
+ }
+ }
+
+ // Memory
+ auto s = MMC->settings();
+ s->set("MinMemAlloc", m_minMemSpinBox->value());
+ s->set("MaxMemAlloc", m_maxMemSpinBox->value());
+ if (m_permGenSpinBox->isVisible())
+ {
+ s->set("PermGen", m_permGenSpinBox->value());
+ }
+ else
+ {
+ s->reset("PermGen");
+ }
+ return true;
+}
+
+bool JavaWizardPage::isRequired()
+{
+ QString currentHostName = QHostInfo::localHostName();
+ QString oldHostName = MMC->settings()->get("LastHostname").toString();
+ if (currentHostName != oldHostName)
+ {
+ MMC->settings()->set("LastHostname", currentHostName);
+ return true;
+ }
+ QString currentJavaPath = MMC->settings()->get("JavaPath").toString();
+ QString actualPath = FS::ResolveExecutable(currentJavaPath);
+ if (actualPath.isNull())
+ {
+ return true;
+ }
+ return false;
+}
+
+bool JavaWizardPage::wantsRefreshButton()
+{
+ return true;
+}
+
+void JavaWizardPage::memoryValueChanged(int)
+{
+ int min = m_minMemSpinBox->value();
+ int max = m_maxMemSpinBox->value();
+ QObject *obj = sender();
+ if (obj == m_minMemSpinBox)
+ {
+ if (min > max)
+ {
+ m_maxMemSpinBox->setValue(min);
+ }
+ }
+ else if (obj == m_maxMemSpinBox)
+ {
+ if (min > max)
+ {
+ m_minMemSpinBox->setValue(max);
+ }
+ }
+ checkJavaPath(m_javaPathTextBox->text());
+}
+
+void JavaWizardPage::javaVersionSelected(BaseVersionPtr version)
+{
+ auto java = std::dynamic_pointer_cast<JavaInstall>(version);
+ if(!java)
+ {
+ return;
+ }
+ auto visible = java->id.requiresPermGen();
+ m_labelPermGen->setVisible(visible);
+ m_permGenSpinBox->setVisible(visible);
+ m_javaPathTextBox->setText(java->path);
+ checkJavaPath(java->path);
+}
+
+void JavaWizardPage::on_javaBrowseBtn_clicked()
+{
+ QString raw_path = QFileDialog::getOpenFileName(this, tr("Find Java executable"));
+ if(raw_path.isNull())
+ {
+ return;
+ }
+ QString cooked_path = FS::NormalizePath(raw_path);
+ m_javaPathTextBox->setText(cooked_path);
+ checkJavaPath(cooked_path);
+}
+
+void JavaWizardPage::setJavaStatus(JavaWizardPage::JavaStatus status)
+{
+ javaStatus = status;
+ switch(javaStatus)
+ {
+ case JavaStatus::Good:
+ m_javaStatusLabel->setIcon(goodIcon);
+ break;
+ case JavaStatus::Pending:
+ m_javaStatusLabel->setIcon(yellowIcon);
+ break;
+ default:
+ case JavaStatus::Bad:
+ m_javaStatusLabel->setIcon(badIcon);
+ break;
+ }
+}
+
+void JavaWizardPage::checkJavaPath(const QString &path)
+{
+ auto realPath = FS::ResolveExecutable(path);
+ if(realPath.isNull())
+ {
+ setJavaStatus(JavaStatus::Bad);
+ return;
+ }
+ setJavaStatus(JavaStatus::Pending);
+ m_checker.reset(new JavaChecker());
+ m_checker->m_path = path;
+ m_checker->m_minMem = m_minMemSpinBox->value();
+ m_checker->m_maxMem = m_maxMemSpinBox->value();
+ if(m_permGenSpinBox->isVisible())
+ {
+ m_checker->m_permGen = m_permGenSpinBox->value();
+ }
+ connect(m_checker.get(), &JavaChecker::checkFinished, this, &JavaWizardPage::checkFinished);
+ m_checker->performCheck();
+}
+
+void JavaWizardPage::checkFinished(JavaCheckResult result)
+{
+ if(result.valid)
+ {
+ setJavaStatus(JavaStatus::Good);
+ }
+ else
+ {
+ setJavaStatus(JavaStatus::Bad);
+ }
+ m_checker.reset();
+}
+
+void JavaWizardPage::retranslate()
+{
+ setTitle(QApplication::translate("JavaWizardPage", "Java", Q_NULLPTR));
+ setSubTitle(QApplication::translate("JavaWizardPage", "You do not have a working Java set up yet or it went missing.\n"
+ "Please select one of the following or browse for a java executable.", Q_NULLPTR));
+ m_memoryGroupBox->setTitle(QApplication::translate("JavaPage", "Memory", Q_NULLPTR));
+ m_maxMemSpinBox->setToolTip(QApplication::translate("JavaPage", "The maximum amount of memory Minecraft is allowed to use.", Q_NULLPTR));
+ m_labelMinMem->setText(QApplication::translate("JavaPage", "Minimum memory allocation:", Q_NULLPTR));
+ m_labelMaxMem->setText(QApplication::translate("JavaPage", "Maximum memory allocation:", Q_NULLPTR));
+ m_minMemSpinBox->setToolTip(QApplication::translate("JavaPage", "The amount of memory Minecraft is started with.", Q_NULLPTR));
+ m_permGenSpinBox->setToolTip(QApplication::translate("JavaPage", "The amount of memory available to store loaded Java classes.", Q_NULLPTR));
+}
diff --git a/application/setupwizard/JavaWizardPage.h b/application/setupwizard/JavaWizardPage.h
new file mode 100644
index 00000000..5a61ff02
--- /dev/null
+++ b/application/setupwizard/JavaWizardPage.h
@@ -0,0 +1,79 @@
+#pragma once
+
+#include "BaseWizardPage.h"
+#include <BaseVersion.h>
+#include <QObjectPtr.h>
+#include <java/JavaChecker.h>
+#include <QIcon>
+
+class QLineEdit;
+class VersionSelectWidget;
+class QSpinBox;
+class QPushButton;
+class QVBoxLayout;
+class QHBoxLayout;
+class QGroupBox;
+class QGridLayout;
+class QLabel;
+class IconLabel;
+
+class JavaWizardPage : public BaseWizardPage
+{
+ Q_OBJECT;
+public:
+ explicit JavaWizardPage(QWidget *parent = Q_NULLPTR);
+
+ virtual ~JavaWizardPage()
+ {
+ };
+
+ bool wantsRefreshButton() override;
+ void refresh() override;
+ void initializePage() override;
+ bool validatePage() override;
+ static bool isRequired();
+
+ enum class JavaStatus
+ {
+ Pending,
+ Good,
+ Bad
+ } javaStatus;
+
+protected slots:
+ void memoryValueChanged(int);
+ void javaVersionSelected(BaseVersionPtr version);
+ void on_javaBrowseBtn_clicked();
+ void checkFinished(JavaCheckResult result);
+
+protected: /* methods */
+ void checkJavaPath(const QString &path);
+ void setJavaStatus(JavaStatus status);
+ void setupUi();
+ void retranslate() override;
+
+private: /* data */
+ VersionSelectWidget *m_versionWidget = nullptr;
+ QVBoxLayout *m_verticalLayout = nullptr;
+
+ QLineEdit * m_javaPathTextBox = nullptr;
+ QPushButton * m_javaBrowseBtn = nullptr;
+ IconLabel * m_javaStatusLabel = nullptr;
+ QHBoxLayout *m_horizontalLayout = nullptr;
+
+ QGroupBox *m_memoryGroupBox = nullptr;
+ QGridLayout *m_gridLayout_2 = nullptr;
+ QSpinBox *m_maxMemSpinBox = nullptr;
+ QLabel *m_labelMinMem = nullptr;
+ QLabel *m_labelMaxMem = nullptr;
+ QSpinBox *m_minMemSpinBox = nullptr;
+ QLabel *m_labelPermGen = nullptr;
+ QSpinBox *m_permGenSpinBox = nullptr;
+ QIcon goodIcon;
+ QIcon yellowIcon;
+ QIcon badIcon;
+
+ uint64_t m_availableMemory = 0ull;
+ shared_qobject_ptr<JavaChecker> m_checker;
+};
+
diff --git a/application/setupwizard/LanguageWizardPage.cpp b/application/setupwizard/LanguageWizardPage.cpp
new file mode 100644
index 00000000..cf427a0d
--- /dev/null
+++ b/application/setupwizard/LanguageWizardPage.cpp
@@ -0,0 +1,74 @@
+#include "LanguageWizardPage.h"
+#include <MultiMC.h>
+#include <translations/TranslationsModel.h>
+
+#include <QVBoxLayout>
+#include <QListView>
+
+LanguageWizardPage::LanguageWizardPage(QWidget *parent)
+ : BaseWizardPage(parent)
+{
+ setObjectName(QStringLiteral("languagePage"));
+ verticalLayout = new QVBoxLayout(this);
+ verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
+ languageView = new QListView(this);
+ languageView->setObjectName(QStringLiteral("languageView"));
+ verticalLayout->addWidget(languageView);
+ retranslate();
+
+ auto translations = MMC->translations();
+ auto index = translations->selectedIndex();
+ languageView->setModel(translations.get());
+ languageView->setCurrentIndex(index);
+ connect(languageView->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &LanguageWizardPage::languageRowChanged);
+}
+
+LanguageWizardPage::~LanguageWizardPage()
+{
+}
+
+bool LanguageWizardPage::wantsRefreshButton()
+{
+ return true;
+}
+
+void LanguageWizardPage::refresh()
+{
+ auto translations = MMC->translations();
+ translations->downloadIndex();
+}
+
+bool LanguageWizardPage::validatePage()
+{
+ auto settings = MMC->settings();
+ auto translations = MMC->translations();
+ QString key = translations->data(languageView->currentIndex(), Qt::UserRole).toString();
+ settings->set("Language", key);
+ return true;
+}
+
+bool LanguageWizardPage::isRequired()
+{
+ auto settings = MMC->settings();
+ if (settings->get("Language").toString().isEmpty())
+ return true;
+ return false;
+}
+
+void LanguageWizardPage::retranslate()
+{
+ setTitle(QApplication::translate("LanguageWizardPage", "Language", Q_NULLPTR));
+ setSubTitle(QApplication::translate("LanguageWizardPage", "Select the language to use in MultiMC", Q_NULLPTR));
+}
+
+void LanguageWizardPage::languageRowChanged(const QModelIndex &current, const QModelIndex &previous)
+{
+ if (current == previous)
+ {
+ return;
+ }
+ auto translations = MMC->translations();
+ QString key = translations->data(current, Qt::UserRole).toString();
+ translations->selectLanguage(key);
+ translations->updateLanguage(key);
+}
diff --git a/application/setupwizard/LanguageWizardPage.h b/application/setupwizard/LanguageWizardPage.h
new file mode 100644
index 00000000..9c24b29d
--- /dev/null
+++ b/application/setupwizard/LanguageWizardPage.h
@@ -0,0 +1,33 @@
+#pragma once
+
+#include "BaseWizardPage.h"
+
+class QVBoxLayout;
+class QListView;
+
+class LanguageWizardPage : public BaseWizardPage
+{
+ Q_OBJECT;
+public:
+ explicit LanguageWizardPage(QWidget *parent = Q_NULLPTR);
+
+ virtual ~LanguageWizardPage();
+
+ bool wantsRefreshButton() override;
+
+ void refresh() override;
+
+ bool validatePage() override;
+
+ static bool isRequired();
+
+protected:
+ void retranslate() override;
+
+protected slots:
+ void languageRowChanged(const QModelIndex &current, const QModelIndex &previous);
+
+private:
+ QVBoxLayout *verticalLayout = nullptr;
+ QListView *languageView = nullptr;
+};
diff --git a/application/setupwizard/SetupWizard.cpp b/application/setupwizard/SetupWizard.cpp
index 18b8aff9..fc5b2555 100644
--- a/application/setupwizard/SetupWizard.cpp
+++ b/application/setupwizard/SetupWizard.cpp
@@ -1,336 +1,98 @@
#include "SetupWizard.h"
+
+#include "LanguageWizardPage.h"
+#include "JavaWizardPage.h"
+#include "AnalyticsWizardPage.h"
+
#include "translations/TranslationsModel.h"
#include <MultiMC.h>
#include <FileSystem.h>
#include <ganalytics.h>
+#include <QAbstractButton>
+
enum Page
{
Language,
Java,
Analytics,
- // Themes,
- // Accounts
-};
-
-#include <QtCore/QVariant>
-#include <QtWidgets/QAction>
-#include <QtWidgets/QApplication>
-#include <QtWidgets/QButtonGroup>
-#include <QtWidgets/QCheckBox>
-#include <QtWidgets/QHeaderView>
-#include <QtWidgets/QListView>
-#include <QtWidgets/QTextBrowser>
-#include <QtWidgets/QVBoxLayout>
-#include <QtWidgets/QWizard>
-#include <QtWidgets/QWizardPage>
-
-class BaseWizardPage : public QWizardPage
-{
-public:
- explicit BaseWizardPage(QWidget *parent = Q_NULLPTR)
- : QWizardPage(parent)
- {
- }
- virtual ~BaseWizardPage() {};
-
-protected:
- virtual void retranslate() = 0;
- void changeEvent(QEvent * event) override
- {
- if (event->type() == QEvent::LanguageChange)
- {
- retranslate();
- }
- QWizardPage::changeEvent(event);
- }
};
-class LanguageWizardPage : public BaseWizardPage
+SetupWizard::SetupWizard(QWidget *parent) : QWizard(parent)
{
- Q_OBJECT;
-public:
- explicit LanguageWizardPage(QWidget *parent = Q_NULLPTR)
- : BaseWizardPage(parent)
- {
- setObjectName(QStringLiteral("languagePage"));
- verticalLayout = new QVBoxLayout(this);
- verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
- languageView = new QListView(this);
- languageView->setObjectName(QStringLiteral("languageView"));
- verticalLayout->addWidget(languageView);
- retranslate();
-
- auto translations = MMC->translations();
- auto index = translations->selectedIndex();
- languageView->setModel(translations.get());
- languageView->setCurrentIndex(index);
- connect(languageView->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &LanguageWizardPage::languageRowChanged);
- }
+ setObjectName(QStringLiteral("SetupWizard"));
+ resize(615, 659);
+ // make it ugly everywhere to avoid variability in theming
+ setWizardStyle(QWizard::ClassicStyle);
+ setOptions(QWizard::NoCancelButton | QWizard::IndependentPages | QWizard::HaveCustomButton1);
- virtual ~LanguageWizardPage()
- {
- };
+ retranslate();
- bool validatePage() override
- {
- auto settings = MMC->settings();
- auto translations = MMC->translations();
- QString key = translations->data(languageView->currentIndex(), Qt::UserRole).toString();
- settings->set("Language", key);
- return true;
- }
+ connect(this, &QWizard::currentIdChanged, this, &SetupWizard::pageChanged);
- static bool isRequired()
+ if (LanguageWizardPage::isRequired())
{
- auto settings = MMC->settings();
- if (settings->get("Language").toString().isEmpty())
- return true;
- return false;
+ setPage(Page::Language, new LanguageWizardPage(this));
}
-
-protected:
- void retranslate() override
+ if (JavaWizardPage::isRequired())
{
- setTitle(QApplication::translate("LanguageWizardPage", "Language", Q_NULLPTR));
- setSubTitle(QApplication::translate("LanguageWizardPage", "Select the language to use in MultiMC", Q_NULLPTR));
+ setPage(Page::Java, new JavaWizardPage(this));
}
-
-protected slots:
- void languageRowChanged(const QModelIndex &current, const QModelIndex &previous)
+ if(AnalyticsWizardPage::isRequired())
{
- if (current == previous)
- {
- return;
- }
- auto translations = MMC->translations();
- QString key = translations->data(current, Qt::UserRole).toString();
- translations->selectLanguage(key);
- translations->updateLanguage(key);
+ setPage(Page::Analytics, new AnalyticsWizardPage(this));
}
+}
-private:
- QVBoxLayout *verticalLayout = nullptr;
- QListView *languageView = nullptr;
-};
-
-#include <dialogs/VersionSelectDialog.h>
-#include <java/JavaInstall.h>
-#include <dialogs/CustomMessageBox.h>
-#include <java/JavaUtils.h>
-
-class JavaWizardPage : public BaseWizardPage
+void SetupWizard::retranslate()
{
- Q_OBJECT;
-public:
- explicit JavaWizardPage(QWidget *parent = Q_NULLPTR)
- : BaseWizardPage(parent)
- {
- setObjectName(QStringLiteral("javaPage"));
- // FIXME: this is dumb and ugly.
- qDebug() << "Java path needs resetting, showing Java selection dialog...";
- JavaInstallPtr java;
-
- VersionSelectDialog vselect(MMC->javalist().get(), tr("Select a Java version"), this, false);
- vselect.setResizeOn(2);
- vselect.exec();
-
- if (vselect.selectedVersion())
- {
- java = std::dynamic_pointer_cast<JavaInstall>(vselect.selectedVersion());
- }
- else
- {
- CustomMessageBox::selectable(this,
- tr("Invalid version selected"),
- tr("You didn't select a valid Java version, so MultiMC will select the default. You can change this in the settings dialog."),
- QMessageBox::Warning)->show();
- JavaUtils ju;
- java = ju.GetDefaultJava();
- }
- if (java)
- {
- MMC->settings()->set("JavaPath", java->path);
- }
- else
- {
- MMC->settings()->set("JavaPath", QString("java"));
- }
- retranslate();
- }
-
- virtual ~JavaWizardPage()
- {
- };
-
- bool validatePage() override
- {
- auto settings = MMC->settings();
- /*
- auto analytics = MMC->analytics();
- auto status = checkBox->isChecked();
- settings->set("AnalyticsSeen", analytics->version());
- settings->set("Analytics", status);
- */
- return true;
- }
-
- static bool isRequired()
- {
- QString currentHostName = QHostInfo::localHostName();
- QString oldHostName = MMC->settings()->get("LastHostname").toString();
- if (currentHostName != oldHostName)
- {
- MMC->settings()->set("LastHostname", currentHostName);
- return true;
- }
- QString currentJavaPath = MMC->settings()->get("JavaPath").toString();
- QString actualPath = FS::ResolveExecutable(currentJavaPath);
- if (actualPath.isNull())
- {
- return true;
- }
- return false;
- }
-
-protected:
- void retranslate() override
- {
- setTitle(QApplication::translate("JavaWizardPage", "Java", Q_NULLPTR));
- setSubTitle(QApplication::translate("JavaWizardPage", "You need to set up Java to proceed.", Q_NULLPTR));
- /*
- textBrowser->setHtml(QApplication::translate("JavaWizardPage",
- "<html><body>"
- "<p>MultiMC sends anonymous usage statistics on every start of the application. This helps us decide what platforms and issues to focus on.</p>"
- "<p>The data is processed by Google Analytics, see their <a href=\"https://support.google.com/analytics/answer/6004245?hl=en\">article on the matter</a>.</p>"
- "<p>The following data is collected:</p>"
- "<ul><li>A random unique ID of the MultiMC installation.<br />It is stored in the application settings (multimc.cfg).</li>"
- "<li>Anonymized IP address.<br />Last octet is set to 0 by Google and not stored.</li>"
- "<li>MultiMC version.</li>"
- "<li>Operating system name, version and architecture.</li>"
- "<li>CPU architecture (kernel architecture on linux).</li>"
- "<li>Size of system memory.</li>"
- "<li>Java version, architecture and memory settings.</li></ul>"
- "<p>The analytics will activate on next start, unless you disable them in the settings.</p>"
- "<p>If we change the tracked information, analytics won't be active for the first run and you will see this page again.</p></body></html>", Q_NULLPTR));
- checkBox->setText(QApplication::translate("JavaWizardPage", "Enable Analytics", Q_NULLPTR));
- */
- }
-private:
- /*
- QVBoxLayout *verticalLayout_3 = nullptr;
- QTextBrowser *textBrowser = nullptr;
- QCheckBox *checkBox = nullptr;
- */
-};
+ setButtonText(QWizard::NextButton, tr("&Next >"));
+ setButtonText(QWizard::BackButton, tr("< &Back"));
+ setButtonText(QWizard::FinishButton, tr("&Finish"));
+ setButtonText(QWizard::CustomButton1, tr("&Refresh"));
+ setWindowTitle(QApplication::translate("SetupWizard", "MultiMC Quick Setup", Q_NULLPTR));
+}
-class AnalyticsWizardPage : public BaseWizardPage
+BaseWizardPage * SetupWizard::getBasePage(int id)
{
- Q_OBJECT;
-public:
- explicit AnalyticsWizardPage(QWidget *parent = Q_NULLPTR)
- : BaseWizardPage(parent)
- {
- setObjectName(QStringLiteral("analyticsPage"));
- verticalLayout_3 = new QVBoxLayout(this);
- verticalLayout_3->setObjectName(QStringLiteral("verticalLayout_3"));
- textBrowser = new QTextBrowser(this);
- textBrowser->setObjectName(QStringLiteral("textBrowser"));
- textBrowser->setAcceptRichText(false);
- textBrowser->setOpenExternalLinks(true);
- verticalLayout_3->addWidget(textBrowser);
-
- checkBox = new QCheckBox(this);
- checkBox->setObjectName(QStringLiteral("checkBox"));
- checkBox->setChecked(true);
- verticalLayout_3->addWidget(checkBox);
- retranslate();
- }
-
- virtual ~AnalyticsWizardPage()
- {
- };
-
- bool validatePage() override
- {
- auto settings = MMC->settings();
- auto analytics = MMC->analytics();
- auto status = checkBox->isChecked();
- settings->set("AnalyticsSeen", analytics->version());
- settings->set("Analytics", status);
- return true;
- }
-
- static bool isRequired()
- {
- auto settings = MMC->settings();
- auto analytics = MMC->analytics();
- if(!settings->get("Analytics").toBool())
- {
- return false;
- }
- if(settings->get("AnalyticsSeen").toInt() < analytics->version())
- {
- return true;
- }
- return false;
- }
+ if(id == -1)
+ return nullptr;
+ auto pagePtr = page(id);
+ if(!pagePtr)
+ return nullptr;
+ return dynamic_cast<BaseWizardPage *>(pagePtr);
+}
-protected:
- void retranslate() override
- {
- setTitle(QApplication::translate("AnalyticsWizardPage", "Analytics", Q_NULLPTR));
- setSubTitle(QApplication::translate("AnalyticsWizardPage", "We track some anonymous statistics about users.", Q_NULLPTR));
- textBrowser->setHtml(QApplication::translate("AnalyticsWizardPage",
- "<html><body>"
- "<p>MultiMC sends anonymous usage statistics on every start of the application. This helps us decide what platforms and issues to focus on.</p>"
- "<p>The data is processed by Google Analytics, see their <a href=\"https://support.google.com/analytics/answer/6004245?hl=en\">article on the matter</a>.</p>"
- "<p>The following data is collected:</p>"
- "<ul><li>A random unique ID of the MultiMC installation.<br />It is stored in the application settings (multimc.cfg).</li>"
- "<li>Anonymized IP address.<br />Last octet is set to 0 by Google and not stored.</li>"
- "<li>MultiMC version.</li>"
- "<li>Operating system name, version and architecture.</li>"
- "<li>CPU architecture (kernel architecture on linux).</li>"
- "<li>Size of system memory.</li>"
- "<li>Java version, architecture and memory settings.</li></ul>"
- "<p>The analytics will activate on next start, unless you disable them in the settings.</p>"
- "<p>If we change the tracked information, analytics won't be active for the first run and you will see this page again.</p></body></html>", Q_NULLPTR));
- checkBox->setText(QApplication::translate("AnalyticsWizardPage", "Enable Analytics", Q_NULLPTR));
- }
-private:
- QVBoxLayout *verticalLayout_3 = nullptr;
- QTextBrowser *textBrowser = nullptr;
- QCheckBox *checkBox = nullptr;
-};
+BaseWizardPage * SetupWizard::getCurrentBasePage()
+{
+ return getBasePage(currentId());
+}
-SetupWizard::SetupWizard(QWidget *parent) : QWizard(parent)
+void SetupWizard::pageChanged(int id)
{
- setObjectName(QStringLiteral("SetupWizard"));
- resize(615, 659);
- // make it ugly everywhere to avoid variability in theming
- setWizardStyle(QWizard::ClassicStyle);
- setOptions(QWizard::NoCancelButton | QWizard::IndependentPages);
- if (LanguageWizardPage::isRequired())
+ auto basePagePtr = getBasePage(id);
+ if(!basePagePtr)
{
- setPage(Page::Language, new LanguageWizardPage(this));
+ return;
}
- if (JavaWizardPage::isRequired())
+ if(basePagePtr->wantsRefreshButton())
{
- setPage(Page::Java, new JavaWizardPage(this));
+ setButtonLayout({QWizard::CustomButton1, QWizard::Stretch, QWizard::BackButton, QWizard::NextButton, QWizard::FinishButton});
+ auto customButton = button(QWizard::CustomButton1);
+ connect(customButton, &QAbstractButton::pressed, [&](){
+ auto basePagePtr = getCurrentBasePage();
+ if(basePagePtr)
+ {
+ basePagePtr->refresh();
+ }
+ });
}
- if(AnalyticsWizardPage::isRequired())
+ else
{
- setPage(Page::Analytics, new AnalyticsWizardPage(this));
+ setButtonLayout({QWizard::Stretch, QWizard::BackButton, QWizard::NextButton, QWizard::FinishButton});
}
}
-void SetupWizard::retranslate()
-{
- setButtonText(QWizard::NextButton, tr("Next >"));
- setButtonText(QWizard::BackButton, tr("< Back"));
- setButtonText(QWizard::FinishButton, tr("Finish"));
- setWindowTitle(QApplication::translate("SetupWizard", "MultiMC Quick Setup", Q_NULLPTR));
-}
void SetupWizard::changeEvent(QEvent *event)
{
@@ -356,4 +118,3 @@ bool SetupWizard::isRequired()
return false;
}
-#include "SetupWizard.moc"
diff --git a/application/setupwizard/SetupWizard.h b/application/setupwizard/SetupWizard.h
index adf254c7..a1e757d8 100644
--- a/application/setupwizard/SetupWizard.h
+++ b/application/setupwizard/SetupWizard.h
@@ -22,6 +22,8 @@ namespace Ui
class SetupWizard;
}
+class BaseWizardPage;
+
class SetupWizard : public QWizard
{
Q_OBJECT
@@ -31,6 +33,11 @@ public: /* con/destructors */
virtual ~SetupWizard();
void changeEvent(QEvent * event) override;
+ BaseWizardPage *getBasePage(int id);
+ BaseWizardPage *getCurrentBasePage();
+
+private slots:
+ void pageChanged(int id);
public: /* methods */
static bool isRequired();