Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into fix_retry_dialog

This commit is contained in:
Trial97
2024-06-28 20:48:28 +03:00
86 changed files with 302 additions and 128 deletions

View File

@@ -92,17 +92,15 @@ void ModUpdateDialog::checkCandidates()
if (!m_modrinth_to_update.empty()) {
m_modrinth_check_task.reset(new ModrinthCheckUpdate(m_modrinth_to_update, versions, loaders, m_mod_model));
connect(m_modrinth_check_task.get(), &CheckUpdateTask::checkFailed, this, [this](Mod* mod, QString reason, QUrl recover_url) {
m_failed_check_update.append({ mod, reason, recover_url });
});
connect(m_modrinth_check_task.get(), &CheckUpdateTask::checkFailed, this,
[this](Mod* mod, QString reason, QUrl recover_url) { m_failed_check_update.append({ mod, reason, recover_url }); });
check_task.addTask(m_modrinth_check_task);
}
if (!m_flame_to_update.empty()) {
m_flame_check_task.reset(new FlameCheckUpdate(m_flame_to_update, versions, loaders, m_mod_model));
connect(m_flame_check_task.get(), &CheckUpdateTask::checkFailed, this, [this](Mod* mod, QString reason, QUrl recover_url) {
m_failed_check_update.append({ mod, reason, recover_url });
});
connect(m_flame_check_task.get(), &CheckUpdateTask::checkFailed, this,
[this](Mod* mod, QString reason, QUrl recover_url) { m_failed_check_update.append({ mod, reason, recover_url }); });
check_task.addTask(m_flame_check_task);
}

View File

@@ -200,7 +200,7 @@ void NewInstanceDialog::setSuggestedPack(const QString& name, InstanceTask* task
importVersion.clear();
if (!task) {
ui->iconButton->setIcon(APPLICATION->icons()->getIcon("default"));
ui->iconButton->setIcon(APPLICATION->icons()->getIcon(InstIconKey));
importIcon = false;
}
@@ -216,7 +216,7 @@ void NewInstanceDialog::setSuggestedPack(const QString& name, QString version, I
importVersion = std::move(version);
if (!task) {
ui->iconButton->setIcon(APPLICATION->icons()->getIcon("default"));
ui->iconButton->setIcon(APPLICATION->icons()->getIcon(InstIconKey));
importIcon = false;
}
@@ -236,6 +236,9 @@ void NewInstanceDialog::setSuggestedIconFromFile(const QString& path, const QStr
void NewInstanceDialog::setSuggestedIcon(const QString& key)
{
if (key == "default")
return;
auto icon = APPLICATION->icons()->getIcon(key);
importIcon = false;

View File

@@ -92,6 +92,19 @@ void ResourceDownloadDialog::accept()
void ResourceDownloadDialog::reject()
{
auto selected = getTasks();
if (selected.count() > 0) {
auto reply = CustomMessageBox::selectable(this, tr("Confirmation Needed"),
tr("You have %1 selected resources.\n"
"Are you sure you want to close this dialog?")
.arg(selected.count()),
QMessageBox::Question, QMessageBox::Yes | QMessageBox::No, QMessageBox::No)
->exec();
if (reply != QMessageBox::Yes) {
return;
}
}
if (!geometrySaveKey().isEmpty())
APPLICATION->settings()->set(geometrySaveKey(), saveGeometry().toBase64());
@@ -356,4 +369,20 @@ QList<BasePage*> ShaderPackDownloadDialog::getPages()
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;
}
setWindowTitle(tr("Change %1 version").arg(meta->name));
m_container->hidePageList();
m_buttons.hide();
auto page = selectedPage();
page->openProject(meta->project_id);
}
} // namespace ResourceDownload

View File

@@ -107,6 +107,8 @@ class ModDownloadDialog final : public ResourceDownloadDialog {
QList<BasePage*> getPages() override;
GetModDependenciesTask::Ptr getModDependenciesTask() override;
void setModMetadata(std::shared_ptr<Metadata::ModStruct>);
private:
BaseInstance* m_instance;
};

View File

@@ -37,7 +37,7 @@ class VersionSelectDialog : public QDialog {
public:
explicit VersionSelectDialog(BaseVersionList* vlist, QString title, QWidget* parent = 0, bool cancelable = true);
virtual ~VersionSelectDialog(){};
virtual ~VersionSelectDialog() {};
int exec() override;

View File

@@ -371,7 +371,7 @@ void SkinManageDialog::on_urlBtn_clicked()
class WaitTask : public Task {
public:
WaitTask() : m_loop(), m_done(false){};
WaitTask() : m_loop(), m_done(false) {};
virtual ~WaitTask() = default;
public slots:

View File

@@ -4,7 +4,7 @@ class BasePage;
class BasePageContainer {
public:
virtual ~BasePageContainer(){};
virtual ~BasePageContainer() {};
virtual bool selectPage(QString pageId) = 0;
virtual BasePage* selectedPage() const = 0;
virtual BasePage* getPage(QString pageId) { return nullptr; };

View File

@@ -50,7 +50,7 @@ class ManagedPackPage : public QWidget, public BasePage {
/** Gets the necessary information about the managed pack, such as
* available versions*/
virtual void parseManagedPack(){};
virtual void parseManagedPack() {};
/** URL of the managed pack.
* Not the version-specific one.
@@ -64,8 +64,8 @@ class ManagedPackPage : public QWidget, public BasePage {
*/
virtual void suggestVersion();
virtual void update(){};
virtual void updateFromFile(){};
virtual void update() {};
virtual void updateFromFile() {};
protected slots:
/** Does the necessary UI changes for when something failed.

View File

@@ -41,6 +41,7 @@
#include "ui_ExternalResourcesPage.h"
#include <QAbstractItemModel>
#include <QAction>
#include <QEvent>
#include <QKeyEvent>
#include <QMenu>
@@ -122,13 +123,19 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr<ModFolderModel>
ui->actionsToolbar->addAction(ui->actionVisitItemPage);
connect(ui->actionVisitItemPage, &QAction::triggered, this, &ModFolderPage::visitModPages);
auto changeVersion = new QAction(tr("Change Version"));
changeVersion->setToolTip(tr("Change mod version"));
changeVersion->setEnabled(false);
ui->actionsToolbar->insertActionAfter(ui->actionUpdateItem, changeVersion);
connect(changeVersion, &QAction::triggered, this, &ModFolderPage::changeModVersion);
ui->actionsToolbar->insertActionAfter(ui->actionVisitItemPage, ui->actionExportMetadata);
connect(ui->actionExportMetadata, &QAction::triggered, this, &ModFolderPage::exportModMetadata);
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] {
[this, check_allow_update, actionRemoveItemMetadata, changeVersion] {
ui->actionUpdateItem->setEnabled(check_allow_update());
auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes();
@@ -138,11 +145,12 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr<ModFolderModel>
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"));
}
changeVersion->setEnabled(mods_list.length() == 1 && mods_list[0]->metadata() != nullptr);
ui->actionVisitItemPage->setEnabled(selected != 0);
actionRemoveItemMetadata->setEnabled(selected != 0);
});
@@ -377,6 +385,57 @@ void ModFolderPage::deleteModMetadata()
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();
}
}
void ModFolderPage::exportModMetadata()
{
auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()).indexes();

View File

@@ -67,6 +67,7 @@ class ModFolderPage : public ExternalResourcesPage {
void installMods();
void updateMods(bool includeDeps = false);
void visitModPages();
void changeModVersion();
protected:
std::shared_ptr<ModFolderModel> m_model;

View File

@@ -168,7 +168,7 @@ class ServersModel : public QAbstractListModel {
m_saveTimer.setInterval(5000);
connect(&m_saveTimer, &QTimer::timeout, this, &ServersModel::save_internal);
}
virtual ~ServersModel(){};
virtual ~ServersModel() {};
void observe()
{

View File

@@ -88,6 +88,17 @@ 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 {};
}
bool checkSide(QString filter, QString value)
{
return filter.isEmpty() || value.isEmpty() || filter == "both" || value == "both" || filter == value;

View File

@@ -35,6 +35,7 @@ class ModModel : public ResourceModel {
virtual ModPlatform::IndexedVersion loadDependencyVersions(const ModPlatform::Dependency& m, QJsonArray& arr) = 0;
void setFilter(std::shared_ptr<ModFilterWidget::Filter> filter) { m_filter = filter; }
virtual QVariant getInstalledPackVersion(ModPlatform::IndexedPack::Ptr) const override;
public slots:
ResourceAPI::SearchArgs createSearchArguments() override;

View File

@@ -59,7 +59,7 @@ class ModPage : public ResourcePage {
protected:
ModPage(ModDownloadDialog* dialog, BaseInstance& instance);
virtual void prepareProviderCategories(){};
virtual void prepareProviderCategories() {};
protected slots:
virtual void filterMods();

View File

@@ -56,6 +56,7 @@ class ResourceModel : public QAbstractListModel {
[[nodiscard]] auto getSortingMethods() const { return m_api->getSortingMethods(); }
virtual QVariant getInstalledPackVersion(ModPlatform::IndexedPack::Ptr) const { return {}; }
/** Whether the version is opted out or not. Currently only makes sense in CF. */
virtual bool optedOut(const ModPlatform::IndexedVersion& ver) const
{

View File

@@ -271,7 +271,9 @@ void ResourcePage::updateVersionList()
m_ui->versionSelectionBox->clear();
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++) {
auto& version = current_pack->versions[i];
if (!m_model->checkVersionFilters(version))
@@ -280,9 +282,10 @@ void ResourcePage::updateVersionList()
auto release_type = current_pack->versions[i].version_type.isValid()
? 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) {
m_ui->versionSelectionBox->addItem(tr("No valid version found."), QVariant(-1));
m_ui->resourceSelectionButton->setText(tr("Cannot select invalid version :("));
@@ -399,7 +402,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);
// ensure the user isn't opening the same mod
@@ -443,4 +446,52 @@ void ResourcePage::openUrl(const QUrl& url)
QDesktopServices::openUrl(url);
}
void ResourcePage::openProject(QVariant projectID)
{
m_ui->sortByBox->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

View File

@@ -83,6 +83,8 @@ class ResourcePage : public QWidget, public BasePage {
QList<DownloadTaskPtr> selectedPacks() { return m_model->selectedPacks(); }
bool hasSelectedPacks() { return !(m_model->selectedPacks().isEmpty()); }
virtual void openProject(QVariant projectID);
protected slots:
virtual void triggerSearch() = 0;
@@ -111,6 +113,8 @@ class ResourcePage : public QWidget, public BasePage {
// Used to do instant searching with a delay to cache quick changes
QTimer m_search_timer;
bool m_do_not_jump_to_mod = false;
};
} // namespace ResourceDownload

View File

@@ -6,7 +6,7 @@
class BaseWizardPage : public QWizardPage {
public:
explicit BaseWizardPage(QWidget* parent = Q_NULLPTR) : QWizardPage(parent) {}
virtual ~BaseWizardPage(){};
virtual ~BaseWizardPage() {};
virtual bool wantsRefreshButton() { return false; }
virtual void refresh() {}

View File

@@ -9,7 +9,7 @@ class JavaWizardPage : public BaseWizardPage {
public:
explicit JavaWizardPage(QWidget* parent = Q_NULLPTR);
virtual ~JavaWizardPage(){};
virtual ~JavaWizardPage() {};
bool wantsRefreshButton() override;
void refresh() override;

View File

@@ -25,7 +25,7 @@ class JavaSettingsWidget : public QWidget {
public:
explicit JavaSettingsWidget(QWidget* parent);
virtual ~JavaSettingsWidget(){};
virtual ~JavaSettingsWidget() {};
enum class JavaStatus { NotSet, Pending, Good, DoesNotExist, DoesNotStart, ReturnedInvalidData } javaStatus = JavaStatus::NotSet;

View File

@@ -27,7 +27,7 @@ class LanguageSelectionWidget : public QWidget {
Q_OBJECT
public:
explicit LanguageSelectionWidget(QWidget* parent = 0);
virtual ~LanguageSelectionWidget(){};
virtual ~LanguageSelectionWidget() {};
QString getSelectedLanguageKey() const;
void retranslate();

View File

@@ -36,6 +36,7 @@
#pragma once
#include <QListView>
#include <QModelIndex>
#include <QWidget>
@@ -86,6 +87,8 @@ class PageContainer : public QWidget, public BasePageContainer {
void changeEvent(QEvent*) override;
void hidePageList() { m_pageList->hide(); }
private:
void createUI();
void retranslate();