From f485885757e287546bb27bda5906bfa4adc5494a Mon Sep 17 00:00:00 2001 From: Petr Mrázek Date: Mon, 2 Jun 2014 00:49:53 +0200 Subject: Add and implement pages and page dialog. --- gui/pages/BasePage.h | 35 +++++ gui/pages/BasePageProvider.h | 28 ++++ gui/pages/ModFolderPage.cpp | 140 +++++++++++++++++ gui/pages/ModFolderPage.h | 60 +++++++ gui/pages/ModFolderPage.ui | 114 ++++++++++++++ gui/pages/VersionPage.cpp | 365 +++++++++++++++++++++++++++++++++++++++++++ gui/pages/VersionPage.h | 70 +++++++++ gui/pages/VersionPage.ui | 169 ++++++++++++++++++++ 8 files changed, 981 insertions(+) create mode 100644 gui/pages/BasePage.h create mode 100644 gui/pages/BasePageProvider.h create mode 100644 gui/pages/ModFolderPage.cpp create mode 100644 gui/pages/ModFolderPage.h create mode 100644 gui/pages/ModFolderPage.ui create mode 100644 gui/pages/VersionPage.cpp create mode 100644 gui/pages/VersionPage.h create mode 100644 gui/pages/VersionPage.ui (limited to 'gui/pages') diff --git a/gui/pages/BasePage.h b/gui/pages/BasePage.h new file mode 100644 index 00000000..90e27d6f --- /dev/null +++ b/gui/pages/BasePage.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 +#include +#include + +class BasePage +{ +public: + virtual ~BasePage(){}; + virtual QString id() = 0; + virtual QString displayName() = 0; + virtual QIcon icon() = 0; + virtual bool shouldDisplay() + { + return true; + } + int index = -1; +}; + +typedef std::shared_ptr BasePagePtr; \ No newline at end of file diff --git a/gui/pages/BasePageProvider.h b/gui/pages/BasePageProvider.h new file mode 100644 index 00000000..cff9c8e7 --- /dev/null +++ b/gui/pages/BasePageProvider.h @@ -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. + */ + +#pragma once + +#include "BasePage.h" +#include + +class BasePageProvider +{ +public: + virtual QList getPages() = 0; + virtual QString dialogTitle() = 0; +}; + +typedef std::shared_ptr BasePageProviderPtr; diff --git a/gui/pages/ModFolderPage.cpp b/gui/pages/ModFolderPage.cpp new file mode 100644 index 00000000..de51edfa --- /dev/null +++ b/gui/pages/ModFolderPage.cpp @@ -0,0 +1,140 @@ +/* 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 "MultiMC.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ModFolderPage.h" +#include "ui_ModFolderPage.h" + +#include "gui/dialogs/CustomMessageBox.h" +#include "gui/dialogs/ModEditDialogCommon.h" + +#include "logic/ModList.h" +#include "logic/Mod.h" + +QString ModFolderPage::displayName() +{ + return m_displayName; +} + +QIcon ModFolderPage::icon() +{ + return QIcon::fromTheme(m_iconName); +} + +QString ModFolderPage::id() +{ + return m_id; +} + +ModFolderPage::ModFolderPage(std::shared_ptr mods, QString id, QString iconName, + QString displayName, QWidget *parent) + : QWidget(parent), ui(new Ui::ModFolderPage) +{ + ui->setupUi(this); + m_mods = mods; + m_id = id; + m_displayName = displayName; + m_iconName = iconName; + ui->modTreeView->setModel(m_mods.get()); + ui->modTreeView->installEventFilter(this); + m_mods->startWatching(); + auto smodel = ui->modTreeView->selectionModel(); + connect(smodel, SIGNAL(currentChanged(QModelIndex, QModelIndex)), + SLOT(modCurrent(QModelIndex, QModelIndex))); +} + +ModFolderPage::~ModFolderPage() +{ + m_mods->stopWatching(); + delete ui; +} + +bool ModFolderPage::modListFilter(QKeyEvent *keyEvent) +{ + switch (keyEvent->key()) + { + case Qt::Key_Delete: + on_rmModBtn_clicked(); + return true; + case Qt::Key_Plus: + on_addModBtn_clicked(); + return true; + default: + break; + } + return QWidget::eventFilter(ui->modTreeView, keyEvent); +} + +bool ModFolderPage::eventFilter(QObject *obj, QEvent *ev) +{ + if (ev->type() != QEvent::KeyPress) + { + return QWidget::eventFilter(obj, ev); + } + QKeyEvent *keyEvent = static_cast(ev); + if (obj == ui->modTreeView) + return modListFilter(keyEvent); + return QWidget::eventFilter(obj, ev); +} + +void ModFolderPage::on_addModBtn_clicked() +{ + QStringList fileNames = QFileDialog::getOpenFileNames( + this, QApplication::translate("ModFolderPage", "Select Loader Mods")); + for (auto filename : fileNames) + { + m_mods->stopWatching(); + m_mods->installMod(QFileInfo(filename)); + m_mods->startWatching(); + } +} +void ModFolderPage::on_rmModBtn_clicked() +{ + int first, last; + auto list = ui->modTreeView->selectionModel()->selectedRows(); + + if (!lastfirst(list, first, last)) + return; + m_mods->stopWatching(); + m_mods->deleteMods(first, last); + m_mods->startWatching(); +} + +void ModFolderPage::on_viewModBtn_clicked() +{ + openDirInDefaultProgram(m_mods->dir().absolutePath(), true); +} + +void ModFolderPage::modCurrent(const QModelIndex ¤t, const QModelIndex &previous) +{ + if (!current.isValid()) + { + ui->frame->clear(); + return; + } + int row = current.row(); + Mod &m = m_mods->operator[](row); + ui->frame->updateWithMod(m); +} diff --git a/gui/pages/ModFolderPage.h b/gui/pages/ModFolderPage.h new file mode 100644 index 00000000..276e23d5 --- /dev/null +++ b/gui/pages/ModFolderPage.h @@ -0,0 +1,60 @@ +/* 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 +#include +#include "BasePage.h" + +class EnabledItemFilter; +class ModList; +namespace Ui +{ +class ModFolderPage; +} + +class ModFolderPage : public QWidget, public BasePage +{ + Q_OBJECT + +public: + explicit ModFolderPage(std::shared_ptr mods, QString id, QString iconName, + QString displayName, QWidget *parent = 0); + virtual ~ModFolderPage(); + virtual QString displayName() override; + virtual QIcon icon() override; + virtual QString id() override; + +protected: + bool eventFilter(QObject *obj, QEvent *ev); + bool modListFilter(QKeyEvent *ev); + +private: + Ui::ModFolderPage *ui; + std::shared_ptr m_mods; + QString m_iconName; + QString m_id; + QString m_displayName; + +public slots: + void modCurrent(const QModelIndex ¤t, const QModelIndex &previous); + +private slots: + void on_addModBtn_clicked(); + void on_rmModBtn_clicked(); + void on_viewModBtn_clicked(); +}; diff --git a/gui/pages/ModFolderPage.ui b/gui/pages/ModFolderPage.ui new file mode 100644 index 00000000..05125be3 --- /dev/null +++ b/gui/pages/ModFolderPage.ui @@ -0,0 +1,114 @@ + + + ModFolderPage + + + + 0 + 0 + 540 + 350 + + + + Mods + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + 0 + 0 + + + + true + + + QAbstractItemView::DropOnly + + + + + + + + 0 + 0 + + + + + + + + + + + + &Add + + + + + + + &Remove + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + &View Folder + + + + + + + + + + ModListView + QTreeView +
gui/widgets/ModListView.h
+
+ + MCModInfoFrame + QFrame +
gui/widgets/MCModInfoFrame.h
+ 1 +
+
+ + +
diff --git a/gui/pages/VersionPage.cpp b/gui/pages/VersionPage.cpp new file mode 100644 index 00000000..34b959e0 --- /dev/null +++ b/gui/pages/VersionPage.cpp @@ -0,0 +1,365 @@ +/* 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 "MultiMC.h" + +#include +#include +#include +#include +#include +#include + +#include "VersionPage.h" +#include "ui_VersionPage.h" + +#include "gui/Platform.h" +#include "gui/dialogs/CustomMessageBox.h" +#include "gui/dialogs/VersionSelectDialog.h" +#include "gui/dialogs/ModEditDialogCommon.h" + +#include "gui/dialogs/ProgressDialog.h" + +#include "logic/ModList.h" +#include "logic/minecraft/InstanceVersion.h" +#include "logic/EnabledItemFilter.h" +#include "logic/forge/ForgeVersionList.h" +#include "logic/forge/ForgeInstaller.h" +#include "logic/liteloader/LiteLoaderVersionList.h" +#include "logic/liteloader/LiteLoaderInstaller.h" +#include "logic/minecraft/VersionBuilder.h" +#include "logic/auth/MojangAccountList.h" + +#include +#include + +#include +#include +#include +#include + +QString VersionPage::displayName() +{ + return tr("Version"); +} + +QIcon VersionPage::icon() +{ + return QIcon::fromTheme("settings"); +} + +QString VersionPage::id() +{ + return "version"; +} + +VersionPage::VersionPage(OneSixInstance *inst, QWidget *parent) + : QWidget(parent), ui(new Ui::VersionPage), m_inst(inst) +{ + ui->setupUi(this); + // libraries! + + m_version = m_inst->getFullVersion(); + if (m_version) + { + main_model = new EnabledItemFilter(this); + main_model->setActive(true); + main_model->setSourceModel(m_version.get()); + ui->libraryTreeView->setModel(main_model); + ui->libraryTreeView->installEventFilter(this); + connect(ui->libraryTreeView->selectionModel(), &QItemSelectionModel::currentChanged, + this, &VersionPage::versionCurrent); + updateVersionControls(); + } + else + { + disableVersionControls(); + } + connect(m_inst, &OneSixInstance::versionReloaded, this, + &VersionPage::updateVersionControls); +} + +VersionPage::~VersionPage() +{ + delete ui; +} + +void VersionPage::updateVersionControls() +{ + ui->forgeBtn->setEnabled(true); + ui->liteloaderBtn->setEnabled(true); +} + +void VersionPage::disableVersionControls() +{ + ui->forgeBtn->setEnabled(false); + ui->liteloaderBtn->setEnabled(false); + ui->reloadLibrariesBtn->setEnabled(false); + ui->removeLibraryBtn->setEnabled(false); +} + +bool VersionPage::reloadInstanceVersion() +{ + try + { + m_inst->reloadVersion(); + return true; + } + catch (MMCError &e) + { + QMessageBox::critical(this, tr("Error"), e.cause()); + return false; + } + catch (...) + { + QMessageBox::critical( + this, tr("Error"), + tr("Failed to load the version description file for reasons unknown.")); + return false; + } +} + +void VersionPage::on_reloadLibrariesBtn_clicked() +{ + reloadInstanceVersion(); +} + +void VersionPage::on_removeLibraryBtn_clicked() +{ + if (ui->libraryTreeView->currentIndex().isValid()) + { + // FIXME: use actual model, not reloading. + if (!m_version->remove(ui->libraryTreeView->currentIndex().row())) + { + QMessageBox::critical(this, tr("Error"), tr("Couldn't remove file")); + } + } +} + +void VersionPage::on_jarmodBtn_clicked() +{ + QFileDialog w; + QSet locations; + QString modsFolder = MMC->settings()->get("CentralModsDir").toString(); + auto f = [&](QStandardPaths::StandardLocation l) + { + QString location = QStandardPaths::writableLocation(l); + if(!QFileInfo::exists(location)) + return; + locations.insert(location); + }; + f(QStandardPaths::DesktopLocation); + f(QStandardPaths::DocumentsLocation); + f(QStandardPaths::DownloadLocation); + f(QStandardPaths::HomeLocation); + QList urls; + for(auto location: locations) + { + urls.append(QUrl::fromLocalFile(location)); + } + urls.append(QUrl::fromLocalFile(modsFolder)); + + w.setFileMode(QFileDialog::ExistingFiles); + w.setAcceptMode(QFileDialog::AcceptOpen); + w.setNameFilter(tr("Minecraft jar mods (*.zip *.jar)")); + w.setDirectory(modsFolder); + w.setSidebarUrls(urls); + + if(w.exec()); + m_version->installJarMods(w.selectedFiles()); +} + +void VersionPage::on_resetLibraryOrderBtn_clicked() +{ + try + { + m_version->resetOrder(); + } + catch (MMCError &e) + { + QMessageBox::critical(this, tr("Error"), e.cause()); + } +} + +void VersionPage::on_moveLibraryUpBtn_clicked() +{ + if (ui->libraryTreeView->selectionModel()->selectedRows().isEmpty()) + { + return; + } + try + { + const int row = ui->libraryTreeView->selectionModel()->selectedRows().first().row(); + const int newRow = 0; + m_version->move(row, InstanceVersion::MoveUp); + // ui->libraryTreeView->selectionModel()->setCurrentIndex(m_version->index(newRow), + // QItemSelectionModel::ClearAndSelect); + } + catch (MMCError &e) + { + QMessageBox::critical(this, tr("Error"), e.cause()); + } +} + +void VersionPage::on_moveLibraryDownBtn_clicked() +{ + if (ui->libraryTreeView->selectionModel()->selectedRows().isEmpty()) + { + return; + } + try + { + const int row = ui->libraryTreeView->selectionModel()->selectedRows().first().row(); + const int newRow = 0; + m_version->move(row, InstanceVersion::MoveDown); + // ui->libraryTreeView->selectionModel()->setCurrentIndex(m_version->index(newRow), + // QItemSelectionModel::ClearAndSelect); + } + catch (MMCError &e) + { + QMessageBox::critical(this, tr("Error"), e.cause()); + } +} + +void VersionPage::on_changeMCVersionBtn_clicked() +{ + VersionSelectDialog vselect(m_inst->versionList().get(), tr("Change Minecraft version"), + this); + if (!vselect.exec() || !vselect.selectedVersion()) + return; + + if (!MMC->accounts()->anyAccountIsValid()) + { + CustomMessageBox::selectable( + this, tr("Error"), + tr("MultiMC cannot download Minecraft or update instances unless you have at least " + "one account added.\nPlease add your Mojang or Minecraft account."), + QMessageBox::Warning)->show(); + return; + } + + if (m_inst->versionIsCustom()) + { + auto result = CustomMessageBox::selectable( + this, tr("Are you sure?"), + tr("This will remove any library/version customization you did previously. " + "This includes things like Forge install and similar."), + QMessageBox::Warning, QMessageBox::Ok | QMessageBox::Abort, + QMessageBox::Abort)->exec(); + + if (result != QMessageBox::Ok) + return; + m_version->revertToVanilla(); + reloadInstanceVersion(); + } + m_inst->setIntendedVersionId(vselect.selectedVersion()->descriptor()); + + auto updateTask = m_inst->doUpdate(); + if (!updateTask) + { + return; + } + ProgressDialog tDialog(this); + connect(updateTask.get(), SIGNAL(failed(QString)), SLOT(onGameUpdateError(QString))); + tDialog.exec(updateTask.get()); +} + +void VersionPage::on_forgeBtn_clicked() +{ + // FIXME: use actual model, not reloading. Move logic to model. + if (m_version->hasFtbPack()) + { + if (QMessageBox::question( + this, tr("Revert?"), + tr("This action will remove the FTB pack version patch. Continue?")) != + QMessageBox::Yes) + { + return; + } + m_version->removeFtbPack(); + reloadInstanceVersion(); + } + if (m_version->usesLegacyCustomJson()) + { + if (QMessageBox::question(this, tr("Revert?"), + tr("This action will remove your custom.json. Continue?")) != + QMessageBox::Yes) + { + return; + } + m_version->revertToVanilla(); + reloadInstanceVersion(); + } + VersionSelectDialog vselect(MMC->forgelist().get(), tr("Select Forge version"), this); + vselect.setExactFilter(1, m_inst->currentVersionId()); + vselect.setEmptyString(tr("No Forge versions are currently available for Minecraft ") + + m_inst->currentVersionId()); + if (vselect.exec() && vselect.selectedVersion()) + { + ProgressDialog dialog(this); + dialog.exec( + ForgeInstaller().createInstallTask(m_inst, vselect.selectedVersion(), this)); + } +} + +void VersionPage::on_liteloaderBtn_clicked() +{ + if (m_version->hasFtbPack()) + { + if (QMessageBox::question( + this, tr("Revert?"), + tr("This action will remove the FTB pack version patch. Continue?")) != + QMessageBox::Yes) + { + return; + } + m_version->removeFtbPack(); + reloadInstanceVersion(); + } + if (m_version->usesLegacyCustomJson()) + { + if (QMessageBox::question(this, tr("Revert?"), + tr("This action will remove your custom.json. Continue?")) != + QMessageBox::Yes) + { + return; + } + m_version->revertToVanilla(); + reloadInstanceVersion(); + } + VersionSelectDialog vselect(MMC->liteloaderlist().get(), tr("Select LiteLoader version"), + this); + vselect.setExactFilter(1, m_inst->currentVersionId()); + vselect.setEmptyString(tr("No LiteLoader versions are currently available for Minecraft ") + + m_inst->currentVersionId()); + if (vselect.exec() && vselect.selectedVersion()) + { + ProgressDialog dialog(this); + dialog.exec( + LiteLoaderInstaller().createInstallTask(m_inst, vselect.selectedVersion(), this)); + } +} + +void VersionPage::versionCurrent(const QModelIndex ¤t, const QModelIndex &previous) +{ + if (!current.isValid()) + { + ui->removeLibraryBtn->setDisabled(true); + } + else + { + ui->removeLibraryBtn->setEnabled(m_version->canRemove(current.row())); + } +} diff --git a/gui/pages/VersionPage.h b/gui/pages/VersionPage.h new file mode 100644 index 00000000..55e244b3 --- /dev/null +++ b/gui/pages/VersionPage.h @@ -0,0 +1,70 @@ +/* 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 +#include +#include "BasePage.h" + +class EnabledItemFilter; +namespace Ui +{ +class VersionPage; +} + +class VersionPage : public QWidget, public BasePage +{ + Q_OBJECT + +public: + explicit VersionPage(OneSixInstance *inst, QWidget *parent = 0); + virtual ~VersionPage(); + virtual QString displayName() override; + virtual QIcon icon() override; + virtual QString id() override; +private +slots: + + // version tab + void on_forgeBtn_clicked(); + void on_liteloaderBtn_clicked(); + void on_reloadLibrariesBtn_clicked(); + void on_removeLibraryBtn_clicked(); + void on_resetLibraryOrderBtn_clicked(); + void on_moveLibraryUpBtn_clicked(); + void on_moveLibraryDownBtn_clicked(); + void on_jarmodBtn_clicked(); + + void updateVersionControls(); + void disableVersionControls(); + void on_changeMCVersionBtn_clicked(); + +protected: + /// FIXME: this shouldn't be necessary! + bool reloadInstanceVersion(); + +private: + Ui::VersionPage *ui; + std::shared_ptr m_version; + EnabledItemFilter *main_model; + OneSixInstance *m_inst; + NetJobPtr forgeJob; + +public +slots: + void versionCurrent(const QModelIndex ¤t, const QModelIndex &previous); +}; diff --git a/gui/pages/VersionPage.ui b/gui/pages/VersionPage.ui new file mode 100644 index 00000000..036295f0 --- /dev/null +++ b/gui/pages/VersionPage.ui @@ -0,0 +1,169 @@ + + + VersionPage + + + + 0 + 0 + 400 + 326 + + + + Version + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAlwaysOff + + + false + + + true + + + + + + + + + + + Change version + + + + + + + Replace any current custom version with Minecraft Forge + + + Install Forge + + + + + + + Install LiteLoader + + + + + + + Add jar mod + + + + + + + Qt::Horizontal + + + + + + + Reload + + + + + + + Remove + + + + + + + Qt::Horizontal + + + + + + + This isn't implemented yet. + + + Move up + + + + + + + This isn't implemented yet. + + + Move down + + + + + + + This isn't implemented yet. + + + Reset order + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + ModListView + QTreeView +
gui/widgets/ModListView.h
+
+
+ + +
-- cgit