diff options
author | Petr Mrázek <peterix@gmail.com> | 2018-03-19 02:36:12 +0100 |
---|---|---|
committer | Petr Mrázek <peterix@gmail.com> | 2018-03-27 09:25:36 +0200 |
commit | 8e44ab2338f4ca63d58de4b3329c384df9d6c053 (patch) | |
tree | 60b915ec620221656d1c3a42f40124b15e9e69f0 /application/pages/instance/VersionPage.cpp | |
parent | 4c7ea0f99a23f73fd3cae87f7dfaab89922a2311 (diff) | |
download | PrismLauncher-8e44ab2338f4ca63d58de4b3329c384df9d6c053.tar.gz PrismLauncher-8e44ab2338f4ca63d58de4b3329c384df9d6c053.tar.bz2 PrismLauncher-8e44ab2338f4ca63d58de4b3329c384df9d6c053.zip |
NOISSUE redo new instance dialog
Diffstat (limited to 'application/pages/instance/VersionPage.cpp')
-rw-r--r-- | application/pages/instance/VersionPage.cpp | 570 |
1 files changed, 570 insertions, 0 deletions
diff --git a/application/pages/instance/VersionPage.cpp b/application/pages/instance/VersionPage.cpp new file mode 100644 index 00000000..00ae0a7e --- /dev/null +++ b/application/pages/instance/VersionPage.cpp @@ -0,0 +1,570 @@ +/* Copyright 2013-2018 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 <QMessageBox> +#include <QEvent> +#include <QKeyEvent> + +#include "VersionPage.h" +#include "ui_VersionPage.h" + +#include "dialogs/CustomMessageBox.h" +#include "dialogs/VersionSelectDialog.h" +#include "dialogs/NewComponentDialog.h" +#include "dialogs/ModEditDialogCommon.h" + +#include "dialogs/ProgressDialog.h" +#include <GuiUtil.h> + +#include <QAbstractItemModel> +#include <QMessageBox> +#include <QListView> +#include <QString> +#include <QUrl> + +#include "minecraft/ComponentList.h" +#include "minecraft/auth/MojangAccountList.h" +#include "minecraft/Mod.h" +#include "icons/IconList.h" +#include "Exception.h" + +#include "MultiMC.h" + +#include <meta/Index.h> +#include <meta/VersionList.h> + +class IconProxy : public QIdentityProxyModel +{ + Q_OBJECT +public: + + IconProxy(QWidget *parentWidget) : QIdentityProxyModel(parentWidget) + { + connect(parentWidget, &QObject::destroyed, this, &IconProxy::widgetGone); + m_parentWidget = parentWidget; + } + + virtual QVariant data(const QModelIndex &proxyIndex, int role = Qt::DisplayRole) const override + { + QVariant var = QIdentityProxyModel::data(mapToSource(proxyIndex), role); + int column = proxyIndex.column(); + if(column == 0 && role == Qt::DecorationRole && m_parentWidget) + { + if(!var.isNull()) + { + auto string = var.toString(); + if(string == "warning") + { + return MMC->getThemedIcon("status-yellow"); + } + else if(string == "error") + { + return MMC->getThemedIcon("status-bad"); + } + } + return MMC->getThemedIcon("status-good"); + } + return var; + } +private slots: + void widgetGone() + { + m_parentWidget = nullptr; + } + +private: + QWidget *m_parentWidget = nullptr; +}; + +QIcon VersionPage::icon() const +{ + return MMC->icons()->getIcon(m_inst->iconKey()); +} +bool VersionPage::shouldDisplay() const +{ + return !m_inst->isRunning(); +} + +VersionPage::VersionPage(MinecraftInstance *inst, QWidget *parent) + : QWidget(parent), ui(new Ui::VersionPage), m_inst(inst) +{ + ui->setupUi(this); + ui->tabWidget->tabBar()->hide(); + m_profile = m_inst->getComponentList(); + + reloadComponentList(); + + if (m_profile) + { + auto proxy = new IconProxy(ui->packageView); + proxy->setSourceModel(m_profile.get()); + ui->packageView->setModel(proxy); + ui->packageView->installEventFilter(this); + ui->packageView->setSelectionMode(QAbstractItemView::SingleSelection); + connect(ui->packageView->selectionModel(), &QItemSelectionModel::currentChanged, this, &VersionPage::versionCurrent); + auto smodel = ui->packageView->selectionModel(); + connect(smodel, &QItemSelectionModel::currentChanged, this, &VersionPage::packageCurrent); + updateVersionControls(); + // select first item. + preselect(0); + } + else + { + disableVersionControls(); + } + connect(m_inst, &MinecraftInstance::versionReloaded, this, + &VersionPage::updateVersionControls); +} + +VersionPage::~VersionPage() +{ + delete ui; +} + +void VersionPage::packageCurrent(const QModelIndex ¤t, const QModelIndex &previous) +{ + if (!current.isValid()) + { + ui->frame->clear(); + return; + } + int row = current.row(); + auto patch = m_profile->getComponent(row); + auto severity = patch->getProblemSeverity(); + switch(severity) + { + case ProblemSeverity::Warning: + ui->frame->setModText(tr("%1 possibly has issues.").arg(patch->getName())); + break; + case ProblemSeverity::Error: + ui->frame->setModText(tr("%1 has issues!").arg(patch->getName())); + break; + default: + case ProblemSeverity::None: + ui->frame->clear(); + return; + } + + auto &problems = patch->getProblems(); + QString problemOut; + for (auto &problem: problems) + { + if(problem.m_severity == ProblemSeverity::Error) + { + problemOut += tr("Error: "); + } + else if(problem.m_severity == ProblemSeverity::Warning) + { + problemOut += tr("Warning: "); + } + problemOut += problem.m_description; + problemOut += "\n"; + } + ui->frame->setModDescription(problemOut); +} + + +void VersionPage::updateVersionControls() +{ + ui->forgeBtn->setEnabled(true); + ui->liteloaderBtn->setEnabled(true); + updateButtons(); +} + +void VersionPage::disableVersionControls() +{ + ui->forgeBtn->setEnabled(false); + ui->liteloaderBtn->setEnabled(false); + ui->reloadBtn->setEnabled(false); + updateButtons(); +} + +bool VersionPage::reloadComponentList() +{ + try + { + m_profile->reload(Net::Mode::Online); + return true; + } + catch (Exception &e) + { + QMessageBox::critical(this, tr("Error"), e.cause()); + return false; + } + catch (...) + { + QMessageBox::critical( + this, tr("Error"), + tr("Couldn't load the instance profile.")); + return false; + } +} + +void VersionPage::on_reloadBtn_clicked() +{ + reloadComponentList(); + m_container->refreshContainer(); +} + +void VersionPage::on_removeBtn_clicked() +{ + if (ui->packageView->currentIndex().isValid()) + { + // FIXME: use actual model, not reloading. + if (!m_profile->remove(ui->packageView->currentIndex().row())) + { + QMessageBox::critical(this, tr("Error"), tr("Couldn't remove file")); + } + } + updateButtons(); + reloadComponentList(); + m_container->refreshContainer(); +} + +void VersionPage::on_modBtn_clicked() +{ + if(m_container) + { + m_container->selectPage("mods"); + } +} + +void VersionPage::on_jarmodBtn_clicked() +{ + auto list = GuiUtil::BrowseForFiles("jarmod", tr("Select jar mods"), tr("Minecraft.jar mods (*.zip *.jar)"), MMC->settings()->get("CentralModsDir").toString(), this->parentWidget()); + if(!list.empty()) + { + m_profile->installJarMods(list); + } + updateButtons(); +} + +void VersionPage::on_jarBtn_clicked() +{ + auto jarPath = GuiUtil::BrowseForFile("jar", tr("Select jar"), tr("Minecraft.jar replacement (*.jar)"), MMC->settings()->get("CentralModsDir").toString(), this->parentWidget()); + if(!jarPath.isEmpty()) + { + m_profile->installCustomJar(jarPath); + } + updateButtons(); +} + +void VersionPage::on_moveUpBtn_clicked() +{ + try + { + m_profile->move(currentRow(), ComponentList::MoveUp); + } + catch (Exception &e) + { + QMessageBox::critical(this, tr("Error"), e.cause()); + } + updateButtons(); +} + +void VersionPage::on_moveDownBtn_clicked() +{ + try + { + m_profile->move(currentRow(), ComponentList::MoveDown); + } + catch (Exception &e) + { + QMessageBox::critical(this, tr("Error"), e.cause()); + } + updateButtons(); +} + +void VersionPage::on_changeVersionBtn_clicked() +{ + auto versionRow = currentRow(); + if(versionRow == -1) + { + return; + } + auto patch = m_profile->getComponent(versionRow); + auto name = patch->getName(); + auto list = patch->getVersionList(); + if(!list) + { + return; + } + auto uid = list->uid(); + // FIXME: this is a horrible HACK. Get version filtering information from the actual metadata... + if(uid == "net.minecraftforge") + { + on_forgeBtn_clicked(); + return; + } + else if (uid == "com.mumfrey.liteloader") + { + on_liteloaderBtn_clicked(); + return; + } + VersionSelectDialog vselect(list.get(), tr("Change %1 version").arg(name), this); + auto currentVersion = patch->getVersion(); + if(!currentVersion.isEmpty()) + { + vselect.setCurrentVersion(currentVersion); + } + if (!vselect.exec() || !vselect.selectedVersion()) + return; + + qDebug() << "Change" << uid << "to" << vselect.selectedVersion()->descriptor(); + bool important = false; + if(uid == "net.minecraft") + { + important = true; + } + m_profile->setComponentVersion(uid, vselect.selectedVersion()->descriptor(), important); + m_profile->resolve(Net::Mode::Online); + m_container->refreshContainer(); +} + +void VersionPage::on_downloadBtn_clicked() +{ + 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; + } + + auto updateTask = m_inst->createUpdateTask(Net::Mode::Online); + if (!updateTask) + { + return; + } + ProgressDialog tDialog(this); + connect(updateTask.get(), SIGNAL(failed(QString)), SLOT(onGameUpdateError(QString))); + // FIXME: unused return value + tDialog.execWithTask(updateTask.get()); + updateButtons(); + m_container->refreshContainer(); +} + +void VersionPage::on_forgeBtn_clicked() +{ + auto vlist = ENV.metadataIndex()->get("net.minecraftforge"); + if(!vlist) + { + return; + } + VersionSelectDialog vselect(vlist.get(), tr("Select Forge version"), this); + vselect.setExactFilter(BaseVersionList::ParentVersionRole, m_profile->getComponentVersion("net.minecraft")); + vselect.setEmptyString(tr("No Forge versions are currently available for Minecraft ") + m_profile->getComponentVersion("net.minecraft")); + vselect.setEmptyErrorString(tr("Couldn't load or download the Forge version lists!")); + + auto currentVersion = m_profile->getComponentVersion("net.minecraftforge"); + if(!currentVersion.isEmpty()) + { + vselect.setCurrentVersion(currentVersion); + } + + if (vselect.exec() && vselect.selectedVersion()) + { + auto vsn = vselect.selectedVersion(); + m_profile->setComponentVersion("net.minecraftforge", vsn->descriptor()); + m_profile->resolve(Net::Mode::Online); + // m_profile->installVersion(); + preselect(m_profile->rowCount(QModelIndex())-1); + m_container->refreshContainer(); + } +} + +void VersionPage::on_addEmptyBtn_clicked() +{ + NewComponentDialog compdialog(QString(), QString(), this); + QStringList blacklist; + for(int i = 0; i < m_profile->rowCount(); i++) + { + auto comp = m_profile->getComponent(i); + blacklist.push_back(comp->getID()); + } + compdialog.setBlacklist(blacklist); + if (compdialog.exec()) + { + qDebug() << "name:" << compdialog.name(); + qDebug() << "uid:" << compdialog.uid(); + m_profile->installEmpty(compdialog.uid(), compdialog.name()); + } +} + +void VersionPage::on_liteloaderBtn_clicked() +{ + auto vlist = ENV.metadataIndex()->get("com.mumfrey.liteloader"); + if(!vlist) + { + return; + } + VersionSelectDialog vselect(vlist.get(), tr("Select LiteLoader version"), this); + vselect.setExactFilter(BaseVersionList::ParentVersionRole, m_profile->getComponentVersion("net.minecraft")); + vselect.setEmptyString(tr("No LiteLoader versions are currently available for Minecraft ") + m_profile->getComponentVersion("net.minecraft")); + vselect.setEmptyErrorString(tr("Couldn't load or download the LiteLoader version lists!")); + + auto currentVersion = m_profile->getComponentVersion("com.mumfrey.liteloader"); + if(!currentVersion.isEmpty()) + { + vselect.setCurrentVersion(currentVersion); + } + + if (vselect.exec() && vselect.selectedVersion()) + { + auto vsn = vselect.selectedVersion(); + m_profile->setComponentVersion("com.mumfrey.liteloader", vsn->descriptor()); + m_profile->resolve(Net::Mode::Online); + // m_profile->installVersion(vselect.selectedVersion()); + preselect(m_profile->rowCount(QModelIndex())-1); + m_container->refreshContainer(); + } +} + +void VersionPage::versionCurrent(const QModelIndex ¤t, const QModelIndex &previous) +{ + currentIdx = current.row(); + updateButtons(currentIdx); +} + +void VersionPage::preselect(int row) +{ + if(row < 0) + { + row = 0; + } + if(row >= m_profile->rowCount(QModelIndex())) + { + row = m_profile->rowCount(QModelIndex()) - 1; + } + if(row < 0) + { + return; + } + auto model_index = m_profile->index(row); + ui->packageView->selectionModel()->select(model_index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); + updateButtons(row); +} + +void VersionPage::updateButtons(int row) +{ + if(row == -1) + row = currentRow(); + auto patch = m_profile->getComponent(row); + if (!patch) + { + ui->removeBtn->setDisabled(true); + ui->moveDownBtn->setDisabled(true); + ui->moveUpBtn->setDisabled(true); + ui->changeVersionBtn->setDisabled(true); + ui->editBtn->setDisabled(true); + ui->customizeBtn->setDisabled(true); + ui->revertBtn->setDisabled(true); + } + else + { + ui->removeBtn->setEnabled(patch->isRemovable()); + ui->moveDownBtn->setEnabled(patch->isMoveable()); + ui->moveUpBtn->setEnabled(patch->isMoveable()); + ui->changeVersionBtn->setEnabled(patch->isVersionChangeable()); + ui->editBtn->setEnabled(patch->isCustom()); + ui->customizeBtn->setEnabled(patch->isCustomizable()); + ui->revertBtn->setEnabled(patch->isRevertible()); + } +} + +void VersionPage::onGameUpdateError(QString error) +{ + CustomMessageBox::selectable(this, tr("Error updating instance"), error, + QMessageBox::Warning)->show(); +} + +Component * VersionPage::current() +{ + auto row = currentRow(); + if(row < 0) + { + return nullptr; + } + return m_profile->getComponent(row); +} + +int VersionPage::currentRow() +{ + if (ui->packageView->selectionModel()->selectedRows().isEmpty()) + { + return -1; + } + return ui->packageView->selectionModel()->selectedRows().first().row(); +} + +void VersionPage::on_customizeBtn_clicked() +{ + auto version = currentRow(); + if(version == -1) + { + return; + } + auto patch = m_profile->getComponent(version); + if(!patch->getVersionFile()) + { + // TODO: wait for the update task to finish here... + return; + } + if(!m_profile->customize(version)) + { + // TODO: some error box here + } + updateButtons(); + preselect(currentIdx); +} + +void VersionPage::on_editBtn_clicked() +{ + auto version = current(); + if(!version) + { + return; + } + auto filename = version->getFilename(); + if(!QFileInfo::exists(filename)) + { + qWarning() << "file" << filename << "can't be opened for editing, doesn't exist!"; + return; + } + MMC->openJsonEditor(filename); +} + +void VersionPage::on_revertBtn_clicked() +{ + auto version = currentRow(); + if(version == -1) + { + return; + } + if(!m_profile->revertToBase(version)) + { + // TODO: some error box here + } + updateButtons(); + preselect(currentIdx); + m_container->refreshContainer(); +} + +#include "VersionPage.moc" + |