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: drag&drop + add folder to watch Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/ui/dialogs/BlockedModsDialog.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'launcher/ui/dialogs/BlockedModsDialog.h') 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(); -- cgit 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: properly handle a currently running hashing task Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- .../flame/FlameInstanceCreationTask.cpp | 2 +- .../modplatform/modpacksch/FTBPackInstallTask.cpp | 2 +- launcher/ui/dialogs/BlockedModsDialog.cpp | 113 +++++++++++++++------ launcher/ui/dialogs/BlockedModsDialog.h | 13 ++- 4 files changed, 94 insertions(+), 36 deletions(-) (limited to 'launcher/ui/dialogs/BlockedModsDialog.h') 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(); -- cgit 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: 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(-) (limited to 'launcher/ui/dialogs/BlockedModsDialog.h') 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: -- cgit