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

Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
Trial97
2023-08-15 12:49:21 +03:00
219 changed files with 3290 additions and 1839 deletions

View File

@ -220,7 +220,7 @@ void CopyInstanceDialog::on_iconButton_clicked()
}
}
void CopyInstanceDialog::on_instNameTextBox_textChanged(const QString& arg1)
void CopyInstanceDialog::on_instNameTextBox_textChanged([[maybe_unused]] const QString& arg1)
{
updateDialogState();
}

View File

@ -195,8 +195,8 @@ void ExportInstanceDialog::loadPackIgnore()
if (!ignoreFile.open(QIODevice::ReadOnly)) {
return;
}
auto data = ignoreFile.readAll();
auto string = QString::fromUtf8(data);
auto ignoreData = ignoreFile.readAll();
auto string = QString::fromUtf8(ignoreData);
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
proxyModel->setBlockedPaths(string.split('\n', Qt::SkipEmptyParts));
#else
@ -206,10 +206,10 @@ void ExportInstanceDialog::loadPackIgnore()
void ExportInstanceDialog::savePackIgnore()
{
auto data = proxyModel->blockedPaths().toStringList().join('\n').toUtf8();
auto ignoreData = proxyModel->blockedPaths().toStringList().join('\n').toUtf8();
auto filename = ignoreFileName();
try {
FS::write(filename, data);
FS::write(filename, ignoreData);
} catch (const Exception& e) {
qWarning() << e.cause();
}

View File

@ -0,0 +1,164 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2023 TheKodeToad <TheKodeToad@proton.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "InstallLoaderDialog.h"
#include <QDialogButtonBox>
#include <QPushButton>
#include <QVBoxLayout>
#include "Application.h"
#include "BuildConfig.h"
#include "DesktopServices.h"
#include "meta/Index.h"
#include "minecraft/MinecraftInstance.h"
#include "minecraft/PackProfile.h"
#include "ui/widgets/PageContainer.h"
#include "ui/widgets/VersionSelectWidget.h"
class InstallLoaderPage : public VersionSelectWidget, public BasePage {
public:
InstallLoaderPage(const QString& id,
const QString& iconName,
const QString& name,
const Version& oldestVersion,
const std::shared_ptr<PackProfile> profile)
: VersionSelectWidget(nullptr), uid(id), iconName(iconName), name(name)
{
const QString minecraftVersion = profile->getComponentVersion("net.minecraft");
setEmptyString(tr("No versions are currently available for Minecraft %1").arg(minecraftVersion));
setExactIfPresentFilter(BaseVersionList::ParentVersionRole, minecraftVersion);
if (oldestVersion != Version() && Version(minecraftVersion) < oldestVersion)
setExactFilter(BaseVersionList::ParentVersionRole, "AAA");
if (const QString currentVersion = profile->getComponentVersion(id); !currentVersion.isNull())
setCurrentVersion(currentVersion);
}
QString id() const override { return uid; }
QString displayName() const override { return name; }
QIcon icon() const override { return APPLICATION->getThemedIcon(iconName); }
void openedImpl() override
{
if (loaded)
return;
const auto versions = APPLICATION->metadataIndex()->get(uid);
if (!versions)
return;
initialize(versions.get());
loaded = true;
}
void setParentContainer(BasePageContainer* container) override
{
auto dialog = dynamic_cast<QDialog*>(dynamic_cast<PageContainer*>(container)->parent());
connect(view(), &QAbstractItemView::doubleClicked, dialog, &QDialog::accept);
}
private:
const QString uid;
const QString iconName;
const QString name;
bool loaded = false;
};
static InstallLoaderPage* pageCast(BasePage* page)
{
auto result = dynamic_cast<InstallLoaderPage*>(page);
Q_ASSERT(result != nullptr);
return result;
}
InstallLoaderDialog::InstallLoaderDialog(std::shared_ptr<PackProfile> profile, const QString& uid, QWidget* parent)
: QDialog(parent), profile(std::move(profile)), container(new PageContainer(this, QString(), this)), buttons(new QDialogButtonBox(this))
{
auto layout = new QVBoxLayout(this);
container->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
layout->addWidget(container);
auto buttonLayout = new QHBoxLayout(this);
auto refreshButton = new QPushButton(tr("&Refresh"), this);
connect(refreshButton, &QPushButton::clicked, this, [this] { pageCast(container->selectedPage())->loadList(); });
buttonLayout->addWidget(refreshButton);
buttons->setOrientation(Qt::Horizontal);
buttons->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok);
connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
buttonLayout->addWidget(buttons);
layout->addLayout(buttonLayout);
setWindowTitle(dialogTitle());
setWindowModality(Qt::WindowModal);
resize(520, 347);
for (BasePage* page : container->getPages()) {
if (page->id() == uid)
container->selectPage(page->id());
connect(pageCast(page), &VersionSelectWidget::selectedVersionChanged, this, [this, page] {
if (page->id() == container->selectedPage()->id())
validate(container->selectedPage());
});
}
connect(container, &PageContainer::selectedPageChanged, this, [this](BasePage* previous, BasePage* current) { validate(current); });
pageCast(container->selectedPage())->selectSearch();
validate(container->selectedPage());
}
QList<BasePage*> InstallLoaderDialog::getPages()
{
return { // Forge
new InstallLoaderPage("net.minecraftforge", "forge", tr("Forge"), {}, profile),
// Fabric
new InstallLoaderPage("net.fabricmc.fabric-loader", "fabricmc", tr("Fabric"), Version("1.14"), profile),
// Quilt
new InstallLoaderPage("org.quiltmc.quilt-loader", "quiltmc", tr("Quilt"), Version("1.14"), profile),
// LiteLoader
new InstallLoaderPage("com.mumfrey.liteloader", "liteloader", tr("LiteLoader"), {}, profile)
};
}
QString InstallLoaderDialog::dialogTitle()
{
return tr("Install Loader");
}
void InstallLoaderDialog::validate(BasePage* page)
{
buttons->button(QDialogButtonBox::Ok)->setEnabled(pageCast(page)->selectedVersion() != nullptr);
}
void InstallLoaderDialog::done(int result)
{
if (result == Accepted) {
auto* page = pageCast(container->selectedPage());
if (page->selectedVersion()) {
profile->setComponentVersion(page->id(), page->selectedVersion()->descriptor());
profile->resolve(Net::Mode::Online);
}
}
QDialog::done(result);
}

View File

@ -0,0 +1,45 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2023 TheKodeToad <TheKodeToad@proton.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <QDialog>
#include "ui/pages/BasePageProvider.h"
class MinecraftInstance;
class PageContainer;
class PackProfile;
class QDialogButtonBox;
class InstallLoaderDialog final : public QDialog, protected BasePageProvider {
Q_OBJECT
public:
explicit InstallLoaderDialog(std::shared_ptr<PackProfile> instance, const QString& uid = QString(), QWidget* parent = nullptr);
QList<BasePage*> getPages() override;
QString dialogTitle() override;
void validate(BasePage* page);
void done(int result) override;
private:
std::shared_ptr<PackProfile> profile;
PageContainer* container;
QDialogButtonBox* buttons;
};

View File

@ -290,7 +290,7 @@ void NewInstanceDialog::on_iconButton_clicked()
}
}
void NewInstanceDialog::on_instNameTextBox_textChanged(const QString& arg1)
void NewInstanceDialog::on_instNameTextBox_textChanged([[maybe_unused]] const QString& arg1)
{
updateDialogState();
}
@ -299,7 +299,7 @@ void NewInstanceDialog::importIconNow()
{
if (importIcon) {
APPLICATION->icons()->installIcon(importIconPath, importIconName);
InstIconKey = importIconName;
InstIconKey = importIconName.mid(0, importIconName.lastIndexOf('.'));
importIcon = false;
}
APPLICATION->settings()->set("NewInstanceGeometry", saveGeometry().toBase64());

View File

@ -163,13 +163,15 @@ void ProfileSetupDialog::checkName(const QString& name)
requestor->get(request);
}
void ProfileSetupDialog::checkFinished(QNetworkReply::NetworkError error, QByteArray data, QList<QNetworkReply::RawHeaderPair> headers)
void ProfileSetupDialog::checkFinished(QNetworkReply::NetworkError error,
QByteArray profileData,
[[maybe_unused]] QList<QNetworkReply::RawHeaderPair> headers)
{
auto requestor = qobject_cast<AuthRequest*>(QObject::sender());
requestor->deleteLater();
if (error == QNetworkReply::NoError) {
auto doc = QJsonDocument::fromJson(data);
auto doc = QJsonDocument::fromJson(profileData);
auto root = doc.object();
auto statusValue = root.value("status").toString("INVALID");
if (statusValue == "AVAILABLE") {
@ -202,11 +204,11 @@ void ProfileSetupDialog::setupProfile(const QString& profileName)
request.setRawHeader("Authorization", QString("Bearer %1").arg(token).toUtf8());
QString payloadTemplate("{\"profileName\":\"%1\"}");
auto data = payloadTemplate.arg(profileName).toUtf8();
auto profileData = payloadTemplate.arg(profileName).toUtf8();
AuthRequest* requestor = new AuthRequest(this);
connect(requestor, &AuthRequest::finished, this, &ProfileSetupDialog::setupProfileFinished);
requestor->post(request, data);
requestor->post(request, profileData);
isWorking = true;
auto button = ui->buttonBox->button(QDialogButtonBox::Cancel);
@ -243,8 +245,8 @@ struct MojangError {
} // namespace
void ProfileSetupDialog::setupProfileFinished(QNetworkReply::NetworkError error,
QByteArray data,
QList<QNetworkReply::RawHeaderPair> headers)
QByteArray errorData,
[[maybe_unused]] QList<QNetworkReply::RawHeaderPair> headers)
{
auto requestor = qobject_cast<AuthRequest*>(QObject::sender());
requestor->deleteLater();
@ -257,7 +259,7 @@ void ProfileSetupDialog::setupProfileFinished(QNetworkReply::NetworkError error,
*/
accept();
} else {
auto parsedError = MojangError::fromJSON(data);
auto parsedError = MojangError::fromJSON(errorData);
ui->errorLabel->setVisible(true);
ui->errorLabel->setText(tr("The server returned the following error:") + "\n\n" + parsedError.errorMessage);
qDebug() << parsedError.rawError;

View File

@ -85,7 +85,7 @@ void ProgressDialog::on_skipButton_clicked(bool checked)
{
Q_UNUSED(checked);
if (ui->skipButton->isEnabled()) // prevent other triggers from aborting
task->abort();
m_task->abort();
}
ProgressDialog::~ProgressDialog()
@ -127,7 +127,7 @@ void ProgressDialog::updateSize(bool recenterParent)
int ProgressDialog::execWithTask(Task* task)
{
this->task = task;
this->m_task = task;
if (!task) {
qDebug() << "Programmer error: Progress dialog created with null task.";
@ -179,8 +179,8 @@ int ProgressDialog::execWithTask(std::unique_ptr<Task>& task)
bool ProgressDialog::handleImmediateResult(QDialog::DialogCode& result)
{
if (task->isFinished()) {
if (task->wasSuccessful()) {
if (m_task->isFinished()) {
if (m_task->wasSuccessful()) {
result = QDialog::Accepted;
} else {
result = QDialog::Rejected;
@ -192,12 +192,12 @@ bool ProgressDialog::handleImmediateResult(QDialog::DialogCode& result)
Task* ProgressDialog::getTask()
{
return task;
return m_task;
}
void ProgressDialog::onTaskStarted() {}
void ProgressDialog::onTaskFailed(QString failure)
void ProgressDialog::onTaskFailed([[maybe_unused]] QString failure)
{
reject();
hide();
@ -209,11 +209,11 @@ void ProgressDialog::onTaskSucceeded()
hide();
}
void ProgressDialog::changeStatus(const QString& status)
void ProgressDialog::changeStatus([[maybe_unused]] const QString& status)
{
ui->globalStatusLabel->setText(task->getStatus());
ui->globalStatusLabel->setText(m_task->getStatus());
ui->globalStatusLabel->adjustSize();
ui->globalStatusDetailsLabel->setText(task->getDetails());
ui->globalStatusDetailsLabel->setText(m_task->getDetails());
ui->globalStatusDetailsLabel->adjustSize();
updateSize();
@ -279,7 +279,7 @@ void ProgressDialog::keyPressEvent(QKeyEvent* e)
void ProgressDialog::closeEvent(QCloseEvent* e)
{
if (task && task->isRunning()) {
if (m_task && m_task->isRunning()) {
e->ignore();
} else {
QDialog::closeEvent(e);

View File

@ -92,7 +92,7 @@ class ProgressDialog : public QDialog {
private:
Ui::ProgressDialog* ui;
Task* task;
Task* m_task;
bool m_is_multi_step = false;
QHash<QUuid, SubTaskProgressBar*> taskProgress;

View File

@ -2,7 +2,7 @@
/*
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
* Copyright (C) 2023 TheKodeToad <TheKodeToad@proton.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -209,15 +209,17 @@ bool ResourceDownloadDialog::selectPage(QString pageId)
return m_container->selectPage(pageId);
}
ResourcePage* ResourceDownloadDialog::getSelectedPage()
ResourcePage* ResourceDownloadDialog::selectedPage()
{
return m_selectedPage;
ResourcePage* result = dynamic_cast<ResourcePage*>(m_container->selectedPage());
Q_ASSERT(result != nullptr);
return result;
}
void ResourceDownloadDialog::addResource(ModPlatform::IndexedPack::Ptr pack, ModPlatform::IndexedVersion& ver)
{
removeResource(pack->name);
m_selectedPage->addResourceToPage(pack, ver, getBaseModel());
selectedPage()->addResourceToPage(pack, ver, getBaseModel());
setButtonStatus();
}
@ -257,14 +259,8 @@ void ResourceDownloadDialog::selectedPageChanged(BasePage* previous, BasePage* s
return;
}
m_selectedPage = dynamic_cast<ResourcePage*>(selected);
if (!m_selectedPage) {
qCritical() << "Page '" << selected->displayName() << "' in ResourceDownloadDialog is not a ResourcePage!";
return;
}
// Same effect as having a global search bar
m_selectedPage->setSearchTerm(prev_page->getSearchTerm());
selectedPage()->setSearchTerm(prev_page->getSearchTerm());
}
ModDownloadDialog::ModDownloadDialog(QWidget* parent, const std::shared_ptr<ModFolderModel>& mods, BaseInstance* instance)
@ -290,8 +286,6 @@ QList<BasePage*> ModDownloadDialog::getPages()
if (APPLICATION->capabilities() & Application::SupportsFlame && FlameAPI::validateModLoaders(loaders))
pages.append(FlameModPage::create(this, *m_instance));
m_selectedPage = dynamic_cast<ModPage*>(pages[0]);
return pages;
}
@ -306,7 +300,7 @@ GetModDependenciesTask::Ptr ModDownloadDialog::getModDependenciesTask()
return makeShared<GetModDependenciesTask>(this, m_instance, model, selectedVers);
}
return nullptr;
};
}
ResourcePackDownloadDialog::ResourcePackDownloadDialog(QWidget* parent,
const std::shared_ptr<ResourcePackFolderModel>& resource_packs,
@ -330,8 +324,6 @@ QList<BasePage*> ResourcePackDownloadDialog::getPages()
if (APPLICATION->capabilities() & Application::SupportsFlame)
pages.append(FlameResourcePackPage::create(this, *m_instance));
m_selectedPage = dynamic_cast<ResourcePackResourcePage*>(pages[0]);
return pages;
}
@ -357,8 +349,6 @@ QList<BasePage*> TexturePackDownloadDialog::getPages()
if (APPLICATION->capabilities() & Application::SupportsFlame)
pages.append(FlameTexturePackPage::create(this, *m_instance));
m_selectedPage = dynamic_cast<TexturePackResourcePage*>(pages[0]);
return pages;
}
@ -379,11 +369,7 @@ ShaderPackDownloadDialog::ShaderPackDownloadDialog(QWidget* parent,
QList<BasePage*> ShaderPackDownloadDialog::getPages()
{
QList<BasePage*> pages;
pages.append(ModrinthShaderPackPage::create(this, *m_instance));
m_selectedPage = dynamic_cast<ShaderPackResourcePage*>(pages[0]);
return pages;
}

View File

@ -2,7 +2,7 @@
/*
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net>
* Copyright (C) 2022 TheKodeToad <TheKodeToad@proton.me>
* Copyright (C) 2023 TheKodeToad <TheKodeToad@proton.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -61,7 +61,7 @@ class ResourceDownloadDialog : public QDialog, public BasePageProvider {
QString dialogTitle() override { return tr("Download %1").arg(resourcesString()); };
bool selectPage(QString pageId);
ResourcePage* getSelectedPage();
ResourcePage* selectedPage();
void addResource(ModPlatform::IndexedPack::Ptr, ModPlatform::IndexedVersion&);
void removeResource(const QString&);
@ -88,7 +88,6 @@ class ResourceDownloadDialog : public QDialog, public BasePageProvider {
const std::shared_ptr<ResourceFolderModel> m_base_model;
PageContainer* m_container = nullptr;
ResourcePage* m_selectedPage = nullptr;
QDialogButtonBox m_buttons;
QVBoxLayout m_vertical_layout;

View File

@ -5,7 +5,7 @@
#include <QPushButton>
ReviewMessageBox::ReviewMessageBox(QWidget* parent, QString const& title, QString const& icon)
ReviewMessageBox::ReviewMessageBox(QWidget* parent, [[maybe_unused]] QString const& title, [[maybe_unused]] QString const& icon)
: QDialog(parent), ui(new Ui::ReviewMessageBox)
{
ui->setupUi(this);

View File

@ -133,15 +133,15 @@ SkinUploadDialog::SkinUploadDialog(MinecraftAccountPtr acct, QWidget* parent) :
ui->setupUi(this);
// FIXME: add a model for this, download/refresh the capes on demand
auto& data = *acct->accountData();
auto& accountData = *acct->accountData();
int index = 0;
ui->capeCombo->addItem(tr("No Cape"), QVariant());
auto currentCape = data.minecraftProfile.currentCape;
auto currentCape = accountData.minecraftProfile.currentCape;
if (currentCape.isEmpty()) {
ui->capeCombo->setCurrentIndex(index);
}
for (auto& cape : data.minecraftProfile.capes) {
for (auto& cape : accountData.minecraftProfile.capes) {
index++;
if (cape.data.size()) {
QPixmap capeImage;

View File

@ -42,7 +42,7 @@
</size>
</property>
<property name="text">
<string notr="true">...</string>
<string>Browse</string>
</property>
</widget>
</item>

View File

@ -54,7 +54,7 @@ VersionSelectDialog::VersionSelectDialog(BaseVersionList* vlist, QString title,
m_verticalLayout = new QVBoxLayout(this);
m_verticalLayout->setObjectName(QStringLiteral("verticalLayout"));
m_versionWidget = new VersionSelectWidget(true, parent);
m_versionWidget = new VersionSelectWidget(parent);
m_verticalLayout->addWidget(m_versionWidget);
m_horizontalLayout = new QHBoxLayout();
@ -74,8 +74,9 @@ VersionSelectDialog::VersionSelectDialog(BaseVersionList* vlist, QString title,
retranslate();
QObject::connect(m_buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
QObject::connect(m_buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
connect(m_buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(m_versionWidget->view(), &QAbstractItemView::doubleClicked, this, &QDialog::accept);
connect(m_buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
QMetaObject::connectSlotsByName(this);
setWindowModality(Qt::WindowModal);
@ -121,6 +122,7 @@ int VersionSelectDialog::exec()
{
QDialog::open();
m_versionWidget->initialize(m_vlist);
m_versionWidget->selectSearch();
if (resizeOnColumn != -1) {
m_versionWidget->setResizeOn(resizeOnColumn);
}
@ -147,6 +149,11 @@ void VersionSelectDialog::setExactFilter(BaseVersionList::ModelRoles role, QStri
m_versionWidget->setExactFilter(role, filter);
}
void VersionSelectDialog::setExactIfPresentFilter(BaseVersionList::ModelRoles role, QString filter)
{
m_versionWidget->setExactIfPresentFilter(role, filter);
}
void VersionSelectDialog::setFuzzyFilter(BaseVersionList::ModelRoles role, QString filter)
{
m_versionWidget->setFuzzyFilter(role, filter);

View File

@ -46,6 +46,7 @@ class VersionSelectDialog : public QDialog {
void setCurrentVersion(const QString& version);
void setFuzzyFilter(BaseVersionList::ModelRoles role, QString filter);
void setExactFilter(BaseVersionList::ModelRoles role, QString filter);
void setExactIfPresentFilter(BaseVersionList::ModelRoles role, QString filter);
void setEmptyString(QString emptyString);
void setEmptyErrorString(QString emptyErrorString);
void setResizeOn(int column);