From e178284172396ee51acb77c2daa8135b4855c12b Mon Sep 17 00:00:00 2001 From: Jan Dalheimer Date: Wed, 16 Jul 2014 00:13:40 +0200 Subject: Merge global settings and accounts into a pagedialog Also split external tools into it's own page --- gui/MainWindow.cpp | 36 +- gui/MainWindow.h | 3 + gui/dialogs/AccountListDialog.cpp | 145 ---- gui/dialogs/AccountListDialog.h | 65 -- gui/dialogs/AccountListDialog.ui | 96 --- gui/dialogs/SettingsDialog.cpp | 710 ------------------- gui/dialogs/SettingsDialog.h | 106 --- gui/dialogs/SettingsDialog.ui | 1173 -------------------------------- gui/pages/BasePageProvider.h | 41 ++ gui/pages/global/AccountListPage.cpp | 140 ++++ gui/pages/global/AccountListPage.h | 80 +++ gui/pages/global/AccountListPage.ui | 89 +++ gui/pages/global/BaseSettingsPage.cpp | 28 + gui/pages/global/BaseSettingsPage.h | 35 + gui/pages/global/ExternalToolsPage.cpp | 177 +++++ gui/pages/global/ExternalToolsPage.h | 66 ++ gui/pages/global/ExternalToolsPage.ui | 145 ++++ gui/pages/global/SettingsPage.cpp | 547 +++++++++++++++ gui/pages/global/SettingsPage.h | 105 +++ gui/pages/global/SettingsPage.ui | 985 +++++++++++++++++++++++++++ 20 files changed, 2463 insertions(+), 2309 deletions(-) delete mode 100644 gui/dialogs/AccountListDialog.cpp delete mode 100644 gui/dialogs/AccountListDialog.h delete mode 100644 gui/dialogs/AccountListDialog.ui delete mode 100644 gui/dialogs/SettingsDialog.cpp delete mode 100644 gui/dialogs/SettingsDialog.h delete mode 100644 gui/dialogs/SettingsDialog.ui create mode 100644 gui/pages/global/AccountListPage.cpp create mode 100644 gui/pages/global/AccountListPage.h create mode 100644 gui/pages/global/AccountListPage.ui create mode 100644 gui/pages/global/BaseSettingsPage.cpp create mode 100644 gui/pages/global/BaseSettingsPage.h create mode 100644 gui/pages/global/ExternalToolsPage.cpp create mode 100644 gui/pages/global/ExternalToolsPage.h create mode 100644 gui/pages/global/ExternalToolsPage.ui create mode 100644 gui/pages/global/SettingsPage.cpp create mode 100644 gui/pages/global/SettingsPage.h create mode 100644 gui/pages/global/SettingsPage.ui (limited to 'gui') diff --git a/gui/MainWindow.cpp b/gui/MainWindow.cpp index 1a92139c..81ee466b 100644 --- a/gui/MainWindow.cpp +++ b/gui/MainWindow.cpp @@ -49,7 +49,6 @@ #include "gui/widgets/LabeledToolButton.h" #include "widgets/ServerStatus.h" -#include "gui/dialogs/SettingsDialog.h" #include "gui/dialogs/NewInstanceDialog.h" #include "gui/dialogs/ProgressDialog.h" #include "gui/dialogs/AboutDialog.h" @@ -58,12 +57,15 @@ #include "gui/dialogs/LwjglSelectDialog.h" #include "gui/dialogs/IconPickerDialog.h" #include "gui/dialogs/CopyInstanceDialog.h" -#include "gui/dialogs/AccountListDialog.h" #include "gui/dialogs/AccountSelectDialog.h" #include "gui/dialogs/UpdateDialog.h" #include "gui/dialogs/EditAccountDialog.h" #include "gui/dialogs/NotificationDialog.h" +#include "gui/pages/global/SettingsPage.h" +#include "gui/pages/global/ExternalToolsPage.h" +#include "gui/pages/global/AccountListPage.h" + #include "gui/ConsoleWindow.h" #include "pagedialog/PageDialog.h" @@ -245,6 +247,14 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi ui->mainToolBar->addAction(accountMenuButtonAction); + // set up global pages dialog + { + m_globalSettingsProvider = std::make_shared(tr("Settings")); + m_globalSettingsProvider->addPage(); + m_globalSettingsProvider->addPage(); + m_globalSettingsProvider->addPage(); + } + // Update the menu when the active account changes. // Shouldn't have to use lambdas here like this, but if I don't, the compiler throws a fit. // Template hell sucks... @@ -937,16 +947,6 @@ void MainWindow::on_actionCheckUpdate_triggered() updater->checkForUpdate(true); } -void MainWindow::on_actionSettings_triggered() -{ - SettingsDialog dialog(this); - dialog.exec(); - // FIXME: quick HACK to make this work. improve, optimize. - proxymodel->invalidate(); - proxymodel->sort(0); - updateToolsMenu(); -} - template void ShowPageDialog(T raw_provider, QWidget * parent, QString open_page = QString()) { @@ -957,6 +957,15 @@ void ShowPageDialog(T raw_provider, QWidget * parent, QString open_page = QStrin dlg.exec(); } +void MainWindow::on_actionSettings_triggered() +{ + ShowPageDialog(m_globalSettingsProvider, this, "global-settings"); + // FIXME: quick HACK to make this work. improve, optimize. + proxymodel->invalidate(); + proxymodel->sort(0); + updateToolsMenu(); +} + void MainWindow::on_actionInstanceSettings_triggered() { ShowPageDialog(m_selectedInstance, this, "settings"); @@ -980,8 +989,7 @@ void MainWindow::on_actionScreenshots_triggered() void MainWindow::on_actionManageAccounts_triggered() { - AccountListDialog dialog(this); - dialog.exec(); + ShowPageDialog(m_globalSettingsProvider, this, "accounts"); } void MainWindow::on_actionReportBug_triggered() diff --git a/gui/MainWindow.h b/gui/MainWindow.h index 36ef883b..32ad4daf 100644 --- a/gui/MainWindow.h +++ b/gui/MainWindow.h @@ -30,6 +30,7 @@ class QLabel; class MinecraftProcess; class ConsoleWindow; class BaseProfilerFactory; +class GenericPageProvider; namespace Ui { @@ -189,6 +190,8 @@ private: QToolButton *changeIconButton; QToolButton *newsLabel; + std::shared_ptr m_globalSettingsProvider; + InstancePtr m_selectedInstance; QString m_currentInstIcon; diff --git a/gui/dialogs/AccountListDialog.cpp b/gui/dialogs/AccountListDialog.cpp deleted file mode 100644 index 688cffa8..00000000 --- a/gui/dialogs/AccountListDialog.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* Copyright 2013 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "AccountListDialog.h" -#include "ui_AccountListDialog.h" - -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include "CustomMessageBox.h" -#include -#include - -#include - -AccountListDialog::AccountListDialog(QWidget *parent) - : QDialog(parent), ui(new Ui::AccountListDialog) -{ - ui->setupUi(this); - - m_accounts = MMC->accounts(); - - ui->listView->setModel(m_accounts.get()); - ui->listView->header()->setSectionResizeMode(QHeaderView::ResizeToContents); - - // Expand the account column - ui->listView->header()->setSectionResizeMode(1, QHeaderView::Stretch); - - QItemSelectionModel *selectionModel = ui->listView->selectionModel(); - - connect(selectionModel, &QItemSelectionModel::selectionChanged, - [this](const QItemSelection &sel, const QItemSelection &dsel) - { updateButtonStates(); }); - - connect(m_accounts.get(), SIGNAL(listChanged()), SLOT(listChanged())); - connect(m_accounts.get(), SIGNAL(activeAccountChanged()), SLOT(listChanged())); - - updateButtonStates(); -} - -AccountListDialog::~AccountListDialog() -{ - delete ui; -} - -void AccountListDialog::listChanged() -{ - updateButtonStates(); -} - -void AccountListDialog::on_addAccountBtn_clicked() -{ - addAccount(tr("Please enter your Mojang or Minecraft account username and password to add " - "your account.")); -} - -void AccountListDialog::on_rmAccountBtn_clicked() -{ - QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes(); - if (selection.size() > 0) - { - QModelIndex selected = selection.first(); - m_accounts->removeAccount(selected); - } -} - -void AccountListDialog::on_setDefaultBtn_clicked() -{ - QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes(); - if (selection.size() > 0) - { - QModelIndex selected = selection.first(); - MojangAccountPtr account = - selected.data(MojangAccountList::PointerRole).value(); - m_accounts->setActiveAccount(account->username()); - } -} - -void AccountListDialog::on_noDefaultBtn_clicked() -{ - m_accounts->setActiveAccount(""); -} - -void AccountListDialog::on_closeBtnBox_rejected() -{ - close(); -} - -void AccountListDialog::updateButtonStates() -{ - // If there is no selection, disable buttons that require something selected. - QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes(); - - ui->rmAccountBtn->setEnabled(selection.size() > 0); - ui->setDefaultBtn->setEnabled(selection.size() > 0); - - ui->noDefaultBtn->setDown(m_accounts->activeAccount().get() == nullptr); -} - -void AccountListDialog::addAccount(const QString &errMsg) -{ - // TODO: The login dialog isn't quite done yet - MojangAccountPtr account = LoginDialog::newAccount(this, errMsg); - - if (account != nullptr) - { - m_accounts->addAccount(account); - if (m_accounts->count() == 1) - m_accounts->setActiveAccount(account->username()); - - // Grab associated player skins - auto job = new NetJob("Player skins: " + account->username()); - - for (AccountProfile profile : account->profiles()) - { - auto meta = MMC->metacache()->resolveEntry("skins", profile.name + ".png"); - auto action = CacheDownload::make( - QUrl("http://" + URLConstants::SKINS_BASE + profile.name + ".png"), meta); - job->addNetAction(action); - meta->stale = true; - } - - job->start(); - } -} diff --git a/gui/dialogs/AccountListDialog.h b/gui/dialogs/AccountListDialog.h deleted file mode 100644 index fe0c8773..00000000 --- a/gui/dialogs/AccountListDialog.h +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright 2013 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include - -#include - -#include "logic/auth/MojangAccountList.h" - -namespace Ui -{ -class AccountListDialog; -} - -class AuthenticateTask; - -class AccountListDialog : public QDialog -{ - Q_OBJECT -public: - explicit AccountListDialog(QWidget *parent = 0); - ~AccountListDialog(); - -public -slots: - void on_addAccountBtn_clicked(); - - void on_rmAccountBtn_clicked(); - - void on_setDefaultBtn_clicked(); - - void on_noDefaultBtn_clicked(); - - // This will be sent when the "close" button is clicked. - void on_closeBtnBox_rejected(); - - void listChanged(); - - //! Updates the states of the dialog's buttons. - void updateButtonStates(); - -protected: - std::shared_ptr m_accounts; - -protected -slots: - void addAccount(const QString& errMsg=""); - -private: - Ui::AccountListDialog *ui; -}; diff --git a/gui/dialogs/AccountListDialog.ui b/gui/dialogs/AccountListDialog.ui deleted file mode 100644 index 72682163..00000000 --- a/gui/dialogs/AccountListDialog.ui +++ /dev/null @@ -1,96 +0,0 @@ - - - AccountListDialog - - - - 0 - 0 - 400 - 300 - - - - Manage Accounts - - - - - - <html><head/><body><p>Welcome! If you're new here, you can click the &quot;Add&quot; button to add your Mojang or Minecraft account.</p></body></html> - - - true - - - - - - - - - - - - - - &Add - - - - - - - &Remove - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - <html><head/><body><p>Set the currently selected account as the active account. The active account is the account that is used to log in (unless it is overridden in an instance-specific setting).</p></body></html> - - - &Set Default - - - - - - - Set no default account. This will cause MultiMC to prompt you to select an account every time you launch an instance that doesn't have its own default set. - - - &No Default - - - - - - - - - - - QDialogButtonBox::Close - - - - - - - - diff --git a/gui/dialogs/SettingsDialog.cpp b/gui/dialogs/SettingsDialog.cpp deleted file mode 100644 index 347cd67e..00000000 --- a/gui/dialogs/SettingsDialog.cpp +++ /dev/null @@ -1,710 +0,0 @@ -/* Copyright 2013 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "MultiMC.h" - -#include "gui/dialogs/SettingsDialog.h" -#include "ui_SettingsDialog.h" - -#include "gui/Platform.h" -#include "gui/dialogs/VersionSelectDialog.h" -#include "gui/dialogs/CustomMessageBox.h" - -#include "logic/NagUtils.h" - -#include "logic/java/JavaUtils.h" -#include "logic/java/JavaVersionList.h" -#include "logic/java/JavaChecker.h" - -#include "logic/updater/UpdateChecker.h" - -#include "logic/tools/BaseProfiler.h" - -#include "logic/settings/SettingsObject.h" -#include -#include -#include -#include - -// FIXME: possibly move elsewhere -enum InstSortMode -{ - // Sort alphabetically by name. - Sort_Name, - // Sort by which instance was launched most recently. - Sort_LastLaunch -}; - -SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent), ui(new Ui::SettingsDialog) -{ - MultiMCPlatform::fixWM_CLASS(this); - ui->setupUi(this); - ui->sortingModeGroup->setId(ui->sortByNameBtn, Sort_Name); - ui->sortingModeGroup->setId(ui->sortLastLaunchedBtn, Sort_LastLaunch); - -#if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0) - ui->jsonEditorTextBox->setClearButtonEnabled(true); -#endif - - restoreGeometry( - QByteArray::fromBase64(MMC->settings()->get("SettingsGeometry").toByteArray())); - - loadSettings(MMC->settings().get()); - updateCheckboxStuff(); - - QObject::connect(MMC->updateChecker().get(), &UpdateChecker::channelListLoaded, this, - &SettingsDialog::refreshUpdateChannelList); - - if (MMC->updateChecker()->hasChannels()) - { - refreshUpdateChannelList(); - } - else - { - MMC->updateChecker()->updateChanList(false); - } - connect(ui->proxyGroup, SIGNAL(buttonClicked(int)), SLOT(proxyChanged(int))); - ui->mceditLink->setOpenExternalLinks(true); - ui->jvisualvmLink->setOpenExternalLinks(true); - ui->jprofilerLink->setOpenExternalLinks(true); -} - -SettingsDialog::~SettingsDialog() -{ - delete ui; -} -void SettingsDialog::showEvent(QShowEvent *ev) -{ - QDialog::showEvent(ev); -} - -void SettingsDialog::closeEvent(QCloseEvent *ev) -{ - MMC->settings()->set("SettingsGeometry", saveGeometry().toBase64()); - - QDialog::closeEvent(ev); -} - -void SettingsDialog::updateCheckboxStuff() -{ - ui->windowWidthSpinBox->setEnabled(!ui->maximizedCheckBox->isChecked()); - ui->windowHeightSpinBox->setEnabled(!ui->maximizedCheckBox->isChecked()); - ui->proxyAddrBox->setEnabled(!ui->proxyNoneBtn->isChecked() && - !ui->proxyDefaultBtn->isChecked()); - ui->proxyAuthBox->setEnabled(!ui->proxyNoneBtn->isChecked() && - !ui->proxyDefaultBtn->isChecked()); -} - -void SettingsDialog::on_ftbLauncherBrowseBtn_clicked() -{ - QString raw_dir = QFileDialog::getExistingDirectory(this, tr("FTB Launcher Directory"), - ui->ftbLauncherBox->text()); - QString cooked_dir = NormalizePath(raw_dir); - - // do not allow current dir - it's dirty. Do not allow dirs that don't exist - if (!cooked_dir.isEmpty() && QDir(cooked_dir).exists()) - { - ui->ftbLauncherBox->setText(cooked_dir); - } -} - -void SettingsDialog::on_ftbBrowseBtn_clicked() -{ - QString raw_dir = - QFileDialog::getExistingDirectory(this, tr("FTB Directory"), ui->ftbBox->text()); - QString cooked_dir = NormalizePath(raw_dir); - - // do not allow current dir - it's dirty. Do not allow dirs that don't exist - if (!cooked_dir.isEmpty() && QDir(cooked_dir).exists()) - { - ui->ftbBox->setText(cooked_dir); - } -} - -void SettingsDialog::on_instDirBrowseBtn_clicked() -{ - QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Instance Directory"), - ui->instDirTextBox->text()); - QString cooked_dir = NormalizePath(raw_dir); - - // do not allow current dir - it's dirty. Do not allow dirs that don't exist - if (!cooked_dir.isEmpty() && QDir(cooked_dir).exists()) - { - ui->instDirTextBox->setText(cooked_dir); - } -} -void SettingsDialog::on_iconsDirBrowseBtn_clicked() -{ - QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Icons Directory"), - ui->iconsDirTextBox->text()); - QString cooked_dir = NormalizePath(raw_dir); - - // do not allow current dir - it's dirty. Do not allow dirs that don't exist - if (!cooked_dir.isEmpty() && QDir(cooked_dir).exists()) - { - ui->iconsDirTextBox->setText(cooked_dir); - } -} - -void SettingsDialog::on_modsDirBrowseBtn_clicked() -{ - QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Mods Directory"), - ui->modsDirTextBox->text()); - QString cooked_dir = NormalizePath(raw_dir); - - // do not allow current dir - it's dirty. Do not allow dirs that don't exist - if (!cooked_dir.isEmpty() && QDir(cooked_dir).exists()) - { - ui->modsDirTextBox->setText(cooked_dir); - } -} - -void SettingsDialog::on_lwjglDirBrowseBtn_clicked() -{ - QString raw_dir = QFileDialog::getExistingDirectory(this, tr("LWJGL Directory"), - ui->lwjglDirTextBox->text()); - QString cooked_dir = NormalizePath(raw_dir); - - // do not allow current dir - it's dirty. Do not allow dirs that don't exist - if (!cooked_dir.isEmpty() && QDir(cooked_dir).exists()) - { - ui->lwjglDirTextBox->setText(cooked_dir); - } -} - -void SettingsDialog::on_jsonEditorBrowseBtn_clicked() -{ - QString raw_file = QFileDialog::getOpenFileName( - this, tr("JSON Editor"), - ui->jsonEditorTextBox->text().isEmpty() -#if defined(Q_OS_LINUX) - ? QString("/usr/bin") -#else - ? QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation).first() -#endif - : ui->jsonEditorTextBox->text()); - QString cooked_file = NormalizePath(raw_file); - - if (cooked_file.isEmpty()) - { - return; - } - - // it has to exist and be an executable - if (QFileInfo(cooked_file).exists() && QFileInfo(cooked_file).isExecutable()) - { - ui->jsonEditorTextBox->setText(cooked_file); - } - else - { - QMessageBox::warning(this, tr("Invalid"), - tr("The file chosen does not seem to be an executable")); - } -} - -void SettingsDialog::on_maximizedCheckBox_clicked(bool checked) -{ - Q_UNUSED(checked); - updateCheckboxStuff(); -} - -void SettingsDialog::on_buttonBox_accepted() -{ - applySettings(MMC->settings().get()); - - // Apply proxy settings - MMC->updateProxySettings(); - - MMC->settings()->set("SettingsGeometry", saveGeometry().toBase64()); -} - -void SettingsDialog::on_buttonBox_rejected() -{ - MMC->settings()->set("SettingsGeometry", saveGeometry().toBase64()); -} - -void SettingsDialog::proxyChanged(int) -{ - updateCheckboxStuff(); -} - -void SettingsDialog::refreshUpdateChannelList() -{ - // Stop listening for selection changes. It's going to change a lot while we update it and - // we don't need to update the - // description label constantly. - QObject::disconnect(ui->updateChannelComboBox, SIGNAL(currentIndexChanged(int)), this, - SLOT(updateChannelSelectionChanged(int))); - - QList channelList = MMC->updateChecker()->getChannelList(); - ui->updateChannelComboBox->clear(); - int selection = -1; - for (int i = 0; i < channelList.count(); i++) - { - UpdateChecker::ChannelListEntry entry = channelList.at(i); - - // When it comes to selection, we'll rely on the indexes of a channel entry being the - // same in the - // combo box as it is in the update checker's channel list. - // This probably isn't very safe, but the channel list doesn't change often enough (or - // at all) for - // this to be a big deal. Hope it doesn't break... - ui->updateChannelComboBox->addItem(entry.name); - - // If the update channel we just added was the selected one, set the current index in - // the combo box to it. - if (entry.id == m_currentUpdateChannel) - { - QLOG_DEBUG() << "Selected index" << i << "channel id" << m_currentUpdateChannel; - selection = i; - } - } - - ui->updateChannelComboBox->setCurrentIndex(selection); - - // Start listening for selection changes again and update the description label. - QObject::connect(ui->updateChannelComboBox, SIGNAL(currentIndexChanged(int)), this, - SLOT(updateChannelSelectionChanged(int))); - refreshUpdateChannelDesc(); - - // Now that we've updated the channel list, we can enable the combo box. - // It starts off disabled so that if the channel list hasn't been loaded, it will be - // disabled. - ui->updateChannelComboBox->setEnabled(true); -} - -void SettingsDialog::updateChannelSelectionChanged(int index) -{ - refreshUpdateChannelDesc(); -} - -void SettingsDialog::refreshUpdateChannelDesc() -{ - // Get the channel list. - QList channelList = MMC->updateChecker()->getChannelList(); - int selectedIndex = ui->updateChannelComboBox->currentIndex(); - if (selectedIndex < 0) - { - return; - } - if (selectedIndex < channelList.count()) - { - // Find the channel list entry with the given index. - UpdateChecker::ChannelListEntry selected = channelList.at(selectedIndex); - - // Set the description text. - ui->updateChannelDescLabel->setText(selected.description); - - // Set the currently selected channel ID. - m_currentUpdateChannel = selected.id; - } -} - -void SettingsDialog::applySettings(SettingsObject *s) -{ - // Language - s->set("Language", - ui->languageBox->itemData(ui->languageBox->currentIndex()).toLocale().bcp47Name()); - - if (ui->resetNotificationsBtn->isChecked()) - { - s->set("ShownNotifications", QString()); - } - - // Updates - s->set("AutoUpdate", ui->autoUpdateCheckBox->isChecked()); - s->set("UpdateChannel", m_currentUpdateChannel); - //FIXME: make generic - switch (ui->themeComboBox->currentIndex()) - { - case 1: - s->set("IconTheme", "pe_dark"); - break; - case 2: - s->set("IconTheme", "pe_light"); - break; - case 0: - default: - s->set("IconTheme", "multimc"); - break; - } - // FTB - s->set("TrackFTBInstances", ui->trackFtbBox->isChecked()); - s->set("FTBLauncherRoot", ui->ftbLauncherBox->text()); - s->set("FTBRoot", ui->ftbBox->text()); - - // Folders - // TODO: Offer to move instances to new instance folder. - s->set("InstanceDir", ui->instDirTextBox->text()); - s->set("CentralModsDir", ui->modsDirTextBox->text()); - s->set("LWJGLDir", ui->lwjglDirTextBox->text()); - s->set("IconsDir", ui->iconsDirTextBox->text()); - - // Editors - QString jsonEditor = ui->jsonEditorTextBox->text(); - if (!jsonEditor.isEmpty() && - (!QFileInfo(jsonEditor).exists() || !QFileInfo(jsonEditor).isExecutable())) - { - QString found = QStandardPaths::findExecutable(jsonEditor); - if (!found.isEmpty()) - { - jsonEditor = found; - } - } - s->set("JsonEditor", jsonEditor); - - // Minecraft version updates - s->set("AutoUpdateMinecraftVersions", ui->autoupdateMinecraft->isChecked()); - - // Console - s->set("ShowConsole", ui->showConsoleCheck->isChecked()); - s->set("AutoCloseConsole", ui->autoCloseConsoleCheck->isChecked()); - - // Window Size - s->set("LaunchMaximized", ui->maximizedCheckBox->isChecked()); - s->set("MinecraftWinWidth", ui->windowWidthSpinBox->value()); - s->set("MinecraftWinHeight", ui->windowHeightSpinBox->value()); - - // Proxy - QString proxyType = "None"; - if (ui->proxyDefaultBtn->isChecked()) - proxyType = "Default"; - else if (ui->proxyNoneBtn->isChecked()) - proxyType = "None"; - else if (ui->proxySOCKS5Btn->isChecked()) - proxyType = "SOCKS5"; - else if (ui->proxyHTTPBtn->isChecked()) - proxyType = "HTTP"; - - s->set("ProxyType", proxyType); - s->set("ProxyAddr", ui->proxyAddrEdit->text()); - s->set("ProxyPort", ui->proxyPortEdit->value()); - s->set("ProxyUser", ui->proxyUserEdit->text()); - s->set("ProxyPass", ui->proxyPassEdit->text()); - - // Memory - s->set("MinMemAlloc", ui->minMemSpinBox->value()); - s->set("MaxMemAlloc", ui->maxMemSpinBox->value()); - s->set("PermGen", ui->permGenSpinBox->value()); - - // Java Settings - s->set("JavaPath", ui->javaPathTextBox->text()); - s->set("JvmArgs", ui->jvmArgsTextBox->text()); - NagUtils::checkJVMArgs(s->get("JvmArgs").toString(), this->parentWidget()); - - // Custom Commands - s->set("PreLaunchCommand", ui->preLaunchCmdTextBox->text()); - s->set("PostExitCommand", ui->postExitCmdTextBox->text()); - - auto sortMode = (InstSortMode)ui->sortingModeGroup->checkedId(); - switch (sortMode) - { - case Sort_LastLaunch: - s->set("InstSortMode", "LastLaunch"); - break; - case Sort_Name: - default: - s->set("InstSortMode", "Name"); - break; - } - - s->set("PostExitCommand", ui->postExitCmdTextBox->text()); - - // Profilers - s->set("JProfilerPath", ui->jprofilerPathEdit->text()); - s->set("JVisualVMPath", ui->jvisualvmPathEdit->text()); - s->set("MCEditPath", ui->mceditPathEdit->text()); -} - -void SettingsDialog::loadSettings(SettingsObject *s) -{ - // Language - ui->languageBox->clear(); - ui->languageBox->addItem(tr("English"), QLocale(QLocale::English)); - foreach(const QString & lang, QDir(MMC->staticData() + "/translations") - .entryList(QStringList() << "*.qm", QDir::Files)) - { - QLocale locale(lang.section(QRegExp("[_\\.]"), 1)); - ui->languageBox->addItem(QLocale::languageToString(locale.language()), locale); - } - ui->languageBox->setCurrentIndex( - ui->languageBox->findData(QLocale(s->get("Language").toString()))); - - // Updates - ui->autoUpdateCheckBox->setChecked(s->get("AutoUpdate").toBool()); - m_currentUpdateChannel = s->get("UpdateChannel").toString(); - //FIXME: make generic - auto theme = s->get("IconTheme").toString(); - if (theme == "pe_dark") - { - ui->themeComboBox->setCurrentIndex(1); - } - else if (theme == "pe_light") - { - ui->themeComboBox->setCurrentIndex(2); - } - else - { - ui->themeComboBox->setCurrentIndex(0); - } - // FTB - ui->trackFtbBox->setChecked(s->get("TrackFTBInstances").toBool()); - ui->ftbLauncherBox->setText(s->get("FTBLauncherRoot").toString()); - ui->ftbBox->setText(s->get("FTBRoot").toString()); - - // Folders - ui->instDirTextBox->setText(s->get("InstanceDir").toString()); - ui->modsDirTextBox->setText(s->get("CentralModsDir").toString()); - ui->lwjglDirTextBox->setText(s->get("LWJGLDir").toString()); - ui->iconsDirTextBox->setText(s->get("IconsDir").toString()); - - // Editors - ui->jsonEditorTextBox->setText(s->get("JsonEditor").toString()); - - // Minecraft version updates - ui->autoupdateMinecraft->setChecked(s->get("AutoUpdateMinecraftVersions").toBool()); - - // Console - ui->showConsoleCheck->setChecked(s->get("ShowConsole").toBool()); - ui->autoCloseConsoleCheck->setChecked(s->get("AutoCloseConsole").toBool()); - - // Window Size - ui->maximizedCheckBox->setChecked(s->get("LaunchMaximized").toBool()); - ui->windowWidthSpinBox->setValue(s->get("MinecraftWinWidth").toInt()); - ui->windowHeightSpinBox->setValue(s->get("MinecraftWinHeight").toInt()); - - // Memory - ui->minMemSpinBox->setValue(s->get("MinMemAlloc").toInt()); - ui->maxMemSpinBox->setValue(s->get("MaxMemAlloc").toInt()); - ui->permGenSpinBox->setValue(s->get("PermGen").toInt()); - - QString sortMode = s->get("InstSortMode").toString(); - - if (sortMode == "LastLaunch") - { - ui->sortLastLaunchedBtn->setChecked(true); - } - else - { - ui->sortByNameBtn->setChecked(true); - } - - // Proxy - QString proxyType = s->get("ProxyType").toString(); - if (proxyType == "Default") - ui->proxyDefaultBtn->setChecked(true); - else if (proxyType == "None") - ui->proxyNoneBtn->setChecked(true); - else if (proxyType == "SOCKS5") - ui->proxySOCKS5Btn->setChecked(true); - else if (proxyType == "HTTP") - ui->proxyHTTPBtn->setChecked(true); - - ui->proxyAddrEdit->setText(s->get("ProxyAddr").toString()); - ui->proxyPortEdit->setValue(s->get("ProxyPort").value()); - ui->proxyUserEdit->setText(s->get("ProxyUser").toString()); - ui->proxyPassEdit->setText(s->get("ProxyPass").toString()); - - // Java Settings - ui->javaPathTextBox->setText(s->get("JavaPath").toString()); - ui->jvmArgsTextBox->setText(s->get("JvmArgs").toString()); - - // Custom Commands - ui->preLaunchCmdTextBox->setText(s->get("PreLaunchCommand").toString()); - ui->postExitCmdTextBox->setText(s->get("PostExitCommand").toString()); - - // Profilers - ui->jprofilerPathEdit->setText(s->get("JProfilerPath").toString()); - ui->jvisualvmPathEdit->setText(s->get("JVisualVMPath").toString()); - ui->mceditPathEdit->setText(s->get("MCEditPath").toString()); -} - -void SettingsDialog::on_javaDetectBtn_clicked() -{ - JavaVersionPtr java; - - VersionSelectDialog vselect(MMC->javalist().get(), tr("Select a Java version"), this, true); - vselect.setResizeOn(2); - vselect.exec(); - - if (vselect.result() == QDialog::Accepted && vselect.selectedVersion()) - { - java = std::dynamic_pointer_cast(vselect.selectedVersion()); - ui->javaPathTextBox->setText(java->path); - } -} - -void SettingsDialog::on_javaBrowseBtn_clicked() -{ - QString dir = QFileDialog::getOpenFileName(this, tr("Find Java executable")); - if (!dir.isNull()) - { - ui->javaPathTextBox->setText(dir); - } -} - -void SettingsDialog::on_javaTestBtn_clicked() -{ - checker.reset(new JavaChecker()); - connect(checker.get(), SIGNAL(checkFinished(JavaCheckResult)), this, - SLOT(checkFinished(JavaCheckResult))); - checker->path = ui->javaPathTextBox->text(); - checker->performCheck(); -} - -void SettingsDialog::checkFinished(JavaCheckResult result) -{ - if (result.valid) - { - QString text; - text += "Java test succeeded!\n"; - if (result.is_64bit) - text += "Using 64bit java.\n"; - text += "\n"; - text += "Platform reported: " + result.realPlatform + "\n"; - text += "Java version reported: " + result.javaVersion; - QMessageBox::information(this, tr("Java test success"), text); - } - else - { - QMessageBox::warning( - this, tr("Java test failure"), - tr("The specified java binary didn't work. You should use the auto-detect feature, " - "or set the path to the java executable.")); - } -} - -void SettingsDialog::on_jprofilerPathBtn_clicked() -{ - QString raw_dir = ui->jprofilerPathEdit->text(); - QString error; - do - { - raw_dir = QFileDialog::getExistingDirectory(this, tr("JProfiler Directory"), raw_dir); - if (raw_dir.isEmpty()) - { - break; - } - QString cooked_dir = NormalizePath(raw_dir); - if (!MMC->profilers()["jprofiler"]->check(cooked_dir, &error)) - { - QMessageBox::critical(this, tr("Error"), - tr("Error while checking JProfiler install:\n%1").arg(error)); - continue; - } - else - { - ui->jprofilerPathEdit->setText(cooked_dir); - break; - } - } while (1); -} -void SettingsDialog::on_jprofilerCheckBtn_clicked() -{ - QString error; - if (!MMC->profilers()["jprofiler"]->check(ui->jprofilerPathEdit->text(), &error)) - { - QMessageBox::critical(this, tr("Error"), - tr("Error while checking JProfiler install:\n%1").arg(error)); - } - else - { - QMessageBox::information(this, tr("OK"), tr("JProfiler setup seems to be OK")); - } -} - -void SettingsDialog::on_jvisualvmPathBtn_clicked() -{ - QString raw_dir = ui->jvisualvmPathEdit->text(); - QString error; - do - { - raw_dir = QFileDialog::getOpenFileName(this, tr("JVisualVM Executable"), raw_dir); - if (raw_dir.isEmpty()) - { - break; - } - QString cooked_dir = NormalizePath(raw_dir); - if (!MMC->profilers()["jvisualvm"]->check(cooked_dir, &error)) - { - QMessageBox::critical(this, tr("Error"), - tr("Error while checking JVisualVM install:\n%1").arg(error)); - continue; - } - else - { - ui->jvisualvmPathEdit->setText(cooked_dir); - break; - } - } while (1); -} -void SettingsDialog::on_jvisualvmCheckBtn_clicked() -{ - QString error; - if (!MMC->profilers()["jvisualvm"]->check(ui->jvisualvmPathEdit->text(), &error)) - { - QMessageBox::critical(this, tr("Error"), - tr("Error while checking JVisualVM install:\n%1").arg(error)); - } - else - { - QMessageBox::information(this, tr("OK"), tr("JVisualVM setup seems to be OK")); - } -} - -void SettingsDialog::on_mceditPathBtn_clicked() -{ - QString raw_dir = ui->mceditPathEdit->text(); - QString error; - do - { -#ifdef Q_OS_OSX -#warning stuff - raw_dir = QFileDialog::getOpenFileName(this, tr("MCEdit Application"), raw_dir); -#else - raw_dir = QFileDialog::getExistingDirectory(this, tr("MCEdit Directory"), raw_dir); -#endif - if (raw_dir.isEmpty()) - { - break; - } - QString cooked_dir = NormalizePath(raw_dir); - if (!MMC->tools()["mcedit"]->check(cooked_dir, &error)) - { - QMessageBox::critical(this, tr("Error"), - tr("Error while checking MCEdit install:\n%1").arg(error)); - continue; - } - else - { - ui->mceditPathEdit->setText(cooked_dir); - break; - } - } while (1); -} - -void SettingsDialog::on_mceditCheckBtn_clicked() -{ - QString error; - if (!MMC->tools()["mcedit"]->check(ui->mceditPathEdit->text(), &error)) - { - QMessageBox::critical(this, tr("Error"), - tr("Error while checking MCEdit install:\n%1").arg(error)); - } - else - { - QMessageBox::information(this, tr("OK"), tr("MCEdit setup seems to be OK")); - } -} diff --git a/gui/dialogs/SettingsDialog.h b/gui/dialogs/SettingsDialog.h deleted file mode 100644 index c65e9fb5..00000000 --- a/gui/dialogs/SettingsDialog.h +++ /dev/null @@ -1,106 +0,0 @@ -/* Copyright 2013 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include -#include - -#include "logic/java/JavaChecker.h" - -class SettingsObject; - -namespace Ui -{ -class SettingsDialog; -} - -class SettingsDialog : public QDialog -{ - Q_OBJECT - -public: - explicit SettingsDialog(QWidget *parent = 0); - ~SettingsDialog(); - - void updateCheckboxStuff(); - - void applySettings(SettingsObject *s); - void loadSettings(SettingsObject *s); - -protected: - virtual void showEvent(QShowEvent *ev); - virtual void closeEvent(QCloseEvent *ev); - -private -slots: - void on_ftbLauncherBrowseBtn_clicked(); - - void on_ftbBrowseBtn_clicked(); - - void on_instDirBrowseBtn_clicked(); - - void on_modsDirBrowseBtn_clicked(); - - void on_lwjglDirBrowseBtn_clicked(); - - - void on_jsonEditorBrowseBtn_clicked(); - - void on_iconsDirBrowseBtn_clicked(); - - void on_maximizedCheckBox_clicked(bool checked); - - void on_buttonBox_accepted(); - - void on_buttonBox_rejected(); - - void on_javaDetectBtn_clicked(); - - void on_javaTestBtn_clicked(); - - void on_javaBrowseBtn_clicked(); - - void checkFinished(JavaCheckResult result); - - void on_jprofilerPathBtn_clicked(); - void on_jprofilerCheckBtn_clicked(); - void on_jvisualvmPathBtn_clicked(); - void on_jvisualvmCheckBtn_clicked(); - void on_mceditPathBtn_clicked(); - void on_mceditCheckBtn_clicked(); - - /*! - * Updates the list of update channels in the combo box. - */ - void refreshUpdateChannelList(); - - /*! - * Updates the channel description label. - */ - void refreshUpdateChannelDesc(); - - void updateChannelSelectionChanged(int index); - void proxyChanged(int); - -private: - Ui::SettingsDialog *ui; - std::shared_ptr checker; - - /*! - * Stores the currently selected update channel. - */ - QString m_currentUpdateChannel; -}; diff --git a/gui/dialogs/SettingsDialog.ui b/gui/dialogs/SettingsDialog.ui deleted file mode 100644 index 94b81dd7..00000000 --- a/gui/dialogs/SettingsDialog.ui +++ /dev/null @@ -1,1173 +0,0 @@ - - - SettingsDialog - - - - 0 - 0 - 545 - 609 - - - - - 0 - 0 - - - - Settings - - - - :/icons/toolbar/settings:/icons/toolbar/settings - - - true - - - - - - QTabWidget::Rounded - - - 0 - - - - Features - - - - - - Update Settings - - - - - - Check for updates when MultiMC starts? - - - - - - - Update Channel: - - - - - - - false - - - - - - - No channel selected. - - - true - - - - - - - - - - FTB - - - - - - false - - - - 0 - 0 - - - - - 28 - 16777215 - - - - Qt::TabFocus - - - ... - - - - - - - Launcher: - - - - - - - false - - - - - - - Track FTB instances - - - - - - - - - - true - - - - 0 - 0 - - - - - 28 - 16777215 - - - - ... - - - - - - - Files: - - - - - - - - - - Folders - - - - - - Instances: - - - - - - - - - - ... - - - - - - - Mods: - - - - - - - - - - - - - ... - - - - - - - LWJGL: - - - - - - - ... - - - - - - - - - - Icons: - - - - - - - ... - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - User Interface - - - - - - - - - 0 - 0 - - - - Language (needs restart): - - - - - - - - - - - - Reset hidden notifications - - - true - - - - - - - true - - - Sorting Mode - - - - - - By last launched - - - sortingModeGroup - - - - - - - By name - - - sortingModeGroup - - - - - - - - - - Icon Theme - - - - - - - 0 - 0 - - - - Qt::StrongFocus - - - - Default - - - - - Simple - - - - - Simple (Light Icons) - - - - - - - - - - - External Editors (leave empty for system default) - - - - - - - - - JSON Editor: - - - - - - - ... - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - Minecraft - - - - - - Minecraft Version Updates - - - - - - Automatically update to latest version revision - - - - - - - - - - Window Size - - - - - - Start Minecraft maximized? - - - - - - - - - Window height: - - - - - - - Window width: - - - - - - - 854 - - - 65536 - - - 1 - - - 854 - - - - - - - 480 - - - 65536 - - - 480 - - - - - - - - - - - - Console Settings - - - - - - Show console while the game is running? - - - - - - - Automatically close console when the game quits? - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - Java - - - - - - Memory - - - - - - The maximum amount of memory Minecraft is allowed to use. - - - MB - - - 512 - - - 65536 - - - 128 - - - 1024 - - - - - - - Minimum memory allocation: - - - - - - - Maximum memory allocation: - - - - - - - The amount of memory Minecraft is started with. - - - MB - - - 256 - - - 65536 - - - 128 - - - 256 - - - - - - - PermGen: - - - - - - - The amount of memory available to store loaded Java classes. - - - MB - - - 64 - - - 999999999 - - - 8 - - - 64 - - - - - - - - - - Java Settings - - - - - - - 0 - 0 - - - - Java path: - - - - - - - - 0 - 0 - - - - Auto-detect... - - - - - - - - 0 - 0 - - - - Test - - - - - - - - 0 - 0 - - - - JVM arguments: - - - - - - - - - - - - - 0 - 0 - - - - - 28 - 16777215 - - - - ... - - - - - - - - - - - - - - - Custom Commands - - - - - - Post-exit command: - - - - - - - Pre-launch command: - - - - - - - - - - - - - - - - - 0 - 0 - - - - Pre-launch command runs before the instance launches and post-exit command runs after it exits. Both will be run in MultiMC's working directory with INST_ID, INST_DIR, and INST_NAME as environment variables. - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - true - - - - - - - - Network settings. - - - Network - - - - - - Proxy - - - - - - Type - - - - - - Uses your system's default proxy settings. - - - Default - - - proxyGroup - - - - - - - None - - - proxyGroup - - - - - - - SOCKS5 - - - proxyGroup - - - - - - - HTTP - - - proxyGroup - - - - - - - - - - Address and Port - - - - - - 127.0.0.1 - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - QAbstractSpinBox::PlusMinus - - - 65535 - - - 8080 - - - - - - - - - - Authentication - - - - - - - - - Username: - - - - - - - Password: - - - - - - - QLineEdit::Password - - - - - - - Note: Proxy username and password are stored in plain text inside MultiMC's configuration file! - - - true - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - External Tools - - - - - - JProfiler - - - - - - - - - - - ... - - - - - - - - - Check - - - - - - - <html><head/><body><p><a href="http://www.ej-technologies.com/products/jprofiler/overview.html"><span style=" text-decoration: underline; color:#0000ff;">http://www.ej-technologies.com/products/jprofiler/overview.html</span></a></p></body></html> - - - - - - - - - - JVisualVM - - - - - - - - - - - ... - - - - - - - - - Check - - - - - - - <html><head/><body><p><a href="http://visualvm.java.net/"><span style=" text-decoration: underline; color:#0000ff;">http://visualvm.java.net/</span></a></p></body></html> - - - - - - - - - - MCEdit - - - - - - - - - - - ... - - - - - - - - - Check - - - - - - - <html><head/><body><p><a href="http://www.mcedit.net/"><span style=" text-decoration: underline; color:#0000ff;">http://www.mcedit.net/</span></a></p></body></html> - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - settingsTabs - autoUpdateCheckBox - updateChannelComboBox - trackFtbBox - ftbLauncherBox - ftbLauncherBrowseBtn - ftbBox - ftbBrowseBtn - instDirTextBox - instDirBrowseBtn - modsDirTextBox - modsDirBrowseBtn - lwjglDirTextBox - lwjglDirBrowseBtn - iconsDirTextBox - iconsDirBrowseBtn - languageBox - resetNotificationsBtn - sortLastLaunchedBtn - sortByNameBtn - themeComboBox - jsonEditorTextBox - jsonEditorBrowseBtn - autoupdateMinecraft - maximizedCheckBox - windowWidthSpinBox - windowHeightSpinBox - showConsoleCheck - autoCloseConsoleCheck - minMemSpinBox - maxMemSpinBox - permGenSpinBox - javaPathTextBox - javaBrowseBtn - javaDetectBtn - javaTestBtn - jvmArgsTextBox - preLaunchCmdTextBox - postExitCmdTextBox - proxyDefaultBtn - proxyNoneBtn - proxySOCKS5Btn - proxyHTTPBtn - proxyAddrEdit - proxyPortEdit - proxyUserEdit - proxyPassEdit - jprofilerPathEdit - jprofilerPathBtn - jprofilerCheckBtn - jvisualvmPathEdit - jvisualvmPathBtn - jvisualvmCheckBtn - mceditPathEdit - mceditPathBtn - mceditCheckBtn - - - - - - - buttonBox - accepted() - SettingsDialog - accept() - - - 257 - 410 - - - 157 - 274 - - - - - buttonBox - rejected() - SettingsDialog - reject() - - - 325 - 410 - - - 286 - 274 - - - - - - - - - diff --git a/gui/pages/BasePageProvider.h b/gui/pages/BasePageProvider.h index cff9c8e7..5e5a11fb 100644 --- a/gui/pages/BasePageProvider.h +++ b/gui/pages/BasePageProvider.h @@ -17,6 +17,7 @@ #include "BasePage.h" #include +#include class BasePageProvider { @@ -25,4 +26,44 @@ public: virtual QString dialogTitle() = 0; }; +class GenericPageProvider : public BasePageProvider +{ + typedef std::function PageCreator; +public: + explicit GenericPageProvider(const QString &dialogTitle) + : m_dialogTitle(dialogTitle) + { + } + + QList getPages() override + { + QList pages; + for (PageCreator creator : m_creators) + { + pages.append(creator()); + } + return pages; + } + QString dialogTitle() override { return m_dialogTitle; } + + void setDialogTitle(const QString &title) + { + m_dialogTitle = title; + } + void addPageCreator(PageCreator page) + { + m_creators.append(page); + } + + template + void addPage() + { + addPageCreator([](){return new PageClass();}); + } + +private: + QList m_creators; + QString m_dialogTitle; +}; + typedef std::shared_ptr BasePageProviderPtr; diff --git a/gui/pages/global/AccountListPage.cpp b/gui/pages/global/AccountListPage.cpp new file mode 100644 index 00000000..cad7d5bc --- /dev/null +++ b/gui/pages/global/AccountListPage.cpp @@ -0,0 +1,140 @@ +/* Copyright 2013 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AccountListPage.h" +#include "ui_AccountListPage.h" + +#include + +#include + +#include "logic/net/NetJob.h" +#include "logic/net/URLConstants.h" + +#include "gui/dialogs/EditAccountDialog.h" +#include "gui/dialogs/ProgressDialog.h" +#include "gui/dialogs/AccountSelectDialog.h" +#include "gui/dialogs/LoginDialog.h" +#include "gui/dialogs/CustomMessageBox.h" +#include "logic/tasks/Task.h" +#include "logic/auth/YggdrasilTask.h" + +#include + +AccountListPage::AccountListPage(QWidget *parent) + : QDialog(parent), ui(new Ui::AccountListPage) +{ + ui->setupUi(this); + + m_accounts = MMC->accounts(); + + ui->listView->setModel(m_accounts.get()); + ui->listView->header()->setSectionResizeMode(QHeaderView::ResizeToContents); + + // Expand the account column + ui->listView->header()->setSectionResizeMode(1, QHeaderView::Stretch); + + QItemSelectionModel *selectionModel = ui->listView->selectionModel(); + + connect(selectionModel, &QItemSelectionModel::selectionChanged, + [this](const QItemSelection &sel, const QItemSelection &dsel) + { updateButtonStates(); }); + + connect(m_accounts.get(), SIGNAL(listChanged()), SLOT(listChanged())); + connect(m_accounts.get(), SIGNAL(activeAccountChanged()), SLOT(listChanged())); + + updateButtonStates(); +} + +AccountListPage::~AccountListPage() +{ + delete ui; +} + +void AccountListPage::listChanged() +{ + updateButtonStates(); +} + +void AccountListPage::on_addAccountBtn_clicked() +{ + addAccount(tr("Please enter your Mojang or Minecraft account username and password to add " + "your account.")); +} + +void AccountListPage::on_rmAccountBtn_clicked() +{ + QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes(); + if (selection.size() > 0) + { + QModelIndex selected = selection.first(); + m_accounts->removeAccount(selected); + } +} + +void AccountListPage::on_setDefaultBtn_clicked() +{ + QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes(); + if (selection.size() > 0) + { + QModelIndex selected = selection.first(); + MojangAccountPtr account = + selected.data(MojangAccountList::PointerRole).value(); + m_accounts->setActiveAccount(account->username()); + } +} + +void AccountListPage::on_noDefaultBtn_clicked() +{ + m_accounts->setActiveAccount(""); +} + +void AccountListPage::updateButtonStates() +{ + // If there is no selection, disable buttons that require something selected. + QModelIndexList selection = ui->listView->selectionModel()->selectedIndexes(); + + ui->rmAccountBtn->setEnabled(selection.size() > 0); + ui->setDefaultBtn->setEnabled(selection.size() > 0); + + ui->noDefaultBtn->setDown(m_accounts->activeAccount().get() == nullptr); +} + +void AccountListPage::addAccount(const QString &errMsg) +{ + // TODO: The login dialog isn't quite done yet + MojangAccountPtr account = LoginDialog::newAccount(this, errMsg); + + if (account != nullptr) + { + m_accounts->addAccount(account); + if (m_accounts->count() == 1) + m_accounts->setActiveAccount(account->username()); + + // Grab associated player skins + auto job = new NetJob("Player skins: " + account->username()); + + for (AccountProfile profile : account->profiles()) + { + auto meta = MMC->metacache()->resolveEntry("skins", profile.name + ".png"); + auto action = CacheDownload::make( + QUrl("http://" + URLConstants::SKINS_BASE + profile.name + ".png"), meta); + job->addNetAction(action); + meta->stale = true; + } + + job->start(); + } +} diff --git a/gui/pages/global/AccountListPage.h b/gui/pages/global/AccountListPage.h new file mode 100644 index 00000000..fd4724d1 --- /dev/null +++ b/gui/pages/global/AccountListPage.h @@ -0,0 +1,80 @@ +/* Copyright 2013 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +#include "gui/pages/BasePage.h" + +#include "logic/auth/MojangAccountList.h" + +namespace Ui +{ +class AccountListPage; +} + +class AuthenticateTask; + +class AccountListPage : public QDialog, public BasePage +{ + Q_OBJECT +public: + explicit AccountListPage(QWidget *parent = 0); + ~AccountListPage(); + + QString displayName() const override + { + return tr("Accounts"); + } + QIcon icon() const override + { + return QIcon::fromTheme("noaccount"); + } + QString id() const override + { + return "accounts"; + } + QString helpPage() const override + { + return "Accounts"; + } + +public +slots: + void on_addAccountBtn_clicked(); + + void on_rmAccountBtn_clicked(); + + void on_setDefaultBtn_clicked(); + + void on_noDefaultBtn_clicked(); + + void listChanged(); + + //! Updates the states of the dialog's buttons. + void updateButtonStates(); + +protected: + std::shared_ptr m_accounts; + +protected +slots: + void addAccount(const QString& errMsg=""); + +private: + Ui::AccountListPage *ui; +}; diff --git a/gui/pages/global/AccountListPage.ui b/gui/pages/global/AccountListPage.ui new file mode 100644 index 00000000..1e5b07eb --- /dev/null +++ b/gui/pages/global/AccountListPage.ui @@ -0,0 +1,89 @@ + + + AccountListPage + + + + 0 + 0 + 400 + 300 + + + + Manage Accounts + + + + + + <html><head/><body><p>Welcome! If you're new here, you can click the &quot;Add&quot; button to add your Mojang or Minecraft account.</p></body></html> + + + true + + + + + + + + + + + + + + &Add + + + + + + + &Remove + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + <html><head/><body><p>Set the currently selected account as the active account. The active account is the account that is used to log in (unless it is overridden in an instance-specific setting).</p></body></html> + + + &Set Default + + + + + + + Set no default account. This will cause MultiMC to prompt you to select an account every time you launch an instance that doesn't have its own default set. + + + &No Default + + + + + + + + + + + + diff --git a/gui/pages/global/BaseSettingsPage.cpp b/gui/pages/global/BaseSettingsPage.cpp new file mode 100644 index 00000000..167b23c0 --- /dev/null +++ b/gui/pages/global/BaseSettingsPage.cpp @@ -0,0 +1,28 @@ +/* Copyright 2014 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "BaseSettingsPage.h" + +#include "MultiMC.h" + +void BaseSettingsPage::opened() +{ + loadSettings(MMC->settings().get()); +} +bool BaseSettingsPage::apply() +{ + applySettings(MMC->settings().get()); + return true; +} diff --git a/gui/pages/global/BaseSettingsPage.h b/gui/pages/global/BaseSettingsPage.h new file mode 100644 index 00000000..55e5f2a4 --- /dev/null +++ b/gui/pages/global/BaseSettingsPage.h @@ -0,0 +1,35 @@ +/* Copyright 2014 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "gui/pages/BasePage.h" + +class SettingsObject; + +class BaseSettingsPage : public BasePage +{ +public: + virtual ~BaseSettingsPage() + { + } + + void opened() override; + bool apply() override; + +protected: + virtual void loadSettings(SettingsObject *object) = 0; + virtual void applySettings(SettingsObject *object) = 0; +}; diff --git a/gui/pages/global/ExternalToolsPage.cpp b/gui/pages/global/ExternalToolsPage.cpp new file mode 100644 index 00000000..e0312ee5 --- /dev/null +++ b/gui/pages/global/ExternalToolsPage.cpp @@ -0,0 +1,177 @@ +/* Copyright 2014 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ExternalToolsPage.h" +#include "ui_ExternalToolsPage.h" + +#include +#include + +#include + +#include "logic/settings/SettingsObject.h" +#include "logic/tools/BaseProfiler.h" +#include "MultiMC.h" + +ExternalToolsPage::ExternalToolsPage(QWidget *parent) : + QWidget(parent), + ui(new Ui::ExternalToolsPage) +{ + ui->setupUi(this); + + ui->mceditLink->setOpenExternalLinks(true); + ui->jvisualvmLink->setOpenExternalLinks(true); + ui->jprofilerLink->setOpenExternalLinks(true); +} + +ExternalToolsPage::~ExternalToolsPage() +{ + delete ui; +} + +void ExternalToolsPage::loadSettings(SettingsObject *object) +{ + ui->jprofilerPathEdit->setText(object->get("JProfilerPath").toString()); + ui->jvisualvmPathEdit->setText(object->get("JVisualVMPath").toString()); + ui->mceditPathEdit->setText(object->get("MCEditPath").toString()); +} +void ExternalToolsPage::applySettings(SettingsObject *object) +{ + object->set("JProfilerPath", ui->jprofilerPathEdit->text()); + object->set("JVisualVMPath", ui->jvisualvmPathEdit->text()); + object->set("MCEditPath", ui->mceditPathEdit->text()); +} + +void ExternalToolsPage::on_jprofilerPathBtn_clicked() +{ + QString raw_dir = ui->jprofilerPathEdit->text(); + QString error; + do + { + raw_dir = QFileDialog::getExistingDirectory(this, tr("JProfiler Directory"), raw_dir); + if (raw_dir.isEmpty()) + { + break; + } + QString cooked_dir = NormalizePath(raw_dir); + if (!MMC->profilers()["jprofiler"]->check(cooked_dir, &error)) + { + QMessageBox::critical(this, tr("Error"), + tr("Error while checking JProfiler install:\n%1").arg(error)); + continue; + } + else + { + ui->jprofilerPathEdit->setText(cooked_dir); + break; + } + } while (1); +} +void ExternalToolsPage::on_jprofilerCheckBtn_clicked() +{ + QString error; + if (!MMC->profilers()["jprofiler"]->check(ui->jprofilerPathEdit->text(), &error)) + { + QMessageBox::critical(this, tr("Error"), + tr("Error while checking JProfiler install:\n%1").arg(error)); + } + else + { + QMessageBox::information(this, tr("OK"), tr("JProfiler setup seems to be OK")); + } +} + +void ExternalToolsPage::on_jvisualvmPathBtn_clicked() +{ + QString raw_dir = ui->jvisualvmPathEdit->text(); + QString error; + do + { + raw_dir = QFileDialog::getOpenFileName(this, tr("JVisualVM Executable"), raw_dir); + if (raw_dir.isEmpty()) + { + break; + } + QString cooked_dir = NormalizePath(raw_dir); + if (!MMC->profilers()["jvisualvm"]->check(cooked_dir, &error)) + { + QMessageBox::critical(this, tr("Error"), + tr("Error while checking JVisualVM install:\n%1").arg(error)); + continue; + } + else + { + ui->jvisualvmPathEdit->setText(cooked_dir); + break; + } + } while (1); +} +void ExternalToolsPage::on_jvisualvmCheckBtn_clicked() +{ + QString error; + if (!MMC->profilers()["jvisualvm"]->check(ui->jvisualvmPathEdit->text(), &error)) + { + QMessageBox::critical(this, tr("Error"), + tr("Error while checking JVisualVM install:\n%1").arg(error)); + } + else + { + QMessageBox::information(this, tr("OK"), tr("JVisualVM setup seems to be OK")); + } +} + +void ExternalToolsPage::on_mceditPathBtn_clicked() +{ + QString raw_dir = ui->mceditPathEdit->text(); + QString error; + do + { +#ifdef Q_OS_OSX +#warning stuff + raw_dir = QFileDialog::getOpenFileName(this, tr("MCEdit Application"), raw_dir); +#else + raw_dir = QFileDialog::getExistingDirectory(this, tr("MCEdit Directory"), raw_dir); +#endif + if (raw_dir.isEmpty()) + { + break; + } + QString cooked_dir = NormalizePath(raw_dir); + if (!MMC->tools()["mcedit"]->check(cooked_dir, &error)) + { + QMessageBox::critical(this, tr("Error"), + tr("Error while checking MCEdit install:\n%1").arg(error)); + continue; + } + else + { + ui->mceditPathEdit->setText(cooked_dir); + break; + } + } while (1); +} +void ExternalToolsPage::on_mceditCheckBtn_clicked() +{ + QString error; + if (!MMC->tools()["mcedit"]->check(ui->mceditPathEdit->text(), &error)) + { + QMessageBox::critical(this, tr("Error"), + tr("Error while checking MCEdit install:\n%1").arg(error)); + } + else + { + QMessageBox::information(this, tr("OK"), tr("MCEdit setup seems to be OK")); + } +} diff --git a/gui/pages/global/ExternalToolsPage.h b/gui/pages/global/ExternalToolsPage.h new file mode 100644 index 00000000..1b35a92b --- /dev/null +++ b/gui/pages/global/ExternalToolsPage.h @@ -0,0 +1,66 @@ +/* Copyright 2014 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include "BaseSettingsPage.h" + +namespace Ui { +class ExternalToolsPage; +} + +class ExternalToolsPage : public QWidget, public BaseSettingsPage +{ + Q_OBJECT + +public: + explicit ExternalToolsPage(QWidget *parent = 0); + ~ExternalToolsPage(); + + QString displayName() const override + { + return tr("External Tools"); + } + QIcon icon() const override + { + return QIcon::fromTheme("plugin-blue"); + } + QString id() const override + { + return "external-tools"; + } + QString helpPage() const override + { + return "External-tools"; + } + +protected: + void loadSettings(SettingsObject *object) override; + void applySettings(SettingsObject *object) override; + +private: + Ui::ExternalToolsPage *ui; + +private +slots: + void on_jprofilerPathBtn_clicked(); + void on_jprofilerCheckBtn_clicked(); + void on_jvisualvmPathBtn_clicked(); + void on_jvisualvmCheckBtn_clicked(); + void on_mceditPathBtn_clicked(); + void on_mceditCheckBtn_clicked(); +}; diff --git a/gui/pages/global/ExternalToolsPage.ui b/gui/pages/global/ExternalToolsPage.ui new file mode 100644 index 00000000..96650f0f --- /dev/null +++ b/gui/pages/global/ExternalToolsPage.ui @@ -0,0 +1,145 @@ + + + ExternalToolsPage + + + + 0 + 0 + 494 + 562 + + + + Form + + + + + + JProfiler + + + + + + + + + + + ... + + + + + + + + + Check + + + + + + + <html><head/><body><p><a href="http://www.ej-technologies.com/products/jprofiler/overview.html"><span style=" text-decoration: underline; color:#0000ff;">http://www.ej-technologies.com/products/jprofiler/overview.html</span></a></p></body></html> + + + + + + + + + + JVisualVM + + + + + + + + + + + ... + + + + + + + + + Check + + + + + + + <html><head/><body><p><a href="http://visualvm.java.net/"><span style=" text-decoration: underline; color:#0000ff;">http://visualvm.java.net/</span></a></p></body></html> + + + + + + + + + + MCEdit + + + + + + + + + + + ... + + + + + + + + + Check + + + + + + + <html><head/><body><p><a href="http://www.mcedit.net/"><span style=" text-decoration: underline; color:#0000ff;">http://www.mcedit.net/</span></a></p></body></html> + + + + + + + + + + Qt::Vertical + + + + 20 + 160 + + + + + + + + + diff --git a/gui/pages/global/SettingsPage.cpp b/gui/pages/global/SettingsPage.cpp new file mode 100644 index 00000000..37b0539c --- /dev/null +++ b/gui/pages/global/SettingsPage.cpp @@ -0,0 +1,547 @@ +/* Copyright 2013 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "SettingsPage.h" +#include "ui_SettingsPage.h" + +#include +#include +#include + +#include + +#include "gui/Platform.h" +#include "gui/dialogs/VersionSelectDialog.h" +#include "gui/dialogs/CustomMessageBox.h" + +#include "logic/NagUtils.h" + +#include "logic/java/JavaUtils.h" +#include "logic/java/JavaVersionList.h" +#include "logic/java/JavaChecker.h" + +#include "logic/updater/UpdateChecker.h" + +#include "logic/tools/BaseProfiler.h" + +#include "logic/settings/SettingsObject.h" +#include "MultiMC.h" + +// FIXME: possibly move elsewhere +enum InstSortMode +{ + // Sort alphabetically by name. + Sort_Name, + // Sort by which instance was launched most recently. + Sort_LastLaunch +}; + +SettingsPage::SettingsPage(QWidget *parent) : QWidget(parent), ui(new Ui::SettingsPage) +{ + MultiMCPlatform::fixWM_CLASS(this); + ui->setupUi(this); + ui->sortingModeGroup->setId(ui->sortByNameBtn, Sort_Name); + ui->sortingModeGroup->setId(ui->sortLastLaunchedBtn, Sort_LastLaunch); + +#if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0) + ui->jsonEditorTextBox->setClearButtonEnabled(true); +#endif + + restoreGeometry( + QByteArray::fromBase64(MMC->settings()->get("SettingsGeometry").toByteArray())); + + QObject::connect(MMC->updateChecker().get(), &UpdateChecker::channelListLoaded, this, + &SettingsPage::refreshUpdateChannelList); + + if (MMC->updateChecker()->hasChannels()) + { + refreshUpdateChannelList(); + } + else + { + MMC->updateChecker()->updateChanList(false); + } + connect(ui->proxyGroup, SIGNAL(buttonClicked(int)), SLOT(proxyChanged(int))); +} + +SettingsPage::~SettingsPage() +{ + delete ui; +} + +void SettingsPage::closeEvent(QCloseEvent *ev) +{ + MMC->settings()->set("SettingsGeometry", saveGeometry().toBase64()); + + QWidget::closeEvent(ev); +} + +void SettingsPage::updateCheckboxStuff() +{ + ui->windowWidthSpinBox->setEnabled(!ui->maximizedCheckBox->isChecked()); + ui->windowHeightSpinBox->setEnabled(!ui->maximizedCheckBox->isChecked()); + ui->proxyAddrBox->setEnabled(!ui->proxyNoneBtn->isChecked() && + !ui->proxyDefaultBtn->isChecked()); + ui->proxyAuthBox->setEnabled(!ui->proxyNoneBtn->isChecked() && + !ui->proxyDefaultBtn->isChecked()); +} + +void SettingsPage::on_ftbLauncherBrowseBtn_clicked() +{ + QString raw_dir = QFileDialog::getExistingDirectory(this, tr("FTB Launcher Directory"), + ui->ftbLauncherBox->text()); + QString cooked_dir = NormalizePath(raw_dir); + + // do not allow current dir - it's dirty. Do not allow dirs that don't exist + if (!cooked_dir.isEmpty() && QDir(cooked_dir).exists()) + { + ui->ftbLauncherBox->setText(cooked_dir); + } +} +void SettingsPage::on_ftbBrowseBtn_clicked() +{ + QString raw_dir = + QFileDialog::getExistingDirectory(this, tr("FTB Directory"), ui->ftbBox->text()); + QString cooked_dir = NormalizePath(raw_dir); + + // do not allow current dir - it's dirty. Do not allow dirs that don't exist + if (!cooked_dir.isEmpty() && QDir(cooked_dir).exists()) + { + ui->ftbBox->setText(cooked_dir); + } +} + +void SettingsPage::on_instDirBrowseBtn_clicked() +{ + QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Instance Directory"), + ui->instDirTextBox->text()); + QString cooked_dir = NormalizePath(raw_dir); + + // do not allow current dir - it's dirty. Do not allow dirs that don't exist + if (!cooked_dir.isEmpty() && QDir(cooked_dir).exists()) + { + ui->instDirTextBox->setText(cooked_dir); + } +} +void SettingsPage::on_iconsDirBrowseBtn_clicked() +{ + QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Icons Directory"), + ui->iconsDirTextBox->text()); + QString cooked_dir = NormalizePath(raw_dir); + + // do not allow current dir - it's dirty. Do not allow dirs that don't exist + if (!cooked_dir.isEmpty() && QDir(cooked_dir).exists()) + { + ui->iconsDirTextBox->setText(cooked_dir); + } +} +void SettingsPage::on_modsDirBrowseBtn_clicked() +{ + QString raw_dir = QFileDialog::getExistingDirectory(this, tr("Mods Directory"), + ui->modsDirTextBox->text()); + QString cooked_dir = NormalizePath(raw_dir); + + // do not allow current dir - it's dirty. Do not allow dirs that don't exist + if (!cooked_dir.isEmpty() && QDir(cooked_dir).exists()) + { + ui->modsDirTextBox->setText(cooked_dir); + } +} +void SettingsPage::on_lwjglDirBrowseBtn_clicked() +{ + QString raw_dir = QFileDialog::getExistingDirectory(this, tr("LWJGL Directory"), + ui->lwjglDirTextBox->text()); + QString cooked_dir = NormalizePath(raw_dir); + + // do not allow current dir - it's dirty. Do not allow dirs that don't exist + if (!cooked_dir.isEmpty() && QDir(cooked_dir).exists()) + { + ui->lwjglDirTextBox->setText(cooked_dir); + } +} + +void SettingsPage::on_jsonEditorBrowseBtn_clicked() +{ + QString raw_file = QFileDialog::getOpenFileName( + this, tr("JSON Editor"), + ui->jsonEditorTextBox->text().isEmpty() +#if defined(Q_OS_LINUX) + ? QString("/usr/bin") +#else + ? QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation).first() +#endif + : ui->jsonEditorTextBox->text()); + QString cooked_file = NormalizePath(raw_file); + + if (cooked_file.isEmpty()) + { + return; + } + + // it has to exist and be an executable + if (QFileInfo(cooked_file).exists() && QFileInfo(cooked_file).isExecutable()) + { + ui->jsonEditorTextBox->setText(cooked_file); + } + else + { + QMessageBox::warning(this, tr("Invalid"), + tr("The file chosen does not seem to be an executable")); + } +} + +void SettingsPage::on_maximizedCheckBox_clicked(bool checked) +{ + Q_UNUSED(checked); + updateCheckboxStuff(); +} + +void SettingsPage::proxyChanged(int) +{ + updateCheckboxStuff(); +} + +void SettingsPage::refreshUpdateChannelList() +{ + // Stop listening for selection changes. It's going to change a lot while we update it and + // we don't need to update the + // description label constantly. + QObject::disconnect(ui->updateChannelComboBox, SIGNAL(currentIndexChanged(int)), this, + SLOT(updateChannelSelectionChanged(int))); + + QList channelList = MMC->updateChecker()->getChannelList(); + ui->updateChannelComboBox->clear(); + int selection = -1; + for (int i = 0; i < channelList.count(); i++) + { + UpdateChecker::ChannelListEntry entry = channelList.at(i); + + // When it comes to selection, we'll rely on the indexes of a channel entry being the + // same in the + // combo box as it is in the update checker's channel list. + // This probably isn't very safe, but the channel list doesn't change often enough (or + // at all) for + // this to be a big deal. Hope it doesn't break... + ui->updateChannelComboBox->addItem(entry.name); + + // If the update channel we just added was the selected one, set the current index in + // the combo box to it. + if (entry.id == m_currentUpdateChannel) + { + QLOG_DEBUG() << "Selected index" << i << "channel id" << m_currentUpdateChannel; + selection = i; + } + } + + ui->updateChannelComboBox->setCurrentIndex(selection); + + // Start listening for selection changes again and update the description label. + QObject::connect(ui->updateChannelComboBox, SIGNAL(currentIndexChanged(int)), this, + SLOT(updateChannelSelectionChanged(int))); + refreshUpdateChannelDesc(); + + // Now that we've updated the channel list, we can enable the combo box. + // It starts off disabled so that if the channel list hasn't been loaded, it will be + // disabled. + ui->updateChannelComboBox->setEnabled(true); +} + +void SettingsPage::updateChannelSelectionChanged(int index) +{ + refreshUpdateChannelDesc(); +} + +void SettingsPage::refreshUpdateChannelDesc() +{ + // Get the channel list. + QList channelList = MMC->updateChecker()->getChannelList(); + int selectedIndex = ui->updateChannelComboBox->currentIndex(); + if (selectedIndex < 0) + { + return; + } + if (selectedIndex < channelList.count()) + { + // Find the channel list entry with the given index. + UpdateChecker::ChannelListEntry selected = channelList.at(selectedIndex); + + // Set the description text. + ui->updateChannelDescLabel->setText(selected.description); + + // Set the currently selected channel ID. + m_currentUpdateChannel = selected.id; + } +} + +void SettingsPage::applySettings(SettingsObject *s) +{ + // Language + s->set("Language", + ui->languageBox->itemData(ui->languageBox->currentIndex()).toLocale().bcp47Name()); + + if (ui->resetNotificationsBtn->isChecked()) + { + s->set("ShownNotifications", QString()); + } + + // Updates + s->set("AutoUpdate", ui->autoUpdateCheckBox->isChecked()); + s->set("UpdateChannel", m_currentUpdateChannel); + //FIXME: make generic + switch (ui->themeComboBox->currentIndex()) + { + case 1: + s->set("IconTheme", "pe_dark"); + break; + case 2: + s->set("IconTheme", "pe_light"); + break; + case 0: + default: + s->set("IconTheme", "multimc"); + break; + } + // FTB + s->set("TrackFTBInstances", ui->trackFtbBox->isChecked()); + s->set("FTBLauncherRoot", ui->ftbLauncherBox->text()); + s->set("FTBRoot", ui->ftbBox->text()); + + // Folders + // TODO: Offer to move instances to new instance folder. + s->set("InstanceDir", ui->instDirTextBox->text()); + s->set("CentralModsDir", ui->modsDirTextBox->text()); + s->set("LWJGLDir", ui->lwjglDirTextBox->text()); + s->set("IconsDir", ui->iconsDirTextBox->text()); + + // Editors + QString jsonEditor = ui->jsonEditorTextBox->text(); + if (!jsonEditor.isEmpty() && + (!QFileInfo(jsonEditor).exists() || !QFileInfo(jsonEditor).isExecutable())) + { + QString found = QStandardPaths::findExecutable(jsonEditor); + if (!found.isEmpty()) + { + jsonEditor = found; + } + } + s->set("JsonEditor", jsonEditor); + + // Minecraft version updates + s->set("AutoUpdateMinecraftVersions", ui->autoupdateMinecraft->isChecked()); + + // Console + s->set("ShowConsole", ui->showConsoleCheck->isChecked()); + s->set("AutoCloseConsole", ui->autoCloseConsoleCheck->isChecked()); + + // Window Size + s->set("LaunchMaximized", ui->maximizedCheckBox->isChecked()); + s->set("MinecraftWinWidth", ui->windowWidthSpinBox->value()); + s->set("MinecraftWinHeight", ui->windowHeightSpinBox->value()); + + // Proxy + QString proxyType = "None"; + if (ui->proxyDefaultBtn->isChecked()) + proxyType = "Default"; + else if (ui->proxyNoneBtn->isChecked()) + proxyType = "None"; + else if (ui->proxySOCKS5Btn->isChecked()) + proxyType = "SOCKS5"; + else if (ui->proxyHTTPBtn->isChecked()) + proxyType = "HTTP"; + + s->set("ProxyType", proxyType); + s->set("ProxyAddr", ui->proxyAddrEdit->text()); + s->set("ProxyPort", ui->proxyPortEdit->value()); + s->set("ProxyUser", ui->proxyUserEdit->text()); + s->set("ProxyPass", ui->proxyPassEdit->text()); + + // Memory + s->set("MinMemAlloc", ui->minMemSpinBox->value()); + s->set("MaxMemAlloc", ui->maxMemSpinBox->value()); + s->set("PermGen", ui->permGenSpinBox->value()); + + // Java Settings + s->set("JavaPath", ui->javaPathTextBox->text()); + s->set("JvmArgs", ui->jvmArgsTextBox->text()); + NagUtils::checkJVMArgs(s->get("JvmArgs").toString(), this->parentWidget()); + + // Custom Commands + s->set("PreLaunchCommand", ui->preLaunchCmdTextBox->text()); + s->set("PostExitCommand", ui->postExitCmdTextBox->text()); + + auto sortMode = (InstSortMode)ui->sortingModeGroup->checkedId(); + switch (sortMode) + { + case Sort_LastLaunch: + s->set("InstSortMode", "LastLaunch"); + break; + case Sort_Name: + default: + s->set("InstSortMode", "Name"); + break; + } + + s->set("PostExitCommand", ui->postExitCmdTextBox->text()); +} +void SettingsPage::loadSettings(SettingsObject *s) +{ + // Language + ui->languageBox->clear(); + ui->languageBox->addItem(tr("English"), QLocale(QLocale::English)); + foreach(const QString & lang, QDir(MMC->staticData() + "/translations") + .entryList(QStringList() << "*.qm", QDir::Files)) + { + QLocale locale(lang.section(QRegExp("[_\\.]"), 1)); + ui->languageBox->addItem(QLocale::languageToString(locale.language()), locale); + } + ui->languageBox->setCurrentIndex( + ui->languageBox->findData(QLocale(s->get("Language").toString()))); + + // Updates + ui->autoUpdateCheckBox->setChecked(s->get("AutoUpdate").toBool()); + m_currentUpdateChannel = s->get("UpdateChannel").toString(); + //FIXME: make generic + auto theme = s->get("IconTheme").toString(); + if (theme == "pe_dark") + { + ui->themeComboBox->setCurrentIndex(1); + } + else if (theme == "pe_light") + { + ui->themeComboBox->setCurrentIndex(2); + } + else + { + ui->themeComboBox->setCurrentIndex(0); + } + // FTB + ui->trackFtbBox->setChecked(s->get("TrackFTBInstances").toBool()); + ui->ftbLauncherBox->setText(s->get("FTBLauncherRoot").toString()); + ui->ftbBox->setText(s->get("FTBRoot").toString()); + + // Folders + ui->instDirTextBox->setText(s->get("InstanceDir").toString()); + ui->modsDirTextBox->setText(s->get("CentralModsDir").toString()); + ui->lwjglDirTextBox->setText(s->get("LWJGLDir").toString()); + ui->iconsDirTextBox->setText(s->get("IconsDir").toString()); + + // Editors + ui->jsonEditorTextBox->setText(s->get("JsonEditor").toString()); + + // Minecraft version updates + ui->autoupdateMinecraft->setChecked(s->get("AutoUpdateMinecraftVersions").toBool()); + + // Console + ui->showConsoleCheck->setChecked(s->get("ShowConsole").toBool()); + ui->autoCloseConsoleCheck->setChecked(s->get("AutoCloseConsole").toBool()); + + // Window Size + ui->maximizedCheckBox->setChecked(s->get("LaunchMaximized").toBool()); + ui->windowWidthSpinBox->setValue(s->get("MinecraftWinWidth").toInt()); + ui->windowHeightSpinBox->setValue(s->get("MinecraftWinHeight").toInt()); + + // Memory + ui->minMemSpinBox->setValue(s->get("MinMemAlloc").toInt()); + ui->maxMemSpinBox->setValue(s->get("MaxMemAlloc").toInt()); + ui->permGenSpinBox->setValue(s->get("PermGen").toInt()); + + QString sortMode = s->get("InstSortMode").toString(); + + if (sortMode == "LastLaunch") + { + ui->sortLastLaunchedBtn->setChecked(true); + } + else + { + ui->sortByNameBtn->setChecked(true); + } + + // Proxy + QString proxyType = s->get("ProxyType").toString(); + if (proxyType == "Default") + ui->proxyDefaultBtn->setChecked(true); + else if (proxyType == "None") + ui->proxyNoneBtn->setChecked(true); + else if (proxyType == "SOCKS5") + ui->proxySOCKS5Btn->setChecked(true); + else if (proxyType == "HTTP") + ui->proxyHTTPBtn->setChecked(true); + + ui->proxyAddrEdit->setText(s->get("ProxyAddr").toString()); + ui->proxyPortEdit->setValue(s->get("ProxyPort").value()); + ui->proxyUserEdit->setText(s->get("ProxyUser").toString()); + ui->proxyPassEdit->setText(s->get("ProxyPass").toString()); + + // Java Settings + ui->javaPathTextBox->setText(s->get("JavaPath").toString()); + ui->jvmArgsTextBox->setText(s->get("JvmArgs").toString()); + + // Custom Commands + ui->preLaunchCmdTextBox->setText(s->get("PreLaunchCommand").toString()); + ui->postExitCmdTextBox->setText(s->get("PostExitCommand").toString()); +} + +void SettingsPage::on_javaDetectBtn_clicked() +{ + JavaVersionPtr java; + + VersionSelectDialog vselect(MMC->javalist().get(), tr("Select a Java version"), this, true); + vselect.setResizeOn(2); + vselect.exec(); + + if (vselect.result() == QDialog::Accepted && vselect.selectedVersion()) + { + java = std::dynamic_pointer_cast(vselect.selectedVersion()); + ui->javaPathTextBox->setText(java->path); + } +} +void SettingsPage::on_javaBrowseBtn_clicked() +{ + QString dir = QFileDialog::getOpenFileName(this, tr("Find Java executable")); + if (!dir.isNull()) + { + ui->javaPathTextBox->setText(dir); + } +} +void SettingsPage::on_javaTestBtn_clicked() +{ + checker.reset(new JavaChecker()); + connect(checker.get(), SIGNAL(checkFinished(JavaCheckResult)), this, + SLOT(checkFinished(JavaCheckResult))); + checker->path = ui->javaPathTextBox->text(); + checker->performCheck(); +} + +void SettingsPage::checkFinished(JavaCheckResult result) +{ + if (result.valid) + { + QString text; + text += "Java test succeeded!\n"; + if (result.is_64bit) + text += "Using 64bit java.\n"; + text += "\n"; + text += "Platform reported: " + result.realPlatform + "\n"; + text += "Java version reported: " + result.javaVersion; + QMessageBox::information(this, tr("Java test success"), text); + } + else + { + QMessageBox::warning( + this, tr("Java test failure"), + tr("The specified java binary didn't work. You should use the auto-detect feature, " + "or set the path to the java executable.")); + } +} diff --git a/gui/pages/global/SettingsPage.h b/gui/pages/global/SettingsPage.h new file mode 100644 index 00000000..46a38ec7 --- /dev/null +++ b/gui/pages/global/SettingsPage.h @@ -0,0 +1,105 @@ +/* Copyright 2013 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +#include "logic/java/JavaChecker.h" +#include "BaseSettingsPage.h" + +class SettingsObject; + +namespace Ui +{ +class SettingsPage; +} + +class SettingsPage : public QWidget, public BaseSettingsPage +{ + Q_OBJECT + +public: + explicit SettingsPage(QWidget *parent = 0); + ~SettingsPage(); + + QString displayName() const override + { + return tr("Settings"); + } + QIcon icon() const override + { + return QIcon::fromTheme("settings"); + } + QString id() const override + { + return "global-settings"; + } + QString helpPage() const override + { + return "Global-settings"; + } + + void updateCheckboxStuff(); + + +protected: + void applySettings(SettingsObject *s) override; + void loadSettings(SettingsObject *s) override; + virtual void closeEvent(QCloseEvent *ev); + +private +slots: + void on_ftbLauncherBrowseBtn_clicked(); + void on_ftbBrowseBtn_clicked(); + + void on_instDirBrowseBtn_clicked(); + void on_modsDirBrowseBtn_clicked(); + void on_lwjglDirBrowseBtn_clicked(); + void on_iconsDirBrowseBtn_clicked(); + + void on_jsonEditorBrowseBtn_clicked(); + + void on_maximizedCheckBox_clicked(bool checked); + + void on_javaDetectBtn_clicked(); + void on_javaTestBtn_clicked(); + void on_javaBrowseBtn_clicked(); + + void checkFinished(JavaCheckResult result); + + /*! + * Updates the list of update channels in the combo box. + */ + void refreshUpdateChannelList(); + + /*! + * Updates the channel description label. + */ + void refreshUpdateChannelDesc(); + + void updateChannelSelectionChanged(int index); + void proxyChanged(int); + +private: + Ui::SettingsPage *ui; + std::shared_ptr checker; + + /*! + * Stores the currently selected update channel. + */ + QString m_currentUpdateChannel; +}; diff --git a/gui/pages/global/SettingsPage.ui b/gui/pages/global/SettingsPage.ui new file mode 100644 index 00000000..ed1d8cda --- /dev/null +++ b/gui/pages/global/SettingsPage.ui @@ -0,0 +1,985 @@ + + + SettingsPage + + + + 0 + 0 + 545 + 609 + + + + + 0 + 0 + + + + Settings + + + + :/icons/toolbar/settings:/icons/toolbar/settings + + + + + + QTabWidget::Rounded + + + 0 + + + + Features + + + + + + Update Settings + + + + + + Check for updates when MultiMC starts? + + + + + + + Update Channel: + + + + + + + false + + + + + + + No channel selected. + + + true + + + + + + + + + + FTB + + + + + + false + + + + 0 + 0 + + + + + 28 + 16777215 + + + + Qt::TabFocus + + + ... + + + + + + + Launcher: + + + + + + + false + + + + + + + Track FTB instances + + + + + + + + + + true + + + + 0 + 0 + + + + + 28 + 16777215 + + + + ... + + + + + + + Files: + + + + + + + + + + Folders + + + + + + Instances: + + + + + + + + + + ... + + + + + + + Mods: + + + + + + + + + + + + + ... + + + + + + + LWJGL: + + + + + + + ... + + + + + + + + + + Icons: + + + + + + + ... + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + User Interface + + + + + + + + + 0 + 0 + + + + Language (needs restart): + + + + + + + + + + + + Reset hidden notifications + + + true + + + + + + + true + + + Sorting Mode + + + + + + By last launched + + + sortingModeGroup + + + + + + + By name + + + sortingModeGroup + + + + + + + + + + Icon Theme + + + + + + + 0 + 0 + + + + Qt::StrongFocus + + + + Default + + + + + Simple + + + + + Simple (Light Icons) + + + + + + + + + + + External Editors (leave empty for system default) + + + + + + + + + JSON Editor: + + + + + + + ... + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + Minecraft + + + + + + Minecraft Version Updates + + + + + + Automatically update to latest version revision + + + + + + + + + + Window Size + + + + + + Start Minecraft maximized? + + + + + + + + + Window height: + + + + + + + Window width: + + + + + + + 854 + + + 65536 + + + 1 + + + 854 + + + + + + + 480 + + + 65536 + + + 480 + + + + + + + + + + + + Console Settings + + + + + + Show console while the game is running? + + + + + + + Automatically close console when the game quits? + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + Java + + + + + + Memory + + + + + + The maximum amount of memory Minecraft is allowed to use. + + + MB + + + 512 + + + 65536 + + + 128 + + + 1024 + + + + + + + Minimum memory allocation: + + + + + + + Maximum memory allocation: + + + + + + + The amount of memory Minecraft is started with. + + + MB + + + 256 + + + 65536 + + + 128 + + + 256 + + + + + + + PermGen: + + + + + + + The amount of memory available to store loaded Java classes. + + + MB + + + 64 + + + 999999999 + + + 8 + + + 64 + + + + + + + + + + Java Settings + + + + + + + 0 + 0 + + + + Java path: + + + + + + + + 0 + 0 + + + + Auto-detect... + + + + + + + + 0 + 0 + + + + Test + + + + + + + + 0 + 0 + + + + JVM arguments: + + + + + + + + + + + + + 0 + 0 + + + + + 28 + 16777215 + + + + ... + + + + + + + + + + + + + + + Custom Commands + + + + + + Post-exit command: + + + + + + + Pre-launch command: + + + + + + + + + + + + + + + + + 0 + 0 + + + + Pre-launch command runs before the instance launches and post-exit command runs after it exits. Both will be run in MultiMC's working directory with INST_ID, INST_DIR, and INST_NAME as environment variables. + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + + + + + + Network settings. + + + Network + + + + + + Proxy + + + + + + Type + + + + + + Uses your system's default proxy settings. + + + Default + + + proxyGroup + + + + + + + None + + + proxyGroup + + + + + + + SOCKS5 + + + proxyGroup + + + + + + + HTTP + + + proxyGroup + + + + + + + + + + Address and Port + + + + + + 127.0.0.1 + + + + + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + QAbstractSpinBox::PlusMinus + + + 65535 + + + 8080 + + + + + + + + + + Authentication + + + + + + + + + Username: + + + + + + + Password: + + + + + + + QLineEdit::Password + + + + + + + Note: Proxy username and password are stored in plain text inside MultiMC's configuration file! + + + true + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + settingsTabs + autoUpdateCheckBox + updateChannelComboBox + trackFtbBox + ftbLauncherBox + ftbLauncherBrowseBtn + ftbBox + ftbBrowseBtn + instDirTextBox + instDirBrowseBtn + modsDirTextBox + modsDirBrowseBtn + lwjglDirTextBox + lwjglDirBrowseBtn + iconsDirTextBox + iconsDirBrowseBtn + languageBox + resetNotificationsBtn + sortLastLaunchedBtn + sortByNameBtn + themeComboBox + jsonEditorTextBox + jsonEditorBrowseBtn + autoupdateMinecraft + maximizedCheckBox + windowWidthSpinBox + windowHeightSpinBox + showConsoleCheck + autoCloseConsoleCheck + minMemSpinBox + maxMemSpinBox + permGenSpinBox + javaPathTextBox + javaBrowseBtn + javaDetectBtn + javaTestBtn + jvmArgsTextBox + preLaunchCmdTextBox + postExitCmdTextBox + proxyDefaultBtn + proxyNoneBtn + proxySOCKS5Btn + proxyHTTPBtn + proxyAddrEdit + proxyPortEdit + proxyUserEdit + proxyPassEdit + + + + + + + + -- cgit v1.2.3