From 6961a39cd20a63116bb562d61472c31f28ea8738 Mon Sep 17 00:00:00 2001 From: txtsd Date: Fri, 4 Nov 2022 11:58:58 +0530 Subject: feat: Assign java max mem based on system RAM If the system has <6GB RAM, it uses (system RAM / 1.5) If the system has >=6GB, it uses 4GB Signed-off-by: txtsd --- launcher/Application.cpp | 16 +++++++++++++++- launcher/Application.h | 2 ++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 5772d7ca..c3c76854 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -566,7 +566,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) // Memory m_settings->registerSetting({"MinMemAlloc", "MinMemoryAlloc"}, 512); - m_settings->registerSetting({"MaxMemAlloc", "MaxMemoryAlloc"}, 4096); + m_settings->registerSetting({"MaxMemAlloc", "MaxMemoryAlloc"}, suitableMaxMem()); m_settings->registerSetting("PermGen", 128); // Java Settings @@ -1633,3 +1633,17 @@ QString Application::getUserAgentUncached() return BuildConfig.USER_AGENT_UNCACHED; } + +int Application::suitableMaxMem() +{ + float totalRAM = (float)Sys::getSystemRam() / (float)Sys::mebibyte; + int maxMemoryAlloc; + + // If totalRAM < 6GB, use (totalRAM / 1.5), else 4GB + if (totalRAM < (4096 * 1.5)) + maxMemoryAlloc = (int) (totalRAM / 1.5); + else + maxMemoryAlloc = 4096; + + return maxMemoryAlloc; +} diff --git a/launcher/Application.h b/launcher/Application.h index 8fa0ab10..280c842f 100644 --- a/launcher/Application.h +++ b/launcher/Application.h @@ -198,6 +198,8 @@ public: void ShowGlobalSettings(class QWidget * parent, QString open_page = QString()); + int suitableMaxMem(); + signals: void updateAllowedChanged(bool status); void globalSettingsAboutToOpen(); -- cgit From e7e56eb1e397a528df91f9ce99f738c49bde363c Mon Sep 17 00:00:00 2001 From: Marcelo Hernandez Date: Sat, 22 Oct 2022 14:50:32 -0400 Subject: add more options to copy instance dialog - Copy game options, copy resource packs, copy shaders, copy servers, and copy mods - Also made a new InstanceCopyPrefs struct to store those options rather than passing 7 different booleans into InstanceCopyTask's constructor Signed-off-by: Marcelo Hernandez --- launcher/CMakeLists.txt | 1 + launcher/InstanceCopyPrefs.h | 18 ++++++ launcher/InstanceCopyTask.cpp | 62 +++++++++++++++++--- launcher/InstanceCopyTask.h | 20 ++++--- launcher/ui/MainWindow.cpp | 12 +++- launcher/ui/dialogs/CopyInstanceDialog.cpp | 90 ++++++++++++++++++++++++++++++ launcher/ui/dialogs/CopyInstanceDialog.h | 15 +++++ launcher/ui/dialogs/CopyInstanceDialog.ui | 58 ++++++++++++++++--- 8 files changed, 254 insertions(+), 22 deletions(-) create mode 100644 launcher/InstanceCopyPrefs.h diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 79ac49c7..77440cca 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -31,6 +31,7 @@ set(CORE_SOURCES # Basic instance manipulation tasks (derived from InstanceTask) InstanceCreationTask.h InstanceCreationTask.cpp + InstanceCopyPrefs.h InstanceCopyTask.h InstanceCopyTask.cpp InstanceImportTask.h diff --git a/launcher/InstanceCopyPrefs.h b/launcher/InstanceCopyPrefs.h new file mode 100644 index 00000000..ac2feab8 --- /dev/null +++ b/launcher/InstanceCopyPrefs.h @@ -0,0 +1,18 @@ +// +// Created by marcelohdez on 10/22/22. +// + +#ifndef LAUNCHER_INSTANCECOPYPREFS_H +#define LAUNCHER_INSTANCECOPYPREFS_H + +struct InstanceCopyPrefs { + bool copySaves; + bool keepPlaytime; + bool copyGameOptions; + bool copyResourcePacks; + bool copyShaderPacks; + bool copyServers; + bool copyMods; +}; + +#endif // LAUNCHER_INSTANCECOPYPREFS_H diff --git a/launcher/InstanceCopyTask.cpp b/launcher/InstanceCopyTask.cpp index b1e33884..360f6cfa 100644 --- a/launcher/InstanceCopyTask.cpp +++ b/launcher/InstanceCopyTask.cpp @@ -5,18 +5,66 @@ #include "pathmatcher/RegexpMatcher.h" #include -InstanceCopyTask::InstanceCopyTask(InstancePtr origInstance, bool copySaves, bool keepPlaytime) +InstanceCopyTask::InstanceCopyTask(InstancePtr origInstance, InstanceCopyPrefs prefs) { m_origInstance = origInstance; - m_keepPlaytime = keepPlaytime; + m_keepPlaytime = prefs.keepPlaytime; + QString filter; - if(!copySaves) + if(!prefs.copySaves) { - // FIXME: get this from the original instance type... - auto matcherReal = new RegexpMatcher("[.]?minecraft/saves"); - matcherReal->caseSensitive(false); - m_matcher.reset(matcherReal); + appendToFilter(filter, "saves"); } + + if(!prefs.copyGameOptions) { + appendToFilter(filter, "options.txt"); + } + + if(!prefs.copyResourcePacks) + { + appendToFilter(filter, "resourcepacks"); + appendToFilter(filter, "texturepacks"); + } + + if(!prefs.copyShaderPacks) + { + appendToFilter(filter, "shaderpacks"); + } + + if(!prefs.copyServers) + { + appendToFilter(filter, "servers.dat"); + appendToFilter(filter, "servers.dat_old"); + appendToFilter(filter, "server-resource-packs"); + } + + if(!prefs.copyMods) + { + appendToFilter(filter, "coremods"); + appendToFilter(filter, "mods"); + appendToFilter(filter, "config"); + } + + if (!filter.isEmpty()) + { + resetFromMatcher(filter); + } +} + +void InstanceCopyTask::appendToFilter(QString& filter, const QString &append) +{ + if (!filter.isEmpty()) + filter.append('|'); // OR regex + + filter.append("[.]?minecraft/" + append); +} + +void InstanceCopyTask::resetFromMatcher(const QString& regexp) +{ + // FIXME: get this from the original instance type... + auto matcherReal = new RegexpMatcher(regexp); + matcherReal->caseSensitive(false); + m_matcher.reset(matcherReal); } void InstanceCopyTask::executeTask() diff --git a/launcher/InstanceCopyTask.h b/launcher/InstanceCopyTask.h index 82901732..d66bec55 100644 --- a/launcher/InstanceCopyTask.h +++ b/launcher/InstanceCopyTask.h @@ -1,20 +1,21 @@ #pragma once -#include "tasks/Task.h" -#include "net/NetJob.h" -#include #include #include -#include "settings/SettingsObject.h" -#include "BaseVersion.h" +#include #include "BaseInstance.h" +#include "BaseVersion.h" +#include "InstanceCopyPrefs.h" #include "InstanceTask.h" +#include "net/NetJob.h" +#include "settings/SettingsObject.h" +#include "tasks/Task.h" class InstanceCopyTask : public InstanceTask { Q_OBJECT public: - explicit InstanceCopyTask(InstancePtr origInstance, bool copySaves, bool keepPlaytime); + explicit InstanceCopyTask(InstancePtr origInstance, InstanceCopyPrefs prefs); protected: //! Entry point for tasks. @@ -22,7 +23,12 @@ protected: void copyFinished(); void copyAborted(); -private: /* data */ +private: + // Helper functions to avoid repeating code + static void appendToFilter(QString &filter, const QString &append); + void resetFromMatcher(const QString ®exp); + + /* data */ InstancePtr m_origInstance; QFuture m_copyFuture; QFutureWatcher m_copyFutureWatcher; diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 97152a48..d51f799c 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1616,7 +1616,17 @@ void MainWindow::on_actionCopyInstance_triggered() if (!copyInstDlg.exec()) return; - auto copyTask = new InstanceCopyTask(m_selectedInstance, copyInstDlg.shouldCopySaves(), copyInstDlg.shouldKeepPlaytime()); + auto copyTask = new InstanceCopyTask( + m_selectedInstance, + InstanceCopyPrefs { + copyInstDlg.shouldCopySaves(), + copyInstDlg.shouldKeepPlaytime(), + copyInstDlg.shouldCopyGameOptions(), + copyInstDlg.shouldCopyResourcePacks(), + copyInstDlg.shouldCopyShaderPacks(), + copyInstDlg.shouldCopyServers(), + copyInstDlg.shouldCopyMods() + }); copyTask->setName(copyInstDlg.instName()); copyTask->setGroup(copyInstDlg.instGroup()); copyTask->setIcon(copyInstDlg.iconKey()); diff --git a/launcher/ui/dialogs/CopyInstanceDialog.cpp b/launcher/ui/dialogs/CopyInstanceDialog.cpp index 9ec341bc..d19888ed 100644 --- a/launcher/ui/dialogs/CopyInstanceDialog.cpp +++ b/launcher/ui/dialogs/CopyInstanceDialog.cpp @@ -80,6 +80,11 @@ CopyInstanceDialog::CopyInstanceDialog(InstancePtr original, QWidget *parent) ui->groupBox->lineEdit()->setPlaceholderText(tr("No group")); ui->copySavesCheckbox->setChecked(m_copySaves); ui->keepPlaytimeCheckbox->setChecked(m_keepPlaytime); + ui->copyGameOptionsCheckbox->setChecked(m_copyGameOptions); + ui->copyResPacksCheckbox->setChecked(m_copyResourcePacks); + ui->copyShaderPacksCheckbox->setChecked(m_copyShaderPacks); + ui->copyServersCheckbox->setChecked(m_copyServers); + ui->copyModsCheckbox->setChecked(m_copyMods); } CopyInstanceDialog::~CopyInstanceDialog() @@ -168,3 +173,88 @@ void CopyInstanceDialog::on_keepPlaytimeCheckbox_stateChanged(int state) m_keepPlaytime = true; } } + +bool CopyInstanceDialog::shouldCopyGameOptions() const +{ + return m_copyGameOptions; +} + +void CopyInstanceDialog::on_copyGameOptionsCheckbox_stateChanged(int state) +{ + if(state == Qt::Unchecked) + { + m_copyGameOptions = false; + } + else if(state == Qt::Checked) + { + m_copyGameOptions = true; + } +} + +bool CopyInstanceDialog::shouldCopyResourcePacks() const +{ + return m_copyResourcePacks; +} + +void CopyInstanceDialog::on_copyResPacksCheckbox_stateChanged(int state) +{ + if(state == Qt::Unchecked) + { + m_copyResourcePacks = false; + } + else if(state == Qt::Checked) + { + m_copyResourcePacks = true; + } +} + +bool CopyInstanceDialog::shouldCopyShaderPacks() const +{ + return m_copyShaderPacks; +} + +void CopyInstanceDialog::on_copyShaderPacksCheckbox_stateChanged(int state) +{ + if(state == Qt::Unchecked) + { + m_copyShaderPacks = false; + } + else if(state == Qt::Checked) + { + m_copyShaderPacks = true; + } +} + +bool CopyInstanceDialog::shouldCopyServers() const +{ + return m_copyServers; +} + +void CopyInstanceDialog::on_copyServersCheckbox_stateChanged(int state) +{ + if(state == Qt::Unchecked) + { + m_copyServers = false; + } + else if(state == Qt::Checked) + { + m_copyServers = true; + } +} + +bool CopyInstanceDialog::shouldCopyMods() const +{ + return m_copyMods; +} + +void CopyInstanceDialog::on_copyModsCheckbox_stateChanged(int state) +{ + if(state == Qt::Unchecked) + { + m_copyMods = false; + } + else if(state == Qt::Checked) + { + m_copyMods = true; + } +} diff --git a/launcher/ui/dialogs/CopyInstanceDialog.h b/launcher/ui/dialogs/CopyInstanceDialog.h index bf3cd920..e4c70494 100644 --- a/launcher/ui/dialogs/CopyInstanceDialog.h +++ b/launcher/ui/dialogs/CopyInstanceDialog.h @@ -41,6 +41,11 @@ public: QString iconKey() const; bool shouldCopySaves() const; bool shouldKeepPlaytime() const; + bool shouldCopyGameOptions() const; + bool shouldCopyResourcePacks() const; + bool shouldCopyShaderPacks() const; + bool shouldCopyServers() const; + bool shouldCopyMods() const; private slots: @@ -48,6 +53,11 @@ slots: void on_instNameTextBox_textChanged(const QString &arg1); void on_copySavesCheckbox_stateChanged(int state); void on_keepPlaytimeCheckbox_stateChanged(int state); + void on_copyGameOptionsCheckbox_stateChanged(int state); + void on_copyResPacksCheckbox_stateChanged(int state); + void on_copyShaderPacksCheckbox_stateChanged(int state); + void on_copyServersCheckbox_stateChanged(int state); + void on_copyModsCheckbox_stateChanged(int state); private: Ui::CopyInstanceDialog *ui; @@ -55,4 +65,9 @@ private: InstancePtr m_original; bool m_copySaves = true; bool m_keepPlaytime = true; + bool m_copyGameOptions = true; + bool m_copyResourcePacks = true; + bool m_copyShaderPacks = true; + bool m_copyServers = true; + bool m_copyMods = true; }; diff --git a/launcher/ui/dialogs/CopyInstanceDialog.ui b/launcher/ui/dialogs/CopyInstanceDialog.ui index f4b191e2..e89439e6 100644 --- a/launcher/ui/dialogs/CopyInstanceDialog.ui +++ b/launcher/ui/dialogs/CopyInstanceDialog.ui @@ -9,8 +9,8 @@ 0 0 - 345 - 323 + 265 + 425 @@ -33,7 +33,7 @@ - 40 + 60 20 @@ -123,6 +123,50 @@ + + + + Copy the in-game options like FOV, max framerate, etc. + + + Copy game options + + + + + + + true + + + Copy resource packs + + + + + + + Copy shader packs + + + + + + + Copy servers + + + + + + + Disabling this will still keep the mod loader (ex: Fabric, Quilt, etc.) but erase the mods folder and their configs. + + + Copy mods + + + @@ -153,8 +197,8 @@ accept() - 248 - 254 + 254 + 316 157 @@ -169,8 +213,8 @@ reject() - 316 - 260 + 322 + 316 286 -- cgit From 15593b5c0912b4fe5ad77d6a27e336e9b68ed861 Mon Sep 17 00:00:00 2001 From: Marcelo Hernandez Date: Sat, 22 Oct 2022 23:04:36 -0400 Subject: Add "Select all" checkbox + ui revamp + code cleanup Signed-off-by: Marcelo Hernandez --- launcher/CMakeLists.txt | 1 + launcher/InstanceCopyPrefs.cpp | 15 ++++ launcher/InstanceCopyPrefs.h | 3 + launcher/InstanceCopyTask.cpp | 4 +- launcher/InstanceCopyTask.h | 2 +- launcher/ui/MainWindow.cpp | 12 +-- launcher/ui/dialogs/CopyInstanceDialog.cpp | 96 ++++++++++---------- launcher/ui/dialogs/CopyInstanceDialog.h | 22 ++--- launcher/ui/dialogs/CopyInstanceDialog.ui | 136 ++++++++++++++++------------- 9 files changed, 150 insertions(+), 141 deletions(-) create mode 100644 launcher/InstanceCopyPrefs.cpp diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 77440cca..7dc060fb 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -32,6 +32,7 @@ set(CORE_SOURCES InstanceCreationTask.h InstanceCreationTask.cpp InstanceCopyPrefs.h + InstanceCopyPrefs.cpp InstanceCopyTask.h InstanceCopyTask.cpp InstanceImportTask.h diff --git a/launcher/InstanceCopyPrefs.cpp b/launcher/InstanceCopyPrefs.cpp new file mode 100644 index 00000000..56b43a03 --- /dev/null +++ b/launcher/InstanceCopyPrefs.cpp @@ -0,0 +1,15 @@ +// +// Created by marcelohdez on 10/22/22. +// + +#include "InstanceCopyPrefs.h" + +InstanceCopyPrefs::InstanceCopyPrefs(bool setAll) + : copySaves(setAll), + keepPlaytime(setAll), + copyGameOptions(setAll), + copyResourcePacks(setAll), + copyShaderPacks(setAll), + copyServers(setAll), + copyMods(setAll) +{} diff --git a/launcher/InstanceCopyPrefs.h b/launcher/InstanceCopyPrefs.h index ac2feab8..d360a8a7 100644 --- a/launcher/InstanceCopyPrefs.h +++ b/launcher/InstanceCopyPrefs.h @@ -6,6 +6,9 @@ #define LAUNCHER_INSTANCECOPYPREFS_H struct InstanceCopyPrefs { + explicit InstanceCopyPrefs(bool setAll); + ~InstanceCopyPrefs() = default; + bool copySaves; bool keepPlaytime; bool copyGameOptions; diff --git a/launcher/InstanceCopyTask.cpp b/launcher/InstanceCopyTask.cpp index 360f6cfa..e0f68224 100644 --- a/launcher/InstanceCopyTask.cpp +++ b/launcher/InstanceCopyTask.cpp @@ -5,7 +5,7 @@ #include "pathmatcher/RegexpMatcher.h" #include -InstanceCopyTask::InstanceCopyTask(InstancePtr origInstance, InstanceCopyPrefs prefs) +InstanceCopyTask::InstanceCopyTask(InstancePtr origInstance, const InstanceCopyPrefs& prefs) { m_origInstance = origInstance; m_keepPlaytime = prefs.keepPlaytime; @@ -51,7 +51,7 @@ InstanceCopyTask::InstanceCopyTask(InstancePtr origInstance, InstanceCopyPrefs p } } -void InstanceCopyTask::appendToFilter(QString& filter, const QString &append) +void InstanceCopyTask::appendToFilter(QString& filter, const QString& append) { if (!filter.isEmpty()) filter.append('|'); // OR regex diff --git a/launcher/InstanceCopyTask.h b/launcher/InstanceCopyTask.h index d66bec55..4abbf6e6 100644 --- a/launcher/InstanceCopyTask.h +++ b/launcher/InstanceCopyTask.h @@ -15,7 +15,7 @@ class InstanceCopyTask : public InstanceTask { Q_OBJECT public: - explicit InstanceCopyTask(InstancePtr origInstance, InstanceCopyPrefs prefs); + explicit InstanceCopyTask(InstancePtr origInstance, const InstanceCopyPrefs& prefs); protected: //! Entry point for tasks. diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index d51f799c..08005b86 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1616,17 +1616,7 @@ void MainWindow::on_actionCopyInstance_triggered() if (!copyInstDlg.exec()) return; - auto copyTask = new InstanceCopyTask( - m_selectedInstance, - InstanceCopyPrefs { - copyInstDlg.shouldCopySaves(), - copyInstDlg.shouldKeepPlaytime(), - copyInstDlg.shouldCopyGameOptions(), - copyInstDlg.shouldCopyResourcePacks(), - copyInstDlg.shouldCopyShaderPacks(), - copyInstDlg.shouldCopyServers(), - copyInstDlg.shouldCopyMods() - }); + auto copyTask = new InstanceCopyTask(m_selectedInstance, copyInstDlg.getChosenOptions()); copyTask->setName(copyInstDlg.instName()); copyTask->setGroup(copyInstDlg.instGroup()); copyTask->setIcon(copyInstDlg.iconKey()); diff --git a/launcher/ui/dialogs/CopyInstanceDialog.cpp b/launcher/ui/dialogs/CopyInstanceDialog.cpp index d19888ed..0a23cd34 100644 --- a/launcher/ui/dialogs/CopyInstanceDialog.cpp +++ b/launcher/ui/dialogs/CopyInstanceDialog.cpp @@ -78,13 +78,13 @@ CopyInstanceDialog::CopyInstanceDialog(InstancePtr original, QWidget *parent) } ui->groupBox->setCurrentIndex(index); ui->groupBox->lineEdit()->setPlaceholderText(tr("No group")); - ui->copySavesCheckbox->setChecked(m_copySaves); - ui->keepPlaytimeCheckbox->setChecked(m_keepPlaytime); - ui->copyGameOptionsCheckbox->setChecked(m_copyGameOptions); - ui->copyResPacksCheckbox->setChecked(m_copyResourcePacks); - ui->copyShaderPacksCheckbox->setChecked(m_copyShaderPacks); - ui->copyServersCheckbox->setChecked(m_copyServers); - ui->copyModsCheckbox->setChecked(m_copyMods); + ui->copySavesCheckbox->setChecked(m_selectedOptions.copySaves); + ui->keepPlaytimeCheckbox->setChecked(m_selectedOptions.keepPlaytime); + ui->copyGameOptionsCheckbox->setChecked(m_selectedOptions.copyGameOptions); + ui->copyResPacksCheckbox->setChecked(m_selectedOptions.copyResourcePacks); + ui->copyShaderPacksCheckbox->setChecked(m_selectedOptions.copyShaderPacks); + ui->copyServersCheckbox->setChecked(m_selectedOptions.copyServers); + ui->copyModsCheckbox->setChecked(m_selectedOptions.copyMods); } CopyInstanceDialog::~CopyInstanceDialog() @@ -139,122 +139,118 @@ void CopyInstanceDialog::on_instNameTextBox_textChanged(const QString &arg1) updateDialogState(); } -bool CopyInstanceDialog::shouldCopySaves() const +const InstanceCopyPrefs& CopyInstanceDialog::getChosenOptions() const { - return m_copySaves; + return m_selectedOptions; } -void CopyInstanceDialog::on_copySavesCheckbox_stateChanged(int state) +void CopyInstanceDialog::on_selectAllCheckbox_stateChanged(int state) { + bool checked; if(state == Qt::Unchecked) { - m_copySaves = false; + checked = false; } else if(state == Qt::Checked) { - m_copySaves = true; + checked = true; } + + checkAllCheckboxes(checked); } -bool CopyInstanceDialog::shouldKeepPlaytime() const +void CopyInstanceDialog::checkAllCheckboxes(bool b) { - return m_keepPlaytime; + ui->keepPlaytimeCheckbox->setChecked(b); + ui->copySavesCheckbox->setChecked(b); + ui->copyGameOptionsCheckbox->setChecked(b); + ui->copyResPacksCheckbox->setChecked(b); + ui->copyShaderPacksCheckbox->setChecked(b); + ui->copyServersCheckbox->setChecked(b); + ui->copyModsCheckbox->setChecked(b); } - -void CopyInstanceDialog::on_keepPlaytimeCheckbox_stateChanged(int state) +void CopyInstanceDialog::on_copySavesCheckbox_stateChanged(int state) { if(state == Qt::Unchecked) { - m_keepPlaytime = false; + m_selectedOptions.copySaves = false; } else if(state == Qt::Checked) { - m_keepPlaytime = true; + m_selectedOptions.copySaves = true; } } -bool CopyInstanceDialog::shouldCopyGameOptions() const -{ - return m_copyGameOptions; -} -void CopyInstanceDialog::on_copyGameOptionsCheckbox_stateChanged(int state) +void CopyInstanceDialog::on_keepPlaytimeCheckbox_stateChanged(int state) { if(state == Qt::Unchecked) { - m_copyGameOptions = false; + m_selectedOptions.keepPlaytime = false; } else if(state == Qt::Checked) { - m_copyGameOptions = true; + m_selectedOptions.keepPlaytime = true; } } -bool CopyInstanceDialog::shouldCopyResourcePacks() const +void CopyInstanceDialog::on_copyGameOptionsCheckbox_stateChanged(int state) { - return m_copyResourcePacks; + if(state == Qt::Unchecked) + { + m_selectedOptions.copyGameOptions = false; + } + else if(state == Qt::Checked) + { + m_selectedOptions.copyGameOptions = true; + } } void CopyInstanceDialog::on_copyResPacksCheckbox_stateChanged(int state) { if(state == Qt::Unchecked) { - m_copyResourcePacks = false; + m_selectedOptions.copyResourcePacks = false; } else if(state == Qt::Checked) { - m_copyResourcePacks = true; + m_selectedOptions.copyResourcePacks = true; } } -bool CopyInstanceDialog::shouldCopyShaderPacks() const -{ - return m_copyShaderPacks; -} - void CopyInstanceDialog::on_copyShaderPacksCheckbox_stateChanged(int state) { if(state == Qt::Unchecked) { - m_copyShaderPacks = false; + m_selectedOptions.copyShaderPacks = false; } else if(state == Qt::Checked) { - m_copyShaderPacks = true; + m_selectedOptions.copyShaderPacks = true; } } -bool CopyInstanceDialog::shouldCopyServers() const -{ - return m_copyServers; -} - void CopyInstanceDialog::on_copyServersCheckbox_stateChanged(int state) { if(state == Qt::Unchecked) { - m_copyServers = false; + m_selectedOptions.copyServers = false; } else if(state == Qt::Checked) { - m_copyServers = true; + m_selectedOptions.copyServers = true; } } -bool CopyInstanceDialog::shouldCopyMods() const -{ - return m_copyMods; -} - void CopyInstanceDialog::on_copyModsCheckbox_stateChanged(int state) { if(state == Qt::Unchecked) { - m_copyMods = false; + m_selectedOptions.copyMods = false; } else if(state == Qt::Checked) { - m_copyMods = true; + m_selectedOptions.copyMods = true; } } diff --git a/launcher/ui/dialogs/CopyInstanceDialog.h b/launcher/ui/dialogs/CopyInstanceDialog.h index e4c70494..e57de0a1 100644 --- a/launcher/ui/dialogs/CopyInstanceDialog.h +++ b/launcher/ui/dialogs/CopyInstanceDialog.h @@ -17,7 +17,7 @@ #include #include "BaseVersion.h" -#include +#include "InstanceCopyPrefs.h" class BaseInstance; @@ -39,18 +39,16 @@ public: QString instName() const; QString instGroup() const; QString iconKey() const; - bool shouldCopySaves() const; - bool shouldKeepPlaytime() const; - bool shouldCopyGameOptions() const; - bool shouldCopyResourcePacks() const; - bool shouldCopyShaderPacks() const; - bool shouldCopyServers() const; - bool shouldCopyMods() const; + const InstanceCopyPrefs& getChosenOptions() const; private slots: void on_iconButton_clicked(); void on_instNameTextBox_textChanged(const QString &arg1); + + // Checkbox options: + void checkAllCheckboxes(bool b); + void on_selectAllCheckbox_stateChanged(int state); void on_copySavesCheckbox_stateChanged(int state); void on_keepPlaytimeCheckbox_stateChanged(int state); void on_copyGameOptionsCheckbox_stateChanged(int state); @@ -63,11 +61,5 @@ private: Ui::CopyInstanceDialog *ui; QString InstIconKey; InstancePtr m_original; - bool m_copySaves = true; - bool m_keepPlaytime = true; - bool m_copyGameOptions = true; - bool m_copyResourcePacks = true; - bool m_copyShaderPacks = true; - bool m_copyServers = true; - bool m_copyMods = true; + InstanceCopyPrefs m_selectedOptions = InstanceCopyPrefs(true); // Default to all options as true }; diff --git a/launcher/ui/dialogs/CopyInstanceDialog.ui b/launcher/ui/dialogs/CopyInstanceDialog.ui index e89439e6..822ed797 100644 --- a/launcher/ui/dialogs/CopyInstanceDialog.ui +++ b/launcher/ui/dialogs/CopyInstanceDialog.ui @@ -9,8 +9,8 @@ 0 0 - 265 - 425 + 341 + 385 @@ -60,7 +60,7 @@ - 40 + 60 20 @@ -83,7 +83,10 @@ - + + + 6 + @@ -110,62 +113,73 @@ - - - Copy saves - - - - - - - Keep play time - - - - - - - Copy the in-game options like FOV, max framerate, etc. - - - Copy game options - - - - - - - true - - - Copy resource packs - - - - - - - Copy shader packs - - - - - - - Copy servers - - - - - - - Disabling this will still keep the mod loader (ex: Fabric, Quilt, etc.) but erase the mods folder and their configs. - - - Copy mods - - + + + + + Copy saves + + + + + + + true + + + Copy resource packs + + + + + + + Disabling this will still keep the mod loader (ex: Fabric, Quilt, etc.) but erase the mods folder and their configs. + + + Copy mods + + + + + + + Copy the in-game options like FOV, max framerate, etc. + + + Copy game options + + + + + + + Copy servers + + + + + + + Keep play time + + + + + + + Copy shader packs + + + + + + + Select all + + + + @@ -183,8 +197,6 @@ iconButton instNameTextBox groupBox - copySavesCheckbox - keepPlaytimeCheckbox -- cgit From 4caf06bc99dfe34f10fae943374c98b88ad8814d Mon Sep 17 00:00:00 2001 From: Marcelo Hernandez Date: Sun, 23 Oct 2022 00:25:38 -0400 Subject: Check "Select all" checkbox if all options are already selected + code cleanup Signed-off-by: Marcelo Hernandez --- launcher/InstanceCopyPrefs.cpp | 19 ++--- launcher/InstanceCopyPrefs.h | 17 ++-- launcher/ui/dialogs/CopyInstanceDialog.cpp | 124 ++++++++++------------------- launcher/ui/dialogs/CopyInstanceDialog.h | 6 +- 4 files changed, 65 insertions(+), 101 deletions(-) diff --git a/launcher/InstanceCopyPrefs.cpp b/launcher/InstanceCopyPrefs.cpp index 56b43a03..fad55d1e 100644 --- a/launcher/InstanceCopyPrefs.cpp +++ b/launcher/InstanceCopyPrefs.cpp @@ -4,12 +4,13 @@ #include "InstanceCopyPrefs.h" -InstanceCopyPrefs::InstanceCopyPrefs(bool setAll) - : copySaves(setAll), - keepPlaytime(setAll), - copyGameOptions(setAll), - copyResourcePacks(setAll), - copyShaderPacks(setAll), - copyServers(setAll), - copyMods(setAll) -{} +bool InstanceCopyPrefs::allTrue() const +{ + return copySaves && + keepPlaytime && + copyGameOptions && + copyResourcePacks && + copyShaderPacks && + copyServers && + copyMods; +} diff --git a/launcher/InstanceCopyPrefs.h b/launcher/InstanceCopyPrefs.h index d360a8a7..c5c1a7ae 100644 --- a/launcher/InstanceCopyPrefs.h +++ b/launcher/InstanceCopyPrefs.h @@ -6,16 +6,15 @@ #define LAUNCHER_INSTANCECOPYPREFS_H struct InstanceCopyPrefs { - explicit InstanceCopyPrefs(bool setAll); - ~InstanceCopyPrefs() = default; + bool copySaves = true; + bool keepPlaytime = true; + bool copyGameOptions = true; + bool copyResourcePacks = true; + bool copyShaderPacks = true; + bool copyServers = true; + bool copyMods = true; - bool copySaves; - bool keepPlaytime; - bool copyGameOptions; - bool copyResourcePacks; - bool copyShaderPacks; - bool copyServers; - bool copyMods; + bool allTrue() const; }; #endif // LAUNCHER_INSTANCECOPYPREFS_H diff --git a/launcher/ui/dialogs/CopyInstanceDialog.cpp b/launcher/ui/dialogs/CopyInstanceDialog.cpp index 0a23cd34..44e70012 100644 --- a/launcher/ui/dialogs/CopyInstanceDialog.cpp +++ b/launcher/ui/dialogs/CopyInstanceDialog.cpp @@ -122,6 +122,40 @@ QString CopyInstanceDialog::instGroup() const return ui->groupBox->currentText(); } +const InstanceCopyPrefs& CopyInstanceDialog::getChosenOptions() const +{ + return m_selectedOptions; +} + +void CopyInstanceDialog::checkAllCheckboxes(const bool& b) +{ + ui->keepPlaytimeCheckbox->setChecked(b); + ui->copySavesCheckbox->setChecked(b); + ui->copyGameOptionsCheckbox->setChecked(b); + ui->copyResPacksCheckbox->setChecked(b); + ui->copyShaderPacksCheckbox->setChecked(b); + ui->copyServersCheckbox->setChecked(b); + ui->copyModsCheckbox->setChecked(b); +} + +// Sets b to true if state is a checked checkbox +void CopyInstanceDialog::checkBool(bool& b, const int& state) +{ + if(state == Qt::Unchecked) + { + b = false; + } + else if(state == Qt::Checked) + { + b = true; + } + + // Have "Select all" checkbox checked if all options are already checked: + ui->selectAllCheckbox->blockSignals(true); + ui->selectAllCheckbox->setChecked(m_selectedOptions.allTrue()); + ui->selectAllCheckbox->blockSignals(false); +} + void CopyInstanceDialog::on_iconButton_clicked() { IconPickerDialog dlg(this); @@ -134,123 +168,51 @@ void CopyInstanceDialog::on_iconButton_clicked() } } + void CopyInstanceDialog::on_instNameTextBox_textChanged(const QString &arg1) { updateDialogState(); } -const InstanceCopyPrefs& CopyInstanceDialog::getChosenOptions() const -{ - return m_selectedOptions; -} - void CopyInstanceDialog::on_selectAllCheckbox_stateChanged(int state) { bool checked; - if(state == Qt::Unchecked) - { - checked = false; - } - else if(state == Qt::Checked) - { - checked = true; - } - + checkBool(checked, state); checkAllCheckboxes(checked); } -void CopyInstanceDialog::checkAllCheckboxes(bool b) -{ - ui->keepPlaytimeCheckbox->setChecked(b); - ui->copySavesCheckbox->setChecked(b); - ui->copyGameOptionsCheckbox->setChecked(b); - ui->copyResPacksCheckbox->setChecked(b); - ui->copyShaderPacksCheckbox->setChecked(b); - ui->copyServersCheckbox->setChecked(b); - ui->copyModsCheckbox->setChecked(b); -} - void CopyInstanceDialog::on_copySavesCheckbox_stateChanged(int state) { - if(state == Qt::Unchecked) - { - m_selectedOptions.copySaves = false; - } - else if(state == Qt::Checked) - { - m_selectedOptions.copySaves = true; - } + checkBool(m_selectedOptions.copySaves, state); } void CopyInstanceDialog::on_keepPlaytimeCheckbox_stateChanged(int state) { - if(state == Qt::Unchecked) - { - m_selectedOptions.keepPlaytime = false; - } - else if(state == Qt::Checked) - { - m_selectedOptions.keepPlaytime = true; - } + checkBool(m_selectedOptions.keepPlaytime, state); } void CopyInstanceDialog::on_copyGameOptionsCheckbox_stateChanged(int state) { - if(state == Qt::Unchecked) - { - m_selectedOptions.copyGameOptions = false; - } - else if(state == Qt::Checked) - { - m_selectedOptions.copyGameOptions = true; - } + checkBool(m_selectedOptions.copyGameOptions, state); } void CopyInstanceDialog::on_copyResPacksCheckbox_stateChanged(int state) { - if(state == Qt::Unchecked) - { - m_selectedOptions.copyResourcePacks = false; - } - else if(state == Qt::Checked) - { - m_selectedOptions.copyResourcePacks = true; - } + checkBool(m_selectedOptions.copyResourcePacks, state); } void CopyInstanceDialog::on_copyShaderPacksCheckbox_stateChanged(int state) { - if(state == Qt::Unchecked) - { - m_selectedOptions.copyShaderPacks = false; - } - else if(state == Qt::Checked) - { - m_selectedOptions.copyShaderPacks = true; - } + checkBool(m_selectedOptions.copyShaderPacks, state); } void CopyInstanceDialog::on_copyServersCheckbox_stateChanged(int state) { - if(state == Qt::Unchecked) - { - m_selectedOptions.copyServers = false; - } - else if(state == Qt::Checked) - { - m_selectedOptions.copyServers = true; - } + checkBool(m_selectedOptions.copyServers, state); } void CopyInstanceDialog::on_copyModsCheckbox_stateChanged(int state) { - if(state == Qt::Unchecked) - { - m_selectedOptions.copyMods = false; - } - else if(state == Qt::Checked) - { - m_selectedOptions.copyMods = true; - } + checkBool(m_selectedOptions.copyMods, state); } diff --git a/launcher/ui/dialogs/CopyInstanceDialog.h b/launcher/ui/dialogs/CopyInstanceDialog.h index e57de0a1..4171c440 100644 --- a/launcher/ui/dialogs/CopyInstanceDialog.h +++ b/launcher/ui/dialogs/CopyInstanceDialog.h @@ -47,7 +47,9 @@ slots: void on_instNameTextBox_textChanged(const QString &arg1); // Checkbox options: - void checkAllCheckboxes(bool b); + void checkAllCheckboxes(const bool& b); + void checkBool(bool& b, const int& state); + void on_selectAllCheckbox_stateChanged(int state); void on_copySavesCheckbox_stateChanged(int state); void on_keepPlaytimeCheckbox_stateChanged(int state); @@ -61,5 +63,5 @@ private: Ui::CopyInstanceDialog *ui; QString InstIconKey; InstancePtr m_original; - InstanceCopyPrefs m_selectedOptions = InstanceCopyPrefs(true); // Default to all options as true + InstanceCopyPrefs m_selectedOptions; }; -- cgit From a89df42561cc3089c4878c0c44353fcd1359bf53 Mon Sep 17 00:00:00 2001 From: Marcelo Hernandez <76508651+marcelohdez@users.noreply.github.com> Date: Mon, 24 Oct 2022 19:27:21 -0400 Subject: Simplify bool check in CopyInstanceDialog.cpp Signed-off-by: Marcelo Hernandez --- launcher/ui/dialogs/CopyInstanceDialog.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/launcher/ui/dialogs/CopyInstanceDialog.cpp b/launcher/ui/dialogs/CopyInstanceDialog.cpp index 44e70012..1b8e2aa0 100644 --- a/launcher/ui/dialogs/CopyInstanceDialog.cpp +++ b/launcher/ui/dialogs/CopyInstanceDialog.cpp @@ -141,14 +141,7 @@ void CopyInstanceDialog::checkAllCheckboxes(const bool& b) // Sets b to true if state is a checked checkbox void CopyInstanceDialog::checkBool(bool& b, const int& state) { - if(state == Qt::Unchecked) - { - b = false; - } - else if(state == Qt::Checked) - { - b = true; - } + b = (state == Qt::Checked); // Have "Select all" checkbox checked if all options are already checked: ui->selectAllCheckbox->blockSignals(true); -- cgit From 385c452ddffa2f40b21d7decede9f255e2b24d45 Mon Sep 17 00:00:00 2001 From: Marcelo Hernandez Date: Mon, 24 Oct 2022 20:49:40 -0400 Subject: remove checkBool function, add updateSelectAllCheckbox function Signed-off-by: Marcelo Hernandez --- launcher/ui/dialogs/CopyInstanceDialog.cpp | 30 +++++++++++++++++------------- launcher/ui/dialogs/CopyInstanceDialog.h | 9 ++++----- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/launcher/ui/dialogs/CopyInstanceDialog.cpp b/launcher/ui/dialogs/CopyInstanceDialog.cpp index 1b8e2aa0..8445f0a9 100644 --- a/launcher/ui/dialogs/CopyInstanceDialog.cpp +++ b/launcher/ui/dialogs/CopyInstanceDialog.cpp @@ -138,12 +138,9 @@ void CopyInstanceDialog::checkAllCheckboxes(const bool& b) ui->copyModsCheckbox->setChecked(b); } -// Sets b to true if state is a checked checkbox -void CopyInstanceDialog::checkBool(bool& b, const int& state) +// Check the "Select all" checkbox checked if all options are already checked: +void CopyInstanceDialog::updateSelectAllCheckbox() { - b = (state == Qt::Checked); - - // Have "Select all" checkbox checked if all options are already checked: ui->selectAllCheckbox->blockSignals(true); ui->selectAllCheckbox->setChecked(m_selectedOptions.allTrue()); ui->selectAllCheckbox->blockSignals(false); @@ -170,42 +167,49 @@ void CopyInstanceDialog::on_instNameTextBox_textChanged(const QString &arg1) void CopyInstanceDialog::on_selectAllCheckbox_stateChanged(int state) { bool checked; - checkBool(checked, state); + checked = (state == Qt::Checked); checkAllCheckboxes(checked); } void CopyInstanceDialog::on_copySavesCheckbox_stateChanged(int state) { - checkBool(m_selectedOptions.copySaves, state); + m_selectedOptions.copySaves = (state == Qt::Checked); + updateSelectAllCheckbox(); } void CopyInstanceDialog::on_keepPlaytimeCheckbox_stateChanged(int state) { - checkBool(m_selectedOptions.keepPlaytime, state); + m_selectedOptions.keepPlaytime = (state == Qt::Checked); + updateSelectAllCheckbox(); } void CopyInstanceDialog::on_copyGameOptionsCheckbox_stateChanged(int state) { - checkBool(m_selectedOptions.copyGameOptions, state); + m_selectedOptions.copyGameOptions = (state == Qt::Checked); + updateSelectAllCheckbox(); } void CopyInstanceDialog::on_copyResPacksCheckbox_stateChanged(int state) { - checkBool(m_selectedOptions.copyResourcePacks, state); + m_selectedOptions.copyResourcePacks = (state == Qt::Checked); + updateSelectAllCheckbox(); } void CopyInstanceDialog::on_copyShaderPacksCheckbox_stateChanged(int state) { - checkBool(m_selectedOptions.copyShaderPacks, state); + m_selectedOptions.copyShaderPacks = (state == Qt::Checked); + updateSelectAllCheckbox(); } void CopyInstanceDialog::on_copyServersCheckbox_stateChanged(int state) { - checkBool(m_selectedOptions.copyServers, state); + m_selectedOptions.copyServers = (state == Qt::Checked); + updateSelectAllCheckbox(); } void CopyInstanceDialog::on_copyModsCheckbox_stateChanged(int state) { - checkBool(m_selectedOptions.copyMods, state); + m_selectedOptions.copyMods = (state == Qt::Checked); + updateSelectAllCheckbox(); } diff --git a/launcher/ui/dialogs/CopyInstanceDialog.h b/launcher/ui/dialogs/CopyInstanceDialog.h index 4171c440..94015334 100644 --- a/launcher/ui/dialogs/CopyInstanceDialog.h +++ b/launcher/ui/dialogs/CopyInstanceDialog.h @@ -45,11 +45,7 @@ private slots: void on_iconButton_clicked(); void on_instNameTextBox_textChanged(const QString &arg1); - - // Checkbox options: - void checkAllCheckboxes(const bool& b); - void checkBool(bool& b, const int& state); - + // Checkboxes void on_selectAllCheckbox_stateChanged(int state); void on_copySavesCheckbox_stateChanged(int state); void on_keepPlaytimeCheckbox_stateChanged(int state); @@ -60,6 +56,9 @@ slots: void on_copyModsCheckbox_stateChanged(int state); private: + void checkAllCheckboxes(const bool& b); + void updateSelectAllCheckbox(); + /* data */ Ui::CopyInstanceDialog *ui; QString InstIconKey; InstancePtr m_original; -- cgit From 63b6c6685ce53e3fac1902e0ee7a6998c5d341d0 Mon Sep 17 00:00:00 2001 From: Marcelo Hernandez Date: Wed, 26 Oct 2022 00:20:36 -0400 Subject: Abstract away InstanceCopyPrefs' internals through new getSelectedFiltersAsRegex() function + fix typo in comment + remove unused import + add [[nodiscard]] to methods Signed-off-by: Marcelo Hernandez --- launcher/InstanceCopyPrefs.cpp | 33 ++++++++++++++++ launcher/InstanceCopyPrefs.h | 5 ++- launcher/InstanceCopyTask.cpp | 60 ++++-------------------------- launcher/InstanceCopyTask.h | 4 -- launcher/ui/dialogs/CopyInstanceDialog.cpp | 3 +- 5 files changed, 45 insertions(+), 60 deletions(-) diff --git a/launcher/InstanceCopyPrefs.cpp b/launcher/InstanceCopyPrefs.cpp index fad55d1e..6432a535 100644 --- a/launcher/InstanceCopyPrefs.cpp +++ b/launcher/InstanceCopyPrefs.cpp @@ -14,3 +14,36 @@ bool InstanceCopyPrefs::allTrue() const copyServers && copyMods; } + +// Returns a single RegEx string of the selected folders/files to filter out (ex: ".minecraft/saves|.minecraft/server.dat") +QString InstanceCopyPrefs::getSelectedFiltersAsRegex() const +{ + QStringList filters; + + if(!copySaves) + filters << "saves"; + + if(!copyGameOptions) + filters << "options.txt"; + + if(!copyResourcePacks) + filters << "resourcepacks" << "texturepacks"; + + if(!copyShaderPacks) + filters << "shaderpacks"; + + if(!copyServers) + filters << "servers.dat" << "servers.dat_old" << "server-resource-packs"; + + if(!copyMods) + filters << "coremods" << "mods" << "config"; + + // If we have any filters to add, join them as a single regex string to return: + if (!filters.isEmpty()) { + const QString MC_ROOT = "[.]?minecraft/"; + // Ensure first filter starts with root, then join other filters with OR regex before root (ex: ".minecraft/saves|.minecraft/mods"): + return MC_ROOT + filters.join("|" + MC_ROOT); + } + + return {}; +} diff --git a/launcher/InstanceCopyPrefs.h b/launcher/InstanceCopyPrefs.h index c5c1a7ae..432d67c4 100644 --- a/launcher/InstanceCopyPrefs.h +++ b/launcher/InstanceCopyPrefs.h @@ -5,6 +5,8 @@ #ifndef LAUNCHER_INSTANCECOPYPREFS_H #define LAUNCHER_INSTANCECOPYPREFS_H +#include + struct InstanceCopyPrefs { bool copySaves = true; bool keepPlaytime = true; @@ -14,7 +16,8 @@ struct InstanceCopyPrefs { bool copyServers = true; bool copyMods = true; - bool allTrue() const; + [[nodiscard]] bool allTrue() const; + [[nodiscard]] QString getSelectedFiltersAsRegex() const; }; #endif // LAUNCHER_INSTANCECOPYPREFS_H diff --git a/launcher/InstanceCopyTask.cpp b/launcher/InstanceCopyTask.cpp index e0f68224..7fbf8636 100644 --- a/launcher/InstanceCopyTask.cpp +++ b/launcher/InstanceCopyTask.cpp @@ -9,62 +9,16 @@ InstanceCopyTask::InstanceCopyTask(InstancePtr origInstance, const InstanceCopyP { m_origInstance = origInstance; m_keepPlaytime = prefs.keepPlaytime; - QString filter; - if(!prefs.copySaves) + QString filters = prefs.getSelectedFiltersAsRegex(); + if (!filters.isEmpty()) { - appendToFilter(filter, "saves"); + // Set regex filter: + // FIXME: get this from the original instance type... + auto matcherReal = new RegexpMatcher(filters); + matcherReal->caseSensitive(false); + m_matcher.reset(matcherReal); } - - if(!prefs.copyGameOptions) { - appendToFilter(filter, "options.txt"); - } - - if(!prefs.copyResourcePacks) - { - appendToFilter(filter, "resourcepacks"); - appendToFilter(filter, "texturepacks"); - } - - if(!prefs.copyShaderPacks) - { - appendToFilter(filter, "shaderpacks"); - } - - if(!prefs.copyServers) - { - appendToFilter(filter, "servers.dat"); - appendToFilter(filter, "servers.dat_old"); - appendToFilter(filter, "server-resource-packs"); - } - - if(!prefs.copyMods) - { - appendToFilter(filter, "coremods"); - appendToFilter(filter, "mods"); - appendToFilter(filter, "config"); - } - - if (!filter.isEmpty()) - { - resetFromMatcher(filter); - } -} - -void InstanceCopyTask::appendToFilter(QString& filter, const QString& append) -{ - if (!filter.isEmpty()) - filter.append('|'); // OR regex - - filter.append("[.]?minecraft/" + append); -} - -void InstanceCopyTask::resetFromMatcher(const QString& regexp) -{ - // FIXME: get this from the original instance type... - auto matcherReal = new RegexpMatcher(regexp); - matcherReal->caseSensitive(false); - m_matcher.reset(matcherReal); } void InstanceCopyTask::executeTask() diff --git a/launcher/InstanceCopyTask.h b/launcher/InstanceCopyTask.h index 4abbf6e6..1f29b854 100644 --- a/launcher/InstanceCopyTask.h +++ b/launcher/InstanceCopyTask.h @@ -24,10 +24,6 @@ protected: void copyAborted(); private: - // Helper functions to avoid repeating code - static void appendToFilter(QString &filter, const QString &append); - void resetFromMatcher(const QString ®exp); - /* data */ InstancePtr m_origInstance; QFuture m_copyFuture; diff --git a/launcher/ui/dialogs/CopyInstanceDialog.cpp b/launcher/ui/dialogs/CopyInstanceDialog.cpp index 8445f0a9..e658f26d 100644 --- a/launcher/ui/dialogs/CopyInstanceDialog.cpp +++ b/launcher/ui/dialogs/CopyInstanceDialog.cpp @@ -44,7 +44,6 @@ #include "BaseVersion.h" #include "icons/IconList.h" -#include "tasks/Task.h" #include "BaseInstance.h" #include "InstanceList.h" @@ -138,7 +137,7 @@ void CopyInstanceDialog::checkAllCheckboxes(const bool& b) ui->copyModsCheckbox->setChecked(b); } -// Check the "Select all" checkbox checked if all options are already checked: +// Check the "Select all" checkbox if all options are already selected: void CopyInstanceDialog::updateSelectAllCheckbox() { ui->selectAllCheckbox->blockSignals(true); -- cgit From c00f96c7ca49a624ea8e9c4774ea11e954bbdc4b Mon Sep 17 00:00:00 2001 From: Marcelo Hernandez Date: Sat, 29 Oct 2022 00:55:33 -0400 Subject: create getters and setters for InstanceCopyPrefs + use pragma once like other .h files in this directory Signed-off-by: Marcelo Hernandez --- launcher/InstanceCopyPrefs.cpp | 72 ++++++++++++++++++++++++++++++ launcher/InstanceCopyPrefs.h | 29 +++++++++--- launcher/InstanceCopyTask.cpp | 2 +- launcher/ui/dialogs/CopyInstanceDialog.cpp | 28 ++++++------ 4 files changed, 109 insertions(+), 22 deletions(-) diff --git a/launcher/InstanceCopyPrefs.cpp b/launcher/InstanceCopyPrefs.cpp index 6432a535..ae30bb82 100644 --- a/launcher/InstanceCopyPrefs.cpp +++ b/launcher/InstanceCopyPrefs.cpp @@ -47,3 +47,75 @@ QString InstanceCopyPrefs::getSelectedFiltersAsRegex() const return {}; } + +// ======= Getters ======= +bool InstanceCopyPrefs::isCopySavesEnabled() const +{ + return copySaves; +} + +bool InstanceCopyPrefs::isKeepPlaytimeEnabled() const +{ + return keepPlaytime; +} + +bool InstanceCopyPrefs::isCopyGameOptionsEnabled() const +{ + return copyGameOptions; +} + +bool InstanceCopyPrefs::isCopyResourcePacksEnabled() const +{ + return copyResourcePacks; +} + +bool InstanceCopyPrefs::isCopyShaderPacksEnabled() const +{ + return copyShaderPacks; +} + +bool InstanceCopyPrefs::isCopyServersEnabled() const +{ + return copyServers; +} + +bool InstanceCopyPrefs::isCopyModsEnabled() const +{ + return copyMods; +} + +// ======= Setters ======= +void InstanceCopyPrefs::enableCopySaves(bool b) +{ + copySaves = b; +} + +void InstanceCopyPrefs::enableKeepPlaytime(bool b) +{ + keepPlaytime = b; +} + +void InstanceCopyPrefs::enableCopyGameOptions(bool b) +{ + copyGameOptions = b; +} + +void InstanceCopyPrefs::enableCopyResourcePacks(bool b) +{ + copyResourcePacks = b; +} + +void InstanceCopyPrefs::enableCopyShaderPacks(bool b) +{ + copyShaderPacks = b; +} + +void InstanceCopyPrefs::enableCopyServers(bool b) +{ + copyServers = b; +} + +void InstanceCopyPrefs::enableCopyMods(bool b) +{ + copyMods = b; +} diff --git a/launcher/InstanceCopyPrefs.h b/launcher/InstanceCopyPrefs.h index 432d67c4..3855965d 100644 --- a/launcher/InstanceCopyPrefs.h +++ b/launcher/InstanceCopyPrefs.h @@ -2,12 +2,32 @@ // Created by marcelohdez on 10/22/22. // -#ifndef LAUNCHER_INSTANCECOPYPREFS_H -#define LAUNCHER_INSTANCECOPYPREFS_H +#pragma once #include struct InstanceCopyPrefs { + public: + [[nodiscard]] bool allTrue() const; + [[nodiscard]] QString getSelectedFiltersAsRegex() const; + // Getters + [[nodiscard]] bool isCopySavesEnabled() const; + [[nodiscard]] bool isKeepPlaytimeEnabled() const; + [[nodiscard]] bool isCopyGameOptionsEnabled() const; + [[nodiscard]] bool isCopyResourcePacksEnabled() const; + [[nodiscard]] bool isCopyShaderPacksEnabled() const; + [[nodiscard]] bool isCopyServersEnabled() const; + [[nodiscard]] bool isCopyModsEnabled() const; + // Setters + void enableCopySaves(bool b); + void enableKeepPlaytime(bool b); + void enableCopyGameOptions(bool b); + void enableCopyResourcePacks(bool b); + void enableCopyShaderPacks(bool b); + void enableCopyServers(bool b); + void enableCopyMods(bool b); + + protected: // data bool copySaves = true; bool keepPlaytime = true; bool copyGameOptions = true; @@ -15,9 +35,4 @@ struct InstanceCopyPrefs { bool copyShaderPacks = true; bool copyServers = true; bool copyMods = true; - - [[nodiscard]] bool allTrue() const; - [[nodiscard]] QString getSelectedFiltersAsRegex() const; }; - -#endif // LAUNCHER_INSTANCECOPYPREFS_H diff --git a/launcher/InstanceCopyTask.cpp b/launcher/InstanceCopyTask.cpp index 7fbf8636..a4ea947d 100644 --- a/launcher/InstanceCopyTask.cpp +++ b/launcher/InstanceCopyTask.cpp @@ -8,7 +8,7 @@ InstanceCopyTask::InstanceCopyTask(InstancePtr origInstance, const InstanceCopyPrefs& prefs) { m_origInstance = origInstance; - m_keepPlaytime = prefs.keepPlaytime; + m_keepPlaytime = prefs.isKeepPlaytimeEnabled(); QString filters = prefs.getSelectedFiltersAsRegex(); if (!filters.isEmpty()) diff --git a/launcher/ui/dialogs/CopyInstanceDialog.cpp b/launcher/ui/dialogs/CopyInstanceDialog.cpp index e658f26d..f76b509e 100644 --- a/launcher/ui/dialogs/CopyInstanceDialog.cpp +++ b/launcher/ui/dialogs/CopyInstanceDialog.cpp @@ -77,13 +77,13 @@ CopyInstanceDialog::CopyInstanceDialog(InstancePtr original, QWidget *parent) } ui->groupBox->setCurrentIndex(index); ui->groupBox->lineEdit()->setPlaceholderText(tr("No group")); - ui->copySavesCheckbox->setChecked(m_selectedOptions.copySaves); - ui->keepPlaytimeCheckbox->setChecked(m_selectedOptions.keepPlaytime); - ui->copyGameOptionsCheckbox->setChecked(m_selectedOptions.copyGameOptions); - ui->copyResPacksCheckbox->setChecked(m_selectedOptions.copyResourcePacks); - ui->copyShaderPacksCheckbox->setChecked(m_selectedOptions.copyShaderPacks); - ui->copyServersCheckbox->setChecked(m_selectedOptions.copyServers); - ui->copyModsCheckbox->setChecked(m_selectedOptions.copyMods); + ui->copySavesCheckbox->setChecked(m_selectedOptions.isCopySavesEnabled()); + ui->keepPlaytimeCheckbox->setChecked(m_selectedOptions.isKeepPlaytimeEnabled()); + ui->copyGameOptionsCheckbox->setChecked(m_selectedOptions.isCopyGameOptionsEnabled()); + ui->copyResPacksCheckbox->setChecked(m_selectedOptions.isCopyResourcePacksEnabled()); + ui->copyShaderPacksCheckbox->setChecked(m_selectedOptions.isCopyShaderPacksEnabled()); + ui->copyServersCheckbox->setChecked(m_selectedOptions.isCopyServersEnabled()); + ui->copyModsCheckbox->setChecked(m_selectedOptions.isCopyModsEnabled()); } CopyInstanceDialog::~CopyInstanceDialog() @@ -172,43 +172,43 @@ void CopyInstanceDialog::on_selectAllCheckbox_stateChanged(int state) void CopyInstanceDialog::on_copySavesCheckbox_stateChanged(int state) { - m_selectedOptions.copySaves = (state == Qt::Checked); + m_selectedOptions.enableCopySaves(state == Qt::Checked); updateSelectAllCheckbox(); } void CopyInstanceDialog::on_keepPlaytimeCheckbox_stateChanged(int state) { - m_selectedOptions.keepPlaytime = (state == Qt::Checked); + m_selectedOptions.enableKeepPlaytime(state == Qt::Checked); updateSelectAllCheckbox(); } void CopyInstanceDialog::on_copyGameOptionsCheckbox_stateChanged(int state) { - m_selectedOptions.copyGameOptions = (state == Qt::Checked); + m_selectedOptions.enableCopyGameOptions(state == Qt::Checked); updateSelectAllCheckbox(); } void CopyInstanceDialog::on_copyResPacksCheckbox_stateChanged(int state) { - m_selectedOptions.copyResourcePacks = (state == Qt::Checked); + m_selectedOptions.enableCopyResourcePacks(state == Qt::Checked); updateSelectAllCheckbox(); } void CopyInstanceDialog::on_copyShaderPacksCheckbox_stateChanged(int state) { - m_selectedOptions.copyShaderPacks = (state == Qt::Checked); + m_selectedOptions.enableCopyShaderPacks(state == Qt::Checked); updateSelectAllCheckbox(); } void CopyInstanceDialog::on_copyServersCheckbox_stateChanged(int state) { - m_selectedOptions.copyServers = (state == Qt::Checked); + m_selectedOptions.enableCopyServers(state == Qt::Checked); updateSelectAllCheckbox(); } void CopyInstanceDialog::on_copyModsCheckbox_stateChanged(int state) { - m_selectedOptions.copyMods = (state == Qt::Checked); + m_selectedOptions.enableCopyMods(state == Qt::Checked); updateSelectAllCheckbox(); } -- cgit From 5d1aac3c53904f7c843dc5cfdbdd33086eb4b6d6 Mon Sep 17 00:00:00 2001 From: Marcelo Hernandez Date: Sat, 29 Oct 2022 22:27:31 -0400 Subject: added option to not copy screenshots + moved select all checkbox to top row, centered. Signed-off-by: Marcelo Hernandez --- launcher/InstanceCopyPrefs.cpp | 16 ++++++- launcher/InstanceCopyPrefs.h | 3 ++ launcher/ui/dialogs/CopyInstanceDialog.cpp | 8 ++++ launcher/ui/dialogs/CopyInstanceDialog.h | 1 + launcher/ui/dialogs/CopyInstanceDialog.ui | 67 ++++++++++++++++++++---------- 5 files changed, 72 insertions(+), 23 deletions(-) diff --git a/launcher/InstanceCopyPrefs.cpp b/launcher/InstanceCopyPrefs.cpp index ae30bb82..7b93a516 100644 --- a/launcher/InstanceCopyPrefs.cpp +++ b/launcher/InstanceCopyPrefs.cpp @@ -12,7 +12,8 @@ bool InstanceCopyPrefs::allTrue() const copyResourcePacks && copyShaderPacks && copyServers && - copyMods; + copyMods && + copyScreenshots; } // Returns a single RegEx string of the selected folders/files to filter out (ex: ".minecraft/saves|.minecraft/server.dat") @@ -38,6 +39,9 @@ QString InstanceCopyPrefs::getSelectedFiltersAsRegex() const if(!copyMods) filters << "coremods" << "mods" << "config"; + if(!copyScreenshots) + filters << "screenshots"; + // If we have any filters to add, join them as a single regex string to return: if (!filters.isEmpty()) { const QString MC_ROOT = "[.]?minecraft/"; @@ -84,6 +88,11 @@ bool InstanceCopyPrefs::isCopyModsEnabled() const return copyMods; } +bool InstanceCopyPrefs::isCopyScreenshotsEnabled() const +{ + return copyScreenshots; +} + // ======= Setters ======= void InstanceCopyPrefs::enableCopySaves(bool b) { @@ -119,3 +128,8 @@ void InstanceCopyPrefs::enableCopyMods(bool b) { copyMods = b; } + +void InstanceCopyPrefs::enableCopyScreenshots(bool b) +{ + copyScreenshots = b; +} diff --git a/launcher/InstanceCopyPrefs.h b/launcher/InstanceCopyPrefs.h index 3855965d..6988b2df 100644 --- a/launcher/InstanceCopyPrefs.h +++ b/launcher/InstanceCopyPrefs.h @@ -18,6 +18,7 @@ struct InstanceCopyPrefs { [[nodiscard]] bool isCopyShaderPacksEnabled() const; [[nodiscard]] bool isCopyServersEnabled() const; [[nodiscard]] bool isCopyModsEnabled() const; + [[nodiscard]] bool isCopyScreenshotsEnabled() const; // Setters void enableCopySaves(bool b); void enableKeepPlaytime(bool b); @@ -26,6 +27,7 @@ struct InstanceCopyPrefs { void enableCopyShaderPacks(bool b); void enableCopyServers(bool b); void enableCopyMods(bool b); + void enableCopyScreenshots(bool b); protected: // data bool copySaves = true; @@ -35,4 +37,5 @@ struct InstanceCopyPrefs { bool copyShaderPacks = true; bool copyServers = true; bool copyMods = true; + bool copyScreenshots = true; }; diff --git a/launcher/ui/dialogs/CopyInstanceDialog.cpp b/launcher/ui/dialogs/CopyInstanceDialog.cpp index f76b509e..3f5122f6 100644 --- a/launcher/ui/dialogs/CopyInstanceDialog.cpp +++ b/launcher/ui/dialogs/CopyInstanceDialog.cpp @@ -84,6 +84,7 @@ CopyInstanceDialog::CopyInstanceDialog(InstancePtr original, QWidget *parent) ui->copyShaderPacksCheckbox->setChecked(m_selectedOptions.isCopyShaderPacksEnabled()); ui->copyServersCheckbox->setChecked(m_selectedOptions.isCopyServersEnabled()); ui->copyModsCheckbox->setChecked(m_selectedOptions.isCopyModsEnabled()); + ui->copyScreenshotsCheckbox->setChecked(m_selectedOptions.isCopyScreenshotsEnabled()); } CopyInstanceDialog::~CopyInstanceDialog() @@ -135,6 +136,7 @@ void CopyInstanceDialog::checkAllCheckboxes(const bool& b) ui->copyShaderPacksCheckbox->setChecked(b); ui->copyServersCheckbox->setChecked(b); ui->copyModsCheckbox->setChecked(b); + ui->copyScreenshotsCheckbox->setChecked(b); } // Check the "Select all" checkbox if all options are already selected: @@ -212,3 +214,9 @@ void CopyInstanceDialog::on_copyModsCheckbox_stateChanged(int state) m_selectedOptions.enableCopyMods(state == Qt::Checked); updateSelectAllCheckbox(); } + +void CopyInstanceDialog::on_copyScreenshotsCheckbox_stateChanged(int state) +{ + m_selectedOptions.enableCopyScreenshots(state == Qt::Checked); + updateSelectAllCheckbox(); +} diff --git a/launcher/ui/dialogs/CopyInstanceDialog.h b/launcher/ui/dialogs/CopyInstanceDialog.h index 94015334..884501d1 100644 --- a/launcher/ui/dialogs/CopyInstanceDialog.h +++ b/launcher/ui/dialogs/CopyInstanceDialog.h @@ -54,6 +54,7 @@ slots: void on_copyShaderPacksCheckbox_stateChanged(int state); void on_copyServersCheckbox_stateChanged(int state); void on_copyModsCheckbox_stateChanged(int state); + void on_copyScreenshotsCheckbox_stateChanged(int state); private: void checkAllCheckboxes(const bool& b); diff --git a/launcher/ui/dialogs/CopyInstanceDialog.ui b/launcher/ui/dialogs/CopyInstanceDialog.ui index 822ed797..b7828fe3 100644 --- a/launcher/ui/dialogs/CopyInstanceDialog.ui +++ b/launcher/ui/dialogs/CopyInstanceDialog.ui @@ -10,7 +10,7 @@ 0 0 341 - 385 + 399 @@ -113,24 +113,30 @@ - - - - - Copy saves + + + + + + 0 + 0 + - - - - - - true + + Qt::LeftToRight - Copy resource packs + Select all + + + false + + + + @@ -151,6 +157,20 @@ + + + + Copy saves + + + + + + + Copy shader packs + + + @@ -158,24 +178,27 @@ - - + + + + true + - Keep play time + Copy resource packs - - + + - Copy shader packs + Keep play time - - + + - Select all + Copy screenshots -- cgit From 028e086960402f685e07163def36d6b5eee1b796 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Mon, 24 Oct 2022 04:08:38 -0700 Subject: send blocked mod info to dialog & prototype UI Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- .../flame/FlameInstanceCreationTask.cpp | 18 ++++++---- .../modplatform/modpacksch/FTBPackInstallTask.cpp | 22 +++++++----- launcher/ui/dialogs/BlockedModsDialog.cpp | 42 +++++++++++++++++++--- launcher/ui/dialogs/BlockedModsDialog.h | 16 +++++++-- 4 files changed, 78 insertions(+), 20 deletions(-) diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp index 48ac02e0..15e660a9 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp @@ -372,13 +372,20 @@ void FlameCreationTask::idResolverSucceeded(QEventLoop& loop) auto results = m_mod_id_resolver->getResults(); // first check for blocked mods - QString text; - QList urls; + QList blocked_mods; auto anyBlocked = false; for (const auto& result : results.files.values()) { if (!result.resolved || result.url.isEmpty()) { - text += QString("%1: %2
").arg(result.fileName, result.websiteUrl); - urls.append(QUrl(result.websiteUrl)); + + BlockedMod blocked_mod; + blocked_mod.name = result.fileName; + blocked_mod.websiteUrl = result.websiteUrl; + blocked_mod.hash = result.hash; + blocked_mod.matched = false; + blocked_mod.localPath = ""; + + blocked_mods.append(blocked_mod); + anyBlocked = true; } } @@ -388,8 +395,7 @@ void FlameCreationTask::idResolverSucceeded(QEventLoop& loop) auto message_dialog = new BlockedModsDialog(m_parent, tr("Blocked mods found"), tr("The following mods were blocked on third party launchers.
" "You will need to manually download them and add them to the modpack"), - text, - urls); + blocked_mods); message_dialog->setModal(true); if (message_dialog->exec()) { diff --git a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp index 7b112d8f..75fda208 100644 --- a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp +++ b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp @@ -176,8 +176,7 @@ void PackInstallTask::resolveMods() void PackInstallTask::onResolveModsSucceeded() { - QString text; - QList urls; + QList blocked_mods; auto anyBlocked = false; Flame::Manifest results = m_mod_id_resolver_task->getResults(); @@ -191,11 +190,19 @@ void PackInstallTask::onResolveModsSucceeded() // First check for blocked mods if (!results_file.resolved || results_file.url.isEmpty()) { - QString type(local_file.type); + // QString type(local_file.type); + + // type[0] = type[0].toUpper(); + + BlockedMod blocked_mod; + blocked_mod.name = local_file.name; + blocked_mod.websiteUrl = results_file.websiteUrl; + blocked_mod.hash = results_file.hash; + blocked_mod.matched = false; + blocked_mod.localPath = ""; + + blocked_mods.append(blocked_mod); - type[0] = type[0].toUpper(); - text += QString("%1: %2 - %3
").arg(type, local_file.name, results_file.websiteUrl); - urls.append(QUrl(results_file.websiteUrl)); anyBlocked = true; } else { local_file.url = results_file.url.toString(); @@ -210,8 +217,7 @@ void PackInstallTask::onResolveModsSucceeded() auto message_dialog = new BlockedModsDialog(m_parent, tr("Blocked files found"), tr("The following files are not available for download in third party launchers.
" "You will need to manually download them and add them to the instance."), - text, - urls); + blocked_mods); if (message_dialog->exec() == QDialog::Accepted) createInstance(); diff --git a/launcher/ui/dialogs/BlockedModsDialog.cpp b/launcher/ui/dialogs/BlockedModsDialog.cpp index fe87b517..e29f8eb3 100644 --- a/launcher/ui/dialogs/BlockedModsDialog.cpp +++ b/launcher/ui/dialogs/BlockedModsDialog.cpp @@ -4,17 +4,22 @@ #include #include +#include -BlockedModsDialog::BlockedModsDialog(QWidget *parent, const QString &title, const QString &text, const QString &body, const QList &urls) : - QDialog(parent), ui(new Ui::BlockedModsDialog), urls(urls) { + +BlockedModsDialog::BlockedModsDialog(QWidget *parent, const QString &title, const QString &text, const QList &mods) : + QDialog(parent), ui(new Ui::BlockedModsDialog), mods(mods) { ui->setupUi(this); auto openAllButton = ui->buttonBox->addButton(tr("Open All"), QDialogButtonBox::ActionRole); connect(openAllButton, &QPushButton::clicked, this, &BlockedModsDialog::openAll); + qDebug() << "Mods List: " << mods; + this->setWindowTitle(title); ui->label->setText(text); ui->textBrowser->setText(body); + update(); } BlockedModsDialog::~BlockedModsDialog() { @@ -22,7 +27,36 @@ BlockedModsDialog::~BlockedModsDialog() { } void BlockedModsDialog::openAll() { - for(auto &url : urls) { - QDesktopServices::openUrl(url); + for(auto &mod : mods) { + QDesktopServices::openUrl(mod.websiteUrl); } } + +void BlockedModsDialog::update() { + QString text; + QString span; + + for (auto &mod : mods) { + if (mod.matched) { + // ✔ -> html for HEAVY CHECK MARK : ✔ + span = QString(" ✔ Found at %1 ").arg(mod.localPath); + } else { + // ✘ -> html for HEAVY BALLOT X : ✘ + span = QString(" ✘ Not Found "); + } + text += QString("%1: %2

Hash: %3 %4


").arg(mod.name, mod.websiteUrl, mod.hash, span); + } + + ui->textBrowser->setText(text); +} + + +QDebug operator<<(QDebug debug, const BlockedMod &m) { + QDebugStateSaver saver(debug); + + debug.nospace() << "{ name: " << m.name << ", websiteUrl: " << m.websiteUrl + << ", hash: " << m.hash << ", matched: " << m.matched + << ", localPath: " << m.localPath <<"}"; + + return debug; +} \ No newline at end of file diff --git a/launcher/ui/dialogs/BlockedModsDialog.h b/launcher/ui/dialogs/BlockedModsDialog.h index 5f5bd61b..4be020ec 100644 --- a/launcher/ui/dialogs/BlockedModsDialog.h +++ b/launcher/ui/dialogs/BlockedModsDialog.h @@ -3,6 +3,15 @@ #include +struct BlockedMod { + QString name; + QString websiteUrl; + QString hash; + bool matched; + QString localPath; + +}; + QT_BEGIN_NAMESPACE namespace Ui { class BlockedModsDialog; } QT_END_NAMESPACE @@ -11,12 +20,15 @@ class BlockedModsDialog : public QDialog { Q_OBJECT public: - BlockedModsDialog(QWidget *parent, const QString &title, const QString &text, const QString &body, const QList &urls); + BlockedModsDialog(QWidget *parent, const QString &title, const QString &text, const QList &mods); ~BlockedModsDialog() override; + private: Ui::BlockedModsDialog *ui; - const QList &urls; + const QList &mods; void openAll(); + void update(); }; + -- cgit From 1598d6582473f1bb6aa02fd9b4dabc8210771e56 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Tue, 25 Oct 2022 01:19:19 -0700 Subject: watch filesystem, compute and match hashes Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/modplatform/helpers/HashUtils.cpp | 58 ++++++++++++++ launcher/modplatform/helpers/HashUtils.h | 15 ++++ launcher/ui/dialogs/BlockedModsDialog.cpp | 120 ++++++++++++++++++++++++++++- launcher/ui/dialogs/BlockedModsDialog.h | 23 +++++- 4 files changed, 212 insertions(+), 4 deletions(-) diff --git a/launcher/modplatform/helpers/HashUtils.cpp b/launcher/modplatform/helpers/HashUtils.cpp index a7bbaba5..bf53aa0e 100644 --- a/launcher/modplatform/helpers/HashUtils.cpp +++ b/launcher/modplatform/helpers/HashUtils.cpp @@ -35,6 +35,18 @@ Hasher::Ptr createFlameHasher(QString file_path) return new FlameHasher(file_path); } +Hasher::Ptr createBlockedModHasher(QString file_path, ModPlatform::Provider provider) +{ + return new BlockedModHasher(file_path, provider); +} + +Hasher::Ptr createBlockedModHasher(QString file_path, ModPlatform::Provider provider, QString type) +{ + auto hasher = new BlockedModHasher(file_path, provider); + hasher->useHashType(type); + return hasher; +} + void ModrinthHasher::executeTask() { QFile file(m_path); @@ -78,4 +90,50 @@ void FlameHasher::executeTask() } } + +BlockedModHasher::BlockedModHasher(QString file_path, ModPlatform::Provider provider) + : Hasher(file_path), provider(provider) { + setObjectName(QString("BlockedModHasher: %1").arg(file_path)); + hash_type = ProviderCaps.hashType(provider).first(); +} + +void BlockedModHasher::executeTask() +{ + QFile file(m_path); + + try { + file.open(QFile::ReadOnly); + } catch (FS::FileSystemException& e) { + qCritical() << QString("Failed to open JAR file in %1").arg(m_path); + qCritical() << QString("Reason: ") << e.cause(); + + emitFailed("Failed to open file for hashing."); + return; + } + + m_hash = ProviderCaps.hash(provider, &file, hash_type); + + file.close(); + + if (m_hash.isEmpty()) { + emitFailed("Empty hash!"); + } else { + emitSucceeded(); + } +} + +QStringList BlockedModHasher::getHashTypes() { + return ProviderCaps.hashType(provider); +} + +bool BlockedModHasher::useHashType(QString type) { + auto types = ProviderCaps.hashType(provider); + if (types.contains(type)) { + hash_type = type; + return true; + } + qDebug() << "Bad hash type " << type << " for provider"; + return false; +} + } // namespace Hashing diff --git a/launcher/modplatform/helpers/HashUtils.h b/launcher/modplatform/helpers/HashUtils.h index 38fddf03..fa3244f6 100644 --- a/launcher/modplatform/helpers/HashUtils.h +++ b/launcher/modplatform/helpers/HashUtils.h @@ -40,8 +40,23 @@ class ModrinthHasher : public Hasher { void executeTask() override; }; +class BlockedModHasher : public Hasher { + public: + BlockedModHasher(QString file_path, ModPlatform::Provider provider); + + void executeTask() override; + + QStringList getHashTypes(); + bool useHashType(QString type); + private: + ModPlatform::Provider provider; + QString hash_type; +}; + Hasher::Ptr createHasher(QString file_path, ModPlatform::Provider provider); Hasher::Ptr createFlameHasher(QString file_path); Hasher::Ptr createModrinthHasher(QString file_path); +Hasher::Ptr createBlockedModHasher(QString file_path, ModPlatform::Provider provider); +Hasher::Ptr createBlockedModHasher(QString file_path, ModPlatform::Provider provider, QString type); } // namespace Hashing diff --git a/launcher/ui/dialogs/BlockedModsDialog.cpp b/launcher/ui/dialogs/BlockedModsDialog.cpp index e29f8eb3..9ba033d7 100644 --- a/launcher/ui/dialogs/BlockedModsDialog.cpp +++ b/launcher/ui/dialogs/BlockedModsDialog.cpp @@ -1,3 +1,6 @@ +#include +#include +#include "Application.h" #include "BlockedModsDialog.h" #include "ui_BlockedModsDialog.h" #include @@ -5,20 +8,29 @@ #include #include +#include -BlockedModsDialog::BlockedModsDialog(QWidget *parent, const QString &title, const QString &text, const QList &mods) : + + +BlockedModsDialog::BlockedModsDialog(QWidget *parent, const QString &title, const QString &text, QList &mods) : QDialog(parent), ui(new Ui::BlockedModsDialog), mods(mods) { ui->setupUi(this); auto openAllButton = ui->buttonBox->addButton(tr("Open All"), QDialogButtonBox::ActionRole); connect(openAllButton, &QPushButton::clicked, this, &BlockedModsDialog::openAll); + connect(&watcher, &QFileSystemWatcher::directoryChanged, this, &BlockedModsDialog::directoryChanged); + + hashing_task = shared_qobject_ptr(new ConcurrentTask(this, "MakeHashesTask", 10)); + qDebug() << "Mods List: " << mods; + setupWatch(); + scanPaths(true); + this->setWindowTitle(title); ui->label->setText(text); - ui->textBrowser->setText(body); update(); } @@ -50,6 +62,110 @@ void BlockedModsDialog::update() { ui->textBrowser->setText(text); } +void BlockedModsDialog::directoryChanged(QString path) { + qDebug() << "Directory changed: " << path; + scanPath(path, false); +} + + +void BlockedModsDialog::setupWatch() { + const QString downloadsFolder = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation); + const QString modsFolder = APPLICATION->settings()->get("CentralModsDir").toString(); + watcher.addPath(downloadsFolder); + watcher.addPath(modsFolder); +} + +void BlockedModsDialog::scanPaths(bool init) { + for (auto &dir : watcher.directories()) { + scanPath(dir, init); + } +} + +void BlockedModsDialog::scanPath(QString path, bool init) { + + QDir scan_dir(path); + QDirIterator scan_it(path, QDir::Filter::Files | QDir::Filter::Hidden, QDirIterator::NoIteratorFlags); + while (scan_it.hasNext()) { + QString file = scan_it.next(); + + if (checked_paths.contains(file)){ + continue; + } + + if (!checkValidPath(file)) { + continue; + } + + auto hash_task = Hashing::createBlockedModHasher(file, ModPlatform::Provider::FLAME, "sha1"); + + qDebug() << "Creating Hash task for path: " << file; + + connect(hash_task.get(), &Task::succeeded, [this, hash_task, file] { + checkMatchHash(hash_task->getResult(), file); + }); + connect(hash_task.get(), &Task::failed, [this, hash_task, file] { + qDebug() << "Failed to hash path: " << file; + }); + + if (init) { + checked_paths.insert(file); + } + + hashing_task->addTask(hash_task); + } + + hashing_task->start(); + +} + +void BlockedModsDialog::checkMatchHash(QString hash, QString path) { + bool match = false; + + qDebug() << "Checking for match on hash: " << hash << " | From path:" << path; + + for (auto &mod : mods) { + if (mod.matched) { + continue; + } + if (mod.hash.compare(hash, Qt::CaseInsensitive) == 0) { + mod.matched = true; + mod.localPath = path; + match = true; + + qDebug() << "Hash match found: " << mod.name << " " << hash << " | From path:" << path; + + break; + } + } + + if (match) { + update(); + } +} + +bool BlockedModsDialog::checkValidPath(QString path) { + + QFileInfo file = QFileInfo(path); + QString filename = file.fileName(); + + for (auto &mod : mods) { + if (mod.name.compare(filename, Qt::CaseInsensitive) == 0) { + qDebug() << "Name match found: " << mod.name << " | From path:" << path; + return true; + } + } + + return false; +} + +bool BlockedModsDialog::allModsMatched() { + for (auto &mod : mods) { + if (!mod.matched) + return false; + } + return true; +} + QDebug operator<<(QDebug debug, const BlockedMod &m) { QDebugStateSaver saver(debug); diff --git a/launcher/ui/dialogs/BlockedModsDialog.h b/launcher/ui/dialogs/BlockedModsDialog.h index 4be020ec..f1ea99ca 100644 --- a/launcher/ui/dialogs/BlockedModsDialog.h +++ b/launcher/ui/dialogs/BlockedModsDialog.h @@ -1,7 +1,14 @@ #pragma once #include +#include +#include +#include + +#include "modplatform/helpers/HashUtils.h" + +#include "tasks/ConcurrentTask.h" struct BlockedMod { QString name; @@ -20,15 +27,27 @@ class BlockedModsDialog : public QDialog { Q_OBJECT public: - BlockedModsDialog(QWidget *parent, const QString &title, const QString &text, const QList &mods); + BlockedModsDialog(QWidget *parent, const QString &title, const QString &text, QList &mods); ~BlockedModsDialog() override; private: Ui::BlockedModsDialog *ui; - const QList &mods; + QList &mods; + QFileSystemWatcher watcher; + shared_qobject_ptr hashing_task; + QSet checked_paths; + void openAll(); void update(); + void directoryChanged(QString path); + void setupWatch(); + void scanPaths(bool init); + void scanPath(QString path, bool init); + void checkMatchHash(QString hash, QString path); + + bool checkValidPath(QString path); + bool allModsMatched(); }; -- cgit From 13c7efa0584caf34950a6e6efa4b8e3bee16d764 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Tue, 25 Oct 2022 10:59:37 -0700 Subject: copy found mods to instance (FTB and Flame) Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/FileSystem.cpp | 22 +++++++++++ launcher/FileSystem.h | 2 + .../flame/FlameInstanceCreationTask.cpp | 35 +++++++++++++++- .../modplatform/flame/FlameInstanceCreationTask.h | 3 ++ .../modplatform/modpacksch/FTBPackInstallTask.cpp | 46 +++++++++++++++++++--- .../modplatform/modpacksch/FTBPackInstallTask.h | 3 ++ launcher/ui/dialogs/BlockedModsDialog.cpp | 7 ++++ launcher/ui/dialogs/BlockedModsDialog.h | 1 + launcher/ui/dialogs/BlockedModsDialog.ui | 37 +++++++++++------ 9 files changed, 137 insertions(+), 19 deletions(-) diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index 4026d6c1..4285fa87 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -163,6 +163,28 @@ bool ensureFolderPathExists(QString foldernamepath) return success; } +bool copyFile(QString &src, QString &dst) { + using copy_opts = fs::copy_options; + + std::error_code err; + + fs::copy_options opt = copy_opts::none; + // The default behavior is to follow symlinks + opt |= copy_opts::copy_symlinks; + + ensureFilePathExists(dst); + + fs::copy(toStdString(src), toStdString(dst), opt, err); + if (err) { + qWarning() << "Failed to copy files:" << QString::fromStdString(err.message()); + qDebug() << "Source file:" << src; + qDebug() << "Destination file:" << dst; + } + + return err.value() == 0; + +} + bool copy::operator()(const QString& offset) { using copy_opts = fs::copy_options; diff --git a/launcher/FileSystem.h b/launcher/FileSystem.h index b46f3281..68f6bc4c 100644 --- a/launcher/FileSystem.h +++ b/launcher/FileSystem.h @@ -75,6 +75,8 @@ bool ensureFilePathExists(QString filenamepath); */ bool ensureFolderPathExists(QString filenamepath); +bool copyFile(QString &src, QString &dst); + class copy { public: copy(const QString& src, const QString& dst) diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp index 15e660a9..fbc4ecf3 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp @@ -399,6 +399,7 @@ void FlameCreationTask::idResolverSucceeded(QEventLoop& loop) message_dialog->setModal(true); if (message_dialog->exec()) { + copyBlockedMods(blocked_mods); setupDownloadJob(loop); } else { m_mod_id_resolver.reset(); @@ -410,6 +411,36 @@ void FlameCreationTask::idResolverSucceeded(QEventLoop& loop) } } +void FlameCreationTask::copyBlockedMods(QList blocked_mods) { + + setStatus(tr("Copying Blocked Mods...")); + setAbortable(false); + int i = 0; + int total = blocked_mods.length(); + setProgress(i, total); + for (auto mod = blocked_mods.begin(); mod != blocked_mods.end(); mod++, i++) { + + if (!mod->matched) { + qDebug() << mod->name << "was not matched to a local file, skipping copy"; + continue; + } + + auto dest_path = FS::PathCombine(m_stagingPath, "minecraft", "mods", mod->name); + + setStatus(tr("Copying Blocked Mods (%1 out of %2 are done)").arg(QString::number(i), QString::number(total))); + + qDebug() << "Will try to copy" << mod->localPath << "to" << dest_path; + + if (!FS::copyFile(mod->localPath, dest_path)) { + qDebug() << "Copy of" << mod->localPath << "to" << dest_path << "Failed"; + } + + setProgress(i+1, total); + } + + setAbortable(true); +} + void FlameCreationTask::setupDownloadJob(QEventLoop& loop) { m_files_job = new NetJob(tr("Mod download"), APPLICATION->network()); @@ -455,7 +486,9 @@ void FlameCreationTask::setupDownloadJob(QEventLoop& loop) m_files_job.reset(); setError(reason); }); - connect(m_files_job.get(), &NetJob::progress, [&](qint64 current, qint64 total) { setProgress(current, total); }); + connect(m_files_job.get(), &NetJob::progress, [&](qint64 current, qint64 total) { + setProgress(current, total); + }); connect(m_files_job.get(), &NetJob::finished, &loop, &QEventLoop::quit); setStatus(tr("Downloading mods...")); diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.h b/launcher/modplatform/flame/FlameInstanceCreationTask.h index ded0e2ce..69a8f1ab 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.h +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.h @@ -10,6 +10,8 @@ #include "net/NetJob.h" +#include "ui/dialogs/BlockedModsDialog.h" + class FlameCreationTask final : public InstanceCreationTask { Q_OBJECT @@ -29,6 +31,7 @@ class FlameCreationTask final : public InstanceCreationTask { private slots: void idResolverSucceeded(QEventLoop&); void setupDownloadJob(QEventLoop&); + void copyBlockedMods(QList blocked_mods); private: QWidget* m_parent = nullptr; diff --git a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp index 75fda208..f6bf2488 100644 --- a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp +++ b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp @@ -176,7 +176,6 @@ void PackInstallTask::resolveMods() void PackInstallTask::onResolveModsSucceeded() { - QList blocked_mods; auto anyBlocked = false; Flame::Manifest results = m_mod_id_resolver_task->getResults(); @@ -201,7 +200,7 @@ void PackInstallTask::onResolveModsSucceeded() blocked_mod.matched = false; blocked_mod.localPath = ""; - blocked_mods.append(blocked_mod); + m_blocked_mods.append(blocked_mod); anyBlocked = true; } else { @@ -217,12 +216,16 @@ void PackInstallTask::onResolveModsSucceeded() auto message_dialog = new BlockedModsDialog(m_parent, tr("Blocked files found"), tr("The following files are not available for download in third party launchers.
" "You will need to manually download them and add them to the instance."), - blocked_mods); + m_blocked_mods); - if (message_dialog->exec() == QDialog::Accepted) + if (message_dialog->exec() == QDialog::Accepted) { + qDebug() << "Post dialog mods list: " << m_blocked_mods; createInstance(); - else + } + else { abort(); + } + } else { createInstance(); } @@ -326,6 +329,9 @@ void PackInstallTask::downloadPack() void PackInstallTask::onModDownloadSucceeded() { m_net_job.reset(); + if (m_blocked_mods.length() > 0) { + copyBlockedMods(); + } emitSucceeded(); } @@ -349,4 +355,34 @@ void PackInstallTask::onModDownloadFailed(QString reason) emitFailed(reason); } +void PackInstallTask::copyBlockedMods() { + + setStatus(tr("Copying Blocked Mods...")); + setAbortable(false); + int i = 0; + int total = m_blocked_mods.length(); + setProgress(i, total); + for (auto mod = m_blocked_mods.begin(); mod != m_blocked_mods.end(); mod++, i++) { + + if (!mod->matched) { + qDebug() << mod->name << "was not matched to a local file, skipping copy"; + continue; + } + + auto dest_path = FS::PathCombine(m_stagingPath, ".minecraft", "mods", mod->name); + + setStatus(tr("Copying Blocked Mods (%1 out of %2 are done)").arg(QString::number(i), QString::number(total))); + + qDebug() << "Will try to copy" << mod->localPath << "to" << dest_path; + + if (!FS::copyFile(mod->localPath, dest_path)) { + qDebug() << "Copy of" << mod->localPath << "to" << dest_path << "Failed"; + } + + setProgress(i+1, total); + } + + setAbortable(true); +} + } // namespace ModpacksCH diff --git a/launcher/modplatform/modpacksch/FTBPackInstallTask.h b/launcher/modplatform/modpacksch/FTBPackInstallTask.h index 7c6fbeb9..2cd4d729 100644 --- a/launcher/modplatform/modpacksch/FTBPackInstallTask.h +++ b/launcher/modplatform/modpacksch/FTBPackInstallTask.h @@ -43,6 +43,7 @@ #include "QObjectPtr.h" #include "modplatform/flame/FileResolvingTask.h" #include "net/NetJob.h" +#include "ui/dialogs/BlockedModsDialog.h" #include @@ -76,6 +77,7 @@ private: void resolveMods(); void createInstance(); void downloadPack(); + void copyBlockedMods(); private: NetJob::Ptr m_net_job = nullptr; @@ -90,6 +92,7 @@ private: Version m_version; QMap m_files_to_copy; + QList m_blocked_mods; //FIXME: nuke QWidget* m_parent; diff --git a/launcher/ui/dialogs/BlockedModsDialog.cpp b/launcher/ui/dialogs/BlockedModsDialog.cpp index 9ba033d7..542d0681 100644 --- a/launcher/ui/dialogs/BlockedModsDialog.cpp +++ b/launcher/ui/dialogs/BlockedModsDialog.cpp @@ -31,6 +31,7 @@ BlockedModsDialog::BlockedModsDialog(QWidget *parent, const QString &title, cons this->setWindowTitle(title); ui->label->setText(text); + ui->labelModsFound->setText("Please download the missing mods."); update(); } @@ -60,6 +61,12 @@ void BlockedModsDialog::update() { } ui->textBrowser->setText(text); + + if (allModsMatched()) { + ui->labelModsFound->setText("All mods found ✔"); + } else { + ui->labelModsFound->setText("Please download the missing mods."); + } } void BlockedModsDialog::directoryChanged(QString path) { diff --git a/launcher/ui/dialogs/BlockedModsDialog.h b/launcher/ui/dialogs/BlockedModsDialog.h index f1ea99ca..93b9f46a 100644 --- a/launcher/ui/dialogs/BlockedModsDialog.h +++ b/launcher/ui/dialogs/BlockedModsDialog.h @@ -51,3 +51,4 @@ private: bool allModsMatched(); }; +QDebug operator<<(QDebug debug, const BlockedMod &m); \ No newline at end of file diff --git a/launcher/ui/dialogs/BlockedModsDialog.ui b/launcher/ui/dialogs/BlockedModsDialog.ui index f4ae95b6..371549cf 100644 --- a/launcher/ui/dialogs/BlockedModsDialog.ui +++ b/launcher/ui/dialogs/BlockedModsDialog.ui @@ -13,8 +13,8 @@ BlockedModsDialog - - + + @@ -24,17 +24,7 @@ - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - + true @@ -44,6 +34,27 @@ + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + +
-- cgit From e9d4793b1e98944dad910b3952c117bb2d3369de Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Tue, 25 Oct 2022 20:18:14 -0700 Subject: minor clean up and add some docs Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/FileSystem.cpp | 7 ++++ launcher/FileSystem.h | 1 + .../flame/FlameInstanceCreationTask.cpp | 2 ++ .../modplatform/modpacksch/FTBPackInstallTask.cpp | 4 +-- launcher/ui/dialogs/BlockedModsDialog.cpp | 42 +++++++++++++--------- launcher/ui/dialogs/BlockedModsDialog.h | 5 ++- 6 files changed, 38 insertions(+), 23 deletions(-) diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index 4285fa87..8fe441b3 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -163,6 +163,10 @@ bool ensureFolderPathExists(QString foldernamepath) return success; } +/// @brief Copy file at src to dest, ensures the full filepath exsists +/// @param src srouce file path +/// @param dst destination file path +/// @return boolean: was there an error during the filecopy? bool copyFile(QString &src, QString &dst) { using copy_opts = fs::copy_options; @@ -185,6 +189,9 @@ bool copyFile(QString &src, QString &dst) { } +/// @brief Copies a directory and it's contents from src to dest +/// @param offset subdirectory form src to copy to dest +/// @return if there was an error during the filecopy bool copy::operator()(const QString& offset) { using copy_opts = fs::copy_options; diff --git a/launcher/FileSystem.h b/launcher/FileSystem.h index 68f6bc4c..ab006d48 100644 --- a/launcher/FileSystem.h +++ b/launcher/FileSystem.h @@ -77,6 +77,7 @@ bool ensureFolderPathExists(QString filenamepath); bool copyFile(QString &src, QString &dst); +/// @brief Copies a directory and it's contents from src to dest class copy { public: copy(const QString& src, const QString& dst) diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp index fbc4ecf3..edacb819 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp @@ -411,6 +411,8 @@ void FlameCreationTask::idResolverSucceeded(QEventLoop& loop) } } +/// @brief copy the matched blocked mods to the instance staging area +/// @param blocked_mods list of the blocked mods and their matched paths void FlameCreationTask::copyBlockedMods(QList blocked_mods) { setStatus(tr("Copying Blocked Mods...")); diff --git a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp index f6bf2488..49fbafd6 100644 --- a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp +++ b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp @@ -189,9 +189,6 @@ void PackInstallTask::onResolveModsSucceeded() // First check for blocked mods if (!results_file.resolved || results_file.url.isEmpty()) { - // QString type(local_file.type); - - // type[0] = type[0].toUpper(); BlockedMod blocked_mod; blocked_mod.name = local_file.name; @@ -355,6 +352,7 @@ void PackInstallTask::onModDownloadFailed(QString reason) emitFailed(reason); } +/// @brief copy the matched blocked mods to the instance staging area void PackInstallTask::copyBlockedMods() { setStatus(tr("Copying Blocked Mods...")); diff --git a/launcher/ui/dialogs/BlockedModsDialog.cpp b/launcher/ui/dialogs/BlockedModsDialog.cpp index 542d0681..f5bc7f73 100644 --- a/launcher/ui/dialogs/BlockedModsDialog.cpp +++ b/launcher/ui/dialogs/BlockedModsDialog.cpp @@ -1,5 +1,3 @@ -#include -#include #include "Application.h" #include "BlockedModsDialog.h" #include "ui_BlockedModsDialog.h" @@ -27,7 +25,7 @@ BlockedModsDialog::BlockedModsDialog(QWidget *parent, const QString &title, cons qDebug() << "Mods List: " << mods; setupWatch(); - scanPaths(true); + scanPaths(); this->setWindowTitle(title); ui->label->setText(text); @@ -45,6 +43,7 @@ void BlockedModsDialog::openAll() { } } +/// @brief update UI with current status of the blocked mod detection void BlockedModsDialog::update() { QString text; QString span; @@ -69,12 +68,15 @@ void BlockedModsDialog::update() { } } +/// @brief Signal fired when a watched direcotry has changed +/// @param path the path to the changed directory void BlockedModsDialog::directoryChanged(QString path) { qDebug() << "Directory changed: " << path; - scanPath(path, false); + scanPath(path); } +/// @brief add the user downloads folder and the global mods folder to the filesystem watcher void BlockedModsDialog::setupWatch() { const QString downloadsFolder = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation); const QString modsFolder = APPLICATION->settings()->get("CentralModsDir").toString(); @@ -82,23 +84,24 @@ void BlockedModsDialog::setupWatch() { watcher.addPath(modsFolder); } -void BlockedModsDialog::scanPaths(bool init) { + +/// @brief scan all watched folder +void BlockedModsDialog::scanPaths() { for (auto &dir : watcher.directories()) { - scanPath(dir, init); + scanPath(dir); } } -void BlockedModsDialog::scanPath(QString path, bool init) { +/// @brief Scan the directory at path, skip paths that do not contain a file name +/// of a blocked mod we are looking for +/// @param path the directory to scan +void BlockedModsDialog::scanPath(QString path) { QDir scan_dir(path); QDirIterator scan_it(path, QDir::Filter::Files | QDir::Filter::Hidden, QDirIterator::NoIteratorFlags); while (scan_it.hasNext()) { QString file = scan_it.next(); - if (checked_paths.contains(file)){ - continue; - } - if (!checkValidPath(file)) { continue; } @@ -113,10 +116,6 @@ void BlockedModsDialog::scanPath(QString path, bool init) { connect(hash_task.get(), &Task::failed, [this, hash_task, file] { qDebug() << "Failed to hash path: " << file; }); - - if (init) { - checked_paths.insert(file); - } hashing_task->addTask(hash_task); } @@ -125,6 +124,10 @@ void BlockedModsDialog::scanPath(QString path, bool init) { } +/// @brief check if the conputed hash for the provided path matches a blocked +/// mod we are looking for +/// @param hash the computed hash for the provided path +/// @param path the path to the local file being compared void BlockedModsDialog::checkMatchHash(QString hash, QString path) { bool match = false; @@ -150,6 +153,9 @@ void BlockedModsDialog::checkMatchHash(QString hash, QString path) { } } +/// @brief Check if the name of the file at path matches the naem of a blocked mod we are searching for +/// @param path the path to check +/// @return boolean: did the path match the name of a blocked mod? bool BlockedModsDialog::checkValidPath(QString path) { QFileInfo file = QFileInfo(path); @@ -165,6 +171,8 @@ bool BlockedModsDialog::checkValidPath(QString path) { return false; } +/// @brief have we found all the mods we're lookign for? +/// @return boolean bool BlockedModsDialog::allModsMatched() { for (auto &mod : mods) { if (!mod.matched) @@ -173,7 +181,7 @@ bool BlockedModsDialog::allModsMatched() { return true; } - +/// qDebug print support for the BlockedMod struct QDebug operator<<(QDebug debug, const BlockedMod &m) { QDebugStateSaver saver(debug); @@ -182,4 +190,4 @@ QDebug operator<<(QDebug debug, const BlockedMod &m) { << ", localPath: " << m.localPath <<"}"; return debug; -} \ No newline at end of file +} diff --git a/launcher/ui/dialogs/BlockedModsDialog.h b/launcher/ui/dialogs/BlockedModsDialog.h index 93b9f46a..cf1d3b3d 100644 --- a/launcher/ui/dialogs/BlockedModsDialog.h +++ b/launcher/ui/dialogs/BlockedModsDialog.h @@ -37,14 +37,13 @@ private: QList &mods; QFileSystemWatcher watcher; shared_qobject_ptr hashing_task; - QSet checked_paths; void openAll(); void update(); void directoryChanged(QString path); void setupWatch(); - void scanPaths(bool init); - void scanPath(QString path, bool init); + void scanPaths(); + void scanPath(QString path); void checkMatchHash(QString hash, QString path); bool checkValidPath(QString path); -- cgit From d2f3dbaa2984b70a71e5fb1b246a31987a6fdf10 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sun, 30 Oct 2022 22:39:12 -0700 Subject: fix mispellings and wrap strings for translation Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/ui/dialogs/BlockedModsDialog.cpp | 18 ++++++++---------- launcher/ui/dialogs/BlockedModsDialog.h | 2 +- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/launcher/ui/dialogs/BlockedModsDialog.cpp b/launcher/ui/dialogs/BlockedModsDialog.cpp index f5bc7f73..136a7371 100644 --- a/launcher/ui/dialogs/BlockedModsDialog.cpp +++ b/launcher/ui/dialogs/BlockedModsDialog.cpp @@ -29,7 +29,7 @@ BlockedModsDialog::BlockedModsDialog(QWidget *parent, const QString &title, cons this->setWindowTitle(title); ui->label->setText(text); - ui->labelModsFound->setText("Please download the missing mods."); + ui->labelModsFound->setText(tr("Please download the missing mods.")); update(); } @@ -51,20 +51,20 @@ void BlockedModsDialog::update() { for (auto &mod : mods) { if (mod.matched) { // ✔ -> html for HEAVY CHECK MARK : ✔ - span = QString(" ✔ Found at %1 ").arg(mod.localPath); + span = QString(tr(" ✔ Found at %1 ")).arg(mod.localPath); } else { // ✘ -> html for HEAVY BALLOT X : ✘ - span = QString(" ✘ Not Found "); + span = QString(tr(" ✘ Not Found ")); } - text += QString("%1: %2

Hash: %3 %4


").arg(mod.name, mod.websiteUrl, mod.hash, span); + text += QString(tr("%1: %2

Hash: %3 %4


")).arg(mod.name, mod.websiteUrl, mod.hash, span); } ui->textBrowser->setText(text); if (allModsMatched()) { - ui->labelModsFound->setText("All mods found ✔"); + ui->labelModsFound->setText(tr("All mods found ✔")); } else { - ui->labelModsFound->setText("Please download the missing mods."); + ui->labelModsFound->setText(tr("Please download the missing mods.")); } } @@ -124,7 +124,7 @@ void BlockedModsDialog::scanPath(QString path) { } -/// @brief check if the conputed hash for the provided path matches a blocked +/// @brief check if the computed hash for the provided path matches a blocked /// mod we are looking for /// @param hash the computed hash for the provided path /// @param path the path to the local file being compared @@ -153,7 +153,7 @@ void BlockedModsDialog::checkMatchHash(QString hash, QString path) { } } -/// @brief Check if the name of the file at path matches the naem of a blocked mod we are searching for +/// @brief Check if the name of the file at path matches the name of a blocked mod we are searching for /// @param path the path to check /// @return boolean: did the path match the name of a blocked mod? bool BlockedModsDialog::checkValidPath(QString path) { @@ -171,8 +171,6 @@ bool BlockedModsDialog::checkValidPath(QString path) { return false; } -/// @brief have we found all the mods we're lookign for? -/// @return boolean bool BlockedModsDialog::allModsMatched() { for (auto &mod : mods) { if (!mod.matched) diff --git a/launcher/ui/dialogs/BlockedModsDialog.h b/launcher/ui/dialogs/BlockedModsDialog.h index cf1d3b3d..0a5c90db 100644 --- a/launcher/ui/dialogs/BlockedModsDialog.h +++ b/launcher/ui/dialogs/BlockedModsDialog.h @@ -50,4 +50,4 @@ private: bool allModsMatched(); }; -QDebug operator<<(QDebug debug, const BlockedMod &m); \ No newline at end of file +QDebug operator<<(QDebug debug, const BlockedMod &m); -- cgit From fda2c116bef33df2ca49d77ff4b016e724f47549 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sun, 30 Oct 2022 22:42:35 -0700 Subject: code quality cleanup Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/FileSystem.cpp | 2 +- launcher/FileSystem.h | 2 +- .../flame/FlameInstanceCreationTask.cpp | 23 +++++++++++----------- .../modplatform/flame/FlameInstanceCreationTask.h | 2 +- .../modplatform/modpacksch/FTBPackInstallTask.cpp | 2 +- 5 files changed, 15 insertions(+), 16 deletions(-) diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index 8fe441b3..508da08d 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -167,7 +167,7 @@ bool ensureFolderPathExists(QString foldernamepath) /// @param src srouce file path /// @param dst destination file path /// @return boolean: was there an error during the filecopy? -bool copyFile(QString &src, QString &dst) { +bool copyFile(QString const& src, QString const& dst) { using copy_opts = fs::copy_options; std::error_code err; diff --git a/launcher/FileSystem.h b/launcher/FileSystem.h index ab006d48..771bda60 100644 --- a/launcher/FileSystem.h +++ b/launcher/FileSystem.h @@ -75,7 +75,7 @@ bool ensureFilePathExists(QString filenamepath); */ bool ensureFolderPathExists(QString filenamepath); -bool copyFile(QString &src, QString &dst); +bool copyFile(QString const& src, QString const& dst); /// @brief Copies a directory and it's contents from src to dest class copy { diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp index edacb819..30438a1a 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp @@ -413,31 +413,32 @@ void FlameCreationTask::idResolverSucceeded(QEventLoop& loop) /// @brief copy the matched blocked mods to the instance staging area /// @param blocked_mods list of the blocked mods and their matched paths -void FlameCreationTask::copyBlockedMods(QList blocked_mods) { +void FlameCreationTask::copyBlockedMods(QList const& blocked_mods) { setStatus(tr("Copying Blocked Mods...")); setAbortable(false); int i = 0; int total = blocked_mods.length(); setProgress(i, total); - for (auto mod = blocked_mods.begin(); mod != blocked_mods.end(); mod++, i++) { + for (auto &mod : blocked_mods) { - if (!mod->matched) { - qDebug() << mod->name << "was not matched to a local file, skipping copy"; + if (!mod.matched) { + qDebug() << mod.name << "was not matched to a local file, skipping copy"; continue; } - auto dest_path = FS::PathCombine(m_stagingPath, "minecraft", "mods", mod->name); + auto dest_path = FS::PathCombine(m_stagingPath, "minecraft", "mods", mod.name); setStatus(tr("Copying Blocked Mods (%1 out of %2 are done)").arg(QString::number(i), QString::number(total))); - qDebug() << "Will try to copy" << mod->localPath << "to" << dest_path; + qDebug() << "Will try to copy" << mod.localPath << "to" << dest_path; - if (!FS::copyFile(mod->localPath, dest_path)) { - qDebug() << "Copy of" << mod->localPath << "to" << dest_path << "Failed"; + if (!FS::copyFile(mod.localPath, dest_path)) { // FIXME: use FS::copy once #333 is merged + qDebug() << "Copy of" << mod.localPath << "to" << dest_path << "Failed"; } - setProgress(i+1, total); + i++; + setProgress(i, total); } setAbortable(true); @@ -488,9 +489,7 @@ void FlameCreationTask::setupDownloadJob(QEventLoop& loop) m_files_job.reset(); setError(reason); }); - connect(m_files_job.get(), &NetJob::progress, [&](qint64 current, qint64 total) { - setProgress(current, total); - }); + connect(m_files_job.get(), &NetJob::progress, this, &FlameCreationTask::setProgress); connect(m_files_job.get(), &NetJob::finished, &loop, &QEventLoop::quit); setStatus(tr("Downloading mods...")); diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.h b/launcher/modplatform/flame/FlameInstanceCreationTask.h index 69a8f1ab..fbc7d5bf 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.h +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.h @@ -31,7 +31,7 @@ class FlameCreationTask final : public InstanceCreationTask { private slots: void idResolverSucceeded(QEventLoop&); void setupDownloadJob(QEventLoop&); - void copyBlockedMods(QList blocked_mods); + void copyBlockedMods(QList const& blocked_mods); private: QWidget* m_parent = nullptr; diff --git a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp index 49fbafd6..5091db0c 100644 --- a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp +++ b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp @@ -326,7 +326,7 @@ void PackInstallTask::downloadPack() void PackInstallTask::onModDownloadSucceeded() { m_net_job.reset(); - if (m_blocked_mods.length() > 0) { + if (!m_blocked_mods.isEmpty()) { copyBlockedMods(); } emitSucceeded(); -- cgit From a7a331a26e43df3dbafdbb29a59d38ba807ffa7d Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sun, 30 Oct 2022 22:49:54 -0700 Subject: ensure FS::copyFile is marked for removal Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/FileSystem.h | 1 + launcher/modplatform/modpacksch/FTBPackInstallTask.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/launcher/FileSystem.h b/launcher/FileSystem.h index 771bda60..11981f68 100644 --- a/launcher/FileSystem.h +++ b/launcher/FileSystem.h @@ -75,6 +75,7 @@ bool ensureFilePathExists(QString filenamepath); */ bool ensureFolderPathExists(QString filenamepath); +// TODO: remove in favor of FS::copy once #333 is merged bool copyFile(QString const& src, QString const& dst); /// @brief Copies a directory and it's contents from src to dest diff --git a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp index 5091db0c..06ef1deb 100644 --- a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp +++ b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp @@ -373,7 +373,7 @@ void PackInstallTask::copyBlockedMods() { qDebug() << "Will try to copy" << mod->localPath << "to" << dest_path; - if (!FS::copyFile(mod->localPath, dest_path)) { + if (!FS::copyFile(mod->localPath, dest_path)) { // FIXME: use FS::copy once #333 is merged qDebug() << "Copy of" << mod->localPath << "to" << dest_path << "Failed"; } -- cgit From 6010ce0dc587527caa05bdc9b4cecdb9bd811375 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Tue, 1 Nov 2022 04:28:57 -0700 Subject: chore(remove FS::copyFile): Now that #333 is merged and FS::copy works on non directory copyFile can be removed. Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/FileSystem.cpp | 26 ---------------------- launcher/FileSystem.h | 3 --- .../flame/FlameInstanceCreationTask.cpp | 2 +- .../modplatform/modpacksch/FTBPackInstallTask.cpp | 2 +- 4 files changed, 2 insertions(+), 31 deletions(-) diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index 508da08d..bf0849ec 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -163,32 +163,6 @@ bool ensureFolderPathExists(QString foldernamepath) return success; } -/// @brief Copy file at src to dest, ensures the full filepath exsists -/// @param src srouce file path -/// @param dst destination file path -/// @return boolean: was there an error during the filecopy? -bool copyFile(QString const& src, QString const& dst) { - using copy_opts = fs::copy_options; - - std::error_code err; - - fs::copy_options opt = copy_opts::none; - // The default behavior is to follow symlinks - opt |= copy_opts::copy_symlinks; - - ensureFilePathExists(dst); - - fs::copy(toStdString(src), toStdString(dst), opt, err); - if (err) { - qWarning() << "Failed to copy files:" << QString::fromStdString(err.message()); - qDebug() << "Source file:" << src; - qDebug() << "Destination file:" << dst; - } - - return err.value() == 0; - -} - /// @brief Copies a directory and it's contents from src to dest /// @param offset subdirectory form src to copy to dest /// @return if there was an error during the filecopy diff --git a/launcher/FileSystem.h b/launcher/FileSystem.h index 11981f68..b7e175fd 100644 --- a/launcher/FileSystem.h +++ b/launcher/FileSystem.h @@ -75,9 +75,6 @@ bool ensureFilePathExists(QString filenamepath); */ bool ensureFolderPathExists(QString filenamepath); -// TODO: remove in favor of FS::copy once #333 is merged -bool copyFile(QString const& src, QString const& dst); - /// @brief Copies a directory and it's contents from src to dest class copy { public: diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp index 30438a1a..5d4dc689 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp @@ -433,7 +433,7 @@ void FlameCreationTask::copyBlockedMods(QList const& blocked_mods) { qDebug() << "Will try to copy" << mod.localPath << "to" << dest_path; - if (!FS::copyFile(mod.localPath, dest_path)) { // FIXME: use FS::copy once #333 is merged + if (!FS::copy(mod.localPath, dest_path)()) { qDebug() << "Copy of" << mod.localPath << "to" << dest_path << "Failed"; } diff --git a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp index 06ef1deb..1e4bbe19 100644 --- a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp +++ b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp @@ -373,7 +373,7 @@ void PackInstallTask::copyBlockedMods() { qDebug() << "Will try to copy" << mod->localPath << "to" << dest_path; - if (!FS::copyFile(mod->localPath, dest_path)) { // FIXME: use FS::copy once #333 is merged + if (!FS::copy(mod->localPath, dest_path)()) { qDebug() << "Copy of" << mod->localPath << "to" << dest_path << "Failed"; } -- cgit From 209a1650e489e21417ce2e1a29862703d51a2cd0 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Tue, 1 Nov 2022 07:06:36 -0700 Subject: clang_format and code cleanup Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- .../flame/FlameInstanceCreationTask.cpp | 11 ++- .../modplatform/modpacksch/FTBPackInstallTask.cpp | 24 +++--- launcher/ui/dialogs/BlockedModsDialog.cpp | 95 ++++++++++------------ 3 files changed, 62 insertions(+), 68 deletions(-) diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp index 5d4dc689..f86e9335 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp @@ -413,15 +413,14 @@ void FlameCreationTask::idResolverSucceeded(QEventLoop& loop) /// @brief copy the matched blocked mods to the instance staging area /// @param blocked_mods list of the blocked mods and their matched paths -void FlameCreationTask::copyBlockedMods(QList const& blocked_mods) { - +void FlameCreationTask::copyBlockedMods(QList const& blocked_mods) +{ setStatus(tr("Copying Blocked Mods...")); setAbortable(false); int i = 0; int total = blocked_mods.length(); setProgress(i, total); - for (auto &mod : blocked_mods) { - + for (auto const& mod : blocked_mods) { if (!mod.matched) { qDebug() << mod.name << "was not matched to a local file, skipping copy"; continue; @@ -433,9 +432,9 @@ void FlameCreationTask::copyBlockedMods(QList const& blocked_mods) { qDebug() << "Will try to copy" << mod.localPath << "to" << dest_path; - if (!FS::copy(mod.localPath, dest_path)()) { + if (!FS::copy(mod.localPath, dest_path)()) { qDebug() << "Copy of" << mod.localPath << "to" << dest_path << "Failed"; - } + } i++; setProgress(i, total); diff --git a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp index 1e4bbe19..70ef7571 100644 --- a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp +++ b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp @@ -353,31 +353,31 @@ void PackInstallTask::onModDownloadFailed(QString reason) } /// @brief copy the matched blocked mods to the instance staging area -void PackInstallTask::copyBlockedMods() { - +void PackInstallTask::copyBlockedMods() +{ setStatus(tr("Copying Blocked Mods...")); setAbortable(false); int i = 0; int total = m_blocked_mods.length(); setProgress(i, total); - for (auto mod = m_blocked_mods.begin(); mod != m_blocked_mods.end(); mod++, i++) { - - if (!mod->matched) { - qDebug() << mod->name << "was not matched to a local file, skipping copy"; + for (auto const& mod : m_blocked_mods) { + if (!mod.matched) { + qDebug() << mod.name << "was not matched to a local file, skipping copy"; continue; } - auto dest_path = FS::PathCombine(m_stagingPath, ".minecraft", "mods", mod->name); + auto dest_path = FS::PathCombine(m_stagingPath, ".minecraft", "mods", mod.name); setStatus(tr("Copying Blocked Mods (%1 out of %2 are done)").arg(QString::number(i), QString::number(total))); - qDebug() << "Will try to copy" << mod->localPath << "to" << dest_path; + qDebug() << "Will try to copy" << mod.localPath << "to" << dest_path; - if (!FS::copy(mod->localPath, dest_path)()) { - qDebug() << "Copy of" << mod->localPath << "to" << dest_path << "Failed"; - } + if (!FS::copy(mod.localPath, dest_path)()) { + qDebug() << "Copy of" << mod.localPath << "to" << dest_path << "Failed"; + } - setProgress(i+1, total); + i++; + setProgress(i, total); } setAbortable(true); diff --git a/launcher/ui/dialogs/BlockedModsDialog.cpp b/launcher/ui/dialogs/BlockedModsDialog.cpp index 136a7371..2cf94250 100644 --- a/launcher/ui/dialogs/BlockedModsDialog.cpp +++ b/launcher/ui/dialogs/BlockedModsDialog.cpp @@ -1,18 +1,16 @@ -#include "Application.h" #include "BlockedModsDialog.h" -#include "ui_BlockedModsDialog.h" -#include -#include #include +#include +#include +#include "Application.h" +#include "ui_BlockedModsDialog.h" #include #include - - - -BlockedModsDialog::BlockedModsDialog(QWidget *parent, const QString &title, const QString &text, QList &mods) : - QDialog(parent), ui(new Ui::BlockedModsDialog), mods(mods) { +BlockedModsDialog::BlockedModsDialog(QWidget* parent, const QString& title, const QString& text, QList& mods) + : QDialog(parent), ui(new Ui::BlockedModsDialog), mods(mods) +{ ui->setupUi(this); auto openAllButton = ui->buttonBox->addButton(tr("Open All"), QDialogButtonBox::ActionRole); @@ -21,7 +19,7 @@ BlockedModsDialog::BlockedModsDialog(QWidget *parent, const QString &title, cons connect(&watcher, &QFileSystemWatcher::directoryChanged, this, &BlockedModsDialog::directoryChanged); hashing_task = shared_qobject_ptr(new ConcurrentTask(this, "MakeHashesTask", 10)); - + qDebug() << "Mods List: " << mods; setupWatch(); @@ -33,22 +31,25 @@ BlockedModsDialog::BlockedModsDialog(QWidget *parent, const QString &title, cons update(); } -BlockedModsDialog::~BlockedModsDialog() { +BlockedModsDialog::~BlockedModsDialog() +{ delete ui; } -void BlockedModsDialog::openAll() { - for(auto &mod : mods) { +void BlockedModsDialog::openAll() +{ + for (auto& mod : mods) { QDesktopServices::openUrl(mod.websiteUrl); } } /// @brief update UI with current status of the blocked mod detection -void BlockedModsDialog::update() { +void BlockedModsDialog::update() +{ QString text; QString span; - for (auto &mod : mods) { + for (auto& mod : mods) { if (mod.matched) { // ✔ -> html for HEAVY CHECK MARK : ✔ span = QString(tr(" ✔ Found at %1 ")).arg(mod.localPath); @@ -70,33 +71,34 @@ void BlockedModsDialog::update() { /// @brief Signal fired when a watched direcotry has changed /// @param path the path to the changed directory -void BlockedModsDialog::directoryChanged(QString path) { +void BlockedModsDialog::directoryChanged(QString path) +{ qDebug() << "Directory changed: " << path; scanPath(path); } - /// @brief add the user downloads folder and the global mods folder to the filesystem watcher -void BlockedModsDialog::setupWatch() { +void BlockedModsDialog::setupWatch() +{ const QString downloadsFolder = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation); const QString modsFolder = APPLICATION->settings()->get("CentralModsDir").toString(); watcher.addPath(downloadsFolder); watcher.addPath(modsFolder); } - /// @brief scan all watched folder -void BlockedModsDialog::scanPaths() { - for (auto &dir : watcher.directories()) { +void BlockedModsDialog::scanPaths() +{ + for (auto& dir : watcher.directories()) { scanPath(dir); } } -/// @brief Scan the directory at path, skip paths that do not contain a file name +/// @brief Scan the directory at path, skip paths that do not contain a file name /// of a blocked mod we are looking for /// @param path the directory to scan -void BlockedModsDialog::scanPath(QString path) { - +void BlockedModsDialog::scanPath(QString path) +{ QDir scan_dir(path); QDirIterator scan_it(path, QDir::Filter::Files | QDir::Filter::Hidden, QDirIterator::NoIteratorFlags); while (scan_it.hasNext()) { @@ -110,30 +112,26 @@ void BlockedModsDialog::scanPath(QString path) { qDebug() << "Creating Hash task for path: " << file; - connect(hash_task.get(), &Task::succeeded, [this, hash_task, file] { - checkMatchHash(hash_task->getResult(), file); - }); - connect(hash_task.get(), &Task::failed, [this, hash_task, file] { - qDebug() << "Failed to hash path: " << file; - }); - + connect(hash_task.get(), &Task::succeeded, [this, hash_task, file] { checkMatchHash(hash_task->getResult(), file); }); + connect(hash_task.get(), &Task::failed, [file] { qDebug() << "Failed to hash path: " << file; }); + hashing_task->addTask(hash_task); } hashing_task->start(); - } /// @brief check if the computed hash for the provided path matches a blocked /// mod we are looking for /// @param hash the computed hash for the provided path /// @param path the path to the local file being compared -void BlockedModsDialog::checkMatchHash(QString hash, QString path) { +void BlockedModsDialog::checkMatchHash(QString hash, QString path) +{ bool match = false; - qDebug() << "Checking for match on hash: " << hash << " | From path:" << path; + qDebug() << "Checking for match on hash: " << hash << "| From path:" << path; - for (auto &mod : mods) { + for (auto& mod : mods) { if (mod.matched) { continue; } @@ -142,7 +140,7 @@ void BlockedModsDialog::checkMatchHash(QString hash, QString path) { mod.localPath = path; match = true; - qDebug() << "Hash match found: " << mod.name << " " << hash << " | From path:" << path; + qDebug() << "Hash match found:" << mod.name << hash << "| From path:" << path; break; } @@ -156,14 +154,14 @@ void BlockedModsDialog::checkMatchHash(QString hash, QString path) { /// @brief Check if the name of the file at path matches the name of a blocked mod we are searching for /// @param path the path to check /// @return boolean: did the path match the name of a blocked mod? -bool BlockedModsDialog::checkValidPath(QString path) { - +bool BlockedModsDialog::checkValidPath(QString path) +{ QFileInfo file = QFileInfo(path); QString filename = file.fileName(); - for (auto &mod : mods) { + for (auto& mod : mods) { if (mod.name.compare(filename, Qt::CaseInsensitive) == 0) { - qDebug() << "Name match found: " << mod.name << " | From path:" << path; + qDebug() << "Name match found:" << mod.name << "| From path:" << path; return true; } } @@ -171,21 +169,18 @@ bool BlockedModsDialog::checkValidPath(QString path) { return false; } -bool BlockedModsDialog::allModsMatched() { - for (auto &mod : mods) { - if (!mod.matched) - return false; - } - return true; +bool BlockedModsDialog::allModsMatched() +{ + return std::all_of(mods.begin(), mods.end(), [](auto const& mod) { return mod.matched; }); } /// qDebug print support for the BlockedMod struct -QDebug operator<<(QDebug debug, const BlockedMod &m) { +QDebug operator<<(QDebug debug, const BlockedMod& m) +{ QDebugStateSaver saver(debug); - debug.nospace() << "{ name: " << m.name << ", websiteUrl: " << m.websiteUrl - << ", hash: " << m.hash << ", matched: " << m.matched - << ", localPath: " << m.localPath <<"}"; + debug.nospace() << "{ name: " << m.name << ", websiteUrl: " << m.websiteUrl << ", hash: " << m.hash << ", matched: " << m.matched + << ", localPath: " << m.localPath << "}"; return debug; } -- cgit From 7f32c6464d84181fc8947f632da340a863dc53d6 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 1 Nov 2022 16:58:22 +0000 Subject: Initial better mod browser link implementation Signed-off-by: TheKodeToad --- launcher/ui/dialogs/ModDownloadDialog.cpp | 5 ++ launcher/ui/dialogs/ModDownloadDialog.h | 2 + launcher/ui/pages/modplatform/ModPage.cpp | 63 +++++++++++++++++++--- launcher/ui/pages/modplatform/ModPage.h | 1 + launcher/ui/pages/modplatform/ModPage.ui | 4 +- .../ui/pages/modplatform/flame/FlameModPage.cpp | 19 ++++++- launcher/ui/pages/modplatform/flame/FlameModPage.h | 2 + .../pages/modplatform/modrinth/ModrinthModPage.cpp | 2 +- 8 files changed, 87 insertions(+), 11 deletions(-) diff --git a/launcher/ui/dialogs/ModDownloadDialog.cpp b/launcher/ui/dialogs/ModDownloadDialog.cpp index d740c8cb..38b4ffcf 100644 --- a/launcher/ui/dialogs/ModDownloadDialog.cpp +++ b/launcher/ui/dialogs/ModDownloadDialog.cpp @@ -187,3 +187,8 @@ void ModDownloadDialog::selectedPageChanged(BasePage* previous, BasePage* select // Same effect as having a global search bar selected_page->setSearchTerm(prev_page->getSearchTerm()); } + +bool ModDownloadDialog::selectPage(QString pageId) +{ + return m_container->selectPage(pageId); +} \ No newline at end of file diff --git a/launcher/ui/dialogs/ModDownloadDialog.h b/launcher/ui/dialogs/ModDownloadDialog.h index 18a5f0f3..125cb776 100644 --- a/launcher/ui/dialogs/ModDownloadDialog.h +++ b/launcher/ui/dialogs/ModDownloadDialog.h @@ -53,6 +53,8 @@ public: const QList getTasks(); const std::shared_ptr &mods; + bool selectPage(QString pageId); + public slots: void confirm(); void accept() override; diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index f2c1746f..7f62fff1 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -2,6 +2,7 @@ /* * PolyMC - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu + * Copyright (C) 2022 TheKodeToad * * 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 @@ -37,6 +38,7 @@ #include "Application.h" #include "ui_ModPage.h" +#include #include #include @@ -80,6 +82,8 @@ ModPage::ModPage(ModDownloadDialog* dialog, BaseInstance* instance, ModAPI* api) ui->packView->setItemDelegate(new ProjectItemDelegate(this)); ui->packView->installEventFilter(this); + + connect(ui->packDescription, &QTextBrowser::anchorClicked, this, &ModPage::openUrl); } ModPage::~ModPage() @@ -158,8 +162,8 @@ void ModPage::triggerSearch() { auto changed = m_filter_widget->changed(); m_filter = m_filter_widget->getFilter(); - - if(changed){ + + if (changed) { ui->packView->clearSelection(); ui->packDescription->clear(); ui->versionSelectionBox->clear(); @@ -241,6 +245,54 @@ void ModPage::onModSelected() ui->packView->adjustSize(); } +void ModPage::openUrl(const QUrl& url) +{ + // do not allow other url schemes for security reasons + if (!(url.scheme() == "http" || url.scheme() == "https")) { + qWarning() << "Unsupported scheme" << url.scheme(); + return; + } + + // detect mod URLs and search instead + int prefixLength; + const char* page; + + if ((url.host() == "modrinth.com" || url.host() == "www.modrinth.com") + && url.path().startsWith("/mod/")) { + prefixLength = 5; + page = "modrinth"; + } + else if (APPLICATION->capabilities() & Application::SupportsFlame + && url.host() == "www.curseforge.com" + && url.path().toLower().startsWith("/minecraft/mc-mods/")) { + prefixLength = 19; + page = "curseforge"; + } + else + prefixLength = 0; + + if (prefixLength != 0) { + QString slug = url.path().mid(prefixLength); + + // remove trailing slash(es) + while (slug.endsWith('/')) + slug.remove(slug.length() - 1, 1); + + // ensure that the path doesn't contain any further slashes, + // and the user isn't opening the same mod; they probably + // intended to view in their web browser + if (!slug.isEmpty() && !slug.contains('/') && slug != current.slug) { + ui->searchEdit->setText(slug); + dialog->selectPage(page); + triggerSearch(); + return; + } + } + + // open in the user's web browser + QDesktopServices::openUrl(url); +} + /******** Make changes to the UI ********/ @@ -270,8 +322,8 @@ void ModPage::updateModVersions(int prev_count) if ((valid || m_filter->versions.empty()) && !optedOut(version)) ui->versionSelectionBox->addItem(version.version, QVariant(i)); } - if (ui->versionSelectionBox->count() == 0 && prev_count != 0) { - ui->versionSelectionBox->addItem(tr("No valid version found!"), QVariant(-1)); + if (ui->versionSelectionBox->count() == 0 && prev_count != 0) { + ui->versionSelectionBox->addItem(tr("No valid version found!"), QVariant(-1)); ui->modSelectionButton->setText(tr("Cannot select invalid version :(")); } @@ -317,8 +369,7 @@ void ModPage::updateUi() text += "
" + tr(" by ") + authorStrs.join(", "); } - - if(current.extraDataLoaded) { + if (current.extraDataLoaded) { if (!current.extraData.donate.isEmpty()) { text += "

" + tr("Donate information: "); auto donateToStr = [](ModPlatform::DonationData& donate) -> QString { diff --git a/launcher/ui/pages/modplatform/ModPage.h b/launcher/ui/pages/modplatform/ModPage.h index ae3d7e77..c9ccbaf2 100644 --- a/launcher/ui/pages/modplatform/ModPage.h +++ b/launcher/ui/pages/modplatform/ModPage.h @@ -82,6 +82,7 @@ class ModPage : public QWidget, public BasePage { void onSelectionChanged(QModelIndex first, QModelIndex second); void onVersionSelectionChanged(QString data); void onModSelected(); + virtual void openUrl(const QUrl& url); protected: Ui::ModPage* ui = nullptr; diff --git a/launcher/ui/pages/modplatform/ModPage.ui b/launcher/ui/pages/modplatform/ModPage.ui index 943f02aa..94365aa5 100644 --- a/launcher/ui/pages/modplatform/ModPage.ui +++ b/launcher/ui/pages/modplatform/ModPage.ui @@ -16,10 +16,10 @@ - true + false - true + false diff --git a/launcher/ui/pages/modplatform/flame/FlameModPage.cpp b/launcher/ui/pages/modplatform/flame/FlameModPage.cpp index fd6e32ff..a4b7b5a1 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModPage.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameModPage.cpp @@ -39,7 +39,7 @@ #include "FlameModModel.h" #include "ui/dialogs/ModDownloadDialog.h" -FlameModPage::FlameModPage(ModDownloadDialog* dialog, BaseInstance* instance) +FlameModPage::FlameModPage(ModDownloadDialog* dialog, BaseInstance* instance) : ModPage(dialog, instance, new FlameAPI()) { listModel = new FlameMod::ListModel(this); @@ -53,7 +53,7 @@ FlameModPage::FlameModPage(ModDownloadDialog* dialog, BaseInstance* instance) ui->sortByBox->addItem(tr("Sort by Author")); ui->sortByBox->addItem(tr("Sort by Downloads")); - // sometimes Qt just ignores virtual slots and doesn't work as intended it seems, + // sometimes Qt just ignores virtual slots and doesn't work as intended it seems, // so it's best not to connect them in the parent's contructor... connect(ui->sortByBox, SIGNAL(currentIndexChanged(int)), this, SLOT(triggerSearch())); connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &FlameModPage::onSelectionChanged); @@ -78,3 +78,18 @@ bool FlameModPage::optedOut(ModPlatform::IndexedVersion& ver) const // other mod providers start loading before being selected, at least with // my Qt, so we need to implement this in every derived class... auto FlameModPage::shouldDisplay() const -> bool { return true; } + +void FlameModPage::openUrl(const QUrl& url) +{ + if (url.scheme().isEmpty()) { + QString query = url.query(QUrl::FullyDecoded); + if (query.startsWith("remoteUrl=")) { + // attempt to resolve url from warning page + query.remove(0, 10); + ModPage::openUrl({QUrl::fromPercentEncoding(query.toUtf8())}); // double decoding is necessary + return; + } + } + + ModPage::openUrl(url); +} \ No newline at end of file diff --git a/launcher/ui/pages/modplatform/flame/FlameModPage.h b/launcher/ui/pages/modplatform/flame/FlameModPage.h index 50dedd6f..aef9c698 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModPage.h +++ b/launcher/ui/pages/modplatform/flame/FlameModPage.h @@ -64,4 +64,6 @@ class FlameModPage : public ModPage { bool optedOut(ModPlatform::IndexedVersion& ver) const override; auto shouldDisplay() const -> bool override; + + void openUrl(const QUrl& url) override; }; diff --git a/launcher/ui/pages/modplatform/modrinth/ModrinthModPage.cpp b/launcher/ui/pages/modplatform/modrinth/ModrinthModPage.cpp index 62e417c8..c531ea90 100644 --- a/launcher/ui/pages/modplatform/modrinth/ModrinthModPage.cpp +++ b/launcher/ui/pages/modplatform/modrinth/ModrinthModPage.cpp @@ -53,7 +53,7 @@ ModrinthModPage::ModrinthModPage(ModDownloadDialog* dialog, BaseInstance* instan ui->sortByBox->addItem(tr("Sort by Last Updated")); ui->sortByBox->addItem(tr("Sort by Newest")); - // sometimes Qt just ignores virtual slots and doesn't work as intended it seems, + // sometimes Qt just ignores virtual slots and doesn't work as intended it seems, // so it's best not to connect them in the parent's constructor... connect(ui->sortByBox, SIGNAL(currentIndexChanged(int)), this, SLOT(triggerSearch())); connect(ui->packView->selectionModel(), &QItemSelectionModel::currentChanged, this, &ModrinthModPage::onSelectionChanged); -- cgit From b9547adce7c7222a2d3c8dc455e7619f2be7a221 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 1 Nov 2022 17:02:24 +0000 Subject: Add more license headers Signed-off-by: TheKodeToad --- launcher/ui/dialogs/ModDownloadDialog.cpp | 1 + launcher/ui/dialogs/ModDownloadDialog.h | 1 + launcher/ui/pages/modplatform/flame/FlameModPage.cpp | 1 + launcher/ui/pages/modplatform/flame/FlameModPage.h | 1 + 4 files changed, 4 insertions(+) diff --git a/launcher/ui/dialogs/ModDownloadDialog.cpp b/launcher/ui/dialogs/ModDownloadDialog.cpp index 38b4ffcf..7f6f450c 100644 --- a/launcher/ui/dialogs/ModDownloadDialog.cpp +++ b/launcher/ui/dialogs/ModDownloadDialog.cpp @@ -2,6 +2,7 @@ /* * PolyMC - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu + * Copyright (C) 2022 TheKodeToad * * 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 diff --git a/launcher/ui/dialogs/ModDownloadDialog.h b/launcher/ui/dialogs/ModDownloadDialog.h index 125cb776..6227b58e 100644 --- a/launcher/ui/dialogs/ModDownloadDialog.h +++ b/launcher/ui/dialogs/ModDownloadDialog.h @@ -2,6 +2,7 @@ /* * PolyMC - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu + * Copyright (C) 2022 TheKodeToad * * 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 diff --git a/launcher/ui/pages/modplatform/flame/FlameModPage.cpp b/launcher/ui/pages/modplatform/flame/FlameModPage.cpp index a4b7b5a1..faf12cea 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModPage.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameModPage.cpp @@ -2,6 +2,7 @@ /* * PolyMC - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu + * Copyright (C) 2022 TheKodeToad * * 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 diff --git a/launcher/ui/pages/modplatform/flame/FlameModPage.h b/launcher/ui/pages/modplatform/flame/FlameModPage.h index aef9c698..da4fcdff 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModPage.h +++ b/launcher/ui/pages/modplatform/flame/FlameModPage.h @@ -2,6 +2,7 @@ /* * PolyMC - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu + * Copyright (C) 2022 TheKodeToad * * 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 -- cgit From d03ae34b61b6c61d0afd4a5ba0d27347c87b0726 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 1 Nov 2022 17:19:54 +0000 Subject: Auto-select first result Signed-off-by: TheKodeToad --- launcher/ui/pages/modplatform/ModPage.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index 7f62fff1..780750a8 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -261,8 +261,7 @@ void ModPage::openUrl(const QUrl& url) && url.path().startsWith("/mod/")) { prefixLength = 5; page = "modrinth"; - } - else if (APPLICATION->capabilities() & Application::SupportsFlame + } else if (APPLICATION->capabilities() & Application::SupportsFlame && url.host() == "www.curseforge.com" && url.path().toLower().startsWith("/minecraft/mc-mods/")) { prefixLength = 19; @@ -282,9 +281,14 @@ void ModPage::openUrl(const QUrl& url) // and the user isn't opening the same mod; they probably // intended to view in their web browser if (!slug.isEmpty() && !slug.contains('/') && slug != current.slug) { - ui->searchEdit->setText(slug); dialog->selectPage(page); + ui->searchEdit->setText(slug); + triggerSearch(); + connect(listModel->activeJob(), &Task::finished, [this] { + ui->packView->setCurrentIndex(listModel->index(0)); + }); + return; } } -- cgit From 6c7d04043984c0c2c25d2cd646be223786defdc3 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 1 Nov 2022 18:12:27 +0000 Subject: Hacky tweaks Signed-off-by: TheKodeToad --- launcher/ui/dialogs/ModDownloadDialog.cpp | 13 ++++++++++--- launcher/ui/dialogs/ModDownloadDialog.h | 4 ++++ launcher/ui/pages/modplatform/ModPage.cpp | 10 ++++++---- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/launcher/ui/dialogs/ModDownloadDialog.cpp b/launcher/ui/dialogs/ModDownloadDialog.cpp index 7f6f450c..876f015a 100644 --- a/launcher/ui/dialogs/ModDownloadDialog.cpp +++ b/launcher/ui/dialogs/ModDownloadDialog.cpp @@ -132,6 +132,8 @@ QList ModDownloadDialog::getPages() if (APPLICATION->capabilities() & Application::SupportsFlame) pages.append(FlameModPage::create(this, m_instance)); + m_selected_page = dynamic_cast(pages[0]); + return pages; } @@ -179,17 +181,22 @@ void ModDownloadDialog::selectedPageChanged(BasePage* previous, BasePage* select return; } - auto* selected_page = dynamic_cast(selected); - if (!selected_page) { + m_selected_page = dynamic_cast(selected); + if (!m_selected_page) { qCritical() << "Page '" << selected->displayName() << "' in ModDownloadDialog is not a ModPage!"; return; } // Same effect as having a global search bar - selected_page->setSearchTerm(prev_page->getSearchTerm()); + m_selected_page->setSearchTerm(prev_page->getSearchTerm()); } bool ModDownloadDialog::selectPage(QString pageId) { return m_container->selectPage(pageId); +} + +ModPage* ModDownloadDialog::getSelectedPage() +{ + return m_selected_page; } \ No newline at end of file diff --git a/launcher/ui/dialogs/ModDownloadDialog.h b/launcher/ui/dialogs/ModDownloadDialog.h index 6227b58e..c637a70a 100644 --- a/launcher/ui/dialogs/ModDownloadDialog.h +++ b/launcher/ui/dialogs/ModDownloadDialog.h @@ -25,6 +25,7 @@ #include "ModDownloadTask.h" #include "minecraft/mod/ModFolderModel.h" #include "ui/pages/BasePageProvider.h" +#include "ui/pages/modplatform/ModPage.h" namespace Ui { @@ -56,6 +57,8 @@ public: bool selectPage(QString pageId); + ModPage* getSelectedPage(); + public slots: void confirm(); void accept() override; @@ -69,6 +72,7 @@ private: PageContainer * m_container = nullptr; QDialogButtonBox * m_buttons = nullptr; QVBoxLayout *m_verticalLayout = nullptr; + ModPage *m_selected_page = nullptr; QHash modTask; BaseInstance *m_instance; diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index 780750a8..6a53e25e 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -282,11 +282,13 @@ void ModPage::openUrl(const QUrl& url) // intended to view in their web browser if (!slug.isEmpty() && !slug.contains('/') && slug != current.slug) { dialog->selectPage(page); - ui->searchEdit->setText(slug); - triggerSearch(); - connect(listModel->activeJob(), &Task::finished, [this] { - ui->packView->setCurrentIndex(listModel->index(0)); + ModPage* newPage = dialog->getSelectedPage(); + newPage->ui->searchEdit->setText(slug); + newPage->triggerSearch(); + + connect(newPage->listModel->activeJob(), &Task::finished, [newPage] { + newPage->ui->packView->setCurrentIndex(newPage->listModel->index(0)); }); return; -- cgit From c890aa18f7b24bbb0429456d8c4a9cbb1c8d2bb1 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 1 Nov 2022 18:25:54 +0000 Subject: Only select correct mod Signed-off-by: TheKodeToad --- launcher/ui/pages/modplatform/ModPage.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index 6a53e25e..231e98f6 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -262,7 +262,7 @@ void ModPage::openUrl(const QUrl& url) prefixLength = 5; page = "modrinth"; } else if (APPLICATION->capabilities() & Application::SupportsFlame - && url.host() == "www.curseforge.com" + && (url.host() == "curseforge.com" || url.host() == "www.curseforge.com") && url.path().toLower().startsWith("/minecraft/mc-mods/")) { prefixLength = 19; page = "curseforge"; @@ -287,8 +287,15 @@ void ModPage::openUrl(const QUrl& url) newPage->ui->searchEdit->setText(slug); newPage->triggerSearch(); - connect(newPage->listModel->activeJob(), &Task::finished, [newPage] { - newPage->ui->packView->setCurrentIndex(newPage->listModel->index(0)); + connect(newPage->listModel->activeJob(), &Task::finished, [slug, newPage] { + for (int row = 0; row < newPage->listModel->rowCount({}); row++) { + QModelIndex index = newPage->listModel->index(row); + auto pack = newPage->listModel->data(index, Qt::UserRole).value(); + if (pack.slug == slug) { + newPage->ui->packView->setCurrentIndex(index); + break; + } + } }); return; -- cgit From d1626d20bd4fdeeb1e9cf0f00d862fc75ddaa663 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 1 Nov 2022 18:30:11 +0000 Subject: Slight cleanup Signed-off-by: TheKodeToad --- launcher/ui/pages/modplatform/ModPage.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index 231e98f6..9bb56290 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -287,12 +287,15 @@ void ModPage::openUrl(const QUrl& url) newPage->ui->searchEdit->setText(slug); newPage->triggerSearch(); - connect(newPage->listModel->activeJob(), &Task::finished, [slug, newPage] { - for (int row = 0; row < newPage->listModel->rowCount({}); row++) { - QModelIndex index = newPage->listModel->index(row); - auto pack = newPage->listModel->data(index, Qt::UserRole).value(); + ModPlatform::ListModel* model = newPage->listModel; + QListView* view = newPage->ui->packView; + + connect(model->activeJob(), &Task::finished, [slug, model, view] { + for (int row = 0; row < model->rowCount({}); row++) { + QModelIndex index = model->index(row); + ModPlatform::IndexedPack pack = model->data(index, Qt::UserRole).value(); if (pack.slug == slug) { - newPage->ui->packView->setCurrentIndex(index); + view->setCurrentIndex(index); break; } } -- cgit From 576867605dc09b1d117598908d41482e168fbc95 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Tue, 1 Nov 2022 18:40:12 +0000 Subject: Add another fallback Signed-off-by: TheKodeToad --- launcher/ui/pages/modplatform/ModPage.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index 9bb56290..f269fc72 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -290,15 +290,18 @@ void ModPage::openUrl(const QUrl& url) ModPlatform::ListModel* model = newPage->listModel; QListView* view = newPage->ui->packView; - connect(model->activeJob(), &Task::finished, [slug, model, view] { + connect(model->activeJob(), &Task::finished, [url, slug, model, view] { for (int row = 0; row < model->rowCount({}); row++) { QModelIndex index = model->index(row); ModPlatform::IndexedPack pack = model->data(index, Qt::UserRole).value(); if (pack.slug == slug) { view->setCurrentIndex(index); - break; + return; } } + + // The final fallback. + QDesktopServices::openUrl(url); }); return; -- cgit From 8dfa3393dc59a386123c84dd30287bf9f1d17faf Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Wed, 2 Nov 2022 08:43:42 +0000 Subject: Formatting and forward-declaration Signed-off-by: TheKodeToad --- launcher/ui/dialogs/ModDownloadDialog.cpp | 10 +++++----- launcher/ui/dialogs/ModDownloadDialog.h | 25 ++++++++++++------------- launcher/ui/pages/modplatform/ModPage.cpp | 13 +++++-------- 3 files changed, 22 insertions(+), 26 deletions(-) diff --git a/launcher/ui/dialogs/ModDownloadDialog.cpp b/launcher/ui/dialogs/ModDownloadDialog.cpp index 876f015a..0a0e61e3 100644 --- a/launcher/ui/dialogs/ModDownloadDialog.cpp +++ b/launcher/ui/dialogs/ModDownloadDialog.cpp @@ -132,7 +132,7 @@ QList ModDownloadDialog::getPages() if (APPLICATION->capabilities() & Application::SupportsFlame) pages.append(FlameModPage::create(this, m_instance)); - m_selected_page = dynamic_cast(pages[0]); + m_selectedPage = dynamic_cast(pages[0]); return pages; } @@ -181,14 +181,14 @@ void ModDownloadDialog::selectedPageChanged(BasePage* previous, BasePage* select return; } - m_selected_page = dynamic_cast(selected); - if (!m_selected_page) { + m_selectedPage = dynamic_cast(selected); + if (!m_selectedPage) { qCritical() << "Page '" << selected->displayName() << "' in ModDownloadDialog is not a ModPage!"; return; } // Same effect as having a global search bar - m_selected_page->setSearchTerm(prev_page->getSearchTerm()); + m_selectedPage->setSearchTerm(prev_page->getSearchTerm()); } bool ModDownloadDialog::selectPage(QString pageId) @@ -198,5 +198,5 @@ bool ModDownloadDialog::selectPage(QString pageId) ModPage* ModDownloadDialog::getSelectedPage() { - return m_selected_page; + return m_selectedPage; } \ No newline at end of file diff --git a/launcher/ui/dialogs/ModDownloadDialog.h b/launcher/ui/dialogs/ModDownloadDialog.h index c637a70a..29bdcf82 100644 --- a/launcher/ui/dialogs/ModDownloadDialog.h +++ b/launcher/ui/dialogs/ModDownloadDialog.h @@ -25,7 +25,6 @@ #include "ModDownloadTask.h" #include "minecraft/mod/ModFolderModel.h" #include "ui/pages/BasePageProvider.h" -#include "ui/pages/modplatform/ModPage.h" namespace Ui { @@ -34,13 +33,14 @@ class ModDownloadDialog; class PageContainer; class QDialogButtonBox; +class ModPage; class ModrinthModPage; class ModDownloadDialog final : public QDialog, public BasePageProvider { Q_OBJECT -public: + public: explicit ModDownloadDialog(const std::shared_ptr& mods, QWidget* parent, BaseInstance* instance); ~ModDownloadDialog() override = default; @@ -53,27 +53,26 @@ public: bool isModSelected(QString name) const; const QList getTasks(); - const std::shared_ptr &mods; + const std::shared_ptr& mods; bool selectPage(QString pageId); - ModPage* getSelectedPage(); -public slots: + public slots: void confirm(); void accept() override; void reject() override; -private slots: + private slots: void selectedPageChanged(BasePage* previous, BasePage* selected); -private: - Ui::ModDownloadDialog *ui = nullptr; - PageContainer * m_container = nullptr; - QDialogButtonBox * m_buttons = nullptr; - QVBoxLayout *m_verticalLayout = nullptr; - ModPage *m_selected_page = nullptr; + private: + Ui::ModDownloadDialog* ui = nullptr; + PageContainer* m_container = nullptr; + QDialogButtonBox* m_buttons = nullptr; + QVBoxLayout* m_verticalLayout = nullptr; + ModPage* m_selectedPage = nullptr; QHash modTask; - BaseInstance *m_instance; + BaseInstance* m_instance; }; diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index f269fc72..af16eaef 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -257,17 +257,15 @@ void ModPage::openUrl(const QUrl& url) int prefixLength; const char* page; - if ((url.host() == "modrinth.com" || url.host() == "www.modrinth.com") - && url.path().startsWith("/mod/")) { + if ((url.host() == "modrinth.com" || url.host() == "www.modrinth.com") && url.path().startsWith("/mod/")) { prefixLength = 5; page = "modrinth"; - } else if (APPLICATION->capabilities() & Application::SupportsFlame - && (url.host() == "curseforge.com" || url.host() == "www.curseforge.com") - && url.path().toLower().startsWith("/minecraft/mc-mods/")) { + } else if (APPLICATION->capabilities() & Application::SupportsFlame && + (url.host() == "curseforge.com" || url.host() == "www.curseforge.com") && + url.path().toLower().startsWith("/minecraft/mc-mods/")) { prefixLength = 19; page = "curseforge"; - } - else + } else prefixLength = 0; if (prefixLength != 0) { @@ -312,7 +310,6 @@ void ModPage::openUrl(const QUrl& url) QDesktopServices::openUrl(url); } - /******** Make changes to the UI ********/ void ModPage::retranslate() -- cgit From 6c45a990ef6b50e909368c3dfd41566ec5ca6986 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Wed, 2 Nov 2022 09:13:44 +0000 Subject: A good use of auto Signed-off-by: TheKodeToad --- launcher/ui/pages/modplatform/ModPage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index af16eaef..f245bfc2 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -291,7 +291,7 @@ void ModPage::openUrl(const QUrl& url) connect(model->activeJob(), &Task::finished, [url, slug, model, view] { for (int row = 0; row < model->rowCount({}); row++) { QModelIndex index = model->index(row); - ModPlatform::IndexedPack pack = model->data(index, Qt::UserRole).value(); + auto pack = model->data(index, Qt::UserRole).value(); if (pack.slug == slug) { view->setCurrentIndex(index); return; -- cgit From a1ed8154f75378a25ea20781d481fb971f616dc8 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Wed, 2 Nov 2022 09:31:39 +0000 Subject: Another fix Signed-off-by: TheKodeToad --- launcher/ui/pages/modplatform/ModPage.cpp | 40 +++++++++++++++++-------------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index f245bfc2..f347d817 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -282,27 +282,31 @@ void ModPage::openUrl(const QUrl& url) dialog->selectPage(page); ModPage* newPage = dialog->getSelectedPage(); - newPage->ui->searchEdit->setText(slug); - newPage->triggerSearch(); - - ModPlatform::ListModel* model = newPage->listModel; - QListView* view = newPage->ui->packView; - - connect(model->activeJob(), &Task::finished, [url, slug, model, view] { - for (int row = 0; row < model->rowCount({}); row++) { - QModelIndex index = model->index(row); - auto pack = model->data(index, Qt::UserRole).value(); - if (pack.slug == slug) { - view->setCurrentIndex(index); - return; + QLineEdit* searchEdit = newPage->ui->searchEdit; + + if (searchEdit->text() != slug) { + searchEdit->setText(slug); + newPage->triggerSearch(); + + ModPlatform::ListModel* model = newPage->listModel; + QListView* view = newPage->ui->packView; + + connect(model->activeJob(), &Task::finished, [url, slug, model, view] { + for (int row = 0; row < model->rowCount({}); row++) { + QModelIndex index = model->index(row); + auto pack = model->data(index, Qt::UserRole).value(); + if (pack.slug == slug) { + view->setCurrentIndex(index); + return; + } } - } - // The final fallback. - QDesktopServices::openUrl(url); - }); + // The final fallback. + QDesktopServices::openUrl(url); + }); - return; + return; + } } } -- cgit From a29d88c31305deda4136df9ad5046aed60a91afd Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Wed, 2 Nov 2022 09:59:52 +0000 Subject: Even more fixes Signed-off-by: TheKodeToad --- launcher/ui/pages/modplatform/ModPage.cpp | 56 +++++++++++++++++-------------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index f347d817..6ec283fc 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -254,19 +254,20 @@ void ModPage::openUrl(const QUrl& url) } // detect mod URLs and search instead - int prefixLength; + int prefixLength = 0; const char* page; if ((url.host() == "modrinth.com" || url.host() == "www.modrinth.com") && url.path().startsWith("/mod/")) { prefixLength = 5; page = "modrinth"; } else if (APPLICATION->capabilities() & Application::SupportsFlame && - (url.host() == "curseforge.com" || url.host() == "www.curseforge.com") && - url.path().toLower().startsWith("/minecraft/mc-mods/")) { - prefixLength = 19; + (url.host() == "curseforge.com" || url.host().endsWith(".curseforge.com"))) { + if (url.path().toLower().startsWith("/minecraft/mc-mods/")) + prefixLength = 19; + else if (url.path().toLower().startsWith("/projects/")) + prefixLength = 10; page = "curseforge"; - } else - prefixLength = 0; + } if (prefixLength != 0) { QString slug = url.path().mid(prefixLength); @@ -282,31 +283,36 @@ void ModPage::openUrl(const QUrl& url) dialog->selectPage(page); ModPage* newPage = dialog->getSelectedPage(); + QLineEdit* searchEdit = newPage->ui->searchEdit; + ModPlatform::ListModel* model = newPage->listModel; + QListView* view = newPage->ui->packView; + + auto jump = [url, slug, model, view] { + for (int row = 0; row < model->rowCount({}); row++) { + QModelIndex index = model->index(row); + auto pack = model->data(index, Qt::UserRole).value(); - if (searchEdit->text() != slug) { - searchEdit->setText(slug); - newPage->triggerSearch(); - - ModPlatform::ListModel* model = newPage->listModel; - QListView* view = newPage->ui->packView; - - connect(model->activeJob(), &Task::finished, [url, slug, model, view] { - for (int row = 0; row < model->rowCount({}); row++) { - QModelIndex index = model->index(row); - auto pack = model->data(index, Qt::UserRole).value(); - if (pack.slug == slug) { - view->setCurrentIndex(index); - return; - } + if (pack.slug == slug) { + view->setCurrentIndex(index); + return; } + } - // The final fallback. - QDesktopServices::openUrl(url); - }); + // The final fallback. + QDesktopServices::openUrl(url); + }; + + searchEdit->setText(slug); + newPage->triggerSearch(); - return; + if (!model->activeJob()) + jump(); + else { + connect(model->activeJob(), &Task::finished, jump); } + + return; } } -- cgit From cb796dbdfbe2099bc77911c01c8633d9f28aedac Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Wed, 2 Nov 2022 16:38:32 +0000 Subject: Remove unnecessary block Signed-off-by: TheKodeToad --- launcher/ui/pages/modplatform/ModPage.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index 6ec283fc..ec6f488f 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -308,9 +308,8 @@ void ModPage::openUrl(const QUrl& url) if (!model->activeJob()) jump(); - else { + else connect(model->activeJob(), &Task::finished, jump); - } return; } -- cgit From 3d11d044d2849c098187de4e973a8787538f4496 Mon Sep 17 00:00:00 2001 From: leo78913 Date: Tue, 25 Oct 2022 19:22:11 -0300 Subject: add an option to lock the toolbars Signed-off-by: leo78913 --- launcher/Application.cpp | 2 ++ launcher/ui/MainWindow.cpp | 32 +++++++++++++++++++++++++++++--- launcher/ui/MainWindow.h | 2 ++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 5772d7ca..9013577c 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -614,6 +614,8 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) // The cat m_settings->registerSetting("TheCat", false); + m_settings->registerSetting("ToolbarsLocked", false); + m_settings->registerSetting("InstSortMode", "Name"); m_settings->registerSetting("SelectedInstance", QString()); diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 28eaa741..ef056fcb 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -262,6 +262,8 @@ public: TranslatedAction actionNoAccountsAdded; TranslatedAction actionNoDefaultAccount; + TranslatedAction actionLockToolbars; + QVector all_toolbuttons; QWidget *centralWidget = nullptr; @@ -420,6 +422,12 @@ public: actionManageAccounts->setCheckable(false); actionManageAccounts->setIcon(APPLICATION->getThemedIcon("accounts")); all_actions.append(&actionManageAccounts); + + actionLockToolbars = TranslatedAction(MainWindow); + actionLockToolbars->setObjectName(QStringLiteral("actionLockToolbars")); + actionLockToolbars.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Lock Toolbars")); + actionLockToolbars->setCheckable(true); + all_actions.append(&actionLockToolbars); } void createMainToolbar(QMainWindow *MainWindow) @@ -427,7 +435,6 @@ public: mainToolBar = TranslatedToolbar(MainWindow); mainToolBar->setVisible(menuBar->isNativeMenuBar() || !APPLICATION->settings()->get("MenuBarInsteadOfToolBar").toBool()); mainToolBar->setObjectName(QStringLiteral("mainToolBar")); - mainToolBar->setMovable(true); mainToolBar->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea); mainToolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); mainToolBar->setFloatable(false); @@ -524,6 +531,8 @@ public: viewMenu->addAction(actionCAT); viewMenu->addSeparator(); + viewMenu->addAction(actionLockToolbars); + menuBar->addMenu(foldersMenu); profileMenu = menuBar->addMenu(tr("&Accounts")); @@ -601,7 +610,6 @@ public: { newsToolBar = TranslatedToolbar(MainWindow); newsToolBar->setObjectName(QStringLiteral("newsToolBar")); - newsToolBar->setMovable(true); newsToolBar->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea); newsToolBar->setIconSize(QSize(16, 16)); newsToolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); @@ -736,7 +744,6 @@ public: instanceToolBar->setObjectName(QStringLiteral("instanceToolBar")); // disabled until we have an instance selected instanceToolBar->setEnabled(false); - instanceToolBar->setMovable(true); // Qt doesn't like vertical moving toolbars, so we have to force them... // See https://github.com/PolyMC/PolyMC/issues/493 connect(instanceToolBar, &QToolBar::orientationChanged, [=](Qt::Orientation){ instanceToolBar->setOrientation(Qt::Vertical); }); @@ -918,6 +925,14 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow connect(ui->actionCAT.operator->(), SIGNAL(toggled(bool)), SLOT(onCatToggled(bool))); setCatBackground(cat_enable); } + + // Lock toolbars + { + bool toolbarsLocked = APPLICATION->settings()->get("ToolbarsLocked").toBool(); + ui->actionLockToolbars->setChecked(toolbarsLocked); + connect(ui->actionLockToolbars.operator->(), SIGNAL(toggled(bool)), SLOT(lockToolbars(bool))); + lockToolbars(toolbarsLocked); + } // start instance when double-clicked connect(view, &InstanceView::activated, this, &MainWindow::instanceActivated); @@ -1073,8 +1088,19 @@ QMenu * MainWindow::createPopupMenu() { QMenu* filteredMenu = QMainWindow::createPopupMenu(); filteredMenu->removeAction( ui->mainToolBar->toggleViewAction() ); + + filteredMenu->addAction(ui->actionLockToolbars); + return filteredMenu; } +void MainWindow::lockToolbars(bool state) +{ + ui->mainToolBar->setMovable(!state); + ui->instanceToolBar->setMovable(!state); + ui->newsToolBar->setMovable(!state); + APPLICATION->settings()->set("ToolbarsLocked", state); +} + void MainWindow::konamiTriggered() { diff --git a/launcher/ui/MainWindow.h b/launcher/ui/MainWindow.h index cb8cb4aa..f9d1f1c7 100644 --- a/launcher/ui/MainWindow.h +++ b/launcher/ui/MainWindow.h @@ -203,6 +203,8 @@ private slots: void globalSettingsClosed(); + void lockToolbars(bool); + #ifndef Q_OS_MAC void keyReleaseEvent(QKeyEvent *event) override; #endif -- cgit From 76050880f16bef13ed152f379e72ce52042676a2 Mon Sep 17 00:00:00 2001 From: flow Date: Thu, 3 Nov 2022 16:14:35 -0300 Subject: fix: use unicode variant for marking '.index' hidden Signed-off-by: flow --- launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp b/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp index 4b878918..cc4e252c 100644 --- a/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp +++ b/launcher/minecraft/mod/tasks/LocalModUpdateTask.cpp @@ -36,7 +36,7 @@ LocalModUpdateTask::LocalModUpdateTask(QDir index_dir, ModPlatform::IndexedPack& } #ifdef Q_OS_WIN32 - SetFileAttributesA(index_dir.path().toStdString().c_str(), FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED); + SetFileAttributesW(index_dir.path().toStdWString().c_str(), FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED); #endif } -- cgit From 353b51f11ea406dd027096c30ec9626ee4e2c417 Mon Sep 17 00:00:00 2001 From: flow Date: Thu, 3 Nov 2022 16:41:55 -0300 Subject: refactor: move MMCStrings -> StringUtils General utilities can go in here >:) Signed-off-by: flow --- launcher/CMakeLists.txt | 4 +- launcher/JavaCommon.cpp | 2 +- launcher/MMCStrings.cpp | 76 ---------------------- launcher/MMCStrings.h | 8 --- launcher/StringUtils.cpp | 76 ++++++++++++++++++++++ launcher/StringUtils.h | 7 ++ launcher/java/JavaInstall.cpp | 7 +- launcher/java/JavaInstallList.cpp | 1 - launcher/java/JavaVersion.cpp | 7 +- launcher/launch/LaunchTask.cpp | 1 - launcher/minecraft/MinecraftInstance.cpp | 1 - launcher/ui/dialogs/ExportInstanceDialog.cpp | 9 ++- .../modplatform/atlauncher/AtlFilterModel.cpp | 5 +- launcher/ui/pages/modplatform/flame/FlameModel.cpp | 1 - .../ui/pages/modplatform/ftb/FtbFilterModel.cpp | 5 +- .../ui/pages/modplatform/legacy_ftb/ListModel.cpp | 4 +- 16 files changed, 106 insertions(+), 108 deletions(-) delete mode 100644 launcher/MMCStrings.cpp delete mode 100644 launcher/MMCStrings.h create mode 100644 launcher/StringUtils.cpp create mode 100644 launcher/StringUtils.h diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 0dae47df..577eba4b 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -24,8 +24,8 @@ set(CORE_SOURCES NullInstance.h MMCZip.h MMCZip.cpp - MMCStrings.h - MMCStrings.cpp + StringUtils.h + StringUtils.cpp RuntimeContext.h # Basic instance manipulation tasks (derived from InstanceTask) diff --git a/launcher/JavaCommon.cpp b/launcher/JavaCommon.cpp index aa4d1123..52cc868a 100644 --- a/launcher/JavaCommon.cpp +++ b/launcher/JavaCommon.cpp @@ -36,7 +36,7 @@ #include "JavaCommon.h" #include "java/JavaUtils.h" #include "ui/dialogs/CustomMessageBox.h" -#include + #include bool JavaCommon::checkJVMArgs(QString jvmargs, QWidget *parent) diff --git a/launcher/MMCStrings.cpp b/launcher/MMCStrings.cpp deleted file mode 100644 index dc91c8d6..00000000 --- a/launcher/MMCStrings.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include "MMCStrings.h" - -/// TAKEN FROM Qt, because it doesn't expose it intelligently -static inline QChar getNextChar(const QString &s, int location) -{ - return (location < s.length()) ? s.at(location) : QChar(); -} - -/// TAKEN FROM Qt, because it doesn't expose it intelligently -int Strings::naturalCompare(const QString &s1, const QString &s2, Qt::CaseSensitivity cs) -{ - for (int l1 = 0, l2 = 0; l1 <= s1.count() && l2 <= s2.count(); ++l1, ++l2) - { - // skip spaces, tabs and 0's - QChar c1 = getNextChar(s1, l1); - while (c1.isSpace()) - c1 = getNextChar(s1, ++l1); - QChar c2 = getNextChar(s2, l2); - while (c2.isSpace()) - c2 = getNextChar(s2, ++l2); - - if (c1.isDigit() && c2.isDigit()) - { - while (c1.digitValue() == 0) - c1 = getNextChar(s1, ++l1); - while (c2.digitValue() == 0) - c2 = getNextChar(s2, ++l2); - - int lookAheadLocation1 = l1; - int lookAheadLocation2 = l2; - int currentReturnValue = 0; - // find the last digit, setting currentReturnValue as we go if it isn't equal - for (QChar lookAhead1 = c1, lookAhead2 = c2; - (lookAheadLocation1 <= s1.length() && lookAheadLocation2 <= s2.length()); - lookAhead1 = getNextChar(s1, ++lookAheadLocation1), - lookAhead2 = getNextChar(s2, ++lookAheadLocation2)) - { - bool is1ADigit = !lookAhead1.isNull() && lookAhead1.isDigit(); - bool is2ADigit = !lookAhead2.isNull() && lookAhead2.isDigit(); - if (!is1ADigit && !is2ADigit) - break; - if (!is1ADigit) - return -1; - if (!is2ADigit) - return 1; - if (currentReturnValue == 0) - { - if (lookAhead1 < lookAhead2) - { - currentReturnValue = -1; - } - else if (lookAhead1 > lookAhead2) - { - currentReturnValue = 1; - } - } - } - if (currentReturnValue != 0) - return currentReturnValue; - } - if (cs == Qt::CaseInsensitive) - { - if (!c1.isLower()) - c1 = c1.toLower(); - if (!c2.isLower()) - c2 = c2.toLower(); - } - int r = QString::localeAwareCompare(c1, c2); - if (r < 0) - return -1; - if (r > 0) - return 1; - } - // The two strings are the same (02 == 2) so fall back to the normal sort - return QString::compare(s1, s2, cs); -} diff --git a/launcher/MMCStrings.h b/launcher/MMCStrings.h deleted file mode 100644 index 48052a00..00000000 --- a/launcher/MMCStrings.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include - -namespace Strings -{ - int naturalCompare(const QString &s1, const QString &s2, Qt::CaseSensitivity cs); -} diff --git a/launcher/StringUtils.cpp b/launcher/StringUtils.cpp new file mode 100644 index 00000000..5ae58642 --- /dev/null +++ b/launcher/StringUtils.cpp @@ -0,0 +1,76 @@ +#include "StringUtils.h" + +/// TAKEN FROM Qt, because it doesn't expose it intelligently +static inline QChar getNextChar(const QString &s, int location) +{ + return (location < s.length()) ? s.at(location) : QChar(); +} + +/// TAKEN FROM Qt, because it doesn't expose it intelligently +int StringUtils::naturalCompare(const QString &s1, const QString &s2, Qt::CaseSensitivity cs) +{ + for (int l1 = 0, l2 = 0; l1 <= s1.count() && l2 <= s2.count(); ++l1, ++l2) + { + // skip spaces, tabs and 0's + QChar c1 = getNextChar(s1, l1); + while (c1.isSpace()) + c1 = getNextChar(s1, ++l1); + QChar c2 = getNextChar(s2, l2); + while (c2.isSpace()) + c2 = getNextChar(s2, ++l2); + + if (c1.isDigit() && c2.isDigit()) + { + while (c1.digitValue() == 0) + c1 = getNextChar(s1, ++l1); + while (c2.digitValue() == 0) + c2 = getNextChar(s2, ++l2); + + int lookAheadLocation1 = l1; + int lookAheadLocation2 = l2; + int currentReturnValue = 0; + // find the last digit, setting currentReturnValue as we go if it isn't equal + for (QChar lookAhead1 = c1, lookAhead2 = c2; + (lookAheadLocation1 <= s1.length() && lookAheadLocation2 <= s2.length()); + lookAhead1 = getNextChar(s1, ++lookAheadLocation1), + lookAhead2 = getNextChar(s2, ++lookAheadLocation2)) + { + bool is1ADigit = !lookAhead1.isNull() && lookAhead1.isDigit(); + bool is2ADigit = !lookAhead2.isNull() && lookAhead2.isDigit(); + if (!is1ADigit && !is2ADigit) + break; + if (!is1ADigit) + return -1; + if (!is2ADigit) + return 1; + if (currentReturnValue == 0) + { + if (lookAhead1 < lookAhead2) + { + currentReturnValue = -1; + } + else if (lookAhead1 > lookAhead2) + { + currentReturnValue = 1; + } + } + } + if (currentReturnValue != 0) + return currentReturnValue; + } + if (cs == Qt::CaseInsensitive) + { + if (!c1.isLower()) + c1 = c1.toLower(); + if (!c2.isLower()) + c2 = c2.toLower(); + } + int r = QString::localeAwareCompare(c1, c2); + if (r < 0) + return -1; + if (r > 0) + return 1; + } + // The two strings are the same (02 == 2) so fall back to the normal sort + return QString::compare(s1, s2, cs); +} diff --git a/launcher/StringUtils.h b/launcher/StringUtils.h new file mode 100644 index 00000000..fbe72117 --- /dev/null +++ b/launcher/StringUtils.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +namespace StringUtils { +int naturalCompare(const QString& s1, const QString& s2, Qt::CaseSensitivity cs); +} // namespace StringUtils diff --git a/launcher/java/JavaInstall.cpp b/launcher/java/JavaInstall.cpp index 5bcf7bcb..d5932bcb 100644 --- a/launcher/java/JavaInstall.cpp +++ b/launcher/java/JavaInstall.cpp @@ -1,9 +1,10 @@ #include "JavaInstall.h" -#include + +#include "StringUtils.h" bool JavaInstall::operator<(const JavaInstall &rhs) { - auto archCompare = Strings::naturalCompare(arch, rhs.arch, Qt::CaseInsensitive); + auto archCompare = StringUtils::naturalCompare(arch, rhs.arch, Qt::CaseInsensitive); if(archCompare != 0) return archCompare < 0; if(id < rhs.id) @@ -14,7 +15,7 @@ bool JavaInstall::operator<(const JavaInstall &rhs) { return false; } - return Strings::naturalCompare(path, rhs.path, Qt::CaseInsensitive) < 0; + return StringUtils::naturalCompare(path, rhs.path, Qt::CaseInsensitive) < 0; } bool JavaInstall::operator==(const JavaInstall &rhs) diff --git a/launcher/java/JavaInstallList.cpp b/launcher/java/JavaInstallList.cpp index 0249bd22..d2bfde05 100644 --- a/launcher/java/JavaInstallList.cpp +++ b/launcher/java/JavaInstallList.cpp @@ -41,7 +41,6 @@ #include "java/JavaInstallList.h" #include "java/JavaCheckerJob.h" #include "java/JavaUtils.h" -#include "MMCStrings.h" #include "minecraft/VersionFilterData.h" JavaInstallList::JavaInstallList(QObject *parent) : BaseVersionList(parent) diff --git a/launcher/java/JavaVersion.cpp b/launcher/java/JavaVersion.cpp index 179ccd8d..0e4fc1d3 100644 --- a/launcher/java/JavaVersion.cpp +++ b/launcher/java/JavaVersion.cpp @@ -1,5 +1,6 @@ #include "JavaVersion.h" -#include + +#include "StringUtils.h" #include #include @@ -98,12 +99,12 @@ bool JavaVersion::operator<(const JavaVersion &rhs) else if(thisPre && rhsPre) { // both are prereleases - use natural compare... - return Strings::naturalCompare(m_prerelease, rhs.m_prerelease, Qt::CaseSensitive) < 0; + return StringUtils::naturalCompare(m_prerelease, rhs.m_prerelease, Qt::CaseSensitive) < 0; } // neither is prerelease, so they are the same -> this cannot be less than rhs return false; } - else return Strings::naturalCompare(m_string, rhs.m_string, Qt::CaseSensitive) < 0; + else return StringUtils::naturalCompare(m_string, rhs.m_string, Qt::CaseSensitive) < 0; } bool JavaVersion::operator==(const JavaVersion &rhs) diff --git a/launcher/launch/LaunchTask.cpp b/launcher/launch/LaunchTask.cpp index 28fcc4f4..9e1794b3 100644 --- a/launcher/launch/LaunchTask.cpp +++ b/launcher/launch/LaunchTask.cpp @@ -37,7 +37,6 @@ #include "launch/LaunchTask.h" #include "MessageLevel.h" -#include "MMCStrings.h" #include "java/JavaChecker.h" #include "tasks/Task.h" #include diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 3a820951..de22b365 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -43,7 +43,6 @@ #include "settings/SettingsObject.h" #include "Application.h" -#include "MMCStrings.h" #include "pathmatcher/RegexpMatcher.h" #include "pathmatcher/MultiMatcher.h" #include "FileSystem.h" diff --git a/launcher/ui/dialogs/ExportInstanceDialog.cpp b/launcher/ui/dialogs/ExportInstanceDialog.cpp index 9f32dd8e..88552b23 100644 --- a/launcher/ui/dialogs/ExportInstanceDialog.cpp +++ b/launcher/ui/dialogs/ExportInstanceDialog.cpp @@ -39,13 +39,12 @@ #include #include #include -#include +#include #include #include -#include #include -#include "MMCStrings.h" +#include "StringUtils.h" #include "SeparatorPrefixTree.h" #include "Application.h" #include @@ -85,7 +84,7 @@ public: // sort and proxy model breaks the original model... if (sortColumn() == 0) { - return Strings::naturalCompare(leftFileInfo.fileName(), rightFileInfo.fileName(), + return StringUtils::naturalCompare(leftFileInfo.fileName(), rightFileInfo.fileName(), Qt::CaseInsensitive) < 0; } if (sortColumn() == 1) @@ -94,7 +93,7 @@ public: auto rightSize = rightFileInfo.size(); if ((leftSize == rightSize) || (leftFileInfo.isDir() && rightFileInfo.isDir())) { - return Strings::naturalCompare(leftFileInfo.fileName(), + return StringUtils::naturalCompare(leftFileInfo.fileName(), rightFileInfo.fileName(), Qt::CaseInsensitive) < 0 ? asc diff --git a/launcher/ui/pages/modplatform/atlauncher/AtlFilterModel.cpp b/launcher/ui/pages/modplatform/atlauncher/AtlFilterModel.cpp index c1ab166b..0887ebee 100644 --- a/launcher/ui/pages/modplatform/atlauncher/AtlFilterModel.cpp +++ b/launcher/ui/pages/modplatform/atlauncher/AtlFilterModel.cpp @@ -20,7 +20,8 @@ #include #include -#include + +#include "StringUtils.h" namespace Atl { @@ -86,7 +87,7 @@ bool FilterModel::lessThan(const QModelIndex &left, const QModelIndex &right) co return lv < rv; } else if (currentSorting == ByName) { - return Strings::naturalCompare(leftPack.name, rightPack.name, Qt::CaseSensitive) >= 0; + return StringUtils::naturalCompare(leftPack.name, rightPack.name, Qt::CaseSensitive) >= 0; } // Invalid sorting set, somehow... diff --git a/launcher/ui/pages/modplatform/flame/FlameModel.cpp b/launcher/ui/pages/modplatform/flame/FlameModel.cpp index 9f8605eb..debae8c3 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModel.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameModel.cpp @@ -3,7 +3,6 @@ #include "Application.h" #include "ui/widgets/ProjectItem.h" -#include #include #include diff --git a/launcher/ui/pages/modplatform/ftb/FtbFilterModel.cpp b/launcher/ui/pages/modplatform/ftb/FtbFilterModel.cpp index cbf347fc..e2b548f2 100644 --- a/launcher/ui/pages/modplatform/ftb/FtbFilterModel.cpp +++ b/launcher/ui/pages/modplatform/ftb/FtbFilterModel.cpp @@ -19,7 +19,8 @@ #include #include "modplatform/modpacksch/FTBPackManifest.h" -#include + +#include "StringUtils.h" namespace Ftb { @@ -81,7 +82,7 @@ bool FilterModel::lessThan(const QModelIndex &left, const QModelIndex &right) co return leftPack.installs < rightPack.installs; } else if (currentSorting == ByName) { - return Strings::naturalCompare(leftPack.name, rightPack.name, Qt::CaseSensitive) >= 0; + return StringUtils::naturalCompare(leftPack.name, rightPack.name, Qt::CaseSensitive) >= 0; } // Invalid sorting set, somehow... diff --git a/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp b/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp index 2d135e59..6f11cc95 100644 --- a/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp +++ b/launcher/ui/pages/modplatform/legacy_ftb/ListModel.cpp @@ -36,7 +36,7 @@ #include "ListModel.h" #include "Application.h" -#include +#include "StringUtils.h" #include #include @@ -66,7 +66,7 @@ bool FilterModel::lessThan(const QModelIndex &left, const QModelIndex &right) co return lv < rv; } else if(currentSorting == Sorting::ByName) { - return Strings::naturalCompare(leftPack.name, rightPack.name, Qt::CaseSensitive) >= 0; + return StringUtils::naturalCompare(leftPack.name, rightPack.name, Qt::CaseSensitive) >= 0; } //UHM, some inavlid value set?! -- cgit From ab6c7244fc472de0bed761cf29700a96dd89e8ad Mon Sep 17 00:00:00 2001 From: flow Date: Thu, 3 Nov 2022 16:44:23 -0300 Subject: refactor: move FS's toStdString to StringUtils This is so that anyone can use it :) Signed-off-by: flow --- launcher/FileSystem.cpp | 26 ++++++-------------------- launcher/StringUtils.h | 13 +++++++++++++ 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/launcher/FileSystem.cpp b/launcher/FileSystem.cpp index 4026d6c1..1cbb538c 100644 --- a/launcher/FileSystem.cpp +++ b/launcher/FileSystem.cpp @@ -44,7 +44,9 @@ #include #include #include + #include "DesktopServices.h" +#include "StringUtils.h" #if defined Q_OS_WIN32 #include @@ -79,22 +81,6 @@ namespace fs = std::filesystem; namespace fs = ghc::filesystem; #endif -#if defined Q_OS_WIN32 - -std::wstring toStdString(QString s) -{ - return s.toStdWString(); -} - -#else - -std::string toStdString(QString s) -{ - return s.toStdString(); -} - -#endif - namespace FS { void ensureExists(const QDir& dir) @@ -191,7 +177,7 @@ bool copy::operator()(const QString& offset) auto dst_path = PathCombine(dst, relative_dst_path); ensureFilePathExists(dst_path); - fs::copy(toStdString(src_path), toStdString(dst_path), opt, err); + fs::copy(StringUtils::toStdString(src_path), StringUtils::toStdString(dst_path), opt, err); if (err) { qWarning() << "Failed to copy files:" << QString::fromStdString(err.message()); qDebug() << "Source file:" << src_path; @@ -213,7 +199,7 @@ bool copy::operator()(const QString& offset) } // If the root src is not a directory, the previous iterator won't run. - if (!fs::is_directory(toStdString(src))) + if (!fs::is_directory(StringUtils::toStdString(src))) copy_file(src, ""); return err.value() == 0; @@ -223,7 +209,7 @@ bool deletePath(QString path) { std::error_code err; - fs::remove_all(toStdString(path), err); + fs::remove_all(StringUtils::toStdString(path), err); if (err) { qWarning() << "Failed to remove files:" << QString::fromStdString(err.message()); @@ -414,7 +400,7 @@ bool overrideFolder(QString overwritten_path, QString override_path) fs::copy_options opt = copy_opts::recursive | copy_opts::overwrite_existing; // FIXME: hello traveller! Apparently std::copy does NOT overwrite existing files on GNU libstdc++ on Windows? - fs::copy(toStdString(override_path), toStdString(overwritten_path), opt, err); + fs::copy(StringUtils::toStdString(override_path), StringUtils::toStdString(overwritten_path), opt, err); if (err) { qCritical() << QString("Failed to apply override from %1 to %2").arg(override_path, overwritten_path); diff --git a/launcher/StringUtils.h b/launcher/StringUtils.h index fbe72117..d7706b0f 100644 --- a/launcher/StringUtils.h +++ b/launcher/StringUtils.h @@ -3,5 +3,18 @@ #include namespace StringUtils { + +#if defined Q_OS_WIN32 +inline std::wstring toStdString(QString s) +{ + return s.toStdWString(); +} +#else +inline std::string toStdString(QString s) +{ + return s.toStdString(); +} +#endif + int naturalCompare(const QString& s1, const QString& s2, Qt::CaseSensitivity cs); } // namespace StringUtils -- cgit From dff5fea9760383984c2e60949341ebdc07eaab5a Mon Sep 17 00:00:00 2001 From: flow Date: Thu, 3 Nov 2022 16:59:03 -0300 Subject: feat: add more separation between types of std::string in StringUtils Signed-off-by: flow --- launcher/StringUtils.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/launcher/StringUtils.h b/launcher/StringUtils.h index d7706b0f..1799605b 100644 --- a/launcher/StringUtils.h +++ b/launcher/StringUtils.h @@ -5,15 +5,27 @@ namespace StringUtils { #if defined Q_OS_WIN32 -inline std::wstring toStdString(QString s) +using string = std::wstring; + +inline string toStdString(QString s) { return s.toStdWString(); } +inline QString fromStdString(string s) +{ + return QString::fromStdWString(s); +} #else -inline std::string toStdString(QString s) +using string = std::string; + +inline string toStdString(QString s) { return s.toStdString(); } +inline QString fromStdString(string s) +{ + return QString::fromStdString(s); +} #endif int naturalCompare(const QString& s1, const QString& s2, Qt::CaseSensitivity cs); -- cgit From d35c2db41e4a1cd9364c2160adb16ddcc4928dce Mon Sep 17 00:00:00 2001 From: flow Date: Thu, 3 Nov 2022 16:59:50 -0300 Subject: fix: separate types of std::string in Packwiz Signed-off-by: flow --- launcher/modplatform/packwiz/Packwiz.cpp | 26 ++++++++++++++++---------- launcher/modplatform/packwiz/Packwiz.h | 4 ---- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/launcher/modplatform/packwiz/Packwiz.cpp b/launcher/modplatform/packwiz/Packwiz.cpp index b1fe963e..0ed29311 100644 --- a/launcher/modplatform/packwiz/Packwiz.cpp +++ b/launcher/modplatform/packwiz/Packwiz.cpp @@ -22,10 +22,14 @@ #include #include -#include +#include "FileSystem.h" +#include "StringUtils.h" + #include "minecraft/mod/Mod.h" #include "modplatform/ModIndex.h" +#include + namespace Packwiz { auto getRealIndexName(QDir& index_dir, QString normalized_fname, bool should_find_match) -> QString @@ -63,22 +67,22 @@ static inline auto indexFileName(QString const& mod_slug) -> QString static ModPlatform::ProviderCapabilities ProviderCaps; // Helper functions for extracting data from the TOML file -auto stringEntry(toml::table table, const std::string entry_name) -> QString +auto stringEntry(toml::table table, QString entry_name) -> QString { - auto node = table[entry_name]; + auto node = table[StringUtils::toStdString(entry_name)]; if (!node) { - qCritical() << QString::fromStdString("Failed to read str property '" + entry_name + "' in mod metadata."); + qCritical() << "Failed to read str property '" + entry_name + "' in mod metadata."; return {}; } - return QString::fromStdString(node.value_or("")); + return node.value_or(""); } -auto intEntry(toml::table table, const std::string entry_name) -> int +auto intEntry(toml::table table, QString entry_name) -> int { - auto node = table[entry_name]; + auto node = table[StringUtils::toStdString(entry_name)]; if (!node) { - qCritical() << QString::fromStdString("Failed to read int property '" + entry_name + "' in mod metadata."); + qCritical() << "Failed to read int property '" + entry_name + "' in mod metadata."; return {}; } @@ -145,6 +149,8 @@ void V1::updateModIndex(QDir& index_dir, Mod& mod) // they want to do! if (index_file.exists()) { index_file.remove(); + } else { + FS::ensureFilePathExists(index_file.fileName()); } if (!index_file.open(QIODevice::ReadWrite)) { @@ -228,14 +234,14 @@ auto V1::getIndexForMod(QDir& index_dir, QString slug) -> Mod toml::table table; #if TOML_EXCEPTIONS try { - table = toml::parse_file(index_dir.absoluteFilePath(real_fname).toStdString()); + table = toml::parse_file(StringUtils::toStdString(index_dir.absoluteFilePath(real_fname))); } catch (const toml::parse_error& err) { qWarning() << QString("Could not open file %1!").arg(normalized_fname); qWarning() << "Reason: " << QString(err.what()); return {}; } #else - table = toml::parse_file(index_dir.absoluteFilePath(real_fname).toStdString()); + table = toml::parse_file(StringUtils::toStdString(index_dir.absoluteFilePath(real_fname))); if (!table) { qWarning() << QString("Could not open file %1!").arg(normalized_fname); qWarning() << "Reason: " << QString(table.error().what()); diff --git a/launcher/modplatform/packwiz/Packwiz.h b/launcher/modplatform/packwiz/Packwiz.h index 3ec80377..9754e5c4 100644 --- a/launcher/modplatform/packwiz/Packwiz.h +++ b/launcher/modplatform/packwiz/Packwiz.h @@ -24,7 +24,6 @@ #include #include -struct toml_table_t; class QDir; // Mod from launcher/minecraft/mod/Mod.h @@ -34,9 +33,6 @@ namespace Packwiz { auto getRealIndexName(QDir& index_dir, QString normalized_index_name, bool should_match = false) -> QString; -auto stringEntry(toml_table_t* parent, const char* entry_name) -> QString; -auto intEntry(toml_table_t* parent, const char* entry_name) -> int; - class V1 { public: struct Mod { -- cgit From 016b3448e81105b60c8c7b42cd41b760eb4b60ed Mon Sep 17 00:00:00 2001 From: DioEgizio <83089242+DioEgizio@users.noreply.github.com> Date: Sat, 5 Nov 2022 13:34:02 +0100 Subject: chore: bump to 6.0 Signed-off-by: DioEgizio <83089242+DioEgizio@users.noreply.github.com> --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 22692dae..0db05f98 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -126,7 +126,7 @@ set(Launcher_NEWS_OPEN_URL "https://prismlauncher.org/news" CACHE STRING "URL th set(Launcher_HELP_URL "https://prismlauncher.org/wiki/help-pages/%1" CACHE STRING "URL (with arg %1 to be substituted with page-id) that gets opened when the user requests help") ######## Set version numbers ######## -set(Launcher_VERSION_MAJOR 5) +set(Launcher_VERSION_MAJOR 6) set(Launcher_VERSION_MINOR 0) set(Launcher_VERSION_NAME "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}") -- cgit From c05f744ec211a211b4a3d0f47f0cdf3efa30fd32 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sun, 23 Oct 2022 06:49:46 -0700 Subject: windows file association is *hard* new macros! Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- program_info/win_install.nsi.in | 160 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) diff --git a/program_info/win_install.nsi.in b/program_info/win_install.nsi.in index 0cd7ea11..070d5c7c 100644 --- a/program_info/win_install.nsi.in +++ b/program_info/win_install.nsi.in @@ -110,6 +110,135 @@ VIAddVersionKey /LANG=${LANG_ENGLISH} "LegalCopyright" "@Launcher_Copyright@" VIAddVersionKey /LANG=${LANG_ENGLISH} "FileVersion" "@Launcher_VERSION_NAME4@" VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductVersion" "@Launcher_VERSION_NAME4@" + +;-------------------------------- +; Shell Associate Macros + +!macro APP_SETUP DESCRIPTION ICON APP_ID APP_NAME APP_EXE COMMANDTEXT COMMAND ; VERB APP_COMPANY + ; setup APP_ID + WriteRegStr ShCtx "Software\Classes\${APP_ID}" "" `${DESCRIPTION}` + WriteRegStr ShCtx "Software\Classes\${APP_ID}\DefaultIcon" "" `${ICON}` + ; default open verb + WriteRegStr ShCtx "Software\Classes\${APP_ID}\shell" "" "open" + WriteRegStr ShCtx "Software\Classes\${APP_ID}\shell\open" "" `${COMMANDTEXT}` + WriteRegStr ShCtx "Software\Classes\${APP_ID}\shell\open\command" "" `${COMMAND}` + + ; if you want the app to use it's own implementation of a verb + ;WriteRegStr ShCtx "Software\Classes\${APP_ID}\shell\${VERB}" "" "${DESCRIPTION}" + ;WriteRegStr ShCtx "Software\Classes\${APP_ID}\shell\${VERB}\command" "" `${COMMAND}` + + WriteRegStr ShCtx "Software\Classes\Applications\${APP_EXE}\shell\open\command" "" `${COMMAND}` + WriteRegStr ShCtx "Software\Classes\Applications\${APP_EXE}" "FriendlyAppName" `${APP_NAME}` ; [Optional] + ;WriteRegStr ShCtx "Software\Classes\Applications\${APP_EXE}" "ApplicationCompany" `${APP_COMPANY}` ; [Optional] + ;WriteRegNone ShCtx "Software\Classes\Applications\${APP_EXE}\SupportedTypes" ".${EXT}" ; [Optional] Only allow "Open With" with specific extension(s) on WinXP+ + + # Register "Default Programs" [Optional] + !ifdef REGISTER_DEFAULTPROGRAMS + WriteRegStr ShCtx "Software\Classes\Applications\${APP_EXE}\Capabilities" "ApplicationDescription" `${DESCRIPTION}` + WriteRegStr ShCtx "Software\RegisteredApplications" `${APP_NAME}` "Software\Classes\Applications\${APP_EXE}\Capabilities" + !endif + +!macroend + +!macro APP_ASSOCIATE EXT APP_ID APP_EXE + ; Backup the previously associated file class + ReadRegStr $R0 ShCtx "Software\Classes\${EXT}" "" + WriteRegStr ShCtx "Software\Classes\${EXT}" "${APP_ID}_backup" "$R0" + + WriteRegStr ShCtx "Software\Classes\${EXT}" "" "${APP_ID}" + WriteRegNone ShCtx "Software\Classes\${EXT}\OpenWithList" "${APP_EXE}" ; Win2000+ + WriteRegNone ShCtx "Software\Classes\${EXT}\OpenWithProgids" "${APP_ID}" ; WinXP+ + + # Register "Default Programs" [Optional] + !ifdef REGISTER_DEFAULTPROGRAMS + WriteRegStr ShCtx "Software\Classes\Applications\${APP_EXE}\Capabilities\FileAssociations" "${EXT}" "${APP_ID}" + !endif + +!macroend + +!macro APP_UNASSOCIATE EXT APP_ID + + # Unregister file type + ClearErrors + ; restore backup + ReadRegStr $R0 ShCtx "Software\Classes\${EXT}" `${APP_ID}_backup` + WriteRegStr ShCtx "Software\Classes\${EXT}" "" "$R0" + + DeleteRegKey /IfEmpty ShCtx "Software\Classes\${APP_ID}" + ${IfNot} ${Errors} + ${AndIf} $R0 == "${APP_ID}" + DeleteRegValue ShCtx "Software\Classes\${EXT}" "" + DeleteRegKey /IfEmpty ShCtx "Software\Classes\${EXT}" + ${EndIf} + + DeleteRegValue ShCtx "Software\Classes\${EXT}\OpenWithList" "${APP_EXE}" + DeleteRegKey /IfEmpty ShCtx "Software\Classes\${EXT}\OpenWithList" + DeleteRegValue ShCtx "Software\Classes\${EXT}\OpenWithProgids" "${APP_ID}" + DeleteRegKey /IfEmpty ShCtx "Software\Classes\${EXT}\OpenWithProgids" + DeleteRegKey /IfEmpty ShCtx "Software\Classes\${EXT}" + + # Attempt to clean up junk left behind by the Windows shell + DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\ApplicationAssociationToasts" "${APP_ID}_${EXT}" + DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\ApplicationAssociationToasts" "Applications\${APP_EXE}_${EXT}" + DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\${EXT}\OpenWithProgids" "${APP_ID}" + DeleteRegKey /IfEmpty HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\${EXT}\OpenWithProgids" + DeleteRegKey /IfEmpty HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\${EXT}\OpenWithList" + DeleteRegKey /IfEmpty HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\${EXT}" + ;DeleteRegKey HKCU "Software\Microsoft\Windows\Roaming\OpenWith\FileExts\.${EXT}" + ;DeleteRegKey HKCU "Software\Microsoft\Windows\CurrentVersion\Explorer\RecentDocs\.${EXT}" + +!macroend + +!macro APP_TEARDOWN APP_ID APP_NAME APP_EXE + + # Unregister file type + ClearErrors + DeleteRegKey /IfEmpty ShCtx "Software\Classes\${APP_ID}\shell" + ${IfNot} ${Errors} + DeleteRegKey ShCtx "Software\Classes\${APP_ID}\DefaultIcon" + ${EndIf} + + # Unregister "Open With" + DeleteRegKey ShCtx "Software\Classes\Applications\${APP_EXE}" + + # Unregister "Default Programs" + !ifdef REGISTER_DEFAULTPROGRAMS + DeleteRegValue ShCtx "Software\RegisteredApplications" `${APP_NAME}` + DeleteRegKey ShCtx "Software\Classes\Applications\${APP_EXE}\Capabilities" + DeleteRegKey /IfEmpty ShCtx "Software\Classes\Applications\${APP_EXE}" + !endif + + DeleteRegKey ShCtx `Software\Classes\${APP_ID}` + DeleteRegKey ShCtx "Software\Classes\Applications\${APP_EXE}" + + # Attempt to clean up junk left behind by the Windows shell + DeleteRegValue HKCU "Software\Microsoft\Windows\CurrentVersion\Search\JumplistData" "$INSTDIR\${APP_EXE}" + DeleteRegValue HKCU "Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\MuiCache" "$INSTDIR\${APP_EXE}.FriendlyAppName" + DeleteRegValue HKCU "Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\MuiCache" "$INSTDIR\${APP_EXE}.ApplicationCompany" + DeleteRegValue HKCU "Software\Microsoft\Windows\ShellNoRoam\MUICache" "$INSTDIR\${APP_EXE}" ; WinXP + DeleteRegValue HKCU "Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Compatibility Assistant\Store" "$INSTDIR\${APP_EXE}" + +!macroend + +; !defines for use with SHChangeNotify +!ifdef SHCNE_ASSOCCHANGED +!undef SHCNE_ASSOCCHANGED +!endif +!define SHCNE_ASSOCCHANGED 0x08000000 +!ifdef SHCNF_FLUSH +!undef SHCNF_FLUSH +!endif +!define SHCNF_FLUSH 0x1000 + + +# ensure this is called at the end of any section that changes shell keys +!macro NotifyShell_AssocChanged +; Using the system.dll plugin to call the SHChangeNotify Win32 API function so we +; can update the shell. + System::Call "shell32::SHChangeNotify(i,i,i,i) (${SHCNE_ASSOCCHANGED}, ${SHCNF_FLUSH}, 0, 0)" +!macroend + + ;-------------------------------- ; The stuff to install @@ -171,6 +300,27 @@ Section /o "Desktop Shortcut" DESKTOP_SHORTCUTS SectionEnd + +!define APP_ID "@Launcher_CommonName@.App" +!define APP_EXE "@Launcher_APP_BINARY_NAME@.exe" +!define APP_ICON "$INSTDIR\${APP_EXE},0" +!define APP_DESCRIPTION "@Launcher_DisplayName@" +!define APP_NAME "@Launcher_DisplayName@" +!define APP_CMD_TEXT "Prism Launcher instance" + +;!define REGISTER_DEFAULTPROGRAMS "on" ; value doesn't matter + +Section -ShellAssoc + + !insertmacro APP_SETUP `${APP_DESCRIPTION}` `${APP_ICON}` `${APP_ID}` `${APP_CMD_TEXT}` `${APP_EXE}` `${APP_CMD_TEXT}` '$INSTDIR\${APP_EXE} "%1"' + + !insertmacro APP_ASSOCIATE ".zip" `${APP_ID}` `${APP_EXE}` + !insertmacro APP_ASSOCIATE ".mrpack" `${APP_ID}` `${APP_EXE}` + + !insertmacro NotifyShell_AssocChanged +SectionEnd + + ;-------------------------------- ; Uninstaller @@ -202,6 +352,16 @@ Section "Uninstall" SectionEnd +Section -un.ShellAssoc + + !insertmacro APP_TEARDOWN `${APP_ID}` `${APP_NAME}` `${APP_EXE}` + + !insertmacro APP_UNASSOCIATE ".zip" `${APP_ID}` + !insertmacro APP_UNASSOCIATE ".mrpack" `${APP_ID}` + + !insertmacro NotifyShell_AssocChanged +SectionEnd + ;-------------------------------- ; Extra command line parameters -- cgit From 96008d3bb25399231a84af8fc863b6d9f3a69007 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sun, 23 Oct 2022 08:44:15 -0700 Subject: add -I import flag & don't clobber .zip assoc Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- program_info/win_install.nsi.in | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/program_info/win_install.nsi.in b/program_info/win_install.nsi.in index 070d5c7c..7bef0faf 100644 --- a/program_info/win_install.nsi.in +++ b/program_info/win_install.nsi.in @@ -140,12 +140,14 @@ VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductVersion" "@Launcher_VERSION_NAME4@ !macroend -!macro APP_ASSOCIATE EXT APP_ID APP_EXE +!macro APP_ASSOCIATE EXT APP_ID APP_EXE OVERWIRTE ; Backup the previously associated file class + ${If} ${OVERWIRTE} == true ReadRegStr $R0 ShCtx "Software\Classes\${EXT}" "" WriteRegStr ShCtx "Software\Classes\${EXT}" "${APP_ID}_backup" "$R0" - WriteRegStr ShCtx "Software\Classes\${EXT}" "" "${APP_ID}" + ${EndIf} + WriteRegNone ShCtx "Software\Classes\${EXT}\OpenWithList" "${APP_EXE}" ; Win2000+ WriteRegNone ShCtx "Software\Classes\${EXT}\OpenWithProgids" "${APP_ID}" ; WinXP+ @@ -161,8 +163,13 @@ VIAddVersionKey /LANG=${LANG_ENGLISH} "ProductVersion" "@Launcher_VERSION_NAME4@ # Unregister file type ClearErrors ; restore backup - ReadRegStr $R0 ShCtx "Software\Classes\${EXT}" `${APP_ID}_backup` - WriteRegStr ShCtx "Software\Classes\${EXT}" "" "$R0" + ReadRegStr $R1 ShCtx "Software\Classes\${EXT}" "" + ${If} $R1 == "${APP_ID}" + ReadRegStr $R0 ShCtx "Software\Classes\${EXT}" `${APP_ID}_backup` + WriteRegStr ShCtx "Software\Classes\${EXT}" "" "$R0" + ${Else} + ReadRegStr $R0 ShCtx "Software\Classes\${EXT}" "" + ${EndIf} DeleteRegKey /IfEmpty ShCtx "Software\Classes\${APP_ID}" ${IfNot} ${Errors} @@ -308,14 +315,14 @@ SectionEnd !define APP_NAME "@Launcher_DisplayName@" !define APP_CMD_TEXT "Prism Launcher instance" -;!define REGISTER_DEFAULTPROGRAMS "on" ; value doesn't matter +!define REGISTER_DEFAULTPROGRAMS ; value doesn't matter Section -ShellAssoc - !insertmacro APP_SETUP `${APP_DESCRIPTION}` `${APP_ICON}` `${APP_ID}` `${APP_CMD_TEXT}` `${APP_EXE}` `${APP_CMD_TEXT}` '$INSTDIR\${APP_EXE} "%1"' + !insertmacro APP_SETUP `${APP_DESCRIPTION}` `${APP_ICON}` `${APP_ID}` `${APP_CMD_TEXT}` `${APP_EXE}` `${APP_CMD_TEXT}` '$INSTDIR\${APP_EXE} -I "%1"' - !insertmacro APP_ASSOCIATE ".zip" `${APP_ID}` `${APP_EXE}` - !insertmacro APP_ASSOCIATE ".mrpack" `${APP_ID}` `${APP_EXE}` + !insertmacro APP_ASSOCIATE ".zip" `${APP_ID}` `${APP_EXE}` false + !insertmacro APP_ASSOCIATE ".mrpack" `${APP_ID}` `${APP_EXE}` true !insertmacro NotifyShell_AssocChanged SectionEnd -- cgit From 9f462dcc27a614fc9098184137dfad443958b883 Mon Sep 17 00:00:00 2001 From: flow Date: Sat, 5 Nov 2022 16:28:54 -0300 Subject: fix: update tomlplusplus submodule This fixes an issue with Windows TOML file parsing with non-latin characters. Signed-off-by: flow --- libraries/tomlplusplus | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/tomlplusplus b/libraries/tomlplusplus index 4b166b69..cc741c9f 160000 --- a/libraries/tomlplusplus +++ b/libraries/tomlplusplus @@ -1 +1 @@ -Subproject commit 4b166b69f28e70a416a1a04a98f365d2aeb90de8 +Subproject commit cc741c9f5f2a62856a2a2e9e275f61eb0591c09c -- cgit From 0938f80b4148cfc1734636e15da5ddb8b9a7bdfb Mon Sep 17 00:00:00 2001 From: leo78913 Date: Sat, 5 Nov 2022 18:10:36 -0300 Subject: Update launcher/ui/MainWindow.cpp Co-authored-by: flow Signed-off-by: leo78913 --- launcher/ui/MainWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index ef056fcb..7bbc1bde 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -930,7 +930,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow { bool toolbarsLocked = APPLICATION->settings()->get("ToolbarsLocked").toBool(); ui->actionLockToolbars->setChecked(toolbarsLocked); - connect(ui->actionLockToolbars.operator->(), SIGNAL(toggled(bool)), SLOT(lockToolbars(bool))); + connect(ui->actionLockToolbars, &QAction::toggled, this, &MainWindow::lockToolbars); lockToolbars(toolbarsLocked); } // start instance when double-clicked -- cgit From 369419870e6d241e4e21bae2ef243dc6a12ac7d4 Mon Sep 17 00:00:00 2001 From: Adrien <66513643+AshtakaOOf@users.noreply.github.com> Date: Sat, 5 Nov 2022 23:55:43 +0100 Subject: add: Spooky Rory Signed-off-by: Adrien <66513643+AshtakaOOf@users.noreply.github.com> --- launcher/resources/backgrounds/backgrounds.qrc | 2 ++ launcher/resources/backgrounds/rory-flat-spooky.png | Bin 0 -> 66906 bytes launcher/resources/backgrounds/rory-spooky.png | Bin 0 -> 95940 bytes 3 files changed, 2 insertions(+) create mode 100644 launcher/resources/backgrounds/rory-flat-spooky.png create mode 100644 launcher/resources/backgrounds/rory-spooky.png diff --git a/launcher/resources/backgrounds/backgrounds.qrc b/launcher/resources/backgrounds/backgrounds.qrc index 652e7084..edfa44c0 100644 --- a/launcher/resources/backgrounds/backgrounds.qrc +++ b/launcher/resources/backgrounds/backgrounds.qrc @@ -8,8 +8,10 @@ rory.png rory-xmas.png rory-bday.png + rory-spooky.png rory-flat.png rory-flat-xmas.png rory-flat-bday.png + rory-flat-spooky.png diff --git a/launcher/resources/backgrounds/rory-flat-spooky.png b/launcher/resources/backgrounds/rory-flat-spooky.png new file mode 100644 index 00000000..6360c612 Binary files /dev/null and b/launcher/resources/backgrounds/rory-flat-spooky.png differ diff --git a/launcher/resources/backgrounds/rory-spooky.png b/launcher/resources/backgrounds/rory-spooky.png new file mode 100644 index 00000000..a727619b Binary files /dev/null and b/launcher/resources/backgrounds/rory-spooky.png differ -- cgit From a0580946dcac871b74e670e354921842bcf07aa6 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 6 Nov 2022 00:04:43 +0100 Subject: fix: allow -ween variants for all cats Signed-off-by: Sefa Eyeoglu --- launcher/ui/MainWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index afbc505e..8cf2bde7 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1564,7 +1564,7 @@ void MainWindow::setCatBackground(bool enabled) QString cat = APPLICATION->settings()->get("BackgroundCat").toString(); if (non_stupid_abs(now.daysTo(xmas)) <= 4) { cat += "-xmas"; - } else if (cat == "kitteh" && non_stupid_abs(now.daysTo(halloween)) <= 4) { + } else if (non_stupid_abs(now.daysTo(halloween)) <= 4) { cat += "-ween"; } else if (non_stupid_abs(now.daysTo(birthday)) <= 12) { cat += "-bday"; -- cgit From 4708ce4226e7b23046b8a099dd033192e68f8fd5 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 6 Nov 2022 00:47:33 +0100 Subject: refactor: rename halloween cats to -spooky Signed-off-by: Sefa Eyeoglu --- launcher/resources/backgrounds/backgrounds.qrc | 2 +- launcher/resources/backgrounds/kitteh-spooky.png | Bin 0 -> 94677 bytes launcher/resources/backgrounds/kitteh-ween.png | Bin 94677 -> 0 bytes launcher/ui/MainWindow.cpp | 2 +- 4 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 launcher/resources/backgrounds/kitteh-spooky.png delete mode 100644 launcher/resources/backgrounds/kitteh-ween.png diff --git a/launcher/resources/backgrounds/backgrounds.qrc b/launcher/resources/backgrounds/backgrounds.qrc index edfa44c0..e55faf15 100644 --- a/launcher/resources/backgrounds/backgrounds.qrc +++ b/launcher/resources/backgrounds/backgrounds.qrc @@ -4,7 +4,7 @@ kitteh.png kitteh-xmas.png kitteh-bday.png - kitteh-ween.png + kitteh-spooky.png rory.png rory-xmas.png rory-bday.png diff --git a/launcher/resources/backgrounds/kitteh-spooky.png b/launcher/resources/backgrounds/kitteh-spooky.png new file mode 100644 index 00000000..deb0bebb Binary files /dev/null and b/launcher/resources/backgrounds/kitteh-spooky.png differ diff --git a/launcher/resources/backgrounds/kitteh-ween.png b/launcher/resources/backgrounds/kitteh-ween.png deleted file mode 100644 index deb0bebb..00000000 Binary files a/launcher/resources/backgrounds/kitteh-ween.png and /dev/null differ diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 8cf2bde7..f6b9888f 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1565,7 +1565,7 @@ void MainWindow::setCatBackground(bool enabled) if (non_stupid_abs(now.daysTo(xmas)) <= 4) { cat += "-xmas"; } else if (non_stupid_abs(now.daysTo(halloween)) <= 4) { - cat += "-ween"; + cat += "-spooky"; } else if (non_stupid_abs(now.daysTo(birthday)) <= 12) { cat += "-bday"; } -- cgit From d5d224d89a6d1fccacbf8ffe8d0981cec32e89fb Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 6 Nov 2022 01:05:10 +0100 Subject: fix: save metacache after clearing If the user closes the launcher right after clearing, it probably didn't actually clear the cache yet. Signed-off-by: Sefa Eyeoglu --- launcher/ui/MainWindow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 28eaa741..bbaf2827 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1899,6 +1899,7 @@ void MainWindow::on_actionReportBug_triggered() void MainWindow::on_actionClearMetadata_triggered() { APPLICATION->metacache()->evictAll(); + APPLICATION->metacache()->SaveNow(); } void MainWindow::on_actionOpenWiki_triggered() -- cgit From 38e1d44dbb60aa6180a29c4a747d73395d3ed79b Mon Sep 17 00:00:00 2001 From: Adrien <66513643+AshtakaOOf@users.noreply.github.com> Date: Sun, 6 Nov 2022 03:42:51 +0100 Subject: Update README.md Add copr Signed-off-by: Adrien <66513643+AshtakaOOf@users.noreply.github.com> --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8ebc4fb4..611f8566 100644 --- a/README.md +++ b/README.md @@ -27,16 +27,17 @@ There are development builds available [here](https://github.com/PrismLauncher/P Portable builds are provided for Linux, Windows, and macOS. -For Arch, Debian and Gentoo, respectively, you can use these packages to get compiled development versions: +For Arch, Debian, Fedora or Opensuse and Gentoo, respectively, you can use these packages to get compiled development versions: -[![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--git-blue?style=flat-square)](https://aur.archlinux.org/packages/prismlauncher-qt5-git/) [![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--qt5--git-blue?style=flat-square)](https://aur.archlinux.org/packages/prismlauncher-git/) [![prismlauncher-git](https://img.shields.io/badge/mpr-prismlauncher--git-orange?style=flat-square)](https://mpr.makedeb.org/packages/prismlauncher-git) [![prismlauncher-9999](https://img.shields.io/badge/gentoo-prismlauncher--9999-purple?style=flat-square)](https://packages.gentoo.org/packages/games-action/prismlauncher) +[![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--git-blue?style=flat-square)](https://aur.archlinux.org/packages/prismlauncher-qt5-git/) [![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--qt5--git-blue?style=flat-square)](https://aur.archlinux.org/packages/prismlauncher-git/) [![prismlauncher-git](https://img.shields.io/badge/mpr-prismlauncher--git-orange?style=flat-square)](https://mpr.makedeb.org/packages/prismlauncher-git) [![prismlauncher-nightly](https://img.shields.io/badge/copr-prismlauncher--nightly-blue?style=flat-square)](https://copr.fedorainfracloud.org/coprs/g3tchoo/prismlauncher/) [![prismlauncher-9999](https://img.shields.io/badge/gentoo-prismlauncher--9999-purple?style=flat-square)](https://packages.gentoo.org/packages/games-action/prismlauncher) -## Help & Support +## Community & Support Feel free to create an issue if you need help. +We have multiple communities that can help you. #### Join our Discord server: -[![Prism Launcher Discord server](https://discordapp.com/api/guilds/1031648380885147709/widget.png?style=banner3)](https://discord.gg/prismlauncher) +[![Prism Launcher Discord server](https://discordapp.com/api/guilds/1031648380885147709/widget.png?style=banner2)](https://discord.gg/prismlauncher) #### Join our Matrix space: [![PrismLauncher Space](https://img.shields.io/matrix/prismlauncher:matrix.org?style=for-the-badge)](https://matrix.to/#/#prismlauncher:matrix.org) -- cgit From 16e3b786fc04ffd8d510bfb2a60157648825954f Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sun, 6 Nov 2022 10:08:54 +0000 Subject: Implement Scrumplex's suggestions Signed-off-by: TheKodeToad --- launcher/ui/dialogs/ModDownloadDialog.cpp | 4 +- launcher/ui/dialogs/ModDownloadDialog.h | 2 +- launcher/ui/pages/modplatform/ModPage.cpp | 46 ++++++++++------------ .../ui/pages/modplatform/flame/FlameModPage.cpp | 5 ++- launcher/ui/pages/modplatform/flame/FlameModPage.h | 2 +- 5 files changed, 27 insertions(+), 32 deletions(-) diff --git a/launcher/ui/dialogs/ModDownloadDialog.cpp b/launcher/ui/dialogs/ModDownloadDialog.cpp index 0a0e61e3..24d23ba9 100644 --- a/launcher/ui/dialogs/ModDownloadDialog.cpp +++ b/launcher/ui/dialogs/ModDownloadDialog.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (C) 2022 TheKodeToad * @@ -199,4 +199,4 @@ bool ModDownloadDialog::selectPage(QString pageId) ModPage* ModDownloadDialog::getSelectedPage() { return m_selectedPage; -} \ No newline at end of file +} diff --git a/launcher/ui/dialogs/ModDownloadDialog.h b/launcher/ui/dialogs/ModDownloadDialog.h index 29bdcf82..fcf6f4fc 100644 --- a/launcher/ui/dialogs/ModDownloadDialog.h +++ b/launcher/ui/dialogs/ModDownloadDialog.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (C) 2022 TheKodeToad * diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index ec6f488f..2f5f95bf 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (C) 2022 TheKodeToad * @@ -43,6 +43,7 @@ #include #include +#include #include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" @@ -254,32 +255,25 @@ void ModPage::openUrl(const QUrl& url) } // detect mod URLs and search instead - int prefixLength = 0; + static const QRegularExpression modrinth(QRegularExpression::anchoredPattern("(?:www\\.)?modrinth\\.com\\/mod\\/([^\\/]+)\\/?")), + curseForge(QRegularExpression::anchoredPattern("(?:www\\.)?curseforge\\.com\\/minecraft\\/mc-mods\\/([^\\/]+)\\/?")), + curseForgeOld(QRegularExpression::anchoredPattern("minecraft\\.curseforge\\.com\\/projects\\/([^\\/]+)\\/?")); + + const QString address = url.host() + url.path(); + QRegularExpressionMatch match; const char* page; - if ((url.host() == "modrinth.com" || url.host() == "www.modrinth.com") && url.path().startsWith("/mod/")) { - prefixLength = 5; + if ((match = modrinth.match(address)).hasMatch()) page = "modrinth"; - } else if (APPLICATION->capabilities() & Application::SupportsFlame && - (url.host() == "curseforge.com" || url.host().endsWith(".curseforge.com"))) { - if (url.path().toLower().startsWith("/minecraft/mc-mods/")) - prefixLength = 19; - else if (url.path().toLower().startsWith("/projects/")) - prefixLength = 10; + else if (APPLICATION->capabilities() & Application::SupportsFlame && + ((match = curseForge.match(address)).hasMatch() || (match = curseForgeOld.match(address)).hasMatch())) page = "curseforge"; - } - if (prefixLength != 0) { - QString slug = url.path().mid(prefixLength); + if (match.hasMatch()) { + const QString slug = match.captured(1); - // remove trailing slash(es) - while (slug.endsWith('/')) - slug.remove(slug.length() - 1, 1); - - // ensure that the path doesn't contain any further slashes, - // and the user isn't opening the same mod; they probably - // intended to view in their web browser - if (!slug.isEmpty() && !slug.contains('/') && slug != current.slug) { + // ensure the user isn't opening the same mod + if (slug != current.slug) { dialog->selectPage(page); ModPage* newPage = dialog->getSelectedPage(); @@ -290,8 +284,8 @@ void ModPage::openUrl(const QUrl& url) auto jump = [url, slug, model, view] { for (int row = 0; row < model->rowCount({}); row++) { - QModelIndex index = model->index(row); - auto pack = model->data(index, Qt::UserRole).value(); + const QModelIndex index = model->index(row); + const auto pack = model->data(index, Qt::UserRole).value(); if (pack.slug == slug) { view->setCurrentIndex(index); @@ -306,10 +300,10 @@ void ModPage::openUrl(const QUrl& url) searchEdit->setText(slug); newPage->triggerSearch(); - if (!model->activeJob()) - jump(); - else + if (model->activeJob()) connect(model->activeJob(), &Task::finished, jump); + else + jump(); return; } diff --git a/launcher/ui/pages/modplatform/flame/FlameModPage.cpp b/launcher/ui/pages/modplatform/flame/FlameModPage.cpp index faf12cea..bad78c97 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModPage.cpp +++ b/launcher/ui/pages/modplatform/flame/FlameModPage.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (C) 2022 TheKodeToad * @@ -84,6 +84,7 @@ void FlameModPage::openUrl(const QUrl& url) { if (url.scheme().isEmpty()) { QString query = url.query(QUrl::FullyDecoded); + if (query.startsWith("remoteUrl=")) { // attempt to resolve url from warning page query.remove(0, 10); @@ -93,4 +94,4 @@ void FlameModPage::openUrl(const QUrl& url) } ModPage::openUrl(url); -} \ No newline at end of file +} diff --git a/launcher/ui/pages/modplatform/flame/FlameModPage.h b/launcher/ui/pages/modplatform/flame/FlameModPage.h index da4fcdff..58479ab9 100644 --- a/launcher/ui/pages/modplatform/flame/FlameModPage.h +++ b/launcher/ui/pages/modplatform/flame/FlameModPage.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (C) 2022 TheKodeToad * -- cgit From 456999eee678cb2e59ca7d27d04bdb01eb0d7ede Mon Sep 17 00:00:00 2001 From: TheLastRar Date: Sun, 6 Nov 2022 14:23:18 +0000 Subject: Fix: Configuration-less config for Qt Install Signed-off-by: TheLastRar --- launcher/CMakeLists.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index f92375fb..09a310ca 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -1066,7 +1066,7 @@ if(INSTALL_BUNDLE STREQUAL "full") # Image formats install( DIRECTORY "${QT_PLUGINS_DIR}/imageformats" - CONFIGURATIONS Debug RelWithDebInfo + CONFIGURATIONS Debug RelWithDebInfo "" DESTINATION ${PLUGIN_DEST_DIR} COMPONENT Runtime REGEX "tga|tiff|mng" EXCLUDE @@ -1084,7 +1084,7 @@ if(INSTALL_BUNDLE STREQUAL "full") # Icon engines install( DIRECTORY "${QT_PLUGINS_DIR}/iconengines" - CONFIGURATIONS Debug RelWithDebInfo + CONFIGURATIONS Debug RelWithDebInfo "" DESTINATION ${PLUGIN_DEST_DIR} COMPONENT Runtime REGEX "fontawesome" EXCLUDE @@ -1102,7 +1102,7 @@ if(INSTALL_BUNDLE STREQUAL "full") # Platform plugins install( DIRECTORY "${QT_PLUGINS_DIR}/platforms" - CONFIGURATIONS Debug RelWithDebInfo + CONFIGURATIONS Debug RelWithDebInfo "" DESTINATION ${PLUGIN_DEST_DIR} COMPONENT Runtime REGEX "minimal|linuxfb|offscreen" EXCLUDE @@ -1121,7 +1121,7 @@ if(INSTALL_BUNDLE STREQUAL "full") if(EXISTS "${QT_PLUGINS_DIR}/styles") install( DIRECTORY "${QT_PLUGINS_DIR}/styles" - CONFIGURATIONS Debug RelWithDebInfo + CONFIGURATIONS Debug RelWithDebInfo "" DESTINATION ${PLUGIN_DEST_DIR} COMPONENT Runtime ) @@ -1139,7 +1139,7 @@ if(INSTALL_BUNDLE STREQUAL "full") if(EXISTS "${QT_PLUGINS_DIR}/tls") install( DIRECTORY "${QT_PLUGINS_DIR}/tls" - CONFIGURATIONS Debug RelWithDebInfo + CONFIGURATIONS Debug RelWithDebInfo "" DESTINATION ${PLUGIN_DEST_DIR} COMPONENT Runtime ) -- cgit From 89aaac3a706f495994f87e4550be3609bb08f907 Mon Sep 17 00:00:00 2001 From: Adrien <66513643+AshtakaOOf@users.noreply.github.com> Date: Sun, 6 Nov 2022 21:56:02 +0100 Subject: Update README.md Signed-off-by: Adrien <66513643+AshtakaOOf@users.noreply.github.com> --- README.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 611f8566..64fb8701 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Prism Launcher is a custom launcher for Minecraft that allows you to easily manage multiple installations of Minecraft at once. -This is a **fork** of the MultiMC Launcher and not endorsed by MultiMC. +This is a **fork** of the MultiMC Launcher and is not endorsed by MultiMC. ## Installation @@ -18,32 +18,31 @@ This is a **fork** of the MultiMC Launcher and not endorsed by MultiMC. Packaging status -- All downloads and instructions for Prism Launcher can be found [on our website](https://prismlauncher.org/download/). -- Last build status can be found [here](https://github.com/PrismLauncher/PrismLauncher/actions). +- All downloads and instructions for Prism Launcher can be found on our [Website](https://prismlauncher.org/download/). +- Last build status can be found in the [GitHub Actions](https://github.com/PrismLauncher/PrismLauncher/actions). ### Development Builds There are development builds available [here](https://github.com/PrismLauncher/PrismLauncher/actions). These have debug information in the binaries, so their file sizes are relatively larger. -Portable builds are provided for Linux, Windows, and macOS. +Portable builds are provided for **Linux**, **Windows**, and **macOS**. -For Arch, Debian, Fedora or Opensuse and Gentoo, respectively, you can use these packages to get compiled development versions: +For **Arch**, **Debian**, **Fedora** or **OpenSUSE** and **Gentoo**, respectively, you can use these packages for the latest development versions: -[![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--git-blue?style=flat-square)](https://aur.archlinux.org/packages/prismlauncher-qt5-git/) [![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--qt5--git-blue?style=flat-square)](https://aur.archlinux.org/packages/prismlauncher-git/) [![prismlauncher-git](https://img.shields.io/badge/mpr-prismlauncher--git-orange?style=flat-square)](https://mpr.makedeb.org/packages/prismlauncher-git) [![prismlauncher-nightly](https://img.shields.io/badge/copr-prismlauncher--nightly-blue?style=flat-square)](https://copr.fedorainfracloud.org/coprs/g3tchoo/prismlauncher/) [![prismlauncher-9999](https://img.shields.io/badge/gentoo-prismlauncher--9999-purple?style=flat-square)](https://packages.gentoo.org/packages/games-action/prismlauncher) +[![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--git-blue?style=flat-square&logo=archlinux)](https://aur.archlinux.org/packages/prismlauncher-qt5-git/) [![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--qt5--git-blue?style=flat-square&logo=archlinux)](https://aur.archlinux.org/packages/prismlauncher-git/) [![prismlauncher-git](https://img.shields.io/badge/mpr-prismlauncher--git-orange?style=flat-square&logo=debian)](https://mpr.makedeb.org/packages/prismlauncher-git) [![prismlauncher-nightly](https://img.shields.io/badge/copr-prismlauncher--nightly-blue?style=flat-square&logo=fedora)](https://copr.fedorainfracloud.org/coprs/g3tchoo/prismlauncher/) [![prismlauncher-9999](https://img.shields.io/badge/gentoo-prismlauncher--9999-purple?style=flat-square&logo=gentoo)](https://packages.gentoo.org/packages/games-action/prismlauncher) ## Community & Support -Feel free to create an issue if you need help. -We have multiple communities that can help you. +Feel free to create a GitHub issue if you find a bug etc. We have multiple communities that can help you. #### Join our Discord server: [![Prism Launcher Discord server](https://discordapp.com/api/guilds/1031648380885147709/widget.png?style=banner2)](https://discord.gg/prismlauncher) #### Join our Matrix space: -[![PrismLauncher Space](https://img.shields.io/matrix/prismlauncher:matrix.org?style=for-the-badge)](https://matrix.to/#/#prismlauncher:matrix.org) +[![PrismLauncher Space](https://img.shields.io/matrix/prismlauncher:matrix.org?style=for-the-badge&logo=matrix)](https://matrix.to/#/#prismlauncher:matrix.org) #### Join our SubReddit: -[![r/PrismLauncher](https://img.shields.io/reddit/subreddit-subscribers/prismlauncher?style=for-the-badge)](https://www.reddit.com/r/PrismLauncher/) +[![r/PrismLauncher](https://img.shields.io/reddit/subreddit-subscribers/prismlauncher?style=for-the-badge&logo=reddit)](https://www.reddit.com/r/PrismLauncher/) ## Building -- cgit From 9ac6114b6379ba001785e76b5f9c10ddc2194d4a Mon Sep 17 00:00:00 2001 From: Tayou Date: Mon, 7 Nov 2022 14:33:37 +0100 Subject: Fix warning in main function main could according to the compiler end up not returning. of course it will always return, but I satisfied the compiler by adding a default case. Signed-off-by: Tayou --- launcher/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/launcher/main.cpp b/launcher/main.cpp index e2116f38..df596449 100644 --- a/launcher/main.cpp +++ b/launcher/main.cpp @@ -91,5 +91,7 @@ int main(int argc, char *argv[]) return 1; case Application::Succeeded: return 0; + default: + return -1; } } -- cgit From 380e76a2e373e1b8e62561b052eeabead855c36a Mon Sep 17 00:00:00 2001 From: Adrien <66513643+AshtakaOOf@users.noreply.github.com> Date: Mon, 7 Nov 2022 17:14:16 +0100 Subject: Add Tumbleweed Signed-off-by: Adrien <66513643+AshtakaOOf@users.noreply.github.com> --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 64fb8701..07b85284 100644 --- a/README.md +++ b/README.md @@ -27,9 +27,9 @@ There are development builds available [here](https://github.com/PrismLauncher/P Portable builds are provided for **Linux**, **Windows**, and **macOS**. -For **Arch**, **Debian**, **Fedora** or **OpenSUSE** and **Gentoo**, respectively, you can use these packages for the latest development versions: +For **Arch**, **Debian**, **Fedora**, **OpenSUSE** and **Gentoo**, respectively, you can use these packages for the latest development versions: -[![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--git-blue?style=flat-square&logo=archlinux)](https://aur.archlinux.org/packages/prismlauncher-qt5-git/) [![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--qt5--git-blue?style=flat-square&logo=archlinux)](https://aur.archlinux.org/packages/prismlauncher-git/) [![prismlauncher-git](https://img.shields.io/badge/mpr-prismlauncher--git-orange?style=flat-square&logo=debian)](https://mpr.makedeb.org/packages/prismlauncher-git) [![prismlauncher-nightly](https://img.shields.io/badge/copr-prismlauncher--nightly-blue?style=flat-square&logo=fedora)](https://copr.fedorainfracloud.org/coprs/g3tchoo/prismlauncher/) [![prismlauncher-9999](https://img.shields.io/badge/gentoo-prismlauncher--9999-purple?style=flat-square&logo=gentoo)](https://packages.gentoo.org/packages/games-action/prismlauncher) +[![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--git-blue?style=flat-square&logo=archlinux&logoColor=white)](https://aur.archlinux.org/packages/prismlauncher-qt5-git/) [![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--qt5--git-blue?style=flat-square&logo=archlinux&logoColor=white)](https://aur.archlinux.org/packages/prismlauncher-git/) [![prismlauncher-git](https://img.shields.io/badge/mpr-prismlauncher--git-orange?style=flat-square&logo=debian)](https://mpr.makedeb.org/packages/prismlauncher-git) [![prismlauncher-nightly](https://img.shields.io/badge/copr-prismlauncher--nightly-blue?style=flat-square&logo=fedora&logoColor=white)](https://copr.fedorainfracloud.org/coprs/g3tchoo/prismlauncher/) [![prismlauncher-nightly](https://img.shields.io/badge/OBS-prismlauncher--nightly-brightgreen?style=flat-square&logo=opensuse&logoColor=white)](https://build.opensuse.org/project/show/home:getchoo) [![prismlauncher-9999](https://img.shields.io/badge/gentoo-prismlauncher--9999-purple?style=flat-square&logo=gentoo&logoColor=white)](https://packages.gentoo.org/packages/games-action/prismlauncher) ## Community & Support -- cgit From 589d160515b7b9185bd09fc4aff5ae2c4abb4243 Mon Sep 17 00:00:00 2001 From: flow Date: Mon, 7 Nov 2022 14:04:48 -0300 Subject: fix: use cross-platform toStdString in FlameHasher Almost the same issue from toml++ :p Signed-off-by: flow --- launcher/modplatform/helpers/HashUtils.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/launcher/modplatform/helpers/HashUtils.cpp b/launcher/modplatform/helpers/HashUtils.cpp index a7bbaba5..b18c87af 100644 --- a/launcher/modplatform/helpers/HashUtils.cpp +++ b/launcher/modplatform/helpers/HashUtils.cpp @@ -4,6 +4,7 @@ #include #include "FileSystem.h" +#include "StringUtils.h" #include @@ -66,7 +67,7 @@ void FlameHasher::executeTask() // CF-specific auto should_filter_out = [](char c) { return (c == 9 || c == 10 || c == 13 || c == 32); }; - std::ifstream file_stream(m_path.toStdString(), std::ifstream::binary); + std::ifstream file_stream(StringUtils::toStdString(m_path), std::ifstream::binary); // TODO: This is very heavy work, but apparently QtConcurrent can't use move semantics, so we can't boop this to another thread. // How do we make this non-blocking then? m_hash = QString::number(MurmurHash2(std::move(file_stream), 4 * MiB, should_filter_out)); -- cgit From 245928a0647036ca94c69a0b6ea15a271944fffa Mon Sep 17 00:00:00 2001 From: Adrien <66513643+AshtakaOOf@users.noreply.github.com> Date: Mon, 7 Nov 2022 20:33:09 +0100 Subject: Update README.md Signed-off-by: Adrien <66513643+AshtakaOOf@users.noreply.github.com> --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 07b85284..cfb7a4af 100644 --- a/README.md +++ b/README.md @@ -25,20 +25,20 @@ This is a **fork** of the MultiMC Launcher and is not endorsed by MultiMC. There are development builds available [here](https://github.com/PrismLauncher/PrismLauncher/actions). These have debug information in the binaries, so their file sizes are relatively larger. -Portable builds are provided for **Linux**, **Windows**, and **macOS**. +Prebuilt Development builds are provided for **Linux**, **Windows** and **macOS**. For **Arch**, **Debian**, **Fedora**, **OpenSUSE** and **Gentoo**, respectively, you can use these packages for the latest development versions: -[![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--git-blue?style=flat-square&logo=archlinux&logoColor=white)](https://aur.archlinux.org/packages/prismlauncher-qt5-git/) [![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--qt5--git-blue?style=flat-square&logo=archlinux&logoColor=white)](https://aur.archlinux.org/packages/prismlauncher-git/) [![prismlauncher-git](https://img.shields.io/badge/mpr-prismlauncher--git-orange?style=flat-square&logo=debian)](https://mpr.makedeb.org/packages/prismlauncher-git) [![prismlauncher-nightly](https://img.shields.io/badge/copr-prismlauncher--nightly-blue?style=flat-square&logo=fedora&logoColor=white)](https://copr.fedorainfracloud.org/coprs/g3tchoo/prismlauncher/) [![prismlauncher-nightly](https://img.shields.io/badge/OBS-prismlauncher--nightly-brightgreen?style=flat-square&logo=opensuse&logoColor=white)](https://build.opensuse.org/project/show/home:getchoo) [![prismlauncher-9999](https://img.shields.io/badge/gentoo-prismlauncher--9999-purple?style=flat-square&logo=gentoo&logoColor=white)](https://packages.gentoo.org/packages/games-action/prismlauncher) +[![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--git-1793D1?style=flat-square&logo=archlinux&logoColor=white)](https://aur.archlinux.org/packages/prismlauncher-qt5-git/) [![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--qt5--git-1793D1?style=flat-square&logo=archlinux&logoColor=white)](https://aur.archlinux.org/packages/prismlauncher-git/) [![prismlauncher-git](https://img.shields.io/badge/mpr-prismlauncher--git-A80030?style=flat-square&logo=debian&logoColor=white)](https://mpr.makedeb.org/packages/prismlauncher-git) [![prismlauncher-nightly](https://img.shields.io/badge/copr-prismlauncher--nightly-51A2DA?style=flat-square&logo=fedora&logoColor=white)](https://copr.fedorainfracloud.org/coprs/g3tchoo/prismlauncher/) [![prismlauncher-nightly](https://img.shields.io/badge/OBS-prismlauncher--nightly-3AB6A9?style=flat-square&logo=opensuse&logoColor=white)](https://build.opensuse.org/project/show/home:getchoo) [![prismlauncher-9999](https://img.shields.io/badge/gentoo-prismlauncher--9999-4D4270?style=flat-square&logo=gentoo&logoColor=white)](https://packages.gentoo.org/packages/games-action/prismlauncher) ## Community & Support -Feel free to create a GitHub issue if you find a bug etc. We have multiple communities that can help you. +Feel free to create a GitHub issue if you find a bug or want to suggest a new feature. We have multiple communities that can also help you. #### Join our Discord server: [![Prism Launcher Discord server](https://discordapp.com/api/guilds/1031648380885147709/widget.png?style=banner2)](https://discord.gg/prismlauncher) -#### Join our Matrix space: +#### Join our Matrix space (Will be opened at a later date): [![PrismLauncher Space](https://img.shields.io/matrix/prismlauncher:matrix.org?style=for-the-badge&logo=matrix)](https://matrix.to/#/#prismlauncher:matrix.org) #### Join our SubReddit: @@ -46,7 +46,7 @@ Feel free to create a GitHub issue if you find a bug etc. We have multiple commu ## Building -If you want to build Prism Launcher yourself, check [Build Instructions](https://prismlauncher.org/wiki/development/build-instructions/) for build instructions. +If you want to build Prism Launcher yourself, check the [Build Instructions](https://prismlauncher.org/wiki/development/build-instructions/). ## Translations @@ -97,6 +97,6 @@ Thanks to the awesome people over at [MacStadium](https://www.macstadium.com/), All launcher code is available under the GPL-3.0-only license. -![https://github.com/PrismLauncher/PrismLauncher/blob/develop/LICENSE](https://img.shields.io/github/license/PrismLauncher/PrismLauncher?style=for-the-badge) +![https://github.com/PrismLauncher/PrismLauncher/blob/develop/LICENSE](https://img.shields.io/github/license/PrismLauncher/PrismLauncher?style=for-the-badge&logo=gnu&color=C4282D) The logo and related assets are under the CC BY-SA 4.0 license. -- cgit From ce2df4b36f91fd8a293504143670e046453eed19 Mon Sep 17 00:00:00 2001 From: txtsd Date: Tue, 8 Nov 2022 17:24:00 +0530 Subject: chore(readme): Specify openSUSE Tumbleweed Signed-off-by: txtsd --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cfb7a4af..f8ea2e84 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ There are development builds available [here](https://github.com/PrismLauncher/P Prebuilt Development builds are provided for **Linux**, **Windows** and **macOS**. -For **Arch**, **Debian**, **Fedora**, **OpenSUSE** and **Gentoo**, respectively, you can use these packages for the latest development versions: +For **Arch**, **Debian**, **Fedora**, **OpenSUSE (Tumbleweed)** and **Gentoo**, respectively, you can use these packages for the latest development versions: [![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--git-1793D1?style=flat-square&logo=archlinux&logoColor=white)](https://aur.archlinux.org/packages/prismlauncher-qt5-git/) [![prismlauncher-git](https://img.shields.io/badge/aur-prismlauncher--qt5--git-1793D1?style=flat-square&logo=archlinux&logoColor=white)](https://aur.archlinux.org/packages/prismlauncher-git/) [![prismlauncher-git](https://img.shields.io/badge/mpr-prismlauncher--git-A80030?style=flat-square&logo=debian&logoColor=white)](https://mpr.makedeb.org/packages/prismlauncher-git) [![prismlauncher-nightly](https://img.shields.io/badge/copr-prismlauncher--nightly-51A2DA?style=flat-square&logo=fedora&logoColor=white)](https://copr.fedorainfracloud.org/coprs/g3tchoo/prismlauncher/) [![prismlauncher-nightly](https://img.shields.io/badge/OBS-prismlauncher--nightly-3AB6A9?style=flat-square&logo=opensuse&logoColor=white)](https://build.opensuse.org/project/show/home:getchoo) [![prismlauncher-9999](https://img.shields.io/badge/gentoo-prismlauncher--9999-4D4270?style=flat-square&logo=gentoo&logoColor=white)](https://packages.gentoo.org/packages/games-action/prismlauncher) -- cgit From 9ad6eb11a37815f7aab89163184d519a2183f4f2 Mon Sep 17 00:00:00 2001 From: flow Date: Wed, 9 Nov 2022 14:14:25 -0300 Subject: refactor: fix CodeQL warnings in StringUtils::naturalCompare I have no idea why this function exists, so better to just let it exist. =D Signed-off-by: flow --- launcher/StringUtils.cpp | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/launcher/StringUtils.cpp b/launcher/StringUtils.cpp index 5ae58642..0f3c3669 100644 --- a/launcher/StringUtils.cpp +++ b/launcher/StringUtils.cpp @@ -1,26 +1,28 @@ #include "StringUtils.h" +/// If you're wondering where these came from exactly, then know you're not the only one =D + /// TAKEN FROM Qt, because it doesn't expose it intelligently -static inline QChar getNextChar(const QString &s, int location) +static inline QChar getNextChar(const QString& s, int location) { return (location < s.length()) ? s.at(location) : QChar(); } /// TAKEN FROM Qt, because it doesn't expose it intelligently -int StringUtils::naturalCompare(const QString &s1, const QString &s2, Qt::CaseSensitivity cs) +int StringUtils::naturalCompare(const QString& s1, const QString& s2, Qt::CaseSensitivity cs) { - for (int l1 = 0, l2 = 0; l1 <= s1.count() && l2 <= s2.count(); ++l1, ++l2) - { + int l1 = 0, l2 = 0; + while (l1 <= s1.count() && l2 <= s2.count()) { // skip spaces, tabs and 0's QChar c1 = getNextChar(s1, l1); while (c1.isSpace()) c1 = getNextChar(s1, ++l1); + QChar c2 = getNextChar(s2, l2); while (c2.isSpace()) c2 = getNextChar(s2, ++l2); - if (c1.isDigit() && c2.isDigit()) - { + if (c1.isDigit() && c2.isDigit()) { while (c1.digitValue() == 0) c1 = getNextChar(s1, ++l1); while (c2.digitValue() == 0) @@ -30,11 +32,8 @@ int StringUtils::naturalCompare(const QString &s1, const QString &s2, Qt::CaseSe int lookAheadLocation2 = l2; int currentReturnValue = 0; // find the last digit, setting currentReturnValue as we go if it isn't equal - for (QChar lookAhead1 = c1, lookAhead2 = c2; - (lookAheadLocation1 <= s1.length() && lookAheadLocation2 <= s2.length()); - lookAhead1 = getNextChar(s1, ++lookAheadLocation1), - lookAhead2 = getNextChar(s2, ++lookAheadLocation2)) - { + for (QChar lookAhead1 = c1, lookAhead2 = c2; (lookAheadLocation1 <= s1.length() && lookAheadLocation2 <= s2.length()); + lookAhead1 = getNextChar(s1, ++lookAheadLocation1), lookAhead2 = getNextChar(s2, ++lookAheadLocation2)) { bool is1ADigit = !lookAhead1.isNull() && lookAhead1.isDigit(); bool is2ADigit = !lookAhead2.isNull() && lookAhead2.isDigit(); if (!is1ADigit && !is2ADigit) @@ -43,14 +42,10 @@ int StringUtils::naturalCompare(const QString &s1, const QString &s2, Qt::CaseSe return -1; if (!is2ADigit) return 1; - if (currentReturnValue == 0) - { - if (lookAhead1 < lookAhead2) - { + if (currentReturnValue == 0) { + if (lookAhead1 < lookAhead2) { currentReturnValue = -1; - } - else if (lookAhead1 > lookAhead2) - { + } else if (lookAhead1 > lookAhead2) { currentReturnValue = 1; } } @@ -58,19 +53,24 @@ int StringUtils::naturalCompare(const QString &s1, const QString &s2, Qt::CaseSe if (currentReturnValue != 0) return currentReturnValue; } - if (cs == Qt::CaseInsensitive) - { + + if (cs == Qt::CaseInsensitive) { if (!c1.isLower()) c1 = c1.toLower(); if (!c2.isLower()) c2 = c2.toLower(); } + int r = QString::localeAwareCompare(c1, c2); if (r < 0) return -1; if (r > 0) return 1; + + l1 += 1; + l2 += 1; } + // The two strings are the same (02 == 2) so fall back to the normal sort return QString::compare(s1, s2, cs); } -- cgit From 99ed0b6c2ca67733a574a13cd215ec5c46c4dcfa Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Thu, 10 Nov 2022 11:14:58 +0000 Subject: Implement flowln's suggestions Signed-off-by: TheKodeToad --- launcher/ui/pages/modplatform/ModPage.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/launcher/ui/pages/modplatform/ModPage.cpp b/launcher/ui/pages/modplatform/ModPage.cpp index 2f5f95bf..234f9f36 100644 --- a/launcher/ui/pages/modplatform/ModPage.cpp +++ b/launcher/ui/pages/modplatform/ModPage.cpp @@ -40,10 +40,10 @@ #include #include +#include #include #include -#include #include "minecraft/MinecraftInstance.h" #include "minecraft/PackProfile.h" @@ -246,6 +246,10 @@ void ModPage::onModSelected() ui->packView->adjustSize(); } +static const QRegularExpression modrinth(QRegularExpression::anchoredPattern("(?:www\\.)?modrinth\\.com\\/mod\\/([^\\/]+)\\/?")); +static const QRegularExpression curseForge(QRegularExpression::anchoredPattern("(?:www\\.)?curseforge\\.com\\/minecraft\\/mc-mods\\/([^\\/]+)\\/?")); +static const QRegularExpression curseForgeOld(QRegularExpression::anchoredPattern("minecraft\\.curseforge\\.com\\/projects\\/([^\\/]+)\\/?")); + void ModPage::openUrl(const QUrl& url) { // do not allow other url schemes for security reasons @@ -255,19 +259,22 @@ void ModPage::openUrl(const QUrl& url) } // detect mod URLs and search instead - static const QRegularExpression modrinth(QRegularExpression::anchoredPattern("(?:www\\.)?modrinth\\.com\\/mod\\/([^\\/]+)\\/?")), - curseForge(QRegularExpression::anchoredPattern("(?:www\\.)?curseforge\\.com\\/minecraft\\/mc-mods\\/([^\\/]+)\\/?")), - curseForgeOld(QRegularExpression::anchoredPattern("minecraft\\.curseforge\\.com\\/projects\\/([^\\/]+)\\/?")); const QString address = url.host() + url.path(); QRegularExpressionMatch match; const char* page; - if ((match = modrinth.match(address)).hasMatch()) + match = modrinth.match(address); + if (match.hasMatch()) page = "modrinth"; - else if (APPLICATION->capabilities() & Application::SupportsFlame && - ((match = curseForge.match(address)).hasMatch() || (match = curseForgeOld.match(address)).hasMatch())) - page = "curseforge"; + else if (APPLICATION->capabilities() & Application::SupportsFlame) { + match = curseForge.match(address); + if (!match.hasMatch()) + match = curseForgeOld.match(address); + + if (match.hasMatch()) + page = "curseforge"; + } if (match.hasMatch()) { const QString slug = match.captured(1); -- cgit From 2f10fa8b61dac5af5866e7ad8e72cf702f15a130 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Fri, 11 Nov 2022 05:41:32 -0700 Subject: add some extra debug logs for CF blocked mods Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/modplatform/flame/FlameInstanceCreationTask.cpp | 1 + launcher/modplatform/modpacksch/FTBPackInstallTask.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp index f86e9335..f0fbdc96 100644 --- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp +++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp @@ -399,6 +399,7 @@ void FlameCreationTask::idResolverSucceeded(QEventLoop& loop) message_dialog->setModal(true); if (message_dialog->exec()) { + qDebug() << "Post dialog blocked mods list: " << blocked_mods; copyBlockedMods(blocked_mods); setupDownloadJob(loop); } else { diff --git a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp index 70ef7571..40aee82b 100644 --- a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp +++ b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp @@ -216,7 +216,7 @@ void PackInstallTask::onResolveModsSucceeded() m_blocked_mods); if (message_dialog->exec() == QDialog::Accepted) { - qDebug() << "Post dialog mods list: " << m_blocked_mods; + qDebug() << "Post dialog blocked mods list: " << m_blocked_mods; createInstance(); } else { -- cgit From bb8ac9b99a3ffe33d2d8cf8939c54940a66cc0d6 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Fri, 11 Nov 2022 05:46:41 -0700 Subject: changed name of file type association Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- program_info/win_install.nsi.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/program_info/win_install.nsi.in b/program_info/win_install.nsi.in index 7bef0faf..42a9e762 100644 --- a/program_info/win_install.nsi.in +++ b/program_info/win_install.nsi.in @@ -313,7 +313,7 @@ SectionEnd !define APP_ICON "$INSTDIR\${APP_EXE},0" !define APP_DESCRIPTION "@Launcher_DisplayName@" !define APP_NAME "@Launcher_DisplayName@" -!define APP_CMD_TEXT "Prism Launcher instance" +!define APP_CMD_TEXT "Minecraft Modpack" !define REGISTER_DEFAULTPROGRAMS ; value doesn't matter -- cgit From 577069cfb4982735c038607c06245e6939d7be79 Mon Sep 17 00:00:00 2001 From: flow Date: Sat, 12 Nov 2022 19:23:57 -0300 Subject: fix: don't have the clear button on instance page filters This thing is otherworldly unoptimized. o.O Signed-off-by: flow --- launcher/ui/pages/instance/ExternalResourcesPage.ui | 6 +----- launcher/ui/pages/instance/VersionPage.ui | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/launcher/ui/pages/instance/ExternalResourcesPage.ui b/launcher/ui/pages/instance/ExternalResourcesPage.ui index 76f8ec18..33a03336 100644 --- a/launcher/ui/pages/instance/ExternalResourcesPage.ui +++ b/launcher/ui/pages/instance/ExternalResourcesPage.ui @@ -27,11 +27,7 @@ - - - true - - + diff --git a/launcher/ui/pages/instance/VersionPage.ui b/launcher/ui/pages/instance/VersionPage.ui index fcba5598..14b7cd9f 100644 --- a/launcher/ui/pages/instance/VersionPage.ui +++ b/launcher/ui/pages/instance/VersionPage.ui @@ -48,11 +48,7 @@ - - - true - - + -- cgit