From 5909af9878d67f2900c92e8d1dd3eec7a53a840a Mon Sep 17 00:00:00 2001
From: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date: Fri, 11 Nov 2022 14:10:45 -0700
Subject: [PATCH 1/7] drag&drop + add folder to watch
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
---
.../flame/FlameInstanceCreationTask.cpp | 8 +-
.../modpacksch/FTBPackInstallTask.cpp | 6 +-
launcher/ui/dialogs/BlockedModsDialog.cpp | 82 +++++++++++++++++--
launcher/ui/dialogs/BlockedModsDialog.h | 8 ++
4 files changed, 92 insertions(+), 12 deletions(-)
diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
index f0fbdc96..eff729eb 100644
--- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
+++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
@@ -393,8 +393,12 @@ void FlameCreationTask::idResolverSucceeded(QEventLoop& loop)
qWarning() << "Blocked mods found, displaying mod list";
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"),
+ 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.
"
+ "Your configured global mods folder and default downloads folder
"
+ "are automatically checked for the downloaded mods.
"
+ "Optionally, you may drag and drop the downloaded mods onto this dialog or add a folder to watch
"
+ "if you did not download the mods to a default location."),
blocked_mods);
message_dialog->setModal(true);
diff --git a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp
index 40aee82b..d74faf08 100644
--- a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp
+++ b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp
@@ -212,7 +212,11 @@ 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."),
+ "You will need to manually download them and add them to the instance.
"
+ "Your configured global mods folder and default downloads folder
"
+ "are automatically checked for the downloaded mods.
"
+ "Optionally, you may drag and drop the downloaded mods onto this dialog or add a folder to watch
"
+ "if you did not download the mods to a default location."),
m_blocked_mods);
if (message_dialog->exec() == QDialog::Accepted) {
diff --git a/launcher/ui/dialogs/BlockedModsDialog.cpp b/launcher/ui/dialogs/BlockedModsDialog.cpp
index 2cf94250..ca757cbc 100644
--- a/launcher/ui/dialogs/BlockedModsDialog.cpp
+++ b/launcher/ui/dialogs/BlockedModsDialog.cpp
@@ -5,20 +5,29 @@
#include "Application.h"
#include "ui_BlockedModsDialog.h"
+
#include
#include
+#include
+#include
+#include
BlockedModsDialog::BlockedModsDialog(QWidget* parent, const QString& title, const QString& text, QList& mods)
: QDialog(parent), ui(new Ui::BlockedModsDialog), mods(mods)
{
+ hashing_task = shared_qobject_ptr(new ConcurrentTask(this, "MakeHashesTask", 10));
+
ui->setupUi(this);
auto openAllButton = ui->buttonBox->addButton(tr("Open All"), QDialogButtonBox::ActionRole);
connect(openAllButton, &QPushButton::clicked, this, &BlockedModsDialog::openAll);
+ auto downloadFolderButton = ui->buttonBox->addButton(tr("Add Download Folder"), QDialogButtonBox::ActionRole);
+ connect(downloadFolderButton, &QPushButton::clicked, this, &BlockedModsDialog::addDownloadFolder);
+
connect(&watcher, &QFileSystemWatcher::directoryChanged, this, &BlockedModsDialog::directoryChanged);
- hashing_task = shared_qobject_ptr(new ConcurrentTask(this, "MakeHashesTask", 10));
+
qDebug() << "Mods List: " << mods;
@@ -28,6 +37,9 @@ BlockedModsDialog::BlockedModsDialog(QWidget* parent, const QString& title, cons
this->setWindowTitle(title);
ui->label->setText(text);
ui->labelModsFound->setText(tr("Please download the missing mods."));
+
+ setAcceptDrops(true);
+
update();
}
@@ -36,6 +48,22 @@ BlockedModsDialog::~BlockedModsDialog()
delete ui;
}
+void BlockedModsDialog::dragEnterEvent(QDragEnterEvent *e) {
+ if (e->mimeData()->hasUrls()) {
+ e->acceptProposedAction();
+ }
+}
+
+void BlockedModsDialog::dropEvent(QDropEvent *e)
+{
+ foreach (const QUrl &url, e->mimeData()->urls()) {
+ QString file = url.toLocalFile();
+ qDebug() << "Dropped file:" << file;
+ addHashTask(file);
+ }
+ hashing_task->start();
+}
+
void BlockedModsDialog::openAll()
{
for (auto& mod : mods) {
@@ -43,6 +71,16 @@ void BlockedModsDialog::openAll()
}
}
+void BlockedModsDialog::addDownloadFolder() {
+ QString dir = QFileDialog::getExistingDirectory(
+ this,
+ tr("Select directory where you downloaded the mods"),
+ QStandardPaths::writableLocation(QStandardPaths::DownloadLocation),
+ QFileDialog::ShowDirsOnly);
+ watcher.addPath(dir);
+ scanPath(dir);
+}
+
/// @brief update UI with current status of the blocked mod detection
void BlockedModsDialog::update()
{
@@ -74,6 +112,7 @@ void BlockedModsDialog::update()
void BlockedModsDialog::directoryChanged(QString path)
{
qDebug() << "Directory changed: " << path;
+ validateMatchedMods();
scanPath(path);
}
@@ -108,19 +147,26 @@ void BlockedModsDialog::scanPath(QString path)
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, [file] { qDebug() << "Failed to hash path: " << file; });
-
- hashing_task->addTask(hash_task);
+ addHashTask(file);
}
hashing_task->start();
}
+/// @brief add a hashing task for the file located at path and connect it to check that hash against
+/// our blocked mods list
+/// @param path the path to the local file being hashed
+void BlockedModsDialog::addHashTask(QString path) {
+ auto hash_task = Hashing::createBlockedModHasher(path, ModPlatform::Provider::FLAME, "sha1");
+
+ qDebug() << "Creating Hash task for path: " << path;
+
+ connect(hash_task.get(), &Task::succeeded, [this, hash_task, path] { checkMatchHash(hash_task->getResult(), path); });
+ connect(hash_task.get(), &Task::failed, [path] { qDebug() << "Failed to hash path: " << path; });
+
+ hashing_task->addTask(hash_task);
+}
+
/// @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
@@ -174,6 +220,24 @@ bool BlockedModsDialog::allModsMatched()
return std::all_of(mods.begin(), mods.end(), [](auto const& mod) { return mod.matched; });
}
+/// @brief ensure matched file paths still exist
+void BlockedModsDialog::validateMatchedMods() {
+ bool changed = false;
+ for (auto& mod : mods) {
+ if (mod.matched) {
+ QFileInfo file = QFileInfo(mod.localPath);
+ if (!file.exists() || !file.isFile()) {
+ mod.localPath = "";
+ mod.matched = false;
+ changed = true;
+ }
+ }
+ }
+ if (changed) {
+ update();
+ }
+}
+
/// qDebug print support for the BlockedMod struct
QDebug operator<<(QDebug debug, const BlockedMod& m)
{
diff --git a/launcher/ui/dialogs/BlockedModsDialog.h b/launcher/ui/dialogs/BlockedModsDialog.h
index 0a5c90db..d683c54d 100644
--- a/launcher/ui/dialogs/BlockedModsDialog.h
+++ b/launcher/ui/dialogs/BlockedModsDialog.h
@@ -31,6 +31,11 @@ public:
~BlockedModsDialog() override;
+protected:
+ void dragEnterEvent(QDragEnterEvent *event) override;
+ // void dragMoveEvent(QDragMoveEvent *event) override;
+ // void dragLeaveEvent(QDragLeaveEvent *event) override;
+ void dropEvent(QDropEvent *event) override;
private:
Ui::BlockedModsDialog *ui;
@@ -39,12 +44,15 @@ private:
shared_qobject_ptr hashing_task;
void openAll();
+ void addDownloadFolder();
void update();
void directoryChanged(QString path);
void setupWatch();
void scanPaths();
void scanPath(QString path);
+ void addHashTask(QString path);
void checkMatchHash(QString hash, QString path);
+ void validateMatchedMods();
bool checkValidPath(QString path);
bool allModsMatched();
From 3f6cc178188a28e551755219bfa0a441ad8cfdcf Mon Sep 17 00:00:00 2001
From: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date: Fri, 11 Nov 2022 15:45:40 -0700
Subject: [PATCH 2/7] properly handle a currently running hashing task
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
---
.../flame/FlameInstanceCreationTask.cpp | 2 +-
.../modpacksch/FTBPackInstallTask.cpp | 2 +-
launcher/ui/dialogs/BlockedModsDialog.cpp | 113 +++++++++++++-----
launcher/ui/dialogs/BlockedModsDialog.h | 13 +-
4 files changed, 94 insertions(+), 36 deletions(-)
diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
index eff729eb..4b9e7b86 100644
--- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
+++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
@@ -396,7 +396,7 @@ void FlameCreationTask::idResolverSucceeded(QEventLoop& loop)
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.
"
"Your configured global mods folder and default downloads folder
"
- "are automatically checked for the downloaded mods.
"
+ "are automatically checked for the downloaded mods and they will be copied to the instance if found.
"
"Optionally, you may drag and drop the downloaded mods onto this dialog or add a folder to watch
"
"if you did not download the mods to a default location."),
blocked_mods);
diff --git a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp
index d74faf08..26d0c5a1 100644
--- a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp
+++ b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp
@@ -214,7 +214,7 @@ void PackInstallTask::onResolveModsSucceeded()
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.
"
"Your configured global mods folder and default downloads folder
"
- "are automatically checked for the downloaded mods.
"
+ "are automatically checked for the downloaded mods and they will be copied to the instance if found.
"
"Optionally, you may drag and drop the downloaded mods onto this dialog or add a folder to watch
"
"if you did not download the mods to a default location."),
m_blocked_mods);
diff --git a/launcher/ui/dialogs/BlockedModsDialog.cpp b/launcher/ui/dialogs/BlockedModsDialog.cpp
index ca757cbc..a1941cb8 100644
--- a/launcher/ui/dialogs/BlockedModsDialog.cpp
+++ b/launcher/ui/dialogs/BlockedModsDialog.cpp
@@ -1,4 +1,5 @@
#include "BlockedModsDialog.h"
+#include
#include
#include
#include
@@ -13,9 +14,10 @@
#include
BlockedModsDialog::BlockedModsDialog(QWidget* parent, const QString& title, const QString& text, QList& mods)
- : QDialog(parent), ui(new Ui::BlockedModsDialog), mods(mods)
+ : QDialog(parent), ui(new Ui::BlockedModsDialog), m_mods(mods)
{
- hashing_task = shared_qobject_ptr(new ConcurrentTask(this, "MakeHashesTask", 10));
+ m_hashing_task = shared_qobject_ptr(new ConcurrentTask(this, "MakeHashesTask", 10));
+ connect(m_hashing_task.get(), &Task::finished, this, &BlockedModsDialog::hashTaskFinished);
ui->setupUi(this);
@@ -25,11 +27,11 @@ BlockedModsDialog::BlockedModsDialog(QWidget* parent, const QString& title, cons
auto downloadFolderButton = ui->buttonBox->addButton(tr("Add Download Folder"), QDialogButtonBox::ActionRole);
connect(downloadFolderButton, &QPushButton::clicked, this, &BlockedModsDialog::addDownloadFolder);
- connect(&watcher, &QFileSystemWatcher::directoryChanged, this, &BlockedModsDialog::directoryChanged);
+ connect(&m_watcher, &QFileSystemWatcher::directoryChanged, this, &BlockedModsDialog::directoryChanged);
- qDebug() << "Mods List: " << mods;
+ qDebug() << "[Blocked Mods Dialog] Mods List: " << mods;
setupWatch();
scanPaths();
@@ -57,16 +59,23 @@ void BlockedModsDialog::dragEnterEvent(QDragEnterEvent *e) {
void BlockedModsDialog::dropEvent(QDropEvent *e)
{
foreach (const QUrl &url, e->mimeData()->urls()) {
- QString file = url.toLocalFile();
- qDebug() << "Dropped file:" << file;
- addHashTask(file);
+ QString filePath = url.toLocalFile();
+ qDebug() << "[Blocked Mods Dialog] Dropped file:" << filePath;
+ addHashTask(filePath);
+
+ // watch for changes
+ QFileInfo file = QFileInfo(filePath);
+ QString path = file.dir().absolutePath();
+ qDebug() << "[Blocked Mods Dialog] Adding watch path:" << path;
+ m_watcher.addPath(path);
}
- hashing_task->start();
+ scanPaths();
+ update();
}
void BlockedModsDialog::openAll()
{
- for (auto& mod : mods) {
+ for (auto& mod : m_mods) {
QDesktopServices::openUrl(mod.websiteUrl);
}
}
@@ -77,8 +86,10 @@ void BlockedModsDialog::addDownloadFolder() {
tr("Select directory where you downloaded the mods"),
QStandardPaths::writableLocation(QStandardPaths::DownloadLocation),
QFileDialog::ShowDirsOnly);
- watcher.addPath(dir);
- scanPath(dir);
+ qDebug() << "[Blocked Mods Dialog] Adding watch path:" << dir;
+ m_watcher.addPath(dir);
+ scanPath(dir, true);
+ update();
}
/// @brief update UI with current status of the blocked mod detection
@@ -87,7 +98,7 @@ void BlockedModsDialog::update()
QString text;
QString span;
- for (auto& mod : mods) {
+ for (auto& mod : m_mods) {
if (mod.matched) {
// ✔ -> html for HEAVY CHECK MARK : ✔
span = QString(tr(" ✔ Found at %1 ")).arg(mod.localPath);
@@ -111,9 +122,9 @@ void BlockedModsDialog::update()
/// @param path the path to the changed directory
void BlockedModsDialog::directoryChanged(QString path)
{
- qDebug() << "Directory changed: " << path;
+ qDebug() << "[Blocked Mods Dialog] Directory changed: " << path;
validateMatchedMods();
- scanPath(path);
+ scanPath(path, true);
}
/// @brief add the user downloads folder and the global mods folder to the filesystem watcher
@@ -121,22 +132,23 @@ void BlockedModsDialog::setupWatch()
{
const QString downloadsFolder = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
const QString modsFolder = APPLICATION->settings()->get("CentralModsDir").toString();
- watcher.addPath(downloadsFolder);
- watcher.addPath(modsFolder);
+ m_watcher.addPath(downloadsFolder);
+ m_watcher.addPath(modsFolder);
}
/// @brief scan all watched folder
void BlockedModsDialog::scanPaths()
{
- for (auto& dir : watcher.directories()) {
- scanPath(dir);
+ for (auto& dir : m_watcher.directories()) {
+ scanPath(dir, false);
}
+ runHashTask();
}
/// @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, bool start_task)
{
QDir scan_dir(path);
QDirIterator scan_it(path, QDir::Filter::Files | QDir::Filter::Hidden, QDirIterator::NoIteratorFlags);
@@ -150,21 +162,35 @@ void BlockedModsDialog::scanPath(QString path)
addHashTask(file);
}
- hashing_task->start();
+ if (start_task) {
+ runHashTask();
+ }
+
+}
+
+/// @brief add a hashing task for the file located at path, add the path to the pending set if the hasing task is already running
+/// @param path the path to the local file being hashed
+void BlockedModsDialog::addHashTask(QString path) {
+ if (m_hashing_task->isRunning()) {
+ qDebug() << "[Blocked Mods Dialog] adding a Hash task for" << path << "to the pending set.";
+ m_pending_hash_paths.insert(path);
+ } else {
+ buildHashTask(path);
+ }
}
/// @brief add a hashing task for the file located at path and connect it to check that hash against
/// our blocked mods list
/// @param path the path to the local file being hashed
-void BlockedModsDialog::addHashTask(QString path) {
+void BlockedModsDialog::buildHashTask(QString path) {
auto hash_task = Hashing::createBlockedModHasher(path, ModPlatform::Provider::FLAME, "sha1");
- qDebug() << "Creating Hash task for path: " << path;
+ qDebug() << "[Blocked Mods Dialog] Creating Hash task for path: " << path;
connect(hash_task.get(), &Task::succeeded, [this, hash_task, path] { checkMatchHash(hash_task->getResult(), path); });
connect(hash_task.get(), &Task::failed, [path] { qDebug() << "Failed to hash path: " << path; });
- hashing_task->addTask(hash_task);
+ m_hashing_task->addTask(hash_task);
}
/// @brief check if the computed hash for the provided path matches a blocked
@@ -175,9 +201,9 @@ void BlockedModsDialog::checkMatchHash(QString hash, QString path)
{
bool match = false;
- qDebug() << "Checking for match on hash: " << hash << "| From path:" << path;
+ qDebug() << "[Blocked Mods Dialog] Checking for match on hash: " << hash << "| From path:" << path;
- for (auto& mod : mods) {
+ for (auto& mod : m_mods) {
if (mod.matched) {
continue;
}
@@ -186,7 +212,7 @@ void BlockedModsDialog::checkMatchHash(QString hash, QString path)
mod.localPath = path;
match = true;
- qDebug() << "Hash match found:" << mod.name << hash << "| From path:" << path;
+ qDebug() << "[Blocked Mods Dialog] Hash match found:" << mod.name << hash << "| From path:" << path;
break;
}
@@ -205,9 +231,9 @@ bool BlockedModsDialog::checkValidPath(QString path)
QFileInfo file = QFileInfo(path);
QString filename = file.fileName();
- for (auto& mod : mods) {
+ for (auto& mod : m_mods) {
if (mod.name.compare(filename, Qt::CaseInsensitive) == 0) {
- qDebug() << "Name match found:" << mod.name << "| From path:" << path;
+ qDebug() << "[Blocked Mods Dialog] Name match found:" << mod.name << "| From path:" << path;
return true;
}
}
@@ -217,13 +243,13 @@ bool BlockedModsDialog::checkValidPath(QString path)
bool BlockedModsDialog::allModsMatched()
{
- return std::all_of(mods.begin(), mods.end(), [](auto const& mod) { return mod.matched; });
+ return std::all_of(m_mods.begin(), m_mods.end(), [](auto const& mod) { return mod.matched; });
}
/// @brief ensure matched file paths still exist
void BlockedModsDialog::validateMatchedMods() {
bool changed = false;
- for (auto& mod : mods) {
+ for (auto& mod : m_mods) {
if (mod.matched) {
QFileInfo file = QFileInfo(mod.localPath);
if (!file.exists() || !file.isFile()) {
@@ -238,6 +264,33 @@ void BlockedModsDialog::validateMatchedMods() {
}
}
+/// @brief run hast task or mark a pending run if it is already runing
+void BlockedModsDialog::runHashTask() {
+ if (!m_hashing_task->isRunning()) {
+ m_rehash_pending = false;
+ m_hashing_task->start();
+ } else {
+ qDebug() << "[Blocked Mods Dialog] queueing another run of the hashing task";
+ qDebug() << "[Blocked Mods Dialog] pending hash tasks:" << m_pending_hash_paths;
+ m_rehash_pending = true;
+ }
+}
+
+void BlockedModsDialog::hashTaskFinished() {
+ qDebug() << "[Blocked Mods Dialog] All hash tasks finished";
+ if (m_rehash_pending) {
+ qDebug() << "[Blocked Mods Dialog] there was a pending rehash, building and running tasks";
+
+ auto path = m_pending_hash_paths.begin();
+ while (path != m_pending_hash_paths.end()) {
+ buildHashTask(*path);
+ path = m_pending_hash_paths.erase(path);
+ }
+
+ runHashTask();
+ }
+}
+
/// qDebug print support for the BlockedMod struct
QDebug operator<<(QDebug debug, const BlockedMod& m)
{
diff --git a/launcher/ui/dialogs/BlockedModsDialog.h b/launcher/ui/dialogs/BlockedModsDialog.h
index d683c54d..ee1e6a09 100644
--- a/launcher/ui/dialogs/BlockedModsDialog.h
+++ b/launcher/ui/dialogs/BlockedModsDialog.h
@@ -39,9 +39,11 @@ protected:
private:
Ui::BlockedModsDialog *ui;
- QList &mods;
- QFileSystemWatcher watcher;
- shared_qobject_ptr hashing_task;
+ QList &m_mods;
+ QFileSystemWatcher m_watcher;
+ shared_qobject_ptr m_hashing_task;
+ QSet m_pending_hash_paths;
+ bool m_rehash_pending;
void openAll();
void addDownloadFolder();
@@ -49,10 +51,13 @@ private:
void directoryChanged(QString path);
void setupWatch();
void scanPaths();
- void scanPath(QString path);
+ void scanPath(QString path, bool start_task);
void addHashTask(QString path);
+ void buildHashTask(QString path);
void checkMatchHash(QString hash, QString path);
void validateMatchedMods();
+ void runHashTask();
+ void hashTaskFinished();
bool checkValidPath(QString path);
bool allModsMatched();
From b9e2c3524ce39769396d1b4d6a2bf1b50a9f0996 Mon Sep 17 00:00:00 2001
From: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date: Fri, 11 Nov 2022 16:07:57 -0700
Subject: [PATCH 3/7] chore: clang format & cleanup
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
---
launcher/ui/dialogs/BlockedModsDialog.cpp | 45 ++++++++++++-----------
launcher/ui/dialogs/BlockedModsDialog.h | 2 -
2 files changed, 23 insertions(+), 24 deletions(-)
diff --git a/launcher/ui/dialogs/BlockedModsDialog.cpp b/launcher/ui/dialogs/BlockedModsDialog.cpp
index a1941cb8..04d37963 100644
--- a/launcher/ui/dialogs/BlockedModsDialog.cpp
+++ b/launcher/ui/dialogs/BlockedModsDialog.cpp
@@ -6,19 +6,18 @@
#include "Application.h"
#include "ui_BlockedModsDialog.h"
-
#include
-#include
#include
#include
#include
+#include
BlockedModsDialog::BlockedModsDialog(QWidget* parent, const QString& title, const QString& text, QList& mods)
: QDialog(parent), ui(new Ui::BlockedModsDialog), m_mods(mods)
{
m_hashing_task = shared_qobject_ptr(new ConcurrentTask(this, "MakeHashesTask", 10));
connect(m_hashing_task.get(), &Task::finished, this, &BlockedModsDialog::hashTaskFinished);
-
+
ui->setupUi(this);
auto openAllButton = ui->buttonBox->addButton(tr("Open All"), QDialogButtonBox::ActionRole);
@@ -29,8 +28,6 @@ BlockedModsDialog::BlockedModsDialog(QWidget* parent, const QString& title, cons
connect(&m_watcher, &QFileSystemWatcher::directoryChanged, this, &BlockedModsDialog::directoryChanged);
-
-
qDebug() << "[Blocked Mods Dialog] Mods List: " << mods;
setupWatch();
@@ -50,15 +47,16 @@ BlockedModsDialog::~BlockedModsDialog()
delete ui;
}
-void BlockedModsDialog::dragEnterEvent(QDragEnterEvent *e) {
+void BlockedModsDialog::dragEnterEvent(QDragEnterEvent* e)
+{
if (e->mimeData()->hasUrls()) {
e->acceptProposedAction();
}
}
-void BlockedModsDialog::dropEvent(QDropEvent *e)
+void BlockedModsDialog::dropEvent(QDropEvent* e)
{
- foreach (const QUrl &url, e->mimeData()->urls()) {
+ foreach (const QUrl& url, e->mimeData()->urls()) {
QString filePath = url.toLocalFile();
qDebug() << "[Blocked Mods Dialog] Dropped file:" << filePath;
addHashTask(filePath);
@@ -80,12 +78,11 @@ void BlockedModsDialog::openAll()
}
}
-void BlockedModsDialog::addDownloadFolder() {
- QString dir = QFileDialog::getExistingDirectory(
- this,
- tr("Select directory where you downloaded the mods"),
- QStandardPaths::writableLocation(QStandardPaths::DownloadLocation),
- QFileDialog::ShowDirsOnly);
+void BlockedModsDialog::addDownloadFolder()
+{
+ QString dir =
+ QFileDialog::getExistingDirectory(this, tr("Select directory where you downloaded the mods"),
+ QStandardPaths::writableLocation(QStandardPaths::DownloadLocation), QFileDialog::ShowDirsOnly);
qDebug() << "[Blocked Mods Dialog] Adding watch path:" << dir;
m_watcher.addPath(dir);
scanPath(dir, true);
@@ -165,12 +162,12 @@ void BlockedModsDialog::scanPath(QString path, bool start_task)
if (start_task) {
runHashTask();
}
-
}
/// @brief add a hashing task for the file located at path, add the path to the pending set if the hasing task is already running
/// @param path the path to the local file being hashed
-void BlockedModsDialog::addHashTask(QString path) {
+void BlockedModsDialog::addHashTask(QString path)
+{
if (m_hashing_task->isRunning()) {
qDebug() << "[Blocked Mods Dialog] adding a Hash task for" << path << "to the pending set.";
m_pending_hash_paths.insert(path);
@@ -179,10 +176,11 @@ void BlockedModsDialog::addHashTask(QString path) {
}
}
-/// @brief add a hashing task for the file located at path and connect it to check that hash against
+/// @brief add a hashing task for the file located at path and connect it to check that hash against
/// our blocked mods list
/// @param path the path to the local file being hashed
-void BlockedModsDialog::buildHashTask(QString path) {
+void BlockedModsDialog::buildHashTask(QString path)
+{
auto hash_task = Hashing::createBlockedModHasher(path, ModPlatform::Provider::FLAME, "sha1");
qDebug() << "[Blocked Mods Dialog] Creating Hash task for path: " << path;
@@ -247,7 +245,8 @@ bool BlockedModsDialog::allModsMatched()
}
/// @brief ensure matched file paths still exist
-void BlockedModsDialog::validateMatchedMods() {
+void BlockedModsDialog::validateMatchedMods()
+{
bool changed = false;
for (auto& mod : m_mods) {
if (mod.matched) {
@@ -264,8 +263,9 @@ void BlockedModsDialog::validateMatchedMods() {
}
}
-/// @brief run hast task or mark a pending run if it is already runing
-void BlockedModsDialog::runHashTask() {
+/// @brief run hash task or mark a pending run if it is already runing
+void BlockedModsDialog::runHashTask()
+{
if (!m_hashing_task->isRunning()) {
m_rehash_pending = false;
m_hashing_task->start();
@@ -276,7 +276,8 @@ void BlockedModsDialog::runHashTask() {
}
}
-void BlockedModsDialog::hashTaskFinished() {
+void BlockedModsDialog::hashTaskFinished()
+{
qDebug() << "[Blocked Mods Dialog] All hash tasks finished";
if (m_rehash_pending) {
qDebug() << "[Blocked Mods Dialog] there was a pending rehash, building and running tasks";
diff --git a/launcher/ui/dialogs/BlockedModsDialog.h b/launcher/ui/dialogs/BlockedModsDialog.h
index ee1e6a09..dac43cba 100644
--- a/launcher/ui/dialogs/BlockedModsDialog.h
+++ b/launcher/ui/dialogs/BlockedModsDialog.h
@@ -33,8 +33,6 @@ public:
protected:
void dragEnterEvent(QDragEnterEvent *event) override;
- // void dragMoveEvent(QDragMoveEvent *event) override;
- // void dragLeaveEvent(QDragLeaveEvent *event) override;
void dropEvent(QDropEvent *event) override;
private:
From 51c27e2748cca3d772cdd9656325b748a819f3c9 Mon Sep 17 00:00:00 2001
From: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date: Fri, 11 Nov 2022 16:33:52 -0700
Subject: [PATCH 4/7] always use the pending path set to avoid task
duplication.
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
---
launcher/ui/dialogs/BlockedModsDialog.cpp | 32 ++++++++++++-----------
1 file changed, 17 insertions(+), 15 deletions(-)
diff --git a/launcher/ui/dialogs/BlockedModsDialog.cpp b/launcher/ui/dialogs/BlockedModsDialog.cpp
index 04d37963..ff331617 100644
--- a/launcher/ui/dialogs/BlockedModsDialog.cpp
+++ b/launcher/ui/dialogs/BlockedModsDialog.cpp
@@ -168,12 +168,8 @@ void BlockedModsDialog::scanPath(QString path, bool start_task)
/// @param path the path to the local file being hashed
void BlockedModsDialog::addHashTask(QString path)
{
- if (m_hashing_task->isRunning()) {
- qDebug() << "[Blocked Mods Dialog] adding a Hash task for" << path << "to the pending set.";
- m_pending_hash_paths.insert(path);
- } else {
- buildHashTask(path);
- }
+ qDebug() << "[Blocked Mods Dialog] adding a Hash task for" << path << "to the pending set.";
+ m_pending_hash_paths.insert(path);
}
/// @brief add a hashing task for the file located at path and connect it to check that hash against
@@ -252,6 +248,8 @@ void BlockedModsDialog::validateMatchedMods()
if (mod.matched) {
QFileInfo file = QFileInfo(mod.localPath);
if (!file.exists() || !file.isFile()) {
+ qDebug() << "[Blocked Mods Dialog] File" << mod.localPath << "for mod" << mod.name
+ << "has vanshed! marking as not matched.";
mod.localPath = "";
mod.matched = false;
changed = true;
@@ -268,7 +266,18 @@ void BlockedModsDialog::runHashTask()
{
if (!m_hashing_task->isRunning()) {
m_rehash_pending = false;
- m_hashing_task->start();
+
+ if (!m_pending_hash_paths.isEmpty()) {
+ qDebug() << "[Blocked Mods Dialog] there are pending hash tasks, building and running tasks";
+
+ auto path = m_pending_hash_paths.begin();
+ while (path != m_pending_hash_paths.end()) {
+ buildHashTask(*path);
+ path = m_pending_hash_paths.erase(path);
+ }
+
+ m_hashing_task->start();
+ }
} else {
qDebug() << "[Blocked Mods Dialog] queueing another run of the hashing task";
qDebug() << "[Blocked Mods Dialog] pending hash tasks:" << m_pending_hash_paths;
@@ -280,14 +289,7 @@ void BlockedModsDialog::hashTaskFinished()
{
qDebug() << "[Blocked Mods Dialog] All hash tasks finished";
if (m_rehash_pending) {
- qDebug() << "[Blocked Mods Dialog] there was a pending rehash, building and running tasks";
-
- auto path = m_pending_hash_paths.begin();
- while (path != m_pending_hash_paths.end()) {
- buildHashTask(*path);
- path = m_pending_hash_paths.erase(path);
- }
-
+ qDebug() << "[Blocked Mods Dialog] task finished with a rehash pending, rerunning";
runHashTask();
}
}
From 9af1b00df52d974a53925345efcd5c047b7d041c Mon Sep 17 00:00:00 2001
From: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date: Fri, 11 Nov 2022 18:05:19 -0700
Subject: [PATCH 5/7] feat: add list of watched folders move explanation text
into dialog class and it's own label
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
---
.../flame/FlameInstanceCreationTask.cpp | 11 ++--
.../modpacksch/FTBPackInstallTask.cpp | 15 ++---
launcher/ui/dialogs/BlockedModsDialog.cpp | 27 +++++++--
launcher/ui/dialogs/BlockedModsDialog.ui | 58 ++++++++++++++++++-
4 files changed, 86 insertions(+), 25 deletions(-)
diff --git a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
index 4b9e7b86..91554b58 100644
--- a/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
+++ b/launcher/modplatform/flame/FlameInstanceCreationTask.cpp
@@ -393,13 +393,10 @@ void FlameCreationTask::idResolverSucceeded(QEventLoop& loop)
qWarning() << "Blocked mods found, displaying mod list";
auto message_dialog = new BlockedModsDialog(m_parent, tr("Blocked mods 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.
"
- "Your configured global mods folder and default downloads folder
"
- "are automatically checked for the downloaded mods and they will be copied to the instance if found.
"
- "Optionally, you may drag and drop the downloaded mods onto this dialog or add a folder to watch
"
- "if you did not download the mods to a default location."),
- blocked_mods);
+ 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);
+
message_dialog->setModal(true);
if (message_dialog->exec()) {
diff --git a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp
index 26d0c5a1..4c7b7a4f 100644
--- a/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp
+++ b/launcher/modplatform/modpacksch/FTBPackInstallTask.cpp
@@ -211,22 +211,17 @@ void PackInstallTask::onResolveModsSucceeded()
qDebug() << "Blocked files found, displaying file list";
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.
"
- "Your configured global mods folder and default downloads folder
"
- "are automatically checked for the downloaded mods and they will be copied to the instance if found.
"
- "Optionally, you may drag and drop the downloaded mods onto this dialog or add a folder to watch
"
- "if you did not download the mods to a default location."),
- m_blocked_mods);
+ 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."),
+ m_blocked_mods);
if (message_dialog->exec() == QDialog::Accepted) {
qDebug() << "Post dialog blocked mods list: " << m_blocked_mods;
createInstance();
- }
- else {
+ } else {
abort();
}
-
+
} else {
createInstance();
}
diff --git a/launcher/ui/dialogs/BlockedModsDialog.cpp b/launcher/ui/dialogs/BlockedModsDialog.cpp
index ff331617..7f6b377b 100644
--- a/launcher/ui/dialogs/BlockedModsDialog.cpp
+++ b/launcher/ui/dialogs/BlockedModsDialog.cpp
@@ -1,5 +1,4 @@
#include "BlockedModsDialog.h"
-#include
#include
#include
#include
@@ -34,7 +33,16 @@ BlockedModsDialog::BlockedModsDialog(QWidget* parent, const QString& title, cons
scanPaths();
this->setWindowTitle(title);
- ui->label->setText(text);
+ ui->labelDescription->setText(text);
+ ui->labelExplain->setText(
+ QString(tr("Your configured global mods folder and default downloads folder "
+ "are automatically checked for the downloaded mods and they will be copied to the instance if found.
"
+ "Optionally, you may drag and drop the downloaded mods onto this dialog or add a folder to watch "
+ "if you did not download the mods to a default location.
"
+ "Global Mods Folder: %1
"
+ "Default Downloads Folder: %2"))
+ .arg(APPLICATION->settings()->get("CentralModsDir").toString(),
+ QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)));
ui->labelModsFound->setText(tr("Please download the missing mods."));
setAcceptDrops(true);
@@ -56,7 +64,7 @@ void BlockedModsDialog::dragEnterEvent(QDragEnterEvent* e)
void BlockedModsDialog::dropEvent(QDropEvent* e)
{
- foreach (const QUrl& url, e->mimeData()->urls()) {
+ for (const QUrl& url : e->mimeData()->urls()) {
QString filePath = url.toLocalFile();
qDebug() << "[Blocked Mods Dialog] Dropped file:" << filePath;
addHashTask(filePath);
@@ -106,7 +114,14 @@ void BlockedModsDialog::update()
text += QString(tr("%1: %2 Hash: %3 %4
")).arg(mod.name, mod.websiteUrl, mod.hash, span);
}
- ui->textBrowser->setText(text);
+ ui->textBrowserModsListing->setText(text);
+
+ QString watching;
+ for (auto& dir : m_watcher.directories()) {
+ watching += QString("%1
").arg(dir);
+ }
+
+ ui->textBrowserWatched->setText(watching);
if (allModsMatched()) {
ui->labelModsFound->setText(tr("All mods found ✔"));
@@ -181,8 +196,8 @@ void BlockedModsDialog::buildHashTask(QString path)
qDebug() << "[Blocked Mods Dialog] Creating Hash task for path: " << path;
- connect(hash_task.get(), &Task::succeeded, [this, hash_task, path] { checkMatchHash(hash_task->getResult(), path); });
- connect(hash_task.get(), &Task::failed, [path] { qDebug() << "Failed to hash path: " << path; });
+ connect(hash_task.get(), &Task::succeeded, this, [this, hash_task, path] { checkMatchHash(hash_task->getResult(), path); });
+ connect(hash_task.get(), &Task::failed, this, [path] { qDebug() << "Failed to hash path: " << path; });
m_hashing_task->addTask(hash_task);
}
diff --git a/launcher/ui/dialogs/BlockedModsDialog.ui b/launcher/ui/dialogs/BlockedModsDialog.ui
index 371549cf..fb1036b7 100644
--- a/launcher/ui/dialogs/BlockedModsDialog.ui
+++ b/launcher/ui/dialogs/BlockedModsDialog.ui
@@ -15,17 +15,36 @@
-
-
+
Qt::RichText
+
+ true
+
-
-
+
+
+
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 165
+
+
true
@@ -34,6 +53,41 @@
+ -
+
+
+
+ 0
+ 1
+
+
+
+ Watched Folders:
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 0
+ 16
+
+
+
+
+ 0
+ 12
+
+
+
+
-
-
From 25b306b7e1c83ecdeb135c8100c3089d9147cde7 Mon Sep 17 00:00:00 2001
From: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date: Fri, 11 Nov 2022 18:32:11 -0700
Subject: [PATCH 6/7] feat: mark folder paths as links
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
---
launcher/ui/dialogs/BlockedModsDialog.cpp | 9 ++++++---
launcher/ui/dialogs/BlockedModsDialog.ui | 9 +++++++++
2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/launcher/ui/dialogs/BlockedModsDialog.cpp b/launcher/ui/dialogs/BlockedModsDialog.cpp
index 7f6b377b..a0dd1a10 100644
--- a/launcher/ui/dialogs/BlockedModsDialog.cpp
+++ b/launcher/ui/dialogs/BlockedModsDialog.cpp
@@ -39,12 +39,15 @@ BlockedModsDialog::BlockedModsDialog(QWidget* parent, const QString& title, cons
"are automatically checked for the downloaded mods and they will be copied to the instance if found.
"
"Optionally, you may drag and drop the downloaded mods onto this dialog or add a folder to watch "
"if you did not download the mods to a default location.
"
- "Global Mods Folder: %1
"
- "Default Downloads Folder: %2"))
+ "Global Mods Folder: %1
"
+ "Default Downloads Folder: %2"))
.arg(APPLICATION->settings()->get("CentralModsDir").toString(),
QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)));
ui->labelModsFound->setText(tr("Please download the missing mods."));
+ // force all URL handeling as external
+ connect(ui->textBrowserWatched, &QTextBrowser::anchorClicked, this, [](const QUrl url) { QDesktopServices::openUrl(url); });
+
setAcceptDrops(true);
update();
@@ -118,7 +121,7 @@ void BlockedModsDialog::update()
QString watching;
for (auto& dir : m_watcher.directories()) {
- watching += QString("%1
").arg(dir);
+ watching += QString("%1
").arg(dir);
}
ui->textBrowserWatched->setText(watching);
diff --git a/launcher/ui/dialogs/BlockedModsDialog.ui b/launcher/ui/dialogs/BlockedModsDialog.ui
index fb1036b7..88105178 100644
--- a/launcher/ui/dialogs/BlockedModsDialog.ui
+++ b/launcher/ui/dialogs/BlockedModsDialog.ui
@@ -35,6 +35,9 @@
true
+
+ true
+
-
@@ -86,6 +89,12 @@
12
+
+ true
+
+
+ false
+
-
From 52d43f843bceb861c92f8989a27194436924e087 Mon Sep 17 00:00:00 2001
From: Rachel Powers <508861+Ryex@users.noreply.github.com>
Date: Thu, 17 Nov 2022 11:46:14 -0700
Subject: [PATCH 7/7] feat(BlockModsDialog): remove redundant Ui info
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
---
launcher/ui/dialogs/BlockedModsDialog.cpp | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/launcher/ui/dialogs/BlockedModsDialog.cpp b/launcher/ui/dialogs/BlockedModsDialog.cpp
index a0dd1a10..edb4ff7d 100644
--- a/launcher/ui/dialogs/BlockedModsDialog.cpp
+++ b/launcher/ui/dialogs/BlockedModsDialog.cpp
@@ -38,12 +38,9 @@ BlockedModsDialog::BlockedModsDialog(QWidget* parent, const QString& title, cons
QString(tr("Your configured global mods folder and default downloads folder "
"are automatically checked for the downloaded mods and they will be copied to the instance if found.
"
"Optionally, you may drag and drop the downloaded mods onto this dialog or add a folder to watch "
- "if you did not download the mods to a default location.
"
- "Global Mods Folder: %1
"
- "Default Downloads Folder: %2"))
+ "if you did not download the mods to a default location."))
.arg(APPLICATION->settings()->get("CentralModsDir").toString(),
QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)));
- ui->labelModsFound->setText(tr("Please download the missing mods."));
// force all URL handeling as external
connect(ui->textBrowserWatched, &QTextBrowser::anchorClicked, this, [](const QUrl url) { QDesktopServices::openUrl(url); });
@@ -127,7 +124,7 @@ void BlockedModsDialog::update()
ui->textBrowserWatched->setText(watching);
if (allModsMatched()) {
- ui->labelModsFound->setText(tr("All mods found ✔"));
+ ui->labelModsFound->setText("✔" + tr("All mods found"));
} else {
ui->labelModsFound->setText(tr("Please download the missing mods."));
}