Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into fix_retry_dialog
This commit is contained in:
commit
515baffb8e
@ -848,24 +848,17 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
||||
{
|
||||
m_metacache.reset(new HttpMetaCache("metacache"));
|
||||
m_metacache->addBase("asset_indexes", QDir("assets/indexes").absolutePath());
|
||||
m_metacache->addBase("asset_objects", QDir("assets/objects").absolutePath());
|
||||
m_metacache->addBase("versions", QDir("versions").absolutePath());
|
||||
m_metacache->addBase("libraries", QDir("libraries").absolutePath());
|
||||
m_metacache->addBase("minecraftforge", QDir("mods/minecraftforge").absolutePath());
|
||||
m_metacache->addBase("fmllibs", QDir("mods/minecraftforge/libs").absolutePath());
|
||||
m_metacache->addBase("liteloader", QDir("mods/liteloader").absolutePath());
|
||||
m_metacache->addBase("general", QDir("cache").absolutePath());
|
||||
m_metacache->addBase("ATLauncherPacks", QDir("cache/ATLauncherPacks").absolutePath());
|
||||
m_metacache->addBase("FTBPacks", QDir("cache/FTBPacks").absolutePath());
|
||||
m_metacache->addBase("ModpacksCHPacks", QDir("cache/ModpacksCHPacks").absolutePath());
|
||||
m_metacache->addBase("TechnicPacks", QDir("cache/TechnicPacks").absolutePath());
|
||||
m_metacache->addBase("FlamePacks", QDir("cache/FlamePacks").absolutePath());
|
||||
m_metacache->addBase("FlameMods", QDir("cache/FlameMods").absolutePath());
|
||||
m_metacache->addBase("ModrinthPacks", QDir("cache/ModrinthPacks").absolutePath());
|
||||
m_metacache->addBase("ModrinthModpacks", QDir("cache/ModrinthModpacks").absolutePath());
|
||||
m_metacache->addBase("root", QDir::currentPath());
|
||||
m_metacache->addBase("translations", QDir("translations").absolutePath());
|
||||
m_metacache->addBase("icons", QDir("cache/icons").absolutePath());
|
||||
m_metacache->addBase("meta", QDir("meta").absolutePath());
|
||||
m_metacache->Load();
|
||||
qDebug() << "<> Cache initialized.";
|
||||
@ -946,8 +939,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
||||
[[fallthrough]];
|
||||
default: {
|
||||
qDebug() << "Exiting because update lockfile is present";
|
||||
QMetaObject::invokeMethod(
|
||||
this, []() { exit(1); }, Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(this, []() { exit(1); }, Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -979,8 +971,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
||||
[[fallthrough]];
|
||||
default: {
|
||||
qDebug() << "Exiting because update lockfile is present";
|
||||
QMetaObject::invokeMethod(
|
||||
this, []() { exit(1); }, Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(this, []() { exit(1); }, Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -992,7 +983,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
||||
"\n"
|
||||
"You are now running %1 .\n"
|
||||
"Check the Prism Launcher updater log at: \n"
|
||||
"%1\n"
|
||||
"%2\n"
|
||||
"for details.")
|
||||
.arg(BuildConfig.printableVersionString())
|
||||
.arg(update_log_path);
|
||||
@ -1674,8 +1665,7 @@ QString Application::getJarPath(QString jarFile)
|
||||
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD)
|
||||
FS::PathCombine(m_rootPath, "share", BuildConfig.LAUNCHER_NAME),
|
||||
#endif
|
||||
FS::PathCombine(m_rootPath, "jars"),
|
||||
FS::PathCombine(applicationDirPath(), "jars"),
|
||||
FS::PathCombine(m_rootPath, "jars"), FS::PathCombine(applicationDirPath(), "jars"),
|
||||
FS::PathCombine(applicationDirPath(), "..", "jars") // from inside build dir, for debuging
|
||||
};
|
||||
for (QString p : potentialPaths) {
|
||||
|
@ -269,13 +269,18 @@ void BaseInstance::setRunning(bool running)
|
||||
|
||||
m_isRunning = running;
|
||||
|
||||
if (!m_settings->get("RecordGameTime").toBool()) {
|
||||
emit runningStatusChanged(running);
|
||||
}
|
||||
|
||||
void BaseInstance::setMinecraftRunning(bool running)
|
||||
{
|
||||
if (!settings()->get("RecordGameTime").toBool()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (running) {
|
||||
m_timeStarted = QDateTime::currentDateTime();
|
||||
setLastLaunch(m_timeStarted.toMSecsSinceEpoch());
|
||||
} else {
|
||||
QDateTime timeEnded = QDateTime::currentDateTime();
|
||||
|
||||
@ -285,8 +290,6 @@ void BaseInstance::setRunning(bool running)
|
||||
|
||||
emit propertiesChanged(this);
|
||||
}
|
||||
|
||||
emit runningStatusChanged(running);
|
||||
}
|
||||
|
||||
int64_t BaseInstance::totalTimePlayed() const
|
||||
|
@ -104,6 +104,7 @@ class BaseInstance : public QObject, public std::enable_shared_from_this<BaseIns
|
||||
/// be unique.
|
||||
virtual QString id() const;
|
||||
|
||||
void setMinecraftRunning(bool running);
|
||||
void setRunning(bool running);
|
||||
bool isRunning() const;
|
||||
int64_t totalTimePlayed() const;
|
||||
|
@ -194,7 +194,8 @@ void LaunchController::login()
|
||||
bool tryagain = true;
|
||||
unsigned int tries = 0;
|
||||
|
||||
if (m_accountToUse->accountType() != AccountType::Offline && m_accountToUse->accountState() == AccountState::Offline) {
|
||||
if ((m_accountToUse->accountType() != AccountType::Offline && m_accountToUse->accountState() == AccountState::Offline) ||
|
||||
m_accountToUse->shouldRefresh()) {
|
||||
// Force account refresh on the account used to launch the instance updating the AccountState
|
||||
// only on first try and if it is not meant to be offline
|
||||
auto accounts = APPLICATION->accounts();
|
||||
|
@ -79,11 +79,9 @@ QProcessEnvironment CleanEnviroment()
|
||||
|
||||
QStringList stripped = {
|
||||
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) || defined(Q_OS_OPENBSD)
|
||||
"LD_LIBRARY_PATH",
|
||||
"LD_PRELOAD",
|
||||
"LD_LIBRARY_PATH", "LD_PRELOAD",
|
||||
#endif
|
||||
"QT_PLUGIN_PATH",
|
||||
"QT_FONTPATH"
|
||||
"QT_PLUGIN_PATH", "QT_FONTPATH"
|
||||
};
|
||||
for (auto key : rawenv.keys()) {
|
||||
auto value = rawenv.value(key);
|
||||
@ -376,7 +374,19 @@ QList<QString> JavaUtils::FindJavaPaths()
|
||||
auto home = qEnvironmentVariable("HOME");
|
||||
|
||||
// javas downloaded by sdkman
|
||||
javas.append(FS::PathCombine(home, ".sdkman/candidates/java"));
|
||||
QDir sdkmanDir(FS::PathCombine(home, ".sdkman/candidates/java"));
|
||||
QStringList sdkmanJavas = sdkmanDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
foreach (const QString& java, sdkmanJavas) {
|
||||
javas.append(sdkmanDir.absolutePath() + "/" + java + "/bin/java");
|
||||
}
|
||||
|
||||
// java in user library folder (like from intellij downloads)
|
||||
QDir userLibraryJVMDir(FS::PathCombine(home, "Library/Java/JavaVirtualMachines/"));
|
||||
QStringList userLibraryJVMJavas = userLibraryJVMDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
foreach (const QString& java, userLibraryJVMJavas) {
|
||||
javas.append(userLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Home/bin/java");
|
||||
javas.append(userLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Commands/java");
|
||||
}
|
||||
|
||||
javas.append(getMinecraftJavaBundle());
|
||||
javas = addJavasFromEnv(javas);
|
||||
|
@ -178,6 +178,7 @@ void LauncherPartLaunch::on_state(LoggedProcess::State state)
|
||||
APPLICATION->showMainWindow();
|
||||
|
||||
m_parent->setPid(-1);
|
||||
m_parent->instance()->setMinecraftRunning(false);
|
||||
// if the exit code wasn't 0, report this as a crash
|
||||
auto exitCode = m_process.exitCode();
|
||||
if (exitCode != 0) {
|
||||
@ -193,7 +194,6 @@ void LauncherPartLaunch::on_state(LoggedProcess::State state)
|
||||
case LoggedProcess::Running:
|
||||
emit logLine(QString("Minecraft process ID: %1\n\n").arg(m_process.processId()), MessageLevel::Launcher);
|
||||
m_parent->setPid(m_process.processId());
|
||||
m_parent->instance()->setLastLaunch();
|
||||
// send the launch script to the launcher part
|
||||
m_process.write(m_launchScript.toUtf8());
|
||||
|
||||
@ -213,6 +213,7 @@ void LauncherPartLaunch::setWorkingDirectory(const QString& wd)
|
||||
void LauncherPartLaunch::proceed()
|
||||
{
|
||||
if (mayProceed) {
|
||||
m_parent->instance()->setMinecraftRunning(true);
|
||||
QString launchString("launch\n");
|
||||
m_process.write(launchString.toUtf8());
|
||||
mayProceed = false;
|
||||
|
@ -282,8 +282,7 @@ void ResourceFolderModel::resolveResource(Resource* res)
|
||||
|
||||
connect(
|
||||
task.get(), &Task::succeeded, this, [=] { onParseSucceeded(ticket, res->internal_id()); }, Qt::ConnectionType::QueuedConnection);
|
||||
connect(
|
||||
task.get(), &Task::failed, this, [=] { onParseFailed(ticket, res->internal_id()); }, Qt::ConnectionType::QueuedConnection);
|
||||
connect(task.get(), &Task::failed, this, [=] { onParseFailed(ticket, res->internal_id()); }, Qt::ConnectionType::QueuedConnection);
|
||||
connect(
|
||||
task.get(), &Task::finished, this,
|
||||
[=] {
|
||||
|
@ -37,7 +37,6 @@
|
||||
|
||||
#include "Application.h"
|
||||
|
||||
#include "StringUtils.h"
|
||||
#include "TexturePackFolderModel.h"
|
||||
|
||||
#include "minecraft/mod/tasks/BasicFolderLoadTask.h"
|
||||
|
@ -20,6 +20,9 @@ void FlameMod::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj)
|
||||
QJsonObject logo = Json::ensureObject(obj, "logo");
|
||||
pack.logoName = Json::ensureString(logo, "title");
|
||||
pack.logoUrl = Json::ensureString(logo, "thumbnailUrl");
|
||||
if (pack.logoUrl.isEmpty()) {
|
||||
pack.logoUrl = Json::ensureString(logo, "url");
|
||||
}
|
||||
|
||||
auto authors = Json::ensureArray(obj, "authors");
|
||||
for (auto authorIter : authors) {
|
||||
|
@ -131,8 +131,9 @@ void Modrinth::loadIndexedPackVersions(ModPlatform::IndexedPack& pack, QJsonArra
|
||||
pack.versionsLoaded = true;
|
||||
}
|
||||
|
||||
auto Modrinth::loadIndexedPackVersion(QJsonObject& obj, QString preferred_hash_type, QString preferred_file_name)
|
||||
-> ModPlatform::IndexedVersion
|
||||
auto Modrinth::loadIndexedPackVersion(QJsonObject& obj,
|
||||
QString preferred_hash_type,
|
||||
QString preferred_file_name) -> ModPlatform::IndexedVersion
|
||||
{
|
||||
ModPlatform::IndexedVersion file;
|
||||
|
||||
@ -246,8 +247,9 @@ auto Modrinth::loadIndexedPackVersion(QJsonObject& obj, QString preferred_hash_t
|
||||
return {};
|
||||
}
|
||||
|
||||
auto Modrinth::loadDependencyVersions([[maybe_unused]] const ModPlatform::Dependency& m, QJsonArray& arr, const BaseInstance* inst)
|
||||
-> ModPlatform::IndexedVersion
|
||||
auto Modrinth::loadDependencyVersions([[maybe_unused]] const ModPlatform::Dependency& m,
|
||||
QJsonArray& arr,
|
||||
const BaseInstance* inst) -> ModPlatform::IndexedVersion
|
||||
{
|
||||
auto profile = (dynamic_cast<const MinecraftInstance*>(inst))->getPackProfile();
|
||||
QString mcVersion = profile->getComponentVersion("net.minecraft");
|
||||
|
@ -90,8 +90,9 @@ auto intEntry(toml::table table, QString entry_name) -> int
|
||||
return node.value_or(0);
|
||||
}
|
||||
|
||||
auto V1::createModFormat([[maybe_unused]] QDir& index_dir, ModPlatform::IndexedPack& mod_pack, ModPlatform::IndexedVersion& mod_version)
|
||||
-> Mod
|
||||
auto V1::createModFormat([[maybe_unused]] QDir& index_dir,
|
||||
ModPlatform::IndexedPack& mod_pack,
|
||||
ModPlatform::IndexedVersion& mod_version) -> Mod
|
||||
{
|
||||
Mod mod;
|
||||
|
||||
|
@ -175,6 +175,8 @@ void HttpMetaCache::evictAll()
|
||||
if (!evictEntry(entry))
|
||||
qCWarning(taskHttpMetaCacheLogC) << "Unexpected missing cache entry" << entry->m_basePath;
|
||||
}
|
||||
map.entry_list.clear();
|
||||
FS::deletePath(map.base_path);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -469,8 +469,7 @@ PrismUpdaterApp::PrismUpdaterApp(int& argc, char** argv) : QApplication(argc, ar
|
||||
target_dir = QDir(m_rootPath).absoluteFilePath("..");
|
||||
}
|
||||
|
||||
QMetaObject::invokeMethod(
|
||||
this, [this, target_dir]() { moveAndFinishUpdate(target_dir); }, Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(this, [this, target_dir]() { moveAndFinishUpdate(target_dir); }, Qt::QueuedConnection);
|
||||
|
||||
} else {
|
||||
QMetaObject::invokeMethod(this, &PrismUpdaterApp::loadReleaseList, Qt::QueuedConnection);
|
||||
|
@ -24,10 +24,7 @@ class Reader {
|
||||
virtual void goToBeginning() = 0;
|
||||
};
|
||||
|
||||
uint32_t hash(
|
||||
Reader* file_stream,
|
||||
std::size_t buffer_size = 4 * MiB,
|
||||
std::function<bool(char)> filter_out = [](char) { return false; });
|
||||
uint32_t hash(Reader* file_stream, std::size_t buffer_size = 4 * MiB, std::function<bool(char)> filter_out = [](char) { return false; });
|
||||
|
||||
struct IncrementalHashInfo {
|
||||
uint32_t h;
|
||||
|
@ -19,7 +19,7 @@
|
||||
};
|
||||
};
|
||||
|
||||
tools.clang-tools = lib.mkForce pkgs.clang-tools_16;
|
||||
tools.clang-tools = lib.mkForce pkgs.clang-tools_18;
|
||||
};
|
||||
|
||||
devShells.default = pkgs.mkShell {
|
||||
|
@ -203,7 +203,10 @@ class ResourceFolderModelTest : public QObject {
|
||||
|
||||
QCOMPARE(model.size(), 0);
|
||||
|
||||
{ EXEC_UPDATE_TASK(model.installResource(folder_resource), QVERIFY) } {
|
||||
{
|
||||
EXEC_UPDATE_TASK(model.installResource(folder_resource), QVERIFY)
|
||||
}
|
||||
{
|
||||
EXEC_UPDATE_TASK(model.installResource(file_mod), QVERIFY)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user