Added mod reinstall dialog
Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
parent
7f6027498e
commit
1a0fd5f993
@ -356,4 +356,19 @@ QList<BasePage*> ShaderPackDownloadDialog::getPages()
|
|||||||
return pages;
|
return pages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModDownloadDialog::setModMetadata(std::shared_ptr<Metadata::ModStruct> meta)
|
||||||
|
{
|
||||||
|
switch (meta->provider) {
|
||||||
|
case ModPlatform::ResourceProvider::MODRINTH:
|
||||||
|
selectPage(Modrinth::id());
|
||||||
|
break;
|
||||||
|
case ModPlatform::ResourceProvider::FLAME:
|
||||||
|
selectPage(Flame::id());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_container->hidePageList();
|
||||||
|
m_buttons.hide();
|
||||||
|
auto page = selectedPage();
|
||||||
|
page->openProject(meta->project_id);
|
||||||
|
}
|
||||||
} // namespace ResourceDownload
|
} // namespace ResourceDownload
|
||||||
|
@ -107,6 +107,8 @@ class ModDownloadDialog final : public ResourceDownloadDialog {
|
|||||||
QList<BasePage*> getPages() override;
|
QList<BasePage*> getPages() override;
|
||||||
GetModDependenciesTask::Ptr getModDependenciesTask() override;
|
GetModDependenciesTask::Ptr getModDependenciesTask() override;
|
||||||
|
|
||||||
|
void setModMetadata(std::shared_ptr<Metadata::ModStruct>);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BaseInstance* m_instance;
|
BaseInstance* m_instance;
|
||||||
};
|
};
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#include "ui_ExternalResourcesPage.h"
|
#include "ui_ExternalResourcesPage.h"
|
||||||
|
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
|
#include <QAction>
|
||||||
#include <QEvent>
|
#include <QEvent>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
@ -121,10 +122,16 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr<ModFolderModel>
|
|||||||
ui->actionsToolbar->addAction(ui->actionVisitItemPage);
|
ui->actionsToolbar->addAction(ui->actionVisitItemPage);
|
||||||
connect(ui->actionVisitItemPage, &QAction::triggered, this, &ModFolderPage::visitModPages);
|
connect(ui->actionVisitItemPage, &QAction::triggered, this, &ModFolderPage::visitModPages);
|
||||||
|
|
||||||
|
auto changeVersion = new QAction(tr("Reinstall"));
|
||||||
|
changeVersion->setToolTip(tr("Reinstall mod"));
|
||||||
|
changeVersion->setEnabled(false);
|
||||||
|
ui->actionsToolbar->insertActionAfter(ui->actionVisitItemPage, changeVersion);
|
||||||
|
connect(changeVersion, &QAction::triggered, this, &ModFolderPage::changeModVersion);
|
||||||
|
|
||||||
auto check_allow_update = [this] { return ui->treeView->selectionModel()->hasSelection() || !m_model->empty(); };
|
auto check_allow_update = [this] { return ui->treeView->selectionModel()->hasSelection() || !m_model->empty(); };
|
||||||
|
|
||||||
connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
||||||
[this, check_allow_update, actionRemoveItemMetadata] {
|
[this, check_allow_update, actionRemoveItemMetadata, changeVersion] {
|
||||||
ui->actionUpdateItem->setEnabled(check_allow_update());
|
ui->actionUpdateItem->setEnabled(check_allow_update());
|
||||||
|
|
||||||
auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes();
|
auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes();
|
||||||
@ -134,11 +141,12 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr<ModFolderModel>
|
|||||||
if (selected <= 1) {
|
if (selected <= 1) {
|
||||||
ui->actionVisitItemPage->setText(tr("Visit mod's page"));
|
ui->actionVisitItemPage->setText(tr("Visit mod's page"));
|
||||||
ui->actionVisitItemPage->setToolTip(tr("Go to mod's home page"));
|
ui->actionVisitItemPage->setToolTip(tr("Go to mod's home page"));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ui->actionVisitItemPage->setText(tr("Visit mods' pages"));
|
ui->actionVisitItemPage->setText(tr("Visit mods' pages"));
|
||||||
ui->actionVisitItemPage->setToolTip(tr("Go to the pages of the selected mods"));
|
ui->actionVisitItemPage->setToolTip(tr("Go to the pages of the selected mods"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
changeVersion->setEnabled(mods_list.length() == 1 && mods_list[0]->metadata() != nullptr);
|
||||||
ui->actionVisitItemPage->setEnabled(selected != 0);
|
ui->actionVisitItemPage->setEnabled(selected != 0);
|
||||||
actionRemoveItemMetadata->setEnabled(selected != 0);
|
actionRemoveItemMetadata->setEnabled(selected != 0);
|
||||||
});
|
});
|
||||||
@ -372,3 +380,54 @@ void ModFolderPage::deleteModMetadata()
|
|||||||
|
|
||||||
m_model->deleteModsMetadata(selection);
|
m_model->deleteModsMetadata(selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModFolderPage::changeModVersion()
|
||||||
|
{
|
||||||
|
if (m_instance->typeName() != "Minecraft")
|
||||||
|
return; // this is a null instance or a legacy instance
|
||||||
|
|
||||||
|
auto profile = static_cast<MinecraftInstance*>(m_instance)->getPackProfile();
|
||||||
|
if (!profile->getModLoaders().has_value()) {
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("Please install a mod loader first!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (APPLICATION->settings()->get("ModMetadataDisabled").toBool()) {
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("Mod updates are unavailable when metadata is disabled!"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes();
|
||||||
|
auto mods_list = m_model->selectedMods(selection);
|
||||||
|
if (mods_list.length() != 1 || mods_list[0]->metadata() == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ResourceDownload::ModDownloadDialog mdownload(this, m_model, m_instance);
|
||||||
|
mdownload.setModMetadata((*mods_list.begin())->metadata());
|
||||||
|
if (mdownload.exec()) {
|
||||||
|
auto tasks = new ConcurrentTask(this, "Download Mods", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
|
||||||
|
connect(tasks, &Task::failed, [this, tasks](QString reason) {
|
||||||
|
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
|
||||||
|
tasks->deleteLater();
|
||||||
|
});
|
||||||
|
connect(tasks, &Task::aborted, [this, tasks]() {
|
||||||
|
CustomMessageBox::selectable(this, tr("Aborted"), tr("Download stopped by user."), QMessageBox::Information)->show();
|
||||||
|
tasks->deleteLater();
|
||||||
|
});
|
||||||
|
connect(tasks, &Task::succeeded, [this, tasks]() {
|
||||||
|
QStringList warnings = tasks->warnings();
|
||||||
|
if (warnings.count())
|
||||||
|
CustomMessageBox::selectable(this, tr("Warnings"), warnings.join('\n'), QMessageBox::Warning)->show();
|
||||||
|
|
||||||
|
tasks->deleteLater();
|
||||||
|
});
|
||||||
|
|
||||||
|
for (auto& task : mdownload.getTasks()) {
|
||||||
|
tasks->addTask(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
ProgressDialog loadDialog(this);
|
||||||
|
loadDialog.setSkipButton(true, tr("Abort"));
|
||||||
|
loadDialog.execWithTask(tasks);
|
||||||
|
|
||||||
|
m_model->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -66,6 +66,7 @@ class ModFolderPage : public ExternalResourcesPage {
|
|||||||
void installMods();
|
void installMods();
|
||||||
void updateMods(bool includeDeps = false);
|
void updateMods(bool includeDeps = false);
|
||||||
void visitModPages();
|
void visitModPages();
|
||||||
|
void changeModVersion();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<ModFolderModel> m_model;
|
std::shared_ptr<ModFolderModel> m_model;
|
||||||
|
@ -79,4 +79,14 @@ bool ModModel::isPackInstalled(ModPlatform::IndexedPack::Ptr pack) const
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVariant ModModel:: getInstalledPackVersion(ModPlatform::IndexedPack::Ptr pack) const
|
||||||
|
{
|
||||||
|
auto allMods = static_cast<MinecraftInstance&>(m_base_instance).loaderModList()->allMods();
|
||||||
|
for (auto mod : allMods) {
|
||||||
|
if (auto meta = mod->metadata(); meta && meta->provider == pack->provider && meta->project_id == pack->addonId) {
|
||||||
|
return meta->version();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
} // namespace ResourceDownload
|
} // namespace ResourceDownload
|
||||||
|
@ -35,6 +35,7 @@ class ModModel : public ResourceModel {
|
|||||||
virtual ModPlatform::IndexedVersion loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) = 0;
|
virtual ModPlatform::IndexedVersion loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) = 0;
|
||||||
|
|
||||||
void setFilter(std::shared_ptr<ModFilterWidget::Filter> filter) { m_filter = filter; }
|
void setFilter(std::shared_ptr<ModFilterWidget::Filter> filter) { m_filter = filter; }
|
||||||
|
virtual QVariant getInstalledPackVersion(ModPlatform::IndexedPack::Ptr) const override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
ResourceAPI::SearchArgs createSearchArguments() override;
|
ResourceAPI::SearchArgs createSearchArguments() override;
|
||||||
|
@ -120,6 +120,8 @@ void ModPage::updateVersionList()
|
|||||||
auto current_pack = getCurrentPack();
|
auto current_pack = getCurrentPack();
|
||||||
if (!current_pack)
|
if (!current_pack)
|
||||||
return;
|
return;
|
||||||
|
auto installedVersion = m_model->getInstalledPackVersion(current_pack);
|
||||||
|
auto installedIndex = -1;
|
||||||
for (int i = 0; i < current_pack->versions.size(); i++) {
|
for (int i = 0; i < current_pack->versions.size(); i++) {
|
||||||
auto version = current_pack->versions[i];
|
auto version = current_pack->versions[i];
|
||||||
bool valid = false;
|
bool valid = false;
|
||||||
@ -129,13 +131,19 @@ void ModPage::updateVersionList()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
QString flag;
|
||||||
|
if (installedIndex == -1 && installedVersion.isValid() && installedVersion == version.fileId) {
|
||||||
|
flag = tr("[installed]");
|
||||||
|
installedIndex = i;
|
||||||
|
}
|
||||||
// Only add the version if it's valid or using the 'Any' filter, but never if the version is opted out
|
// Only add the version if it's valid or using the 'Any' filter, but never if the version is opted out
|
||||||
if ((valid || m_filter->versions.empty()) && !optedOut(version)) {
|
if ((valid || m_filter->versions.empty()) && !optedOut(version)) {
|
||||||
auto release_type = version.version_type.isValid() ? QString(" [%1]").arg(version.version_type.toString()) : "";
|
auto release_type = version.version_type.isValid() ? QString(" [%1]").arg(version.version_type.toString()) : "";
|
||||||
m_ui->versionSelectionBox->addItem(QString("%1%2").arg(version.version, release_type), QVariant(i));
|
m_ui->versionSelectionBox->addItem(QString("%1%2%3").arg(version.version, release_type, flag), QVariant(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (installedIndex != -1)
|
||||||
|
m_ui->versionSelectionBox->setCurrentIndex(installedIndex);
|
||||||
if (m_ui->versionSelectionBox->count() == 0) {
|
if (m_ui->versionSelectionBox->count() == 0) {
|
||||||
m_ui->versionSelectionBox->addItem(tr("No valid version found!"), QVariant(-1));
|
m_ui->versionSelectionBox->addItem(tr("No valid version found!"), QVariant(-1));
|
||||||
m_ui->resourceSelectionButton->setText(tr("Cannot select invalid version :("));
|
m_ui->resourceSelectionButton->setText(tr("Cannot select invalid version :("));
|
||||||
|
@ -55,6 +55,8 @@ class ResourceModel : public QAbstractListModel {
|
|||||||
|
|
||||||
[[nodiscard]] auto getSortingMethods() const { return m_api->getSortingMethods(); }
|
[[nodiscard]] auto getSortingMethods() const { return m_api->getSortingMethods(); }
|
||||||
|
|
||||||
|
virtual QVariant getInstalledPackVersion(ModPlatform::IndexedPack::Ptr) const { return {}; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void fetchMore(const QModelIndex& parent) override;
|
void fetchMore(const QModelIndex& parent) override;
|
||||||
// NOTE: Can't use [[nodiscard]] here because of https://bugreports.qt.io/browse/QTBUG-58628 on Qt 5.12
|
// NOTE: Can't use [[nodiscard]] here because of https://bugreports.qt.io/browse/QTBUG-58628 on Qt 5.12
|
||||||
|
@ -260,7 +260,9 @@ void ResourcePage::updateVersionList()
|
|||||||
m_ui->versionSelectionBox->clear();
|
m_ui->versionSelectionBox->clear();
|
||||||
m_ui->versionSelectionBox->blockSignals(false);
|
m_ui->versionSelectionBox->blockSignals(false);
|
||||||
|
|
||||||
if (current_pack)
|
if (current_pack) {
|
||||||
|
auto installedVersion = m_model->getInstalledPackVersion(current_pack);
|
||||||
|
|
||||||
for (int i = 0; i < current_pack->versions.size(); i++) {
|
for (int i = 0; i < current_pack->versions.size(); i++) {
|
||||||
auto& version = current_pack->versions[i];
|
auto& version = current_pack->versions[i];
|
||||||
if (optedOut(version))
|
if (optedOut(version))
|
||||||
@ -269,9 +271,10 @@ void ResourcePage::updateVersionList()
|
|||||||
auto release_type = current_pack->versions[i].version_type.isValid()
|
auto release_type = current_pack->versions[i].version_type.isValid()
|
||||||
? QString(" [%1]").arg(current_pack->versions[i].version_type.toString())
|
? QString(" [%1]").arg(current_pack->versions[i].version_type.toString())
|
||||||
: "";
|
: "";
|
||||||
m_ui->versionSelectionBox->addItem(current_pack->versions[i].version, QVariant(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
m_ui->versionSelectionBox->addItem(QString("%1%2").arg(version.version, release_type), QVariant(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
if (m_ui->versionSelectionBox->count() == 0) {
|
if (m_ui->versionSelectionBox->count() == 0) {
|
||||||
m_ui->versionSelectionBox->addItem(tr("No valid version found."), QVariant(-1));
|
m_ui->versionSelectionBox->addItem(tr("No valid version found."), QVariant(-1));
|
||||||
m_ui->resourceSelectionButton->setText(tr("Cannot select invalid version :("));
|
m_ui->resourceSelectionButton->setText(tr("Cannot select invalid version :("));
|
||||||
@ -388,7 +391,7 @@ void ResourcePage::openUrl(const QUrl& url)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!page.isNull()) {
|
if (!page.isNull() && !m_do_not_jump_to_mod) {
|
||||||
const QString slug = match.captured(1);
|
const QString slug = match.captured(1);
|
||||||
|
|
||||||
// ensure the user isn't opening the same mod
|
// ensure the user isn't opening the same mod
|
||||||
@ -432,4 +435,53 @@ void ResourcePage::openUrl(const QUrl& url)
|
|||||||
QDesktopServices::openUrl(url);
|
QDesktopServices::openUrl(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResourcePage::openProject(QVariant projectID)
|
||||||
|
{
|
||||||
|
m_ui->sortByBox->hide();
|
||||||
|
m_ui->searchButton->hide();
|
||||||
|
m_ui->searchEdit->hide();
|
||||||
|
m_ui->resourceFilterButton->hide();
|
||||||
|
m_ui->packView->hide();
|
||||||
|
m_ui->resourceSelectionButton->hide();
|
||||||
|
m_do_not_jump_to_mod = true;
|
||||||
|
|
||||||
|
auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
|
||||||
|
|
||||||
|
auto okBtn = buttonBox->button(QDialogButtonBox::Ok);
|
||||||
|
okBtn->setDefault(true);
|
||||||
|
okBtn->setAutoDefault(true);
|
||||||
|
okBtn->setText(tr("Reinstall"));
|
||||||
|
okBtn->setShortcut(tr("Ctrl+Return"));
|
||||||
|
okBtn->setEnabled(false);
|
||||||
|
|
||||||
|
auto cancelBtn = buttonBox->button(QDialogButtonBox::Cancel);
|
||||||
|
cancelBtn->setDefault(false);
|
||||||
|
cancelBtn->setAutoDefault(false);
|
||||||
|
|
||||||
|
connect(okBtn, &QPushButton::clicked, this, [this] {
|
||||||
|
onResourceSelected();
|
||||||
|
m_parent_dialog->accept();
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(cancelBtn, &QPushButton::clicked, m_parent_dialog, &ResourceDownloadDialog::reject);
|
||||||
|
m_ui->gridLayout_4->addWidget(buttonBox, 1, 2);
|
||||||
|
|
||||||
|
auto jump = [this, okBtn] {
|
||||||
|
for (int row = 0; row < m_model->rowCount({}); row++) {
|
||||||
|
const QModelIndex index = m_model->index(row);
|
||||||
|
m_ui->packView->setCurrentIndex(index);
|
||||||
|
okBtn->setEnabled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_ui->packDescription->setText(tr("The resource was not found"));
|
||||||
|
};
|
||||||
|
|
||||||
|
m_ui->searchEdit->setText("#" + projectID.toString());
|
||||||
|
triggerSearch();
|
||||||
|
|
||||||
|
if (m_model->hasActiveSearchJob())
|
||||||
|
connect(m_model->activeSearchJob().get(), &Task::finished, jump);
|
||||||
|
else
|
||||||
|
jump();
|
||||||
|
}
|
||||||
} // namespace ResourceDownload
|
} // namespace ResourceDownload
|
||||||
|
@ -83,6 +83,8 @@ class ResourcePage : public QWidget, public BasePage {
|
|||||||
QList<DownloadTaskPtr> selectedPacks() { return m_model->selectedPacks(); }
|
QList<DownloadTaskPtr> selectedPacks() { return m_model->selectedPacks(); }
|
||||||
bool hasSelectedPacks() { return !(m_model->selectedPacks().isEmpty()); }
|
bool hasSelectedPacks() { return !(m_model->selectedPacks().isEmpty()); }
|
||||||
|
|
||||||
|
virtual void openProject(QVariant projectID);
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
virtual void triggerSearch() {}
|
virtual void triggerSearch() {}
|
||||||
|
|
||||||
@ -118,6 +120,8 @@ class ResourcePage : public QWidget, public BasePage {
|
|||||||
|
|
||||||
// Used to do instant searching with a delay to cache quick changes
|
// Used to do instant searching with a delay to cache quick changes
|
||||||
QTimer m_search_timer;
|
QTimer m_search_timer;
|
||||||
|
|
||||||
|
bool m_do_not_jump_to_mod = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ResourceDownload
|
} // namespace ResourceDownload
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <QListView>
|
||||||
#include <QModelIndex>
|
#include <QModelIndex>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
@ -86,6 +87,8 @@ class PageContainer : public QWidget, public BasePageContainer {
|
|||||||
|
|
||||||
void changeEvent(QEvent*) override;
|
void changeEvent(QEvent*) override;
|
||||||
|
|
||||||
|
void hidePageList() { m_pageList->hide(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void createUI();
|
void createUI();
|
||||||
void retranslate();
|
void retranslate();
|
||||||
|
Loading…
Reference in New Issue
Block a user