drag&drop + add folder to watch

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
This commit is contained in:
Rachel Powers 2022-11-11 14:10:45 -07:00
parent 64576f4c4c
commit 5909af9878
4 changed files with 92 additions and 12 deletions

View File

@ -393,8 +393,12 @@ void FlameCreationTask::idResolverSucceeded(QEventLoop& loop)
qWarning() << "Blocked mods found, displaying mod list"; qWarning() << "Blocked mods found, displaying mod list";
auto message_dialog = new BlockedModsDialog(m_parent, tr("Blocked mods found"), auto message_dialog = new BlockedModsDialog(m_parent, tr("Blocked mods found"),
tr("The following mods were blocked on third party launchers.<br/>" tr("The following files are not available for download in third party launchers.<br/>"
"You will need to manually download them and add them to the modpack"), "You will need to manually download them and add them to the instance.<br/><br/>"
"Your configured global mods folder and default downloads folder<br/>"
"are automatically checked for the downloaded mods.<br/>"
"Optionally, you may drag and drop the downloaded mods onto this dialog or add a folder to watch<br/>"
"if you did not download the mods to a default location."),
blocked_mods); blocked_mods);
message_dialog->setModal(true); message_dialog->setModal(true);

View File

@ -212,7 +212,11 @@ void PackInstallTask::onResolveModsSucceeded()
auto message_dialog = new BlockedModsDialog(m_parent, tr("Blocked files found"), auto message_dialog = new BlockedModsDialog(m_parent, tr("Blocked files found"),
tr("The following files are not available for download in third party launchers.<br/>" tr("The following files are not available for download in third party launchers.<br/>"
"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.<br/><br/>"
"Your configured global mods folder and default downloads folder<br/>"
"are automatically checked for the downloaded mods.<br/>"
"Optionally, you may drag and drop the downloaded mods onto this dialog or add a folder to watch<br/>"
"if you did not download the mods to a default location."),
m_blocked_mods); m_blocked_mods);
if (message_dialog->exec() == QDialog::Accepted) { if (message_dialog->exec() == QDialog::Accepted) {

View File

@ -5,20 +5,29 @@
#include "Application.h" #include "Application.h"
#include "ui_BlockedModsDialog.h" #include "ui_BlockedModsDialog.h"
#include <QDebug> #include <QDebug>
#include <QStandardPaths> #include <QStandardPaths>
#include <QDragEnterEvent>
#include <QFileDialog>
#include <QFileInfo>
BlockedModsDialog::BlockedModsDialog(QWidget* parent, const QString& title, const QString& text, QList<BlockedMod>& mods) BlockedModsDialog::BlockedModsDialog(QWidget* parent, const QString& title, const QString& text, QList<BlockedMod>& mods)
: QDialog(parent), ui(new Ui::BlockedModsDialog), mods(mods) : QDialog(parent), ui(new Ui::BlockedModsDialog), mods(mods)
{ {
hashing_task = shared_qobject_ptr<ConcurrentTask>(new ConcurrentTask(this, "MakeHashesTask", 10));
ui->setupUi(this); ui->setupUi(this);
auto openAllButton = ui->buttonBox->addButton(tr("Open All"), QDialogButtonBox::ActionRole); auto openAllButton = ui->buttonBox->addButton(tr("Open All"), QDialogButtonBox::ActionRole);
connect(openAllButton, &QPushButton::clicked, this, &BlockedModsDialog::openAll); 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); connect(&watcher, &QFileSystemWatcher::directoryChanged, this, &BlockedModsDialog::directoryChanged);
hashing_task = shared_qobject_ptr<ConcurrentTask>(new ConcurrentTask(this, "MakeHashesTask", 10));
qDebug() << "Mods List: " << mods; qDebug() << "Mods List: " << mods;
@ -28,6 +37,9 @@ BlockedModsDialog::BlockedModsDialog(QWidget* parent, const QString& title, cons
this->setWindowTitle(title); this->setWindowTitle(title);
ui->label->setText(text); ui->label->setText(text);
ui->labelModsFound->setText(tr("Please download the missing mods.")); ui->labelModsFound->setText(tr("Please download the missing mods."));
setAcceptDrops(true);
update(); update();
} }
@ -36,6 +48,22 @@ BlockedModsDialog::~BlockedModsDialog()
delete ui; 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() void BlockedModsDialog::openAll()
{ {
for (auto& mod : mods) { 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 /// @brief update UI with current status of the blocked mod detection
void BlockedModsDialog::update() void BlockedModsDialog::update()
{ {
@ -74,6 +112,7 @@ void BlockedModsDialog::update()
void BlockedModsDialog::directoryChanged(QString path) void BlockedModsDialog::directoryChanged(QString path)
{ {
qDebug() << "Directory changed: " << path; qDebug() << "Directory changed: " << path;
validateMatchedMods();
scanPath(path); scanPath(path);
} }
@ -108,19 +147,26 @@ void BlockedModsDialog::scanPath(QString path)
continue; continue;
} }
auto hash_task = Hashing::createBlockedModHasher(file, ModPlatform::Provider::FLAME, "sha1"); addHashTask(file);
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);
} }
hashing_task->start(); 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 /// @brief check if the computed hash for the provided path matches a blocked
/// mod we are looking for /// mod we are looking for
/// @param hash the computed hash for the provided path /// @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; }); 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 print support for the BlockedMod struct
QDebug operator<<(QDebug debug, const BlockedMod& m) QDebug operator<<(QDebug debug, const BlockedMod& m)
{ {

View File

@ -31,6 +31,11 @@ public:
~BlockedModsDialog() override; ~BlockedModsDialog() override;
protected:
void dragEnterEvent(QDragEnterEvent *event) override;
// void dragMoveEvent(QDragMoveEvent *event) override;
// void dragLeaveEvent(QDragLeaveEvent *event) override;
void dropEvent(QDropEvent *event) override;
private: private:
Ui::BlockedModsDialog *ui; Ui::BlockedModsDialog *ui;
@ -39,12 +44,15 @@ private:
shared_qobject_ptr<ConcurrentTask> hashing_task; shared_qobject_ptr<ConcurrentTask> hashing_task;
void openAll(); void openAll();
void addDownloadFolder();
void update(); void update();
void directoryChanged(QString path); void directoryChanged(QString path);
void setupWatch(); void setupWatch();
void scanPaths(); void scanPaths();
void scanPath(QString path); void scanPath(QString path);
void addHashTask(QString path);
void checkMatchHash(QString hash, QString path); void checkMatchHash(QString hash, QString path);
void validateMatchedMods();
bool checkValidPath(QString path); bool checkValidPath(QString path);
bool allModsMatched(); bool allModsMatched();