diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8077ea59a..4fb2d6794 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -594,7 +594,7 @@ jobs: flatpak: runs-on: ubuntu-latest container: - image: bilelmoussaoui/flatpak-github-actions:kde-5.15-22.08 + image: bilelmoussaoui/flatpak-github-actions:kde-5.15-23.08 options: --privileged steps: - name: Checkout diff --git a/flake.lock b/flake.lock index 70c8cba4f..3422af0ac 100644 --- a/flake.lock +++ b/flake.lock @@ -106,11 +106,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1699343069, - "narHash": "sha256-s7BBhyLA6MI6FuJgs4F/SgpntHBzz40/qV0xLPW6A1Q=", + "lastModified": 1700108881, + "narHash": "sha256-+Lqybl8kj0+nD/IlAWPPG/RDTa47gff9nbei0u7BntE=", "owner": "nixos", "repo": "nixpkgs", - "rev": "ec750fd01963ab6b20ee1f0cb488754e8036d89d", + "rev": "7414e9ee0b3e9903c24d3379f577a417f0aae5f1", "type": "github" }, "original": { @@ -153,11 +153,11 @@ ] }, "locked": { - "lastModified": 1699271226, - "narHash": "sha256-8Jt1KW3xTjolD6c6OjJm9USx/jmL+VVmbooADCkdDfU=", + "lastModified": 1700064067, + "narHash": "sha256-1ZWNDzhu8UlVCK7+DUN9dVQfiHX1bv6OQP9VxstY/gs=", "owner": "cachix", "repo": "pre-commit-hooks.nix", - "rev": "ea758da1a6dcde6dc36db348ed690d09b9864128", + "rev": "e558068cba67b23b4fbc5537173dbb43748a17e8", "type": "github" }, "original": { diff --git a/flatpak/org.prismlauncher.PrismLauncher.yml b/flatpak/org.prismlauncher.PrismLauncher.yml index 46b6da36a..89727751e 100644 --- a/flatpak/org.prismlauncher.PrismLauncher.yml +++ b/flatpak/org.prismlauncher.PrismLauncher.yml @@ -1,6 +1,6 @@ id: org.prismlauncher.PrismLauncher runtime: org.kde.Platform -runtime-version: "5.15-22.08" +runtime-version: "5.15-23.08" sdk: org.kde.Sdk sdk-extensions: - org.freedesktop.Sdk.Extension.openjdk17 @@ -113,6 +113,9 @@ modules: version-query: .tag_name url-query: .tarball_url timestamp-query: .published_at + # from https://github.com/flathub/net.gaijin.WarThunder/blob/7ea6f7a9f84b9c77150c003a7059dc03f8dcbc7f/gamemode.patch + - type: patch + path: patches/gamemode.patch cleanup: - /include - /lib/pkgconfig diff --git a/flatpak/patches/gamemode.patch b/flatpak/patches/gamemode.patch new file mode 100644 index 000000000..3cc0d7412 --- /dev/null +++ b/flatpak/patches/gamemode.patch @@ -0,0 +1,12 @@ +diff -ruN a/common/common-pidfds.c b/common/common-pidfds.c +--- a/common/common-pidfds.c 2021-02-18 20:00:12.000000000 +0100 ++++ b/common/common-pidfds.c 2023-09-07 08:57:42.954362763 +0200 +@@ -58,6 +58,8 @@ + { + return (int)syscall(__NR_pidfd_open, pid, flags); + } ++#else ++#include + #endif + + /* pidfd functions */ diff --git a/garnix.yaml b/garnix.yaml index 3bf145248..6cf8f7214 100644 --- a/garnix.yaml +++ b/garnix.yaml @@ -1,5 +1,6 @@ builds: - exclude: [] + exclude: + - "*.x86_64-darwin.*" include: - "checks.x86_64-linux.*" - "devShells.*.*" diff --git a/launcher/DesktopServices.cpp b/launcher/DesktopServices.cpp index 004e5e085..17eb7c2df 100644 --- a/launcher/DesktopServices.cpp +++ b/launcher/DesktopServices.cpp @@ -108,12 +108,9 @@ bool openDirectory(const QString& path, [[maybe_unused]] bool ensureExists) #if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD) if (!isSandbox()) { return IndirectOpen(f); - } else { - return f(); } -#else - return f(); #endif + return f(); } bool openFile(const QString& path) diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 7cb4100ea..e2769f2f4 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -565,6 +565,22 @@ QProcessEnvironment MinecraftInstance::createEnvironment() for (auto it = variables.begin(); it != variables.end(); ++it) { env.insert(it.key(), it.value()); } + // custom env + + auto insertEnv = [&env](QMap envMap) { + if (envMap.isEmpty()) + return; + + for (auto iter = envMap.begin(); iter != envMap.end(); iter++) + env.insert(iter.key(), iter.value().toString()); + }; + + bool overrideEnv = settings()->get("OverrideEnv").toBool(); + + if (!overrideEnv) + insertEnv(APPLICATION->settings()->get("Env").toMap()); + else + insertEnv(settings()->get("Env").toMap()); return env; } @@ -606,24 +622,6 @@ QProcessEnvironment MinecraftInstance::createLaunchEnvironment() env.insert("__GLX_VENDOR_LIBRARY_NAME", "nvidia"); } #endif - - // custom env - - auto insertEnv = [&env](QMap envMap) { - if (envMap.isEmpty()) - return; - - for (auto iter = envMap.begin(); iter != envMap.end(); iter++) - env.insert(iter.key(), iter.value().toString()); - }; - - bool overrideEnv = settings()->get("OverrideEnv").toBool(); - - if (!overrideEnv) - insertEnv(APPLICATION->settings()->get("Env").toMap()); - else - insertEnv(settings()->get("Env").toMap()); - return env; } diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index 11f7cd0f1..fc543202f 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -37,9 +37,9 @@ #include "ModFolderModel.h" #include -#include #include #include +#include #include #include #include @@ -65,8 +65,8 @@ ModFolderModel::ModFolderModel(const QString& dir, BaseInstance* instance, bool m_column_names = QStringList({ "Enable", "Image", "Name", "Version", "Last Modified", "Provider" }); m_column_names_translated = QStringList({ tr("Enable"), tr("Image"), tr("Name"), tr("Version"), tr("Last Modified"), tr("Provider") }); m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::VERSION, SortType::DATE, SortType::PROVIDER }; - m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Interactive, QHeaderView::Stretch, - QHeaderView::ResizeToContents, QHeaderView::ResizeToContents, QHeaderView::ResizeToContents }; + m_column_resize_modes = { QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Stretch, + QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Interactive }; m_columnsHideable = { false, true, false, true, true, true }; } diff --git a/launcher/minecraft/mod/ResourceFolderModel.cpp b/launcher/minecraft/mod/ResourceFolderModel.cpp index 80524678c..0c3fb6933 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.cpp +++ b/launcher/minecraft/mod/ResourceFolderModel.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -516,36 +517,22 @@ void ResourceFolderModel::setupHeaderAction(QAction* act, int column) act->setText(columnNames().at(column)); } -void ResourceFolderModel::saveHiddenColumn(int column, bool hidden) +void ResourceFolderModel::saveColumns(QTreeView* tree) { - auto const setting_name = QString("UI/%1_Page/HiddenColumns").arg(id()); + auto const setting_name = QString("UI/%1_Page/Columns").arg(id()); auto setting = (m_instance->settings()->contains(setting_name)) ? m_instance->settings()->getSetting(setting_name) : m_instance->settings()->registerSetting(setting_name); - auto hiddenColumns = setting->get().toStringList(); - auto name = columnNames(false).at(column); - auto index = hiddenColumns.indexOf(name); - if (index >= 0 && !hidden) { - hiddenColumns.removeAt(index); - } else if (index < 0 && hidden) { - hiddenColumns.append(name); - } - setting->set(hiddenColumns); + setting->set(tree->header()->saveState()); } -void ResourceFolderModel::loadHiddenColumns(QTreeView* tree) +void ResourceFolderModel::loadColumns(QTreeView* tree) { - auto const setting_name = QString("UI/%1_Page/HiddenColumns").arg(id()); + auto const setting_name = QString("UI/%1_Page/Columns").arg(id()); auto setting = (m_instance->settings()->contains(setting_name)) ? m_instance->settings()->getSetting(setting_name) : m_instance->settings()->registerSetting(setting_name); - auto hiddenColumns = setting->get().toStringList(); - auto col_names = columnNames(false); - for (auto col_name : hiddenColumns) { - auto index = col_names.indexOf(col_name); - if (index >= 0) - tree->setColumnHidden(index, true); - } + tree->header()->restoreState(setting->get().toByteArray()); } QMenu* ResourceFolderModel::createHeaderContextMenu(QTreeView* tree) @@ -570,7 +557,7 @@ QMenu* ResourceFolderModel::createHeaderContextMenu(QTreeView* tree) if (m_column_resize_modes.at(c) == QHeaderView::ResizeToContents) tree->resizeColumnToContents(c); } - saveHiddenColumn(col, !toggled); + saveColumns(tree); }); menu->addAction(act); diff --git a/launcher/minecraft/mod/ResourceFolderModel.h b/launcher/minecraft/mod/ResourceFolderModel.h index 60b8879c0..b3f6d9a58 100644 --- a/launcher/minecraft/mod/ResourceFolderModel.h +++ b/launcher/minecraft/mod/ResourceFolderModel.h @@ -117,8 +117,8 @@ class ResourceFolderModel : public QAbstractListModel { [[nodiscard]] QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; void setupHeaderAction(QAction* act, int column); - void saveHiddenColumn(int column, bool hidden); - void loadHiddenColumns(QTreeView* tree); + void saveColumns(QTreeView* tree); + void loadColumns(QTreeView* tree); QMenu* createHeaderContextMenu(QTreeView* tree); /** This creates a proxy model to filter / sort the model for a UI. @@ -201,8 +201,7 @@ class ResourceFolderModel : public QAbstractListModel { QList m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::DATE }; QStringList m_column_names = { "Enable", "Name", "Last Modified" }; QStringList m_column_names_translated = { tr("Enable"), tr("Name"), tr("Last Modified") }; - QList m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Stretch, - QHeaderView::ResizeToContents }; + QList m_column_resize_modes = { QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::Interactive }; QList m_columnsHideable = { false, false, true }; QDir m_dir; diff --git a/launcher/minecraft/mod/ResourcePackFolderModel.cpp b/launcher/minecraft/mod/ResourcePackFolderModel.cpp index efe1cc5dd..693b8af05 100644 --- a/launcher/minecraft/mod/ResourcePackFolderModel.cpp +++ b/launcher/minecraft/mod/ResourcePackFolderModel.cpp @@ -52,8 +52,8 @@ ResourcePackFolderModel::ResourcePackFolderModel(const QString& dir, BaseInstanc m_column_names = QStringList({ "Enable", "Image", "Name", "Pack Format", "Last Modified" }); m_column_names_translated = QStringList({ tr("Enable"), tr("Image"), tr("Name"), tr("Pack Format"), tr("Last Modified") }); m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::PACK_FORMAT, SortType::DATE }; - m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::ResizeToContents, - QHeaderView::ResizeToContents }; + m_column_resize_modes = { QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::Interactive, + QHeaderView::Interactive }; m_columnsHideable = { false, true, false, true, true }; } diff --git a/launcher/minecraft/mod/TexturePackFolderModel.cpp b/launcher/minecraft/mod/TexturePackFolderModel.cpp index e39be1fb9..f210501c7 100644 --- a/launcher/minecraft/mod/TexturePackFolderModel.cpp +++ b/launcher/minecraft/mod/TexturePackFolderModel.cpp @@ -47,8 +47,7 @@ TexturePackFolderModel::TexturePackFolderModel(const QString& dir, BaseInstance* m_column_names = QStringList({ "Enable", "Image", "Name", "Last Modified" }); m_column_names_translated = QStringList({ tr("Enable"), tr("Image"), tr("Name"), tr("Last Modified") }); m_column_sort_keys = { SortType::ENABLED, SortType::NAME, SortType::NAME, SortType::DATE }; - m_column_resize_modes = { QHeaderView::ResizeToContents, QHeaderView::Interactive, QHeaderView::Stretch, - QHeaderView::ResizeToContents }; + m_column_resize_modes = { QHeaderView::Interactive, QHeaderView::Interactive, QHeaderView::Stretch, QHeaderView::Interactive }; m_columnsHideable = { false, true, false, true }; } diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 1da982dad..7b4d1c8a5 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1198,17 +1198,27 @@ void MainWindow::on_actionViewCentralModsFolder_triggered() void MainWindow::on_actionViewIconThemeFolder_triggered() { - DesktopServices::openDirectory(APPLICATION->themeManager()->getIconThemesFolder().path()); + DesktopServices::openDirectory(APPLICATION->themeManager()->getIconThemesFolder().path(), true); } void MainWindow::on_actionViewWidgetThemeFolder_triggered() { - DesktopServices::openDirectory(APPLICATION->themeManager()->getApplicationThemesFolder().path()); + DesktopServices::openDirectory(APPLICATION->themeManager()->getApplicationThemesFolder().path(), true); } void MainWindow::on_actionViewCatPackFolder_triggered() { - DesktopServices::openDirectory(APPLICATION->themeManager()->getCatPacksFolder().path()); + DesktopServices::openDirectory(APPLICATION->themeManager()->getCatPacksFolder().path(), true); +} + +void MainWindow::on_actionViewIconsFolder_triggered() +{ + DesktopServices::openDirectory(APPLICATION->icons()->getDirectory(), true); +} + +void MainWindow::on_actionViewLogsFolder_triggered() +{ + DesktopServices::openDirectory("logs", true); } void MainWindow::refreshInstances() diff --git a/launcher/ui/MainWindow.h b/launcher/ui/MainWindow.h index 0b7287404..d2e154643 100644 --- a/launcher/ui/MainWindow.h +++ b/launcher/ui/MainWindow.h @@ -117,6 +117,8 @@ class MainWindow : public QMainWindow { void on_actionViewIconThemeFolder_triggered(); void on_actionViewWidgetThemeFolder_triggered(); void on_actionViewCatPackFolder_triggered(); + void on_actionViewIconsFolder_triggered(); + void on_actionViewLogsFolder_triggered(); void on_actionViewSelectedInstFolder_triggered(); diff --git a/launcher/ui/MainWindow.ui b/launcher/ui/MainWindow.ui index 91b2c2703..1ee3a5632 100644 --- a/launcher/ui/MainWindow.ui +++ b/launcher/ui/MainWindow.ui @@ -194,6 +194,9 @@ + + + @@ -545,10 +548,10 @@ .. - View &Instance Folder + &Instances - Open the instance folder in a file browser. + Open the instances folder in a file browser. @@ -557,7 +560,7 @@ .. - View Launcher &Root Folder + Launcher &Root Open the launcher's root folder in a file browser. @@ -569,12 +572,36 @@ .. - View &Central Mods Folder + &Central Mods Open the central mods folder in a file browser. + + + + .. + + + Instance Icons + + + Open the instance icons folder in a file browser. + + + + + + .. + + + Logs + + + Open the logs folder in a file browser. + + Themes @@ -718,10 +745,10 @@ .. - View &Widget Themes Folder + &Widget Themes - View Widget Theme Folder + Open the widget themes folder in a file browser. @@ -730,18 +757,22 @@ .. - View I&con Theme Folder + I&con Theme - View Icon Theme Folder + Open the icon theme folder in a file browser. - + + .. - View Cat Packs Folder + Cat Packs + + + Open the cat packs folder in a file browser. diff --git a/launcher/ui/dialogs/ModUpdateDialog.cpp b/launcher/ui/dialogs/ModUpdateDialog.cpp index 298bdad97..cbaaf88b9 100644 --- a/launcher/ui/dialogs/ModUpdateDialog.cpp +++ b/launcher/ui/dialogs/ModUpdateDialog.cpp @@ -39,7 +39,8 @@ static std::optional mcLoaders(BaseInstance* inst) ModUpdateDialog::ModUpdateDialog(QWidget* parent, BaseInstance* instance, const std::shared_ptr mods, - QList& search_for) + QList& search_for, + bool includeDeps) : ReviewMessageBox(parent, tr("Confirm mods to update"), "") , m_parent(parent) , m_mod_model(mods) @@ -47,6 +48,7 @@ ModUpdateDialog::ModUpdateDialog(QWidget* parent, , m_second_try_metadata( new ConcurrentTask(nullptr, "Second Metadata Search", APPLICATION->settings()->get("NumberOfConcurrentTasks").toInt())) , m_instance(instance) + , m_include_deps(includeDeps) { ReviewMessageBox::setGeometry(0, 0, 800, 600); @@ -186,7 +188,7 @@ void ModUpdateDialog::checkCandidates() } } - if (!APPLICATION->settings()->get("ModDependenciesDisabled").toBool()) { // dependencies + if (m_include_deps && !APPLICATION->settings()->get("ModDependenciesDisabled").toBool()) { // dependencies auto depTask = makeShared(this, m_instance, m_mod_model.get(), selectedVers); connect(depTask.get(), &Task::failed, this, diff --git a/launcher/ui/dialogs/ModUpdateDialog.h b/launcher/ui/dialogs/ModUpdateDialog.h index b79aa4943..98f6780bf 100644 --- a/launcher/ui/dialogs/ModUpdateDialog.h +++ b/launcher/ui/dialogs/ModUpdateDialog.h @@ -19,7 +19,8 @@ class ModUpdateDialog final : public ReviewMessageBox { explicit ModUpdateDialog(QWidget* parent, BaseInstance* instance, const std::shared_ptr mod_model, - QList& search_for); + QList& search_for, + bool includeDeps); void checkCandidates(); @@ -61,4 +62,5 @@ class ModUpdateDialog final : public ReviewMessageBox { bool m_no_updates = false; bool m_aborted = false; + bool m_include_deps = false; }; diff --git a/launcher/ui/pages/global/APIPage.ui b/launcher/ui/pages/global/APIPage.ui index 492741ba4..93591e440 100644 --- a/launcher/ui/pages/global/APIPage.ui +++ b/launcher/ui/pages/global/APIPage.ui @@ -209,6 +209,9 @@ <html><head/><body><p>Note: you only need to set this to access private data. Read the <a href="https://docs.modrinth.com/api-spec/#section/Authentication">documentation</a> for more information.</p></body></html> + + true + diff --git a/launcher/ui/pages/global/AccountListPage.cpp b/launcher/ui/pages/global/AccountListPage.cpp index 3a21cdd9b..2fd8a0402 100644 --- a/launcher/ui/pages/global/AccountListPage.cpp +++ b/launcher/ui/pages/global/AccountListPage.cpp @@ -231,6 +231,7 @@ void AccountListPage::updateButtonStates() ui->actionNoDefault->setEnabled(true); ui->actionNoDefault->setChecked(false); } + ui->listView->resizeColumnToContents(3); } void AccountListPage::on_actionUploadSkin_triggered() diff --git a/launcher/ui/pages/global/JavaPage.ui b/launcher/ui/pages/global/JavaPage.ui index 5a547637c..fd16572d3 100644 --- a/launcher/ui/pages/global/JavaPage.ui +++ b/launcher/ui/pages/global/JavaPage.ui @@ -84,7 +84,7 @@ MiB - 128 + 8 1048576 @@ -106,7 +106,7 @@ MiB - 128 + 8 1048576 @@ -128,7 +128,7 @@ MiB - 64 + 4 999999999 diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.cpp b/launcher/ui/pages/instance/ExternalResourcesPage.cpp index ae42ee048..48a71b809 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.cpp +++ b/launcher/ui/pages/instance/ExternalResourcesPage.cpp @@ -42,6 +42,7 @@ #include "minecraft/mod/ResourceFolderModel.h" #include "ui/GuiUtil.h" +#include #include #include #include @@ -95,7 +96,8 @@ ExternalResourcesPage::ExternalResourcesPage(BaseInstance* instance, std::shared connect(viewHeader, &QHeaderView::customContextMenuRequested, this, &ExternalResourcesPage::ShowHeaderContextMenu); - m_model->loadHiddenColumns(ui->treeView); + m_model->loadColumns(ui->treeView); + connect(ui->treeView->header(), &QHeaderView::sectionResized, this, [this] { m_model->saveColumns(ui->treeView); }); } ExternalResourcesPage::~ExternalResourcesPage() diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.ui b/launcher/ui/pages/instance/ExternalResourcesPage.ui index ba703f77d..ff08e12d2 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.ui +++ b/launcher/ui/pages/instance/ExternalResourcesPage.ui @@ -70,6 +70,9 @@ + + true + Actions @@ -146,17 +149,6 @@ Download a new resource - - - false - - - Check for &Updates - - - Try to check or update all selected resources (all resources if none are selected) - - false @@ -168,15 +160,15 @@ Go to mods home page - + - false + true - Remove metadata + Check for &Updates - Remove mod's metadata + Try to check or update all selected resources (all resources if none are selected) diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.ui b/launcher/ui/pages/instance/InstanceSettingsPage.ui index ad348cc0b..3b06ac865 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.ui +++ b/launcher/ui/pages/instance/InstanceSettingsPage.ui @@ -155,7 +155,7 @@ MiB - 128 + 8 1048576 @@ -177,7 +177,7 @@ MiB - 128 + 8 1048576 @@ -199,7 +199,7 @@ MiB - 64 + 4 999999999 diff --git a/launcher/ui/pages/instance/ModFolderPage.cpp b/launcher/ui/pages/instance/ModFolderPage.cpp index 8df7c1418..46b71883b 100644 --- a/launcher/ui/pages/instance/ModFolderPage.cpp +++ b/launcher/ui/pages/instance/ModFolderPage.cpp @@ -84,50 +84,71 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, std::shared_ptr connect(ui->actionDownloadItem, &QAction::triggered, this, &ModFolderPage::installMods); + // update menu + auto updateMenu = ui->actionUpdateItem->menu(); + if (updateMenu) { + updateMenu->clear(); + } else { + 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 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); }); + + 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 actionRemoveItemMetadata = updateMenu->addAction(tr("Reset update metadata")); + actionRemoveItemMetadata->setToolTip(tr("Remove mod's metadata")); + connect(actionRemoveItemMetadata, &QAction::triggered, this, &ModFolderPage::deleteModMetadata); + actionRemoveItemMetadata->setEnabled(false); + + ui->actionUpdateItem->setMenu(updateMenu); + ui->actionUpdateItem->setToolTip(tr("Try to check or update all selected mods (all mods if none are selected)")); - ui->actionsToolbar->insertActionAfter(ui->actionAddItem, ui->actionUpdateItem); 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); - ui->actionRemoveItemMetadata->setToolTip(tr("Remove mod's metadata")); - ui->actionsToolbar->insertActionAfter(ui->actionRemoveItem, ui->actionRemoveItemMetadata); - connect(ui->actionRemoveItemMetadata, &QAction::triggered, this, &ModFolderPage::deleteModMetadata); - auto check_allow_update = [this] { return ui->treeView->selectionModel()->hasSelection() || !m_model->empty(); }; - connect(ui->treeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, [this, check_allow_update] { - ui->actionUpdateItem->setEnabled(check_allow_update()); + 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")); + 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")); - ui->actionRemoveItemMetadata->setToolTip(tr("Remove mod's metadata")); - } else { - ui->actionVisitItemPage->setText(tr("Visit mods' pages")); - ui->actionVisitItemPage->setToolTip(tr("Go to the pages of the selected mods")); + } 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); + }); - ui->actionRemoveItemMetadata->setToolTip(tr("Remove mods' metadata")); - } - ui->actionVisitItemPage->setEnabled(selected != 0); - ui->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::rowsInserted, this, - [this, check_allow_update] { ui->actionUpdateItem->setEnabled(check_allow_update()); }); + connect(mods.get(), &ModFolderModel::rowsRemoved, this, updateButtons); - connect(mods.get(), &ModFolderModel::rowsRemoved, this, - [this, check_allow_update] { ui->actionUpdateItem->setEnabled(check_allow_update()); }); - - connect(mods.get(), &ModFolderModel::updateFinished, this, - [this, check_allow_update] { ui->actionUpdateItem->setEnabled(check_allow_update()); }); + connect(mods.get(), &ModFolderModel::updateFinished, this, updateButtons); } } @@ -204,7 +225,7 @@ void ModFolderPage::installMods() } } -void ModFolderPage::updateMods() +void ModFolderPage::updateMods(bool includeDeps) { if (m_instance->typeName() != "Minecraft") return; // this is a null instance or a legacy instance @@ -236,7 +257,7 @@ void ModFolderPage::updateMods() if (use_all) mods_list = m_model->allMods(); - ModUpdateDialog update_dialog(this, m_instance, m_model, mods_list); + ModUpdateDialog update_dialog(this, m_instance, m_model, mods_list, includeDeps); update_dialog.checkCandidates(); if (update_dialog.aborted()) { diff --git a/launcher/ui/pages/instance/ModFolderPage.h b/launcher/ui/pages/instance/ModFolderPage.h index 0c654d0d1..4672350c6 100644 --- a/launcher/ui/pages/instance/ModFolderPage.h +++ b/launcher/ui/pages/instance/ModFolderPage.h @@ -64,7 +64,7 @@ class ModFolderPage : public ExternalResourcesPage { void deleteModMetadata(); void installMods(); - void updateMods(); + void updateMods(bool includeDeps = false); void visitModPages(); protected: diff --git a/launcher/ui/widgets/JavaSettingsWidget.cpp b/launcher/ui/widgets/JavaSettingsWidget.cpp index d2d921918..bd6b6b118 100644 --- a/launcher/ui/widgets/JavaSettingsWidget.cpp +++ b/launcher/ui/widgets/JavaSettingsWidget.cpp @@ -80,7 +80,7 @@ void JavaSettingsWidget::setupUi() m_minMemSpinBox = new QSpinBox(m_memoryGroupBox); m_minMemSpinBox->setObjectName(QStringLiteral("minMemSpinBox")); m_minMemSpinBox->setSuffix(QStringLiteral(" MiB")); - m_minMemSpinBox->setMinimum(128); + m_minMemSpinBox->setMinimum(8); m_minMemSpinBox->setMaximum(1048576); m_minMemSpinBox->setSingleStep(128); m_labelMinMem->setBuddy(m_minMemSpinBox); @@ -93,7 +93,7 @@ void JavaSettingsWidget::setupUi() m_maxMemSpinBox = new QSpinBox(m_memoryGroupBox); m_maxMemSpinBox->setObjectName(QStringLiteral("maxMemSpinBox")); m_maxMemSpinBox->setSuffix(QStringLiteral(" MiB")); - m_maxMemSpinBox->setMinimum(128); + m_maxMemSpinBox->setMinimum(8); m_maxMemSpinBox->setMaximum(1048576); m_maxMemSpinBox->setSingleStep(128); m_labelMaxMem->setBuddy(m_maxMemSpinBox); @@ -112,7 +112,7 @@ void JavaSettingsWidget::setupUi() m_permGenSpinBox = new QSpinBox(m_memoryGroupBox); m_permGenSpinBox->setObjectName(QStringLiteral("permGenSpinBox")); m_permGenSpinBox->setSuffix(QStringLiteral(" MiB")); - m_permGenSpinBox->setMinimum(64); + m_permGenSpinBox->setMinimum(4); m_permGenSpinBox->setMaximum(1048576); m_permGenSpinBox->setSingleStep(8); m_gridLayout_2->addWidget(m_permGenSpinBox, 2, 1, 1, 1); diff --git a/launcher/ui/widgets/ModListView.cpp b/launcher/ui/widgets/ModListView.cpp index c72d4c522..a38c7c86a 100644 --- a/launcher/ui/widgets/ModListView.cpp +++ b/launcher/ui/widgets/ModListView.cpp @@ -48,14 +48,14 @@ void ModListView::setModel(QAbstractItemModel* model) return; } if (!string.size()) { - head->setSectionResizeMode(0, QHeaderView::ResizeToContents); + head->setSectionResizeMode(0, QHeaderView::Interactive); head->setSectionResizeMode(1, QHeaderView::Stretch); for (int i = 2; i < head->count(); i++) - head->setSectionResizeMode(i, QHeaderView::ResizeToContents); + head->setSectionResizeMode(i, QHeaderView::Interactive); } else { head->setSectionResizeMode(0, QHeaderView::Stretch); for (int i = 1; i < head->count(); i++) - head->setSectionResizeMode(i, QHeaderView::ResizeToContents); + head->setSectionResizeMode(i, QHeaderView::Interactive); } }