743af4769e
Version patches get a lot of new flags that determine which actions are allowed Version page respects the flags Customize, revert and edit for version patches Builting patches can be customized
394 lines
9.3 KiB
C++
394 lines
9.3 KiB
C++
/* Copyright 2013-2015 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 <pathutils.h>
|
|
#include <QMessageBox>
|
|
#include <QEvent>
|
|
#include <QKeyEvent>
|
|
|
|
#include "VersionPage.h"
|
|
#include "ui_VersionPage.h"
|
|
|
|
#include "Platform.h"
|
|
#include "dialogs/CustomMessageBox.h"
|
|
#include "dialogs/VersionSelectDialog.h"
|
|
#include "dialogs/ModEditDialogCommon.h"
|
|
|
|
#include "dialogs/ProgressDialog.h"
|
|
#include <GuiUtil.h>
|
|
|
|
#include <QAbstractItemModel>
|
|
#include <QMessageBox>
|
|
#include <QListView>
|
|
#include <QString>
|
|
#include <QUrl>
|
|
|
|
#include "minecraft/MinecraftProfile.h"
|
|
#include "forge/ForgeVersionList.h"
|
|
#include "forge/ForgeInstaller.h"
|
|
#include "liteloader/LiteLoaderVersionList.h"
|
|
#include "liteloader/LiteLoaderInstaller.h"
|
|
#include "auth/MojangAccountList.h"
|
|
#include "minecraft/Mod.h"
|
|
#include "icons/IconList.h"
|
|
|
|
|
|
QIcon VersionPage::icon() const
|
|
{
|
|
return ENV.icons()->getIcon(m_inst->iconKey());
|
|
}
|
|
bool VersionPage::shouldDisplay() const
|
|
{
|
|
return !m_inst->isRunning();
|
|
}
|
|
|
|
VersionPage::VersionPage(OneSixInstance *inst, QWidget *parent)
|
|
: QWidget(parent), ui(new Ui::VersionPage), m_inst(inst)
|
|
{
|
|
ui->setupUi(this);
|
|
ui->tabWidget->tabBar()->hide();
|
|
|
|
reloadMinecraftProfile();
|
|
|
|
m_version = m_inst->getMinecraftProfile();
|
|
if (m_version)
|
|
{
|
|
ui->packageView->setModel(m_version.get());
|
|
ui->packageView->installEventFilter(this);
|
|
ui->packageView->setSelectionMode(QAbstractItemView::SingleSelection);
|
|
connect(ui->packageView->selectionModel(), &QItemSelectionModel::currentChanged,
|
|
this, &VersionPage::versionCurrent);
|
|
updateVersionControls();
|
|
// select first item.
|
|
preselect(0);
|
|
}
|
|
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);
|
|
updateButtons();
|
|
}
|
|
|
|
void VersionPage::disableVersionControls()
|
|
{
|
|
ui->forgeBtn->setEnabled(false);
|
|
ui->liteloaderBtn->setEnabled(false);
|
|
ui->reloadBtn->setEnabled(false);
|
|
updateButtons();
|
|
}
|
|
|
|
bool VersionPage::reloadMinecraftProfile()
|
|
{
|
|
try
|
|
{
|
|
m_inst->reloadProfile();
|
|
return true;
|
|
}
|
|
catch (MMCError &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()
|
|
{
|
|
reloadMinecraftProfile();
|
|
}
|
|
|
|
void VersionPage::on_removeBtn_clicked()
|
|
{
|
|
if (ui->packageView->currentIndex().isValid())
|
|
{
|
|
// FIXME: use actual model, not reloading.
|
|
if (!m_version->remove(ui->packageView->currentIndex().row()))
|
|
{
|
|
QMessageBox::critical(this, tr("Error"), tr("Couldn't remove file"));
|
|
}
|
|
}
|
|
updateButtons();
|
|
}
|
|
|
|
void VersionPage::on_jarmodBtn_clicked()
|
|
{
|
|
auto list = GuiUtil::BrowseForMods("jarmod", tr("Select jar mods"), tr("Minecraft.jar mods (*.zip *.jar)"), this->parentWidget());
|
|
if(!list.empty())
|
|
{
|
|
m_version->installJarMods(list);
|
|
}
|
|
updateButtons();
|
|
}
|
|
|
|
void VersionPage::on_resetOrderBtn_clicked()
|
|
{
|
|
try
|
|
{
|
|
m_version->resetOrder();
|
|
}
|
|
catch (MMCError &e)
|
|
{
|
|
QMessageBox::critical(this, tr("Error"), e.cause());
|
|
}
|
|
updateButtons();
|
|
}
|
|
|
|
void VersionPage::on_moveUpBtn_clicked()
|
|
{
|
|
try
|
|
{
|
|
m_version->move(currentRow(), MinecraftProfile::MoveUp);
|
|
}
|
|
catch (MMCError &e)
|
|
{
|
|
QMessageBox::critical(this, tr("Error"), e.cause());
|
|
}
|
|
updateButtons();
|
|
}
|
|
|
|
void VersionPage::on_moveDownBtn_clicked()
|
|
{
|
|
try
|
|
{
|
|
m_version->move(currentRow(), MinecraftProfile::MoveDown);
|
|
}
|
|
catch (MMCError &e)
|
|
{
|
|
QMessageBox::critical(this, tr("Error"), e.cause());
|
|
}
|
|
updateButtons();
|
|
}
|
|
|
|
void VersionPage::on_changeVersionBtn_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_version->isVanilla())
|
|
{
|
|
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();
|
|
reloadMinecraftProfile();
|
|
}
|
|
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());
|
|
updateButtons();
|
|
}
|
|
|
|
void VersionPage::on_forgeBtn_clicked()
|
|
{
|
|
VersionSelectDialog vselect(MMC->forgelist().get(), tr("Select Forge version"), this);
|
|
vselect.setExactFilter(BaseVersionList::ParentGameVersionRole, m_inst->currentVersionId());
|
|
vselect.setEmptyString(tr("No Forge versions are currently available for Minecraft ") +
|
|
m_inst->currentVersionId());
|
|
vselect.setEmptyErrorString(tr("Couldn't load or download the Forge version lists!"));
|
|
if (vselect.exec() && vselect.selectedVersion())
|
|
{
|
|
ProgressDialog dialog(this);
|
|
dialog.exec(
|
|
ForgeInstaller().createInstallTask(m_inst, vselect.selectedVersion(), this));
|
|
preselect(m_version->rowCount(QModelIndex())-1);
|
|
}
|
|
}
|
|
|
|
void VersionPage::on_liteloaderBtn_clicked()
|
|
{
|
|
VersionSelectDialog vselect(MMC->liteloaderlist().get(), tr("Select LiteLoader version"),
|
|
this);
|
|
vselect.setExactFilter(BaseVersionList::ParentGameVersionRole, m_inst->currentVersionId());
|
|
vselect.setEmptyString(tr("No LiteLoader versions are currently available for Minecraft ") +
|
|
m_inst->currentVersionId());
|
|
vselect.setEmptyErrorString(tr("Couldn't load or download the LiteLoader version lists!"));
|
|
if (vselect.exec() && vselect.selectedVersion())
|
|
{
|
|
ProgressDialog dialog(this);
|
|
dialog.exec(
|
|
LiteLoaderInstaller().createInstallTask(m_inst, vselect.selectedVersion(), this));
|
|
preselect(m_version->rowCount(QModelIndex())-1);
|
|
}
|
|
}
|
|
|
|
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_version->rowCount(QModelIndex()))
|
|
{
|
|
row = m_version->rowCount(QModelIndex()) - 1;
|
|
}
|
|
if(row < 0)
|
|
{
|
|
return;
|
|
}
|
|
auto model_index = m_version->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_version->versionPatch(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->isEditable());
|
|
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();
|
|
}
|
|
|
|
ProfilePatchPtr VersionPage::current()
|
|
{
|
|
auto row = currentRow();
|
|
if(row < 0)
|
|
{
|
|
return nullptr;
|
|
}
|
|
return m_version->versionPatch(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;
|
|
}
|
|
if(!m_version->customize(version))
|
|
{
|
|
// TODO: some error box here
|
|
}
|
|
updateButtons();
|
|
preselect(currentIdx);
|
|
}
|
|
|
|
void VersionPage::on_editBtn_clicked()
|
|
{
|
|
auto version = current();
|
|
if(!version)
|
|
{
|
|
return;
|
|
}
|
|
auto filename = version->getPatchFilename();
|
|
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_version->revert(version))
|
|
{
|
|
// TODO: some error box here
|
|
}
|
|
updateButtons();
|
|
preselect(currentIdx);
|
|
}
|