mirror of
https://github.com/PrismLauncher/PrismLauncher.git
synced 2025-06-13 05:37:42 +02:00
Add update UI for all resource types
Signed-off-by: TheKodeToad <TheKodeToad@proton.me>
This commit is contained in:
@ -316,7 +316,7 @@ void LaunchController::launchInstance()
|
||||
online_mode = "online";
|
||||
|
||||
// Prepend Server Status
|
||||
QStringList servers = { "authserver.mojang.com", "session.minecraft.net", "textures.minecraft.net", "api.mojang.com" };
|
||||
QStringList servers = { "session.minecraft.net", "textures.minecraft.net", "api.mojang.com" };
|
||||
QString resolved_servers = "";
|
||||
QHostInfo host_info;
|
||||
|
||||
|
@ -255,7 +255,7 @@ class ResourceFolderModel : public QAbstractListModel {
|
||||
protected:
|
||||
// Represents the relationship between a column's index (represented by the list index), and it's sorting key.
|
||||
// As such, the order in with they appear is very important!
|
||||
QList<SortType> m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::DATE };
|
||||
QList<SortType> m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::DATE, SortType::PROVIDER };
|
||||
QStringList m_column_names = { "Enable", "Name", "Last Modified", "Provider" };
|
||||
QStringList m_column_names_translated = { tr("Enable"), tr("Name"), tr("Last Modified"), tr("Provider") };
|
||||
QList<QHeaderView::ResizeMode> m_column_resize_modes = { QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::Interactive };
|
||||
|
@ -51,8 +51,9 @@ ResourcePackFolderModel::ResourcePackFolderModel(const QDir& dir, BaseInstance*
|
||||
: ResourceFolderModel(dir, instance, is_indexed, create_dir, parent)
|
||||
{
|
||||
m_column_names = QStringList({ "Enable", "Image", "Name", "Pack Format", "Last Modified", "Provider" });
|
||||
m_column_names_translated = QStringList({ tr("Enable"), tr("Image"), tr("Name"), tr("Pack Format"), tr("Last Modified"), tr("Provider") });
|
||||
m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::PACK_FORMAT, SortType::DATE };
|
||||
m_column_names_translated =
|
||||
QStringList({ tr("Enable"), tr("Image"), tr("Name"), tr("Pack Format"), tr("Last Modified"), tr("Provider") });
|
||||
m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::PACK_FORMAT, SortType::DATE, SortType::PROVIDER };
|
||||
m_column_resize_modes = { QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::Interactive,
|
||||
QHeaderView::Interactive };
|
||||
m_columnsHideable = { false, true, false, true, true, true };
|
||||
|
@ -20,4 +20,6 @@ class ShaderPackFolderModel : public ResourceFolderModel {
|
||||
{
|
||||
return new LocalShaderPackParseTask(m_next_resolution_ticket, static_cast<ShaderPack&>(resource));
|
||||
}
|
||||
|
||||
RESOURCE_HELPERS(ShaderPack);
|
||||
};
|
||||
|
@ -83,7 +83,7 @@ class ResourceAPI {
|
||||
struct VersionSearchArgs {
|
||||
ModPlatform::IndexedPack pack;
|
||||
|
||||
std::optional<std::list<Version> > mcVersions;
|
||||
std::optional<std::list<Version>> mcVersions;
|
||||
std::optional<ModPlatform::ModLoaderTypes> loaders;
|
||||
|
||||
VersionSearchArgs(VersionSearchArgs const&) = default;
|
||||
|
@ -110,11 +110,14 @@ auto V1::createModFormat([[maybe_unused]] const QDir& index_dir,
|
||||
mod.hash = mod_version.hash;
|
||||
|
||||
mod.provider = mod_pack.provider;
|
||||
mod.version_number = mod_version.version_number;
|
||||
mod.file_id = mod_version.fileId;
|
||||
mod.project_id = mod_pack.addonId;
|
||||
mod.side = stringToSide(mod_pack.side);
|
||||
|
||||
mod.version_number = mod_version.version_number;
|
||||
if (mod.version_number.isNull()) // on CurseForge, there is only a version name - not a versio
|
||||
mod.version_number = mod_version.version;
|
||||
|
||||
return mod;
|
||||
}
|
||||
|
||||
@ -164,10 +167,9 @@ void V1::updateModIndex(const QDir& index_dir, Mod& mod)
|
||||
qCritical() << QString("Did not write file %1 because missing information!").arg(normalized_fname);
|
||||
return;
|
||||
}
|
||||
update = toml::table{
|
||||
{ "file-id", mod.file_id.toInt() },
|
||||
{ "project-id", mod.project_id.toInt() },
|
||||
};
|
||||
update = toml::table{ { "file-id", mod.file_id.toInt() },
|
||||
{ "project-id", mod.project_id.toInt() },
|
||||
{ "x-prismlauncher-version-number", mod.version_number.toStdString() } };
|
||||
break;
|
||||
case (ModPlatform::ResourceProvider::MODRINTH):
|
||||
if (mod.mod_id().toString().isEmpty() || mod.version().toString().isEmpty()) {
|
||||
@ -177,6 +179,7 @@ void V1::updateModIndex(const QDir& index_dir, Mod& mod)
|
||||
update = toml::table{
|
||||
{ "mod-id", mod.mod_id().toString().toStdString() },
|
||||
{ "version", mod.version().toString().toStdString() },
|
||||
{ "x-prismlauncher-version-number", mod.version_number.toStdString() },
|
||||
};
|
||||
break;
|
||||
}
|
||||
@ -199,8 +202,7 @@ void V1::updateModIndex(const QDir& index_dir, Mod& mod)
|
||||
{ "hash-format", mod.hash_format.toStdString() },
|
||||
{ "hash", mod.hash.toStdString() },
|
||||
} },
|
||||
{ "update", toml::table{ { ModPlatform::ProviderCapabilities::name(mod.provider), update },
|
||||
{ "x-prismlauncher-version-number", mod.version_number.toStdString() } } } };
|
||||
{ "update", toml::table{ { ModPlatform::ProviderCapabilities::name(mod.provider), update } } } };
|
||||
std::stringstream ss;
|
||||
ss << tbl;
|
||||
in_stream << QString::fromStdString(ss.str());
|
||||
@ -295,23 +297,23 @@ auto V1::getIndexForMod(const QDir& index_dir, QString slug) -> Mod
|
||||
{ // [update] info
|
||||
using Provider = ModPlatform::ResourceProvider;
|
||||
|
||||
auto update_table = table["update"].as_table();
|
||||
if (!update_table) {
|
||||
auto update_table = table["update"];
|
||||
if (!update_table || !update_table.is_table()) {
|
||||
qCritical() << QString("No [update] section found on mod metadata!");
|
||||
return {};
|
||||
}
|
||||
|
||||
mod.version_number = stringEntry(*update_table, "x-prismlauncher-version-number");
|
||||
|
||||
toml::table* mod_provider_table = nullptr;
|
||||
if ((mod_provider_table = (*update_table)[ModPlatform::ProviderCapabilities::name(Provider::FLAME)].as_table())) {
|
||||
if ((mod_provider_table = update_table[ModPlatform::ProviderCapabilities::name(Provider::FLAME)].as_table())) {
|
||||
mod.provider = Provider::FLAME;
|
||||
mod.file_id = intEntry(*mod_provider_table, "file-id");
|
||||
mod.project_id = intEntry(*mod_provider_table, "project-id");
|
||||
} else if ((mod_provider_table = (*update_table)[ModPlatform::ProviderCapabilities::name(Provider::MODRINTH)].as_table())) {
|
||||
mod.version_number = stringEntry(*mod_provider_table, "x-prismlauncher-version-number");
|
||||
} else if ((mod_provider_table = update_table[ModPlatform::ProviderCapabilities::name(Provider::MODRINTH)].as_table())) {
|
||||
mod.provider = Provider::MODRINTH;
|
||||
mod.mod_id() = stringEntry(*mod_provider_table, "mod-id");
|
||||
mod.version() = stringEntry(*mod_provider_table, "version");
|
||||
mod.version_number = stringEntry(*mod_provider_table, "x-prismlauncher-version-number");
|
||||
} else {
|
||||
qCritical() << QString("No mod provider on mod metadata!");
|
||||
return {};
|
||||
|
@ -52,9 +52,9 @@ class V1 {
|
||||
|
||||
// [update]
|
||||
ModPlatform::ResourceProvider provider{};
|
||||
QString version_number{};
|
||||
QVariant file_id{};
|
||||
QVariant project_id{};
|
||||
QString version_number{};
|
||||
|
||||
public:
|
||||
// This is a totally heuristic, but should work for now.
|
||||
|
@ -38,7 +38,8 @@ ResourceUpdateDialog::ResourceUpdateDialog(QWidget* parent,
|
||||
BaseInstance* instance,
|
||||
const std::shared_ptr<ResourceFolderModel> resource_model,
|
||||
QList<Resource*>& search_for,
|
||||
bool includeDeps)
|
||||
bool include_deps,
|
||||
bool filter_loaders)
|
||||
: ReviewMessageBox(parent, tr("Confirm mods to update"), "")
|
||||
, m_parent(parent)
|
||||
, m_resource_model(resource_model)
|
||||
@ -46,7 +47,8 @@ ResourceUpdateDialog::ResourceUpdateDialog(QWidget* parent,
|
||||
, m_second_try_metadata(
|
||||
new ConcurrentTask(nullptr, "Second Metadata Search", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt()))
|
||||
, m_instance(instance)
|
||||
, m_include_deps(includeDeps)
|
||||
, m_include_deps(include_deps)
|
||||
, m_filter_loaders(filter_loaders)
|
||||
{
|
||||
ReviewMessageBox::setGeometry(0, 0, 800, 600);
|
||||
|
||||
@ -85,7 +87,7 @@ void ResourceUpdateDialog::checkCandidates()
|
||||
}
|
||||
|
||||
auto versions = mcVersions(m_instance);
|
||||
auto loaders = mcLoaders(m_instance);
|
||||
auto loaders = m_filter_loaders ? mcLoaders(m_instance) : std::optional<ModPlatform::ModLoaderTypes>();
|
||||
|
||||
SequentialTask check_task(m_parent, tr("Checking for updates"));
|
||||
|
||||
@ -224,10 +226,10 @@ void ResourceUpdateDialog::checkCandidates()
|
||||
if (dep->pack->provider == ModPlatform::ResourceProvider::FLAME)
|
||||
changelog = api.getModFileChangelog(dep->version.addonId.toInt(), dep->version.fileId.toInt());
|
||||
auto download_task = makeShared<ResourceDownloadTask>(dep->pack, dep->version, m_resource_model);
|
||||
CheckUpdateTask::Update updatable = {
|
||||
dep->pack->name, dep->version.hash, tr("Not installed"), dep->version.version, dep->version.version_type,
|
||||
changelog, dep->pack->provider, download_task
|
||||
};
|
||||
CheckUpdateTask::Update updatable = { dep->pack->name, dep->version.hash,
|
||||
tr("Not installed"), dep->version.version,
|
||||
dep->version.version_type, changelog,
|
||||
dep->pack->provider, download_task };
|
||||
|
||||
appendResource(updatable, getRequiredBy.value(dep->version.addonId.toString()));
|
||||
m_tasks.insert(updatable.name, updatable.download);
|
||||
|
@ -20,7 +20,8 @@ class ResourceUpdateDialog final : public ReviewMessageBox {
|
||||
BaseInstance* instance,
|
||||
std::shared_ptr<ResourceFolderModel> resource_model,
|
||||
QList<Resource*>& search_for,
|
||||
bool includeDeps);
|
||||
bool include_deps,
|
||||
bool filter_loaders);
|
||||
|
||||
void checkCandidates();
|
||||
|
||||
@ -63,4 +64,5 @@ class ResourceUpdateDialog final : public ReviewMessageBox {
|
||||
bool m_no_updates = false;
|
||||
bool m_aborted = false;
|
||||
bool m_include_deps = false;
|
||||
bool m_filter_loaders = false;
|
||||
};
|
||||
|
@ -70,15 +70,15 @@
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="WideBar" name="actionsToolbar">
|
||||
<property name="useDefaultAction" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Actions</string>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonTextOnly</enum>
|
||||
</property>
|
||||
<property name="useDefaultAction" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="toolBarArea">
|
||||
<enum>RightToolBarArea</enum>
|
||||
</attribute>
|
||||
@ -95,10 +95,10 @@
|
||||
</widget>
|
||||
<action name="actionAddItem">
|
||||
<property name="text">
|
||||
<string>&Add</string>
|
||||
<string>&Add File</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Add</string>
|
||||
<string>Add a locally downloaded file.</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRemoveItem">
|
||||
@ -106,7 +106,7 @@
|
||||
<string>&Remove</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Remove selected item</string>
|
||||
<string>Remove all selected items.</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEnableItem">
|
||||
@ -114,7 +114,7 @@
|
||||
<string>&Enable</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Enable selected item</string>
|
||||
<string>Enable all selected items.</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionDisableItem">
|
||||
@ -122,7 +122,7 @@
|
||||
<string>&Disable</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Disable selected item</string>
|
||||
<string>Disable all selected items.</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionViewConfigs">
|
||||
@ -137,6 +137,9 @@
|
||||
<property name="text">
|
||||
<string>View &Folder</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Open the folder in the system file manager.</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionDownloadItem">
|
||||
<property name="enabled">
|
||||
@ -146,18 +149,7 @@
|
||||
<string>&Download</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Download a new resource</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionVisitItemPage">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Visit mod's page</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Go to mods home page</string>
|
||||
<string>Download resources from online mod platforms.</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionUpdateItem">
|
||||
@ -168,7 +160,23 @@
|
||||
<string>Check for &Updates</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Try to check or update all selected resources (all resources if none are selected)</string>
|
||||
<string>Try to check or update all selected resources (all resources if none are selected).</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionResetItemMetadata">
|
||||
<property name="text">
|
||||
<string>Reset Update Metadata</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::NoRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionVerifyItemDependencies">
|
||||
<property name="text">
|
||||
<string>Verify Dependencies</string>
|
||||
</property>
|
||||
<property name="menuRole">
|
||||
<enum>QAction::NoRole</enum>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
|
@ -68,88 +68,37 @@
|
||||
#include "tasks/ConcurrentTask.h"
|
||||
#include "ui/dialogs/ProgressDialog.h"
|
||||
|
||||
ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr<ModFolderModel> mods, QWidget* parent)
|
||||
: ExternalResourcesPage(inst, mods, parent), m_model(mods)
|
||||
ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr<ModFolderModel> model, QWidget* parent)
|
||||
: ExternalResourcesPage(inst, model, parent), m_model(model)
|
||||
{
|
||||
// This is structured like that so that these changes
|
||||
// do not affect the Resource pack and Shader pack tabs
|
||||
{
|
||||
ui->actionDownloadItem->setText(tr("Download mods"));
|
||||
ui->actionDownloadItem->setToolTip(tr("Download mods from online mod platforms"));
|
||||
ui->actionDownloadItem->setEnabled(true);
|
||||
ui->actionAddItem->setText(tr("Add file"));
|
||||
ui->actionAddItem->setToolTip(tr("Add a locally downloaded file"));
|
||||
ui->actionDownloadItem->setText(tr("Download Mods"));
|
||||
ui->actionDownloadItem->setToolTip(tr("Download mods from online mod platforms"));
|
||||
ui->actionDownloadItem->setEnabled(true);
|
||||
ui->actionsToolbar->insertActionBefore(ui->actionAddItem, ui->actionDownloadItem);
|
||||
|
||||
ui->actionsToolbar->insertActionBefore(ui->actionAddItem, ui->actionDownloadItem);
|
||||
connect(ui->actionDownloadItem, &QAction::triggered, this, &ModFolderPage::downloadMods);
|
||||
|
||||
connect(ui->actionDownloadItem, &QAction::triggered, this, &ModFolderPage::installMods);
|
||||
ui->actionUpdateItem->setToolTip(tr("Try to check or update all selected mods (all mods if none are selected)"));
|
||||
connect(ui->actionUpdateItem, &QAction::triggered, this, &ModFolderPage::updateMods);
|
||||
ui->actionsToolbar->insertActionBefore(ui->actionAddItem, ui->actionUpdateItem);
|
||||
|
||||
// update menu
|
||||
auto updateMenu = ui->actionUpdateItem->menu();
|
||||
if (updateMenu) {
|
||||
updateMenu->clear();
|
||||
} else {
|
||||
updateMenu = new QMenu(this);
|
||||
}
|
||||
auto updateMenu = new QMenu(this);
|
||||
|
||||
auto update = updateMenu->addAction(tr("Check for Updates"));
|
||||
update->setToolTip(tr("Try to check or update all selected mods (all mods if none are selected)"));
|
||||
connect(update, &QAction::triggered, this, &ModFolderPage::updateMods);
|
||||
auto update = updateMenu->addAction(tr("Check for Updates"));
|
||||
connect(update, &QAction::triggered, this, &ModFolderPage::updateMods);
|
||||
|
||||
auto updateWithDeps = updateMenu->addAction(tr("Verify Dependencies"));
|
||||
updateWithDeps->setToolTip(
|
||||
tr("Try to update and check for missing dependencies all selected mods (all mods if none are selected)"));
|
||||
connect(updateWithDeps, &QAction::triggered, this, [this] { updateMods(true); });
|
||||
updateMenu->addAction(ui->actionVerifyItemDependencies);
|
||||
connect(ui->actionVerifyItemDependencies, &QAction::triggered, this, [this] { updateMods(true); });
|
||||
|
||||
auto depsDisabled = APPLICATION->settings()->getSetting("ModDependenciesDisabled");
|
||||
updateWithDeps->setVisible(!depsDisabled->get().toBool());
|
||||
connect(depsDisabled.get(), &Setting::SettingChanged, this,
|
||||
[updateWithDeps](const Setting& setting, QVariant value) { updateWithDeps->setVisible(!value.toBool()); });
|
||||
auto depsDisabled = APPLICATION->settings()->getSetting("ModDependenciesDisabled");
|
||||
ui->actionVerifyItemDependencies->setVisible(!depsDisabled->get().toBool());
|
||||
connect(depsDisabled.get(), &Setting::SettingChanged, this,
|
||||
[this](const Setting& setting, const QVariant& value) { ui->actionVerifyItemDependencies->setVisible(!value.toBool()); });
|
||||
|
||||
auto actionRemoveItemMetadata = updateMenu->addAction(tr("Reset update metadata"));
|
||||
actionRemoveItemMetadata->setToolTip(tr("Remove mod's metadata"));
|
||||
connect(actionRemoveItemMetadata, &QAction::triggered, this, &ModFolderPage::deleteModMetadata);
|
||||
actionRemoveItemMetadata->setEnabled(false);
|
||||
updateMenu->addAction(ui->actionResetItemMetadata);
|
||||
connect(ui->actionResetItemMetadata, &QAction::triggered, this, &ModFolderPage::deleteModMetadata);
|
||||
|
||||
ui->actionUpdateItem->setMenu(updateMenu);
|
||||
|
||||
ui->actionUpdateItem->setToolTip(tr("Try to check or update all selected mods (all mods if none are selected)"));
|
||||
connect(ui->actionUpdateItem, &QAction::triggered, this, &ModFolderPage::updateMods);
|
||||
ui->actionsToolbar->insertActionBefore(ui->actionAddItem, ui->actionUpdateItem);
|
||||
|
||||
ui->actionVisitItemPage->setToolTip(tr("Go to mod's home page"));
|
||||
ui->actionsToolbar->addAction(ui->actionVisitItemPage);
|
||||
connect(ui->actionVisitItemPage, &QAction::triggered, this, &ModFolderPage::visitModPages);
|
||||
|
||||
auto check_allow_update = [this] { return ui->treeView->selectionModel()->hasSelection() || !m_model->empty(); };
|
||||
|
||||
connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
||||
[this, check_allow_update, actionRemoveItemMetadata] {
|
||||
ui->actionUpdateItem->setEnabled(check_allow_update());
|
||||
|
||||
auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes();
|
||||
auto mods_list = m_model->selectedMods(selection);
|
||||
auto selected = std::count_if(mods_list.cbegin(), mods_list.cend(),
|
||||
[](Mod* v) { return v->metadata() != nullptr || v->homeurl().size() != 0; });
|
||||
if (selected <= 1) {
|
||||
ui->actionVisitItemPage->setText(tr("Visit mod's page"));
|
||||
ui->actionVisitItemPage->setToolTip(tr("Go to mod's home page"));
|
||||
|
||||
} else {
|
||||
ui->actionVisitItemPage->setText(tr("Visit mods' pages"));
|
||||
ui->actionVisitItemPage->setToolTip(tr("Go to the pages of the selected mods"));
|
||||
}
|
||||
ui->actionVisitItemPage->setEnabled(selected != 0);
|
||||
actionRemoveItemMetadata->setEnabled(selected != 0);
|
||||
});
|
||||
|
||||
auto updateButtons = [this, check_allow_update] { ui->actionUpdateItem->setEnabled(check_allow_update()); };
|
||||
connect(mods.get(), &ModFolderModel::rowsInserted, this, updateButtons);
|
||||
|
||||
connect(mods.get(), &ModFolderModel::rowsRemoved, this, updateButtons);
|
||||
|
||||
connect(mods.get(), &ModFolderModel::updateFinished, this, updateButtons);
|
||||
}
|
||||
ui->actionUpdateItem->setMenu(updateMenu);
|
||||
}
|
||||
|
||||
bool ModFolderPage::shouldDisplay() const
|
||||
@ -182,7 +131,7 @@ void ModFolderPage::removeItems(const QItemSelection& selection)
|
||||
m_model->deleteResources(selection.indexes());
|
||||
}
|
||||
|
||||
void ModFolderPage::installMods()
|
||||
void ModFolderPage::downloadMods()
|
||||
{
|
||||
if (m_instance->typeName() != "Minecraft")
|
||||
return; // this is a null instance or a legacy instance
|
||||
@ -195,7 +144,7 @@ void ModFolderPage::installMods()
|
||||
|
||||
ResourceDownload::ModDownloadDialog mdownload(this, m_model, m_instance);
|
||||
if (mdownload.exec()) {
|
||||
auto tasks = new ConcurrentTask(this, "Download Mods", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
|
||||
auto tasks = new ConcurrentTask(this, tr("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();
|
||||
@ -257,7 +206,7 @@ void ModFolderPage::updateMods(bool includeDeps)
|
||||
if (use_all)
|
||||
mods_list = m_model->allResources();
|
||||
|
||||
ResourceUpdateDialog update_dialog(this, m_instance, m_model, mods_list, includeDeps);
|
||||
ResourceUpdateDialog update_dialog(this, m_instance, m_model, mods_list, includeDeps, true);
|
||||
update_dialog.checkCandidates();
|
||||
|
||||
if (update_dialog.aborted()) {
|
||||
@ -307,6 +256,27 @@ void ModFolderPage::updateMods(bool includeDeps)
|
||||
}
|
||||
}
|
||||
|
||||
void ModFolderPage::deleteModMetadata()
|
||||
{
|
||||
auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes();
|
||||
auto selectionCount = m_model->selectedMods(selection).length();
|
||||
if (selectionCount == 0)
|
||||
return;
|
||||
if (selectionCount > 1) {
|
||||
auto response = CustomMessageBox::selectable(this, tr("Confirm Removal"),
|
||||
tr("You are about to remove the metadata for %1 mods.\n"
|
||||
"Are you sure?")
|
||||
.arg(selectionCount),
|
||||
QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
|
||||
->exec();
|
||||
|
||||
if (response != QMessageBox::Yes)
|
||||
return;
|
||||
}
|
||||
|
||||
m_model->deleteMetadata(selection);
|
||||
}
|
||||
|
||||
CoreModFolderPage::CoreModFolderPage(BaseInstance* inst, std::shared_ptr<ModFolderModel> mods, QWidget* parent)
|
||||
: ModFolderPage(inst, mods, parent)
|
||||
{}
|
||||
@ -340,34 +310,3 @@ bool NilModFolderPage::shouldDisplay() const
|
||||
{
|
||||
return m_model->dir().exists();
|
||||
}
|
||||
|
||||
void ModFolderPage::visitModPages()
|
||||
{
|
||||
auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes();
|
||||
for (auto mod : m_model->selectedMods(selection)) {
|
||||
auto url = mod->metaurl();
|
||||
if (!url.isEmpty())
|
||||
DesktopServices::openUrl(url);
|
||||
}
|
||||
}
|
||||
|
||||
void ModFolderPage::deleteModMetadata()
|
||||
{
|
||||
auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes();
|
||||
auto selectionCount = m_model->selectedMods(selection).length();
|
||||
if (selectionCount == 0)
|
||||
return;
|
||||
if (selectionCount > 1) {
|
||||
auto response = CustomMessageBox::selectable(this, tr("Confirm Removal"),
|
||||
tr("You are about to remove the metadata for %1 mods.\n"
|
||||
"Are you sure?")
|
||||
.arg(selectionCount),
|
||||
QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
|
||||
->exec();
|
||||
|
||||
if (response != QMessageBox::Yes)
|
||||
return;
|
||||
}
|
||||
|
||||
m_model->deleteMetadata(selection);
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ class ModFolderPage : public ExternalResourcesPage {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ModFolderPage(BaseInstance* inst, std::shared_ptr<ModFolderModel> mods, QWidget* parent = nullptr);
|
||||
explicit ModFolderPage(BaseInstance* inst, std::shared_ptr<ModFolderModel> model, QWidget* parent = nullptr);
|
||||
virtual ~ModFolderPage() = default;
|
||||
|
||||
void setFilter(const QString& filter) { m_fileSelectionFilter = filter; }
|
||||
@ -61,11 +61,10 @@ class ModFolderPage : public ExternalResourcesPage {
|
||||
|
||||
private slots:
|
||||
void removeItems(const QItemSelection& selection) override;
|
||||
void deleteModMetadata();
|
||||
|
||||
void installMods();
|
||||
void downloadMods();
|
||||
void updateMods(bool includeDeps = false);
|
||||
void visitModPages();
|
||||
void deleteModMetadata();
|
||||
|
||||
protected:
|
||||
std::shared_ptr<ModFolderModel> m_model;
|
||||
|
@ -42,17 +42,31 @@
|
||||
#include "ui/dialogs/CustomMessageBox.h"
|
||||
#include "ui/dialogs/ProgressDialog.h"
|
||||
#include "ui/dialogs/ResourceDownloadDialog.h"
|
||||
#include "ui/dialogs/ResourceUpdateDialog.h"
|
||||
|
||||
ResourcePackPage::ResourcePackPage(MinecraftInstance* instance, std::shared_ptr<ResourcePackFolderModel> model, QWidget* parent)
|
||||
: ExternalResourcesPage(instance, model, parent)
|
||||
: ExternalResourcesPage(instance, model, parent), m_model(model)
|
||||
{
|
||||
ui->actionDownloadItem->setText(tr("Download packs"));
|
||||
ui->actionDownloadItem->setToolTip(tr("Download resource packs from online platforms"));
|
||||
ui->actionDownloadItem->setText(tr("Download Packs"));
|
||||
ui->actionDownloadItem->setToolTip(tr("Download resource packs from online mod platforms"));
|
||||
ui->actionDownloadItem->setEnabled(true);
|
||||
connect(ui->actionDownloadItem, &QAction::triggered, this, &ResourcePackPage::downloadRPs);
|
||||
ui->actionsToolbar->insertActionBefore(ui->actionAddItem, ui->actionDownloadItem);
|
||||
|
||||
ui->actionViewConfigs->setVisible(false);
|
||||
connect(ui->actionDownloadItem, &QAction::triggered, this, &ResourcePackPage::downloadResourcePacks);
|
||||
|
||||
ui->actionUpdateItem->setToolTip(tr("Try to check or update all selected resource packs (all resource packs if none are selected)"));
|
||||
connect(ui->actionUpdateItem, &QAction::triggered, this, &ResourcePackPage::updateResourcePacks);
|
||||
ui->actionsToolbar->insertActionBefore(ui->actionAddItem, ui->actionUpdateItem);
|
||||
|
||||
auto updateMenu = new QMenu(this);
|
||||
|
||||
auto update = updateMenu->addAction(ui->actionUpdateItem->text());
|
||||
connect(update, &QAction::triggered, this, &ResourcePackPage::updateResourcePacks);
|
||||
|
||||
updateMenu->addAction(ui->actionResetItemMetadata);
|
||||
connect(ui->actionResetItemMetadata, &QAction::triggered, this, &ResourcePackPage::deleteResourcePackMetadata);
|
||||
|
||||
ui->actionUpdateItem->setMenu(updateMenu);
|
||||
}
|
||||
|
||||
bool ResourcePackPage::onSelectionChanged(const QModelIndex& current, [[maybe_unused]] const QModelIndex& previous)
|
||||
@ -65,12 +79,12 @@ bool ResourcePackPage::onSelectionChanged(const QModelIndex& current, [[maybe_un
|
||||
return true;
|
||||
}
|
||||
|
||||
void ResourcePackPage::downloadRPs()
|
||||
void ResourcePackPage::downloadResourcePacks()
|
||||
{
|
||||
if (m_instance->typeName() != "Minecraft")
|
||||
return; // this is a null instance or a legacy instance
|
||||
|
||||
ResourceDownload::ResourcePackDownloadDialog mdownload(this, std::static_pointer_cast<ResourcePackFolderModel>(m_model), m_instance);
|
||||
ResourceDownload::ResourcePackDownloadDialog mdownload(this, m_model, m_instance);
|
||||
if (mdownload.exec()) {
|
||||
auto tasks =
|
||||
new ConcurrentTask(this, "Download Resource Pack", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
|
||||
@ -101,3 +115,103 @@ void ResourcePackPage::downloadRPs()
|
||||
m_model->update();
|
||||
}
|
||||
}
|
||||
|
||||
void ResourcePackPage::updateResourcePacks()
|
||||
{
|
||||
if (m_instance->typeName() != "Minecraft")
|
||||
return; // this is a null instance or a legacy instance
|
||||
|
||||
auto profile = static_cast<MinecraftInstance*>(m_instance)->getPackProfile();
|
||||
if (APPLICATION->settings()->get("ModMetadataDisabled").toBool()) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Resource pack updates are unavailable when metadata is disabled!"));
|
||||
return;
|
||||
}
|
||||
if (m_instance != nullptr && m_instance->isRunning()) {
|
||||
auto response =
|
||||
CustomMessageBox::selectable(this, tr("Confirm Update"),
|
||||
tr("Updating resource packs while the game is running may cause pack duplication and game crashes.\n"
|
||||
"The old files may not be deleted as they are in use.\n"
|
||||
"Are you sure you want to do this?"),
|
||||
QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
|
||||
->exec();
|
||||
|
||||
if (response != QMessageBox::Yes)
|
||||
return;
|
||||
}
|
||||
auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes();
|
||||
|
||||
auto mods_list = m_model->selectedResources(selection);
|
||||
bool use_all = mods_list.empty();
|
||||
if (use_all)
|
||||
mods_list = m_model->allResources();
|
||||
|
||||
ResourceUpdateDialog update_dialog(this, m_instance, m_model, mods_list, false, false);
|
||||
update_dialog.checkCandidates();
|
||||
|
||||
if (update_dialog.aborted()) {
|
||||
CustomMessageBox::selectable(this, tr("Aborted"), tr("The resource pack updater was aborted!"), QMessageBox::Warning)->show();
|
||||
return;
|
||||
}
|
||||
if (update_dialog.noUpdates()) {
|
||||
QString message{ tr("'%1' is up-to-date! :)").arg(mods_list.front()->name()) };
|
||||
if (mods_list.size() > 1) {
|
||||
if (use_all) {
|
||||
message = tr("All resource packs are up-to-date! :)");
|
||||
} else {
|
||||
message = tr("All selected resource packs are up-to-date! :)");
|
||||
}
|
||||
}
|
||||
CustomMessageBox::selectable(this, tr("Update checker"), message)->exec();
|
||||
return;
|
||||
}
|
||||
|
||||
if (update_dialog.exec()) {
|
||||
auto tasks = new ConcurrentTask(this, "Download Resource Packs", 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 : update_dialog.getTasks()) {
|
||||
tasks->addTask(task);
|
||||
}
|
||||
|
||||
ProgressDialog loadDialog(this);
|
||||
loadDialog.setSkipButton(true, tr("Abort"));
|
||||
loadDialog.execWithTask(tasks);
|
||||
|
||||
m_model->update();
|
||||
}
|
||||
}
|
||||
|
||||
void ResourcePackPage::deleteResourcePackMetadata()
|
||||
{
|
||||
auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes();
|
||||
auto selectionCount = m_model->selectedResourcePacks(selection).length();
|
||||
if (selectionCount == 0)
|
||||
return;
|
||||
if (selectionCount > 1) {
|
||||
auto response = CustomMessageBox::selectable(this, tr("Confirm Removal"),
|
||||
tr("You are about to remove the metadata for %1 resource packs.\n"
|
||||
"Are you sure?")
|
||||
.arg(selectionCount),
|
||||
QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
|
||||
->exec();
|
||||
|
||||
if (response != QMessageBox::Yes)
|
||||
return;
|
||||
}
|
||||
|
||||
m_model->deleteMetadata(selection);
|
||||
}
|
||||
|
@ -59,5 +59,12 @@ class ResourcePackPage : public ExternalResourcesPage {
|
||||
|
||||
public slots:
|
||||
bool onSelectionChanged(const QModelIndex& current, const QModelIndex& previous) override;
|
||||
void downloadRPs();
|
||||
|
||||
private slots:
|
||||
void downloadResourcePacks();
|
||||
void updateResourcePacks();
|
||||
void deleteResourcePackMetadata();
|
||||
|
||||
protected:
|
||||
std::shared_ptr<ResourcePackFolderModel> m_model;
|
||||
};
|
||||
|
@ -45,27 +45,41 @@
|
||||
#include "ui/dialogs/CustomMessageBox.h"
|
||||
#include "ui/dialogs/ProgressDialog.h"
|
||||
#include "ui/dialogs/ResourceDownloadDialog.h"
|
||||
#include "ui/dialogs/ResourceUpdateDialog.h"
|
||||
|
||||
ShaderPackPage::ShaderPackPage(MinecraftInstance* instance, std::shared_ptr<ShaderPackFolderModel> model, QWidget* parent)
|
||||
: ExternalResourcesPage(instance, model, parent)
|
||||
: ExternalResourcesPage(instance, model, parent), m_model(model)
|
||||
{
|
||||
ui->actionDownloadItem->setText(tr("Download shaders"));
|
||||
ui->actionDownloadItem->setToolTip(tr("Download shaders from online platforms"));
|
||||
ui->actionDownloadItem->setText(tr("Download Packs"));
|
||||
ui->actionDownloadItem->setToolTip(tr("Download shader packs from online mod platforms"));
|
||||
ui->actionDownloadItem->setEnabled(true);
|
||||
connect(ui->actionDownloadItem, &QAction::triggered, this, &ShaderPackPage::downloadShaders);
|
||||
ui->actionsToolbar->insertActionBefore(ui->actionAddItem, ui->actionDownloadItem);
|
||||
|
||||
ui->actionViewConfigs->setVisible(false);
|
||||
connect(ui->actionDownloadItem, &QAction::triggered, this, &ShaderPackPage::downloadShaderPack);
|
||||
|
||||
ui->actionUpdateItem->setToolTip(tr("Try to check or update all selected shader packs (all shader packs if none are selected)"));
|
||||
connect(ui->actionUpdateItem, &QAction::triggered, this, &ShaderPackPage::updateShaderPacks);
|
||||
ui->actionsToolbar->insertActionBefore(ui->actionAddItem, ui->actionUpdateItem);
|
||||
|
||||
auto updateMenu = new QMenu(this);
|
||||
|
||||
auto update = updateMenu->addAction(ui->actionUpdateItem->text());
|
||||
connect(update, &QAction::triggered, this, &ShaderPackPage::updateShaderPacks);
|
||||
|
||||
updateMenu->addAction(ui->actionResetItemMetadata);
|
||||
connect(ui->actionResetItemMetadata, &QAction::triggered, this, &ShaderPackPage::deleteShaderPackMetadata);
|
||||
|
||||
ui->actionUpdateItem->setMenu(updateMenu);
|
||||
}
|
||||
|
||||
void ShaderPackPage::downloadShaders()
|
||||
void ShaderPackPage::downloadShaderPack()
|
||||
{
|
||||
if (m_instance->typeName() != "Minecraft")
|
||||
return; // this is a null instance or a legacy instance
|
||||
|
||||
ResourceDownload::ShaderPackDownloadDialog mdownload(this, std::static_pointer_cast<ShaderPackFolderModel>(m_model), m_instance);
|
||||
ResourceDownload::ShaderPackDownloadDialog mdownload(this, m_model, m_instance);
|
||||
if (mdownload.exec()) {
|
||||
auto tasks = new ConcurrentTask(this, "Download Shaders", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
|
||||
auto tasks = new ConcurrentTask(this, "Download Shader Packs", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
|
||||
connect(tasks, &Task::failed, [this, tasks](QString reason) {
|
||||
CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show();
|
||||
tasks->deleteLater();
|
||||
@ -93,3 +107,103 @@ void ShaderPackPage::downloadShaders()
|
||||
m_model->update();
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderPackPage::updateShaderPacks()
|
||||
{
|
||||
if (m_instance->typeName() != "Minecraft")
|
||||
return; // this is a null instance or a legacy instance
|
||||
|
||||
auto profile = static_cast<MinecraftInstance*>(m_instance)->getPackProfile();
|
||||
if (APPLICATION->settings()->get("ModMetadataDisabled").toBool()) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Shader pack updates are unavailable when metadata is disabled!"));
|
||||
return;
|
||||
}
|
||||
if (m_instance != nullptr && m_instance->isRunning()) {
|
||||
auto response =
|
||||
CustomMessageBox::selectable(this, tr("Confirm Update"),
|
||||
tr("Updating shader packs while the game is running may pack duplication and game crashes.\n"
|
||||
"The old files may not be deleted as they are in use.\n"
|
||||
"Are you sure you want to do this?"),
|
||||
QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
|
||||
->exec();
|
||||
|
||||
if (response != QMessageBox::Yes)
|
||||
return;
|
||||
}
|
||||
auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes();
|
||||
|
||||
auto mods_list = m_model->selectedResources(selection);
|
||||
bool use_all = mods_list.empty();
|
||||
if (use_all)
|
||||
mods_list = m_model->allResources();
|
||||
|
||||
ResourceUpdateDialog update_dialog(this, m_instance, m_model, mods_list, false, false);
|
||||
update_dialog.checkCandidates();
|
||||
|
||||
if (update_dialog.aborted()) {
|
||||
CustomMessageBox::selectable(this, tr("Aborted"), tr("The shader pack updater was aborted!"), QMessageBox::Warning)->show();
|
||||
return;
|
||||
}
|
||||
if (update_dialog.noUpdates()) {
|
||||
QString message{ tr("'%1' is up-to-date! :)").arg(mods_list.front()->name()) };
|
||||
if (mods_list.size() > 1) {
|
||||
if (use_all) {
|
||||
message = tr("All shader packs are up-to-date! :)");
|
||||
} else {
|
||||
message = tr("All selected shader packs are up-to-date! :)");
|
||||
}
|
||||
}
|
||||
CustomMessageBox::selectable(this, tr("Update checker"), message)->exec();
|
||||
return;
|
||||
}
|
||||
|
||||
if (update_dialog.exec()) {
|
||||
auto tasks = new ConcurrentTask(this, "Download Shader Packs", 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 : update_dialog.getTasks()) {
|
||||
tasks->addTask(task);
|
||||
}
|
||||
|
||||
ProgressDialog loadDialog(this);
|
||||
loadDialog.setSkipButton(true, tr("Abort"));
|
||||
loadDialog.execWithTask(tasks);
|
||||
|
||||
m_model->update();
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderPackPage::deleteShaderPackMetadata()
|
||||
{
|
||||
auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes();
|
||||
auto selectionCount = m_model->selectedShaderPacks(selection).length();
|
||||
if (selectionCount == 0)
|
||||
return;
|
||||
if (selectionCount > 1) {
|
||||
auto response = CustomMessageBox::selectable(this, tr("Confirm Removal"),
|
||||
tr("You are about to remove the metadata for %1 shader packs.\n"
|
||||
"Are you sure?")
|
||||
.arg(selectionCount),
|
||||
QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
|
||||
->exec();
|
||||
|
||||
if (response != QMessageBox::Yes)
|
||||
return;
|
||||
}
|
||||
|
||||
m_model->deleteMetadata(selection);
|
||||
}
|
||||
|
@ -53,5 +53,10 @@ class ShaderPackPage : public ExternalResourcesPage {
|
||||
bool shouldDisplay() const override { return true; }
|
||||
|
||||
public slots:
|
||||
void downloadShaders();
|
||||
void downloadShaderPack();
|
||||
void updateShaderPacks();
|
||||
void deleteShaderPackMetadata();
|
||||
|
||||
private:
|
||||
std::shared_ptr<ShaderPackFolderModel> m_model;
|
||||
};
|
||||
|
@ -44,17 +44,31 @@
|
||||
#include "ui/dialogs/CustomMessageBox.h"
|
||||
#include "ui/dialogs/ProgressDialog.h"
|
||||
#include "ui/dialogs/ResourceDownloadDialog.h"
|
||||
#include "ui/dialogs/ResourceUpdateDialog.h"
|
||||
|
||||
TexturePackPage::TexturePackPage(MinecraftInstance* instance, std::shared_ptr<TexturePackFolderModel> model, QWidget* parent)
|
||||
: ExternalResourcesPage(instance, model, parent)
|
||||
: ExternalResourcesPage(instance, model, parent), m_model(model)
|
||||
{
|
||||
ui->actionDownloadItem->setText(tr("Download packs"));
|
||||
ui->actionDownloadItem->setToolTip(tr("Download texture packs from online platforms"));
|
||||
ui->actionDownloadItem->setText(tr("Download Packs"));
|
||||
ui->actionDownloadItem->setToolTip(tr("Download texture packs from online mod platforms"));
|
||||
ui->actionDownloadItem->setEnabled(true);
|
||||
connect(ui->actionDownloadItem, &QAction::triggered, this, &TexturePackPage::downloadTPs);
|
||||
ui->actionsToolbar->insertActionBefore(ui->actionAddItem, ui->actionDownloadItem);
|
||||
|
||||
ui->actionViewConfigs->setVisible(false);
|
||||
connect(ui->actionDownloadItem, &QAction::triggered, this, &TexturePackPage::downloadTexturePacks);
|
||||
|
||||
ui->actionUpdateItem->setToolTip(tr("Try to check or update all selected texture packs (all texture packs if none are selected)"));
|
||||
connect(ui->actionUpdateItem, &QAction::triggered, this, &TexturePackPage::updateTexturePacks);
|
||||
ui->actionsToolbar->insertActionBefore(ui->actionAddItem, ui->actionUpdateItem);
|
||||
|
||||
auto updateMenu = new QMenu(this);
|
||||
|
||||
auto update = updateMenu->addAction(ui->actionUpdateItem->text());
|
||||
connect(update, &QAction::triggered, this, &TexturePackPage::updateTexturePacks);
|
||||
|
||||
updateMenu->addAction(ui->actionResetItemMetadata);
|
||||
connect(ui->actionResetItemMetadata, &QAction::triggered, this, &TexturePackPage::deleteTexturePackMetadata);
|
||||
|
||||
ui->actionUpdateItem->setMenu(updateMenu);
|
||||
}
|
||||
|
||||
bool TexturePackPage::onSelectionChanged(const QModelIndex& current, [[maybe_unused]] const QModelIndex& previous)
|
||||
@ -67,12 +81,12 @@ bool TexturePackPage::onSelectionChanged(const QModelIndex& current, [[maybe_unu
|
||||
return true;
|
||||
}
|
||||
|
||||
void TexturePackPage::downloadTPs()
|
||||
void TexturePackPage::downloadTexturePacks()
|
||||
{
|
||||
if (m_instance->typeName() != "Minecraft")
|
||||
return; // this is a null instance or a legacy instance
|
||||
|
||||
ResourceDownload::TexturePackDownloadDialog mdownload(this, std::static_pointer_cast<TexturePackFolderModel>(m_model), m_instance);
|
||||
ResourceDownload::TexturePackDownloadDialog mdownload(this, m_model, m_instance);
|
||||
if (mdownload.exec()) {
|
||||
auto tasks =
|
||||
new ConcurrentTask(this, "Download Texture Packs", APPLICATION->settings()->get("NumberOfConcurrentDownloads").toInt());
|
||||
@ -103,3 +117,103 @@ void TexturePackPage::downloadTPs()
|
||||
m_model->update();
|
||||
}
|
||||
}
|
||||
|
||||
void TexturePackPage::updateTexturePacks()
|
||||
{
|
||||
if (m_instance->typeName() != "Minecraft")
|
||||
return; // this is a null instance or a legacy instance
|
||||
|
||||
auto profile = static_cast<MinecraftInstance*>(m_instance)->getPackProfile();
|
||||
if (APPLICATION->settings()->get("ModMetadataDisabled").toBool()) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Texture pack updates are unavailable when metadata is disabled!"));
|
||||
return;
|
||||
}
|
||||
if (m_instance != nullptr && m_instance->isRunning()) {
|
||||
auto response =
|
||||
CustomMessageBox::selectable(this, tr("Confirm Update"),
|
||||
tr("Updating texture packs while the game is running may cause pack duplication and game crashes.\n"
|
||||
"The old files may not be deleted as they are in use.\n"
|
||||
"Are you sure you want to do this?"),
|
||||
QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
|
||||
->exec();
|
||||
|
||||
if (response != QMessageBox::Yes)
|
||||
return;
|
||||
}
|
||||
auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes();
|
||||
|
||||
auto mods_list = m_model->selectedResources(selection);
|
||||
bool use_all = mods_list.empty();
|
||||
if (use_all)
|
||||
mods_list = m_model->allResources();
|
||||
|
||||
ResourceUpdateDialog update_dialog(this, m_instance, m_model, mods_list, false, false);
|
||||
update_dialog.checkCandidates();
|
||||
|
||||
if (update_dialog.aborted()) {
|
||||
CustomMessageBox::selectable(this, tr("Aborted"), tr("The texture pack updater was aborted!"), QMessageBox::Warning)->show();
|
||||
return;
|
||||
}
|
||||
if (update_dialog.noUpdates()) {
|
||||
QString message{ tr("'%1' is up-to-date! :)").arg(mods_list.front()->name()) };
|
||||
if (mods_list.size() > 1) {
|
||||
if (use_all) {
|
||||
message = tr("All texture packs are up-to-date! :)");
|
||||
} else {
|
||||
message = tr("All selected texture packs are up-to-date! :)");
|
||||
}
|
||||
}
|
||||
CustomMessageBox::selectable(this, tr("Update checker"), message)->exec();
|
||||
return;
|
||||
}
|
||||
|
||||
if (update_dialog.exec()) {
|
||||
auto tasks = new ConcurrentTask(this, "Download Texture Packs", 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 : update_dialog.getTasks()) {
|
||||
tasks->addTask(task);
|
||||
}
|
||||
|
||||
ProgressDialog loadDialog(this);
|
||||
loadDialog.setSkipButton(true, tr("Abort"));
|
||||
loadDialog.execWithTask(tasks);
|
||||
|
||||
m_model->update();
|
||||
}
|
||||
}
|
||||
|
||||
void TexturePackPage::deleteTexturePackMetadata()
|
||||
{
|
||||
auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes();
|
||||
auto selectionCount = m_model->selectedTexturePacks(selection).length();
|
||||
if (selectionCount == 0)
|
||||
return;
|
||||
if (selectionCount > 1) {
|
||||
auto response = CustomMessageBox::selectable(this, tr("Confirm Removal"),
|
||||
tr("You are about to remove the metadata for %1 texture packs.\n"
|
||||
"Are you sure?")
|
||||
.arg(selectionCount),
|
||||
QMessageBox::Warning, QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
|
||||
->exec();
|
||||
|
||||
if (response != QMessageBox::Yes)
|
||||
return;
|
||||
}
|
||||
|
||||
m_model->deleteMetadata(selection);
|
||||
}
|
||||
|
@ -56,5 +56,10 @@ class TexturePackPage : public ExternalResourcesPage {
|
||||
|
||||
public slots:
|
||||
bool onSelectionChanged(const QModelIndex& current, const QModelIndex& previous) override;
|
||||
void downloadTPs();
|
||||
void downloadTexturePacks();
|
||||
void updateTexturePacks();
|
||||
void deleteTexturePackMetadata();
|
||||
|
||||
private:
|
||||
std::shared_ptr<TexturePackFolderModel> m_model;
|
||||
};
|
||||
|
Reference in New Issue
Block a user