NOISSUE feature complete setup wizard

This commit is contained in:
Petr Mrázek
2017-01-05 04:05:08 +01:00
parent 4c0db2b99d
commit e1bd1c6145
17 changed files with 1075 additions and 553 deletions

View File

@ -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));
}

View File

@ -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;
};

View File

@ -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);
}
};

View File

@ -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));
}

View File

@ -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;
};

View File

@ -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);
}

View File

@ -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;
};

View File

@ -1,306 +1,21 @@
#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
{
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);
}
virtual ~LanguageWizardPage()
{
};
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;
}
static bool isRequired()
{
auto settings = MMC->settings();
if (settings->get("Language").toString().isEmpty())
return true;
return false;
}
protected:
void retranslate() override
{
setTitle(QApplication::translate("LanguageWizardPage", "Language", Q_NULLPTR));
setSubTitle(QApplication::translate("LanguageWizardPage", "Select the language to use in MultiMC", Q_NULLPTR));
}
protected slots:
void 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);
}
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
{
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;
*/
};
class AnalyticsWizardPage : public BaseWizardPage
{
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;
}
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;
};
SetupWizard::SetupWizard(QWidget *parent) : QWizard(parent)
@ -309,7 +24,12 @@ SetupWizard::SetupWizard(QWidget *parent) : QWizard(parent)
resize(615, 659);
// make it ugly everywhere to avoid variability in theming
setWizardStyle(QWizard::ClassicStyle);
setOptions(QWizard::NoCancelButton | QWizard::IndependentPages);
setOptions(QWizard::NoCancelButton | QWizard::IndependentPages | QWizard::HaveCustomButton1);
retranslate();
connect(this, &QWizard::currentIdChanged, this, &SetupWizard::pageChanged);
if (LanguageWizardPage::isRequired())
{
setPage(Page::Language, new LanguageWizardPage(this));
@ -326,12 +46,54 @@ SetupWizard::SetupWizard(QWidget *parent) : QWizard(parent)
void SetupWizard::retranslate()
{
setButtonText(QWizard::NextButton, tr("Next >"));
setButtonText(QWizard::BackButton, tr("< Back"));
setButtonText(QWizard::FinishButton, tr("Finish"));
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));
}
BaseWizardPage * SetupWizard::getBasePage(int id)
{
if(id == -1)
return nullptr;
auto pagePtr = page(id);
if(!pagePtr)
return nullptr;
return dynamic_cast<BaseWizardPage *>(pagePtr);
}
BaseWizardPage * SetupWizard::getCurrentBasePage()
{
return getBasePage(currentId());
}
void SetupWizard::pageChanged(int id)
{
auto basePagePtr = getBasePage(id);
if(!basePagePtr)
{
return;
}
if(basePagePtr->wantsRefreshButton())
{
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();
}
});
}
else
{
setButtonLayout({QWizard::Stretch, QWizard::BackButton, QWizard::NextButton, QWizard::FinishButton});
}
}
void SetupWizard::changeEvent(QEvent *event)
{
if (event->type() == QEvent::LanguageChange)
@ -356,4 +118,3 @@ bool SetupWizard::isRequired()
return false;
}
#include "SetupWizard.moc"

View File

@ -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();