From 73b1b58a966469ec5b28ebc9899fcebf1df567b3 Mon Sep 17 00:00:00 2001 From: blue Date: Sat, 19 Feb 2022 21:31:49 +0300 Subject: [PATCH] Downloads folder now is movable --- core/handlers/messagehandler.cpp | 6 +++- core/handlers/messagehandler.h | 1 + core/main.cpp | 1 + core/networkaccess.cpp | 18 +++++++---- core/squawk.cpp | 6 ++++ core/squawk.h | 1 + shared/pathcheck.cpp | 23 +++++++++++++++ shared/pathcheck.h | 3 ++ ui/squawk.cpp | 1 + ui/squawk.h | 1 + ui/widgets/settings/pagegeneral.cpp | 46 ++++++++++++++++++++++++++++- ui/widgets/settings/pagegeneral.h | 7 +++++ ui/widgets/settings/pagegeneral.ui | 2 +- ui/widgets/settings/settings.cpp | 12 +++++++- ui/widgets/settings/settings.h | 5 ++++ ui/widgets/settings/settings.ui | 20 +++++++++++-- 16 files changed, 141 insertions(+), 12 deletions(-) diff --git a/core/handlers/messagehandler.cpp b/core/handlers/messagehandler.cpp index fc05a67..1e89dd6 100644 --- a/core/handlers/messagehandler.cpp +++ b/core/handlers/messagehandler.cpp @@ -304,7 +304,11 @@ void Core::MessageHandler::performSending(Shared::Message data, bool newMessage) //so, the final path changes. Let's assume it changes always since it costs me close to nothing QString attachPath = data.getAttachPath(); if (attachPath.size() > 0) { - changes.insert("attachPath", attachPath); + QString squawkified = Shared::squawkifyPath(attachPath); + changes.insert("attachPath", squawkified); + if (attachPath != squawkified) { + data.setAttachPath(squawkified); + } } if (ri != 0) { diff --git a/core/handlers/messagehandler.h b/core/handlers/messagehandler.h index b88c46a..4f03484 100644 --- a/core/handlers/messagehandler.h +++ b/core/handlers/messagehandler.h @@ -29,6 +29,7 @@ #include #include +#include namespace Core { diff --git a/core/main.cpp b/core/main.cpp index 9a10062..79ca648 100644 --- a/core/main.cpp +++ b/core/main.cpp @@ -160,6 +160,7 @@ int main(int argc, char *argv[]) QObject::connect(&w, &Squawk::uploadVCard, squawk, &Core::Squawk::uploadVCard); QObject::connect(&w, &Squawk::responsePassword, squawk, &Core::Squawk::responsePassword); QObject::connect(&w, &Squawk::localPathInvalid, squawk, &Core::Squawk::onLocalPathInvalid); + QObject::connect(&w, &Squawk::changeDownloadsPath, squawk, &Core::Squawk::changeDownloadsPath); QObject::connect(squawk, &Core::Squawk::newAccount, &w, &Squawk::newAccount); QObject::connect(squawk, &Core::Squawk::addContact, &w, &Squawk::addContact); diff --git a/core/networkaccess.cpp b/core/networkaccess.cpp index 25fafc8..7c55e19 100644 --- a/core/networkaccess.cpp +++ b/core/networkaccess.cpp @@ -438,10 +438,10 @@ void Core::NetworkAccess::onUploadProgress(qint64 bytesReceived, qint64 bytesTot QString Core::NetworkAccess::getFileRemoteUrl(const QString& path) { - QString p; + QString p = Shared::squawkifyPath(path); try { - p = storage.getUrl(path); + p = storage.getUrl(p); } catch (const Archive::NotFound& err) { } catch (...) { @@ -574,10 +574,16 @@ std::list Core::NetworkAccess::reportPathInvalid(const QStr void Core::NetworkAccess::moveFilesDirectory(const QString& newPath) { - QDir dir; - if (dir.rename(currentPath, newPath)) { - currentPath = newPath; - } else { + QDir dir(currentPath); + bool success = true; + qDebug() << "moving" << currentPath << "to" << newPath; + for (QFileInfo fileInfo : dir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System)) { + QString fileName = fileInfo.fileName(); + success = dir.rename(fileName, newPath + QDir::separator() + fileName) && success; + } + + if (!success) { qDebug() << "couldn't move downloads directory, most probably downloads will be broken"; } + currentPath = newPath; } diff --git a/core/squawk.cpp b/core/squawk.cpp index 69d2eef..9f2b445 100644 --- a/core/squawk.cpp +++ b/core/squawk.cpp @@ -785,3 +785,9 @@ void Core::Squawk::onLocalPathInvalid(const QString& path) } } } + +void Core::Squawk::changeDownloadsPath(const QString& path) +{ + network.moveFilesDirectory(path); +} + diff --git a/core/squawk.h b/core/squawk.h index 5db9fa8..738a957 100644 --- a/core/squawk.h +++ b/core/squawk.h @@ -123,6 +123,7 @@ public slots: void uploadVCard(const QString& account, const Shared::VCard& card); void responsePassword(const QString& account, const QString& password); void onLocalPathInvalid(const QString& path); + void changeDownloadsPath(const QString& path); private: typedef std::deque Accounts; diff --git a/shared/pathcheck.cpp b/shared/pathcheck.cpp index 0850742..1929387 100644 --- a/shared/pathcheck.cpp +++ b/shared/pathcheck.cpp @@ -53,3 +53,26 @@ QString Shared::resolvePath(QString path) QVariant dpv = settings.value("downloadsPath"); return path.replace(squawk, dpv.toString() + "/"); } + +QString Shared::squawkifyPath(QString path) +{ + QSettings settings; + QString current = settings.value("downloadsPath").toString(); + + if (path.startsWith(current)) { + path.replace(0, current.size() + 1, "squawk://"); + } + + return path; +} + +bool Shared::isSubdirectoryOfSettings(const QString& path) +{ + + QSettings settings; + QDir oldPath(settings.value("downloadsPath").toString()); + QDir newPath(path); + + return newPath.canonicalPath().startsWith(oldPath.canonicalPath()); +} + diff --git a/shared/pathcheck.h b/shared/pathcheck.h index 6e7cd39..62dcaeb 100644 --- a/shared/pathcheck.h +++ b/shared/pathcheck.h @@ -13,10 +13,13 @@ namespace Shared { QString downloadsPathCheck(); +QString downloadsPathCheck(QString path); QString defaultDownloadsPath(); QString getAbsoluteWritablePath(const QString& path); QString resolvePath(QString path); +QString squawkifyPath(QString path); +bool isSubdirectoryOfSettings(const QString& path); } diff --git a/ui/squawk.cpp b/ui/squawk.cpp index 7acda3d..e24640a 100644 --- a/ui/squawk.cpp +++ b/ui/squawk.cpp @@ -125,6 +125,7 @@ void Squawk::onPreferences() preferences = new Settings(); preferences->setAttribute(Qt::WA_DeleteOnClose); connect(preferences, &Settings::destroyed, this, &Squawk::onPreferencesClosed); + connect(preferences, &Settings::changeDownloadsPath, this, &Squawk::changeDownloadsPath); preferences->show(); } else { diff --git a/ui/squawk.h b/ui/squawk.h index b419057..7551f66 100644 --- a/ui/squawk.h +++ b/ui/squawk.h @@ -80,6 +80,7 @@ signals: void uploadVCard(const QString& account, const Shared::VCard& card); void responsePassword(const QString& account, const QString& password); void localPathInvalid(const QString& path); + void changeDownloadsPath(const QString& path); public slots: void writeSettings(); diff --git a/ui/widgets/settings/pagegeneral.cpp b/ui/widgets/settings/pagegeneral.cpp index 56cb610..a546bd0 100644 --- a/ui/widgets/settings/pagegeneral.cpp +++ b/ui/widgets/settings/pagegeneral.cpp @@ -3,14 +3,58 @@ PageGeneral::PageGeneral(QWidget* parent): QWidget(parent), - m_ui(new Ui::PageGeneral()) + m_ui(new Ui::PageGeneral()), + dialog(nullptr) { m_ui->setupUi(this); QSettings settings; m_ui->downloadsPathInput->setText(settings.value("downloadsPath").toString()); + connect(m_ui->downloadsPathButton, &QPushButton::clicked, this, &PageGeneral::onBrowseButtonClicked); } PageGeneral::~PageGeneral() { + if (dialog != nullptr) { + dialog->deleteLater(); + } +} + +void PageGeneral::onBrowseButtonClicked() +{ + if (dialog == nullptr) { + QSettings settings; + dialog = new QFileDialog(this, tr("Select where downloads folder is going to be"), settings.value("downloadsPath").toString()); + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->setAcceptMode(QFileDialog::AcceptSave); //I find it the most convinient way + dialog->setFileMode(QFileDialog::AnyFile); //Otherwise the directory is supposed to be + dialog->setOption(QFileDialog::ShowDirsOnly, true); //selected and not to be navigated + dialog->setOption(QFileDialog::DontConfirmOverwrite, true); + dialog->setModal(true); + connect(dialog, &QFileDialog::accepted, this, &PageGeneral::onDialogAccepted); + connect(dialog, &QFileDialog::destroyed, this, &PageGeneral::onDialogDestroyed); + dialog->show(); + } else { + dialog->show(); + dialog->raise(); + dialog->activateWindow(); + } +} + +void PageGeneral::onDialogAccepted() +{ + QStringList files = dialog->selectedFiles(); + QString path; + if (files.size() > 0) { + path = files[0]; + } else { + path = dialog->directory().canonicalPath(); + } + m_ui->downloadsPathInput->setText(path); + emit variableModified("downloadsPath", path); +} + +void PageGeneral::onDialogDestroyed() +{ + dialog = nullptr; } diff --git a/ui/widgets/settings/pagegeneral.h b/ui/widgets/settings/pagegeneral.h index cb89bfa..ec00bba 100644 --- a/ui/widgets/settings/pagegeneral.h +++ b/ui/widgets/settings/pagegeneral.h @@ -5,6 +5,7 @@ #include #include #include +#include namespace Ui { @@ -24,8 +25,14 @@ public: signals: void variableModified(const QString& key, const QVariant& value); +private slots: + void onBrowseButtonClicked(); + void onDialogAccepted(); + void onDialogDestroyed(); + private: QScopedPointer m_ui; + QFileDialog* dialog; }; #endif // PAGEGENERAL_H diff --git a/ui/widgets/settings/pagegeneral.ui b/ui/widgets/settings/pagegeneral.ui index e010980..e412668 100644 --- a/ui/widgets/settings/pagegeneral.ui +++ b/ui/widgets/settings/pagegeneral.ui @@ -33,7 +33,7 @@ - PushButton + Browse diff --git a/ui/widgets/settings/settings.cpp b/ui/widgets/settings/settings.cpp index 3ab38bb..27401bb 100644 --- a/ui/widgets/settings/settings.cpp +++ b/ui/widgets/settings/settings.cpp @@ -42,11 +42,21 @@ void Settings::apply() for (const std::pair& pair: modifiedSettings) { if (pair.first == "style") { Shared::Global::setStyle(pair.second.toString()); + settings.setValue(pair.first, pair.second); } else if (pair.first == "theme") { Shared::Global::setTheme(pair.second.toString()); + settings.setValue(pair.first, pair.second); + } else if (pair.first == "downloadsPath") { + QString path = pair.second.toString(); + if (!Shared::isSubdirectoryOfSettings(path)) { + path = Shared::getAbsoluteWritablePath(path); + if (path.size() > 0) { + settings.setValue(pair.first, path); + emit changeDownloadsPath(path); + } + } } - settings.setValue(pair.first, pair.second); } modifiedSettings.clear(); diff --git a/ui/widgets/settings/settings.h b/ui/widgets/settings/settings.h index 5031139..5a6b37c 100644 --- a/ui/widgets/settings/settings.h +++ b/ui/widgets/settings/settings.h @@ -5,8 +5,10 @@ #include #include #include +#include #include "shared/global.h" +#include "shared/pathcheck.h" namespace Ui { @@ -23,6 +25,9 @@ public: Settings(QWidget* parent = nullptr); ~Settings(); +signals: + void changeDownloadsPath(const QString& path); + public slots: void apply(); void confirm(); diff --git a/ui/widgets/settings/settings.ui b/ui/widgets/settings/settings.ui index fe092dc..d97a3f2 100644 --- a/ui/widgets/settings/settings.ui +++ b/ui/widgets/settings/settings.ui @@ -10,6 +10,9 @@ 363 + + Preferences + 0 @@ -183,10 +186,23 @@ 0 - - + + + + + + Qt::Horizontal + + + + 40 + 20 + + + +