From 81ecba8daaa36acb837c3f906870122d4cc17c76 Mon Sep 17 00:00:00 2001 From: alex-z Date: Thu, 11 May 2023 18:29:58 +0200 Subject: [PATCH] Allow opening a file or folder in the local sync root. Signed-off-by: alex-z --- src/gui/editlocallyjob.cpp | 25 +++++++++++++++++++------ src/gui/editlocallyjob.h | 2 ++ src/gui/folder.cpp | 3 +-- src/libsync/syncengine.cpp | 10 ++++++++-- src/libsync/syncengine.h | 4 +++- 5 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/gui/editlocallyjob.cpp b/src/gui/editlocallyjob.cpp index 18055d8d6b..78aedd34f8 100644 --- a/src/gui/editlocallyjob.cpp +++ b/src/gui/editlocallyjob.cpp @@ -147,7 +147,7 @@ void EditLocallyJob::proceedWithSetup() return; } - if (_relPathParent != QStringLiteral("/") && (!_fileParentItem || _fileParentItem->isEmpty())) { + if (!isFileParentItemValid()) { showError(tr("Could not find a file for local editing. Make sure its path is valid and it is synced locally."), _relPath); return; } @@ -269,17 +269,27 @@ void EditLocallyJob::startSyncBeforeOpening() // connect to a SyncEngine::itemDiscovered so we can complete the job as soon as the file in question is discovered QObject::connect(&_folderForFile->syncEngine(), &SyncEngine::itemDiscovered, this, &EditLocallyJob::slotItemDiscovered); - _folderForFile->syncEngine().setSingleItemDiscoveryOptions({_relPathParent == QStringLiteral("/") ? QString{} : _relPathParent, _relativePathToRemoteRoot, _fileParentItem}); + _folderForFile->syncEngine().setSingleItemDiscoveryOptions({_relPathParent, _relativePathToRemoteRoot, _fileParentItem}); FolderMan::instance()->forceSyncForFolder(_folderForFile); } bool EditLocallyJob::eraseBlacklistRecordForItem() { - if (!_folderForFile || !_fileParentItem) { + if (!_folderForFile || !isFileParentItemValid()) { qCWarning(lcEditLocallyJob) << "_folderForFile or _fileParentItem is invalid!"; return false; } + if (!_fileParentItem && _relPathParent == QStringLiteral("/")) { + return true; + } + + Q_ASSERT(_fileParentItem); + if (!_fileParentItem) { + qCWarning(lcEditLocallyJob) << "_fileParentItem is invalid!"; + return false; + } + Q_ASSERT(!_folderForFile->isSyncRunning()); if (_folderForFile->isSyncRunning()) { qCWarning(lcEditLocallyJob) << "_folderForFile is syncing"; @@ -622,9 +632,7 @@ void EditLocallyJob::lockFile() }; const auto runSingleFileDiscovery = [this] { - const SyncEngine::SingleItemDiscoveryOptions singleItemDiscoveryOptions = {(_relPathParent == QStringLiteral("/") ? QString{} : _relPathParent), - _relativePathToRemoteRoot, - _fileParentItem}; + const SyncEngine::SingleItemDiscoveryOptions singleItemDiscoveryOptions = {_relPathParent, _relativePathToRemoteRoot, _fileParentItem}; _folderForFile->syncEngine().setSingleItemDiscoveryOptions(singleItemDiscoveryOptions); FolderMan::instance()->forceSyncForFolder(_folderForFile); }; @@ -704,4 +712,9 @@ int EditLocallyJob::fileLockTimeRemainingMinutes(const qint64 lockTime, const qi return remainingTimeInMinutes; } +bool EditLocallyJob::isFileParentItemValid() const +{ + return (_fileParentItem && !_fileParentItem->isEmpty()) || _relPathParent == QStringLiteral("/"); +} + } diff --git a/src/gui/editlocallyjob.h b/src/gui/editlocallyjob.h index 06364fba96..e778cf4a8c 100644 --- a/src/gui/editlocallyjob.h +++ b/src/gui/editlocallyjob.h @@ -90,6 +90,8 @@ private: [[nodiscard]] static int fileLockTimeRemainingMinutes(const qint64 lockTime, const qint64 lockTimeOut); + [[nodiscard]] bool isFileParentItemValid() const; + bool _tokenVerified = false; bool _shouldScheduleFolderSyncAfterFileIsOpened = false; diff --git a/src/gui/folder.cpp b/src/gui/folder.cpp index 96b26798f0..b16d0daf6e 100644 --- a/src/gui/folder.cpp +++ b/src/gui/folder.cpp @@ -911,8 +911,7 @@ void Folder::startSync(const QStringList &pathList) fullLocalDiscoveryInterval.count() >= 0 // negative means we don't require periodic full runs && _timeSinceLastFullLocalDiscovery.hasExpired(fullLocalDiscoveryInterval.count()); - if (!singleItemDiscoveryOptions.filePathRelative.isEmpty() - && singleItemDiscoveryOptions.discoveryDirItem && !singleItemDiscoveryOptions.discoveryDirItem->isEmpty()) { + if (singleItemDiscoveryOptions.isValid() && singleItemDiscoveryOptions.discoveryPath != QStringLiteral("/")) { qCInfo(lcFolder) << "Going to sync just one file"; _engine->setLocalDiscoveryOptions(LocalDiscoveryStyle::DatabaseAndFilesystem, {singleItemDiscoveryOptions.discoveryPath}); _localDiscoveryTracker->startSyncPartialDiscovery(); diff --git a/src/libsync/syncengine.cpp b/src/libsync/syncengine.cpp index f9a834d9ea..e8ec169d7d 100644 --- a/src/libsync/syncengine.cpp +++ b/src/libsync/syncengine.cpp @@ -123,6 +123,12 @@ SyncEngine::~SyncEngine() _excludedFiles.reset(); } +bool SyncEngine::SingleItemDiscoveryOptions::isValid() const +{ + return !filePathRelative.isEmpty() && !discoveryPath.isEmpty() + && ((discoveryDirItem && !discoveryDirItem->isEmpty()) || discoveryPath == QStringLiteral("/")); +} + /** * Check if the item is in the blacklist. * If it should not be sync'ed because of the blacklist, update the item with the error instruction @@ -658,12 +664,12 @@ void SyncEngine::startSync() ProcessDirectoryJob *discoveryJob = nullptr; - if (!singleItemDiscoveryOptions().filePathRelative.isEmpty()) { + if (singleItemDiscoveryOptions().isValid()) { _discoveryPhase->_listExclusiveFiles.clear(); _discoveryPhase->_listExclusiveFiles.push_back(singleItemDiscoveryOptions().filePathRelative); } - if (!singleItemDiscoveryOptions().discoveryPath.isEmpty() && singleItemDiscoveryOptions().discoveryDirItem) { + if (singleItemDiscoveryOptions().isValid() && singleItemDiscoveryOptions().discoveryDirItem) { ProcessDirectoryJob::PathTuple path = {}; path._local = path._original = path._server = path._target = singleItemDiscoveryOptions().discoveryPath; diff --git a/src/libsync/syncengine.h b/src/libsync/syncengine.h index 1c60c60072..3db1b3f2ae 100644 --- a/src/libsync/syncengine.h +++ b/src/libsync/syncengine.h @@ -57,10 +57,12 @@ class OWNCLOUDSYNC_EXPORT SyncEngine : public QObject { Q_OBJECT public: - struct SingleItemDiscoveryOptions { + struct OWNCLOUDSYNC_EXPORT SingleItemDiscoveryOptions { QString discoveryPath; QString filePathRelative; SyncFileItemPtr discoveryDirItem; + + [[nodiscard]] bool isValid() const; }; SyncEngine(AccountPtr account,