diff options
author | Claudio Cambra <claudio.cambra@nextcloud.com> | 2022-10-28 20:40:06 +0300 |
---|---|---|
committer | Claudio Cambra <claudio.cambra@gmail.com> | 2022-10-29 14:32:48 +0300 |
commit | 9f7a699ad99fdb58e98f679f2b35134857bc8ff2 (patch) | |
tree | df37b6709fad04144f3051a47c986fefed34f82b | |
parent | 4b6fdcc5502fc158e39e812d93a4447530ac0410 (diff) |
Refactor edit locally handler management away from application and into own class
Signed-off-by: Claudio Cambra <claudio.cambra@nextcloud.com>
-rw-r--r-- | src/gui/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/gui/application.cpp | 39 | ||||
-rw-r--r-- | src/gui/application.h | 2 | ||||
-rw-r--r-- | src/gui/editlocallyhandler.cpp | 13 | ||||
-rw-r--r-- | src/gui/editlocallyhandler.h | 9 | ||||
-rw-r--r-- | src/gui/editlocallymanager.cpp | 93 | ||||
-rw-r--r-- | src/gui/editlocallymanager.h | 56 |
7 files changed, 169 insertions, 45 deletions
diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 6aa35f6b6..4995dafcb 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -83,6 +83,8 @@ set(client_SRCS connectionvalidator.cpp editlocallyhandler.h editlocallyhandler.cpp + editlocallymanager.h + editlocallymanager.cpp folder.h folder.cpp foldercreationdialog.h diff --git a/src/gui/application.cpp b/src/gui/application.cpp index 3c53314a6..fafc33a24 100644 --- a/src/gui/application.cpp +++ b/src/gui/application.cpp @@ -22,7 +22,7 @@ #include "config.h" #include "account.h" #include "accountstate.h" -#include "editlocallyhandler.h" +#include "editlocallymanager.h" #include "connectionvalidator.h" #include "folder.h" #include "folderman.h" @@ -750,43 +750,10 @@ void Application::handleEditLocallyFromOptions() return; } - handleEditLocally(_editFileLocallyUrl); + EditLocallyManager::instance()->editLocally(_editFileLocallyUrl); _editFileLocallyUrl.clear(); } -void Application::handleEditLocally(const QUrl &url) const -{ - auto pathSplit = url.path().split('/', Qt::SkipEmptyParts); - - if (pathSplit.size() < 2) { - qCWarning(lcApplication) << "Invalid URL for file local editing: " + pathSplit.join('/'); - return; - } - - // for a sample URL "nc://open/admin@nextcloud.lan:8080/Photos/lovely.jpg", QUrl::path would return "admin@nextcloud.lan:8080/Photos/lovely.jpg" - const auto userId = pathSplit.takeFirst(); - const auto fileRemotePath = pathSplit.join('/'); - const auto urlQuery = QUrlQuery{url}; - - auto token = QString{}; - if (urlQuery.hasQueryItem(QStringLiteral("token"))) { - token = urlQuery.queryItemValue(QStringLiteral("token")); - } else { - qCWarning(lcApplication) << "Invalid URL for file local editing: missing token"; - } - - // We need to make sure the handler sticks around until it is finished - const auto editLocallyHandler = new EditLocallyHandler(userId, fileRemotePath, token); - const auto editLocallyHandlerDeleter = [editLocallyHandler]{ delete editLocallyHandler; }; - connect(editLocallyHandler, &EditLocallyHandler::error, this, editLocallyHandlerDeleter); - connect(editLocallyHandler, &EditLocallyHandler::fileOpened, this, editLocallyHandlerDeleter); - - connect(editLocallyHandler, &EditLocallyHandler::setupFinished, - editLocallyHandler, [editLocallyHandler]{ editLocallyHandler->startEditLocally(); }); - editLocallyHandler->startSetup(); - -} - QString substLang(const QString &lang) { // Map the more appropriate script codes @@ -927,7 +894,7 @@ bool Application::event(QEvent *event) // On macOS, Qt does not handle receiving a custom URI as it does on other systems (as an application argument). // Instead, it sends out a QFileOpenEvent. We therefore need custom handling for our URI handling on macOS. qCInfo(lcApplication) << "macOS: Opening local file for editing: " << openEvent->url(); - handleEditLocally(openEvent->url()); + EditLocallyManager::instance()->editLocally(openEvent->url()); } else { const auto errorParsingLocalFileEditingUrl = QStringLiteral("The supplied url for local file editing '%1' is invalid!").arg(openEvent->url().toString()); qCInfo(lcApplication) << errorParsingLocalFileEditingUrl; diff --git a/src/gui/application.h b/src/gui/application.h index 6c00f6a50..a485eea89 100644 --- a/src/gui/application.h +++ b/src/gui/application.h @@ -87,8 +87,6 @@ public slots: /// Attempt to show() the tray icon again. Used if no systray was available initially. void tryTrayAgain(); - void handleEditLocally(const QUrl &url) const; - protected: void parseOptions(const QStringList &); void setupTranslations(); diff --git a/src/gui/editlocallyhandler.cpp b/src/gui/editlocallyhandler.cpp index 80d38b07c..64210a7ff 100644 --- a/src/gui/editlocallyhandler.cpp +++ b/src/gui/editlocallyhandler.cpp @@ -19,6 +19,7 @@ #include <QtConcurrent> #include "accountmanager.h" +#include "editlocallymanager.h" #include "folder.h" #include "folderman.h" #include "syncengine.h" @@ -28,8 +29,6 @@ namespace OCC { Q_LOGGING_CATEGORY(lcEditLocallyHandler, "nextcloud.gui.editlocallyhandler", QtInfoMsg) -static QHash<QString, QMetaObject::Connection> editLocallySyncFinishedConnections; - EditLocallyHandler::EditLocallyHandler(const QString &userId, const QString &relPath, const QString &token, @@ -277,7 +276,9 @@ void EditLocallyHandler::startEditLocally() _folderForFile->startSync(); const auto syncFinishedConnection = connect(_folderForFile, &Folder::syncFinished, this, &EditLocallyHandler::folderSyncFinished); - editLocallySyncFinishedConnections.insert(_localFilePath, syncFinishedConnection); + + EditLocallyManager::instance()->folderSyncFinishedConnections.insert(_localFilePath, + syncFinishedConnection); } void EditLocallyHandler::folderSyncFinished(const OCC::SyncResult &result) @@ -293,9 +294,11 @@ void EditLocallyHandler::disconnectSyncFinished() const return; } - if (const auto existingConnection = editLocallySyncFinishedConnections.value(_localFilePath)) { + const auto manager = EditLocallyManager::instance(); + + if (const auto existingConnection = manager->folderSyncFinishedConnections.value(_localFilePath)) { disconnect(existingConnection); - editLocallySyncFinishedConnections.remove(_localFilePath); + manager->folderSyncFinishedConnections.remove(_localFilePath); } } diff --git a/src/gui/editlocallyhandler.h b/src/gui/editlocallyhandler.h index 04791ce93..f7b27b71a 100644 --- a/src/gui/editlocallyhandler.h +++ b/src/gui/editlocallyhandler.h @@ -16,11 +16,16 @@ #include <QObject> -#include "accountmanager.h" -#include "folder.h" +#include "accountstate.h" namespace OCC { +class EditLocallyHandler; +using EditLocallyHandlerPtr = QSharedPointer<EditLocallyHandler>; + +class Folder; +class SyncResult; + class EditLocallyHandler : public QObject { Q_OBJECT diff --git a/src/gui/editlocallymanager.cpp b/src/gui/editlocallymanager.cpp new file mode 100644 index 000000000..1d8bea8c9 --- /dev/null +++ b/src/gui/editlocallymanager.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (C) by Claudio Cambra <claudio.cambra@nextcloud.com> + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "editlocallymanager.h" + +#include <QUrl> +#include <QLoggingCategory> + +#include "editlocallyhandler.h" + +namespace OCC { + +Q_LOGGING_CATEGORY(lcEditLocallyManager, "nextcloud.gui.editlocallymanager", QtInfoMsg) + +EditLocallyManager *EditLocallyManager::_instance = nullptr; + +EditLocallyManager::EditLocallyManager(QObject *parent) + : QObject{parent} +{ +} + +EditLocallyManager *EditLocallyManager::instance() +{ + if (!_instance) { + _instance = new EditLocallyManager(); + } + return _instance; +} + +void EditLocallyManager::editLocally(const QUrl &url) +{ + const auto inputs = parseEditLocallyUrl(url); + createHandler(inputs.userId, inputs.relPath, inputs.token); +} + +EditLocallyManager::EditLocallyInputData EditLocallyManager::parseEditLocallyUrl(const QUrl &url) +{ + const auto separator = QChar::fromLatin1('/'); + auto pathSplit = url.path().split(separator, Qt::SkipEmptyParts); + + if (pathSplit.size() < 2) { + qCWarning(lcEditLocallyManager) << "Invalid URL for file local editing: " + pathSplit.join(separator); + return {}; + } + + // for a sample URL "nc://open/admin@nextcloud.lan:8080/Photos/lovely.jpg", QUrl::path would return "admin@nextcloud.lan:8080/Photos/lovely.jpg" + const auto userId = pathSplit.takeFirst(); + const auto fileRemotePath = pathSplit.join(separator); + const auto urlQuery = QUrlQuery{url}; + + auto token = QString{}; + if (urlQuery.hasQueryItem(QStringLiteral("token"))) { + token = urlQuery.queryItemValue(QStringLiteral("token")); + } else { + qCWarning(lcEditLocallyManager) << "Invalid URL for file local editing: missing token"; + } + + return {userId, fileRemotePath, token}; +} + +void EditLocallyManager::createHandler(const QString &userId, + const QString &relPath, + const QString &token) +{ + const EditLocallyHandlerPtr handler(new EditLocallyHandler(userId, relPath, token)); + // We need to make sure the handler sticks around until it is finished + _handlers.insert(token, handler); + + const auto removeHandler = [this, token] { _handlers.remove(token); }; + const auto setupHandler = [handler] { handler->startEditLocally(); }; + + connect(handler.data(), &EditLocallyHandler::error, + this, removeHandler); + connect(handler.data(), &EditLocallyHandler::fileOpened, + this, removeHandler); + connect(handler.data(), &EditLocallyHandler::setupFinished, + handler.data(), setupHandler); + + handler->startSetup(); +} + +} diff --git a/src/gui/editlocallymanager.h b/src/gui/editlocallymanager.h new file mode 100644 index 000000000..3ba414fca --- /dev/null +++ b/src/gui/editlocallymanager.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) by Claudio Cambra <claudio.cambra@nextcloud.com> + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#pragma once + +#include <QObject> +#include <QHash> + +#include "editlocallyhandler.h" + +namespace OCC { + +class EditLocallyManager : public QObject +{ + Q_OBJECT + +public: + [[nodiscard]] static EditLocallyManager *instance(); + + QHash<QString, QMetaObject::Connection> folderSyncFinishedConnections; + +public slots: + void editLocally(const QUrl &url); + +private slots: + void createHandler(const QString &userId, + const QString &relPath, + const QString &token); + +private: + explicit EditLocallyManager(QObject *parent = nullptr); + static EditLocallyManager *_instance; + + struct EditLocallyInputData { + QString userId; + QString relPath; + QString token; + }; + + [[nodiscard]] static EditLocallyInputData parseEditLocallyUrl(const QUrl &url); + + QHash<QString, EditLocallyHandlerPtr> _handlers; +}; + +} |