diff options
author | Petr Mrázek <peterix@gmail.com> | 2017-01-05 04:05:08 +0100 |
---|---|---|
committer | Petr Mrázek <peterix@gmail.com> | 2017-01-05 04:05:08 +0100 |
commit | e1bd1c614519974d7bfc0efc8dcbfafa9418e2fa (patch) | |
tree | 2592a85455ff45925eaa19e8023061a5089be89a /application/setupwizard | |
parent | 4c0db2b99decf407b1f5cf0afc6f29db87ac03ca (diff) | |
download | MultiMC-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.cpp | 79 | ||||
-rw-r--r-- | application/setupwizard/AnalyticsWizardPage.h | 26 | ||||
-rw-r--r-- | application/setupwizard/BaseWizardPage.h | 33 | ||||
-rw-r--r-- | application/setupwizard/JavaWizardPage.cpp | 327 | ||||
-rw-r--r-- | application/setupwizard/JavaWizardPage.h | 79 | ||||
-rw-r--r-- | application/setupwizard/LanguageWizardPage.cpp | 74 | ||||
-rw-r--r-- | application/setupwizard/LanguageWizardPage.h | 33 | ||||
-rw-r--r-- | application/setupwizard/SetupWizard.cpp | 353 | ||||
-rw-r--r-- | application/setupwizard/SetupWizard.h | 7 |
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 ¤t, 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 ¤t, 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 ¤t, 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(); |