]> dgit.raspbian.org Git - nextcloud-desktop.git/commitdiff
Set VFS PinState to Excluded for ignored files.
authorDries Mys <dries.mys@my-dreams.be>
Sun, 2 Jul 2023 17:05:37 +0000 (19:05 +0200)
committerMatthieu Gallien <matthieu_gallien@yahoo.fr>
Thu, 20 Jul 2023 11:44:55 +0000 (13:44 +0200)
Setting PinState to Excluded ensures the syncing icon is not shown for ignored items.
If the PinState is not set to Excluded, also all parent directories are shown as being synced, which is very inconvenient for the end user as it seems that some folder are never fully synced by Nextcloud which isn't the case.
As long as .lnk files are not converted to placeholder files, also set them to Excluded to hide the syncing icon.

Closes #5524
Closes #5594

Co-authored-by: Matthieu Gallien <matthieu_gallien@yahoo.fr>
Signed-off-by: Dries Mys <dries.mys@my-dreams.be>
src/common/pinstate.h
src/gui/folder.cpp
src/gui/folder.h
src/gui/folderwatcher.cpp
src/gui/folderwatcher.h
src/libsync/vfs/cfapi/cfapiwrapper.cpp
src/libsync/vfs/cfapi/vfs_cfapi.cpp
src/libsync/vfs/cfapi/vfs_cfapi.h

index 7d4222a01ccc8bd79d309734995f75867972e726..d2bc9f11ba00117780e496c61c1a8843081edbcf 100644 (file)
@@ -75,6 +75,13 @@ enum class PinState {
      * dehydrated (which is an arbitrary decision).
      */
     Unspecified = 3,
+
+    /** The file will never be synced to the cloud.
+     * 
+     * Usefull for ignored files to indicate to the OS the file will never be
+     * synced
+     */
+    Excluded = 4,
 };
 Q_ENUM_NS(PinState)
 
index 31542c6bc9f6da087afab5bc05e1409918920885..664054a37f2ad44a25ba2eb9af157b90e445105f 100644 (file)
@@ -561,6 +561,21 @@ void Folder::slotWatchedPathChanged(const QString &path, ChangeReason reason)
 
     auto relativePath = path.midRef(this->path().size());
 
+    if (pathIsIgnored(path)) {
+        const auto pinState = _vfs->pinState(relativePath.toString());
+        if (!pinState || *pinState != PinState::Excluded) {
+            if (!_vfs->setPinState(relativePath.toString(), PinState::Excluded))
+                qCWarning(lcFolder) << "Could not set pin state of" << relativePath << "to excluded";
+        }
+        return;
+    } else {
+        const auto pinState = _vfs->pinState(relativePath.toString());
+        if (pinState && *pinState == PinState::Excluded) {
+            if (!_vfs->setPinState(relativePath.toString(), PinState::Inherited))
+                qCWarning(lcFolder) << "Could not switch pin state of" << relativePath << "from" << *pinState << "to inherited";
+        }
+    }
+
     // Add to list of locally modified paths
     //
     // We do this before checking for our own sync-related changes to make
@@ -806,6 +821,21 @@ void Folder::removeFromSettings() const
     settings->remove(FolderMan::escapeAlias(_definition.alias));
 }
 
+bool Folder::pathIsIgnored(const QString &path) const
+{
+    if (path.isEmpty()) {
+        return true;
+    }
+
+#ifndef OWNCLOUD_TEST
+    if (isFileExcludedAbsolute(path) && !Utility::isConflictFile(path)) {
+        qCDebug(lcFolder) << "* Ignoring file" << path;
+        return true;
+    }
+#endif
+    return false;
+}
+
 bool Folder::isFileExcludedAbsolute(const QString &fullPath) const
 {
     return _engine->excludedFiles().isExcluded(fullPath, path(), _definition.ignoreHiddenFiles);
index 9d654baed92585d3a3befafabc48f1fa30acd32f..cac47809ba112c38ee587b92ff402b05002eeec9 100644 (file)
@@ -233,6 +233,9 @@ public:
     /// Removes the folder from the account's settings.
     void removeFromSettings() const;
 
+    /* Check if the path is ignored. */
+    [[nodiscard]] bool pathIsIgnored(const QString &path) const;
+
     /**
       * Returns whether a file inside this folder should be excluded.
       */
index 3d1f73cba3d478eeb0338fcb803ca0185122f34c..b050af74cfc000440fe7dd855ee14070a69e11d7 100644 (file)
@@ -66,20 +66,9 @@ void FolderWatcher::init(const QString &root)
     _timer.start();
 }
 
-bool FolderWatcher::pathIsIgnored(const QString &path)
+bool FolderWatcher::pathIsIgnored(const QString &path) const
 {
-    if (path.isEmpty())
-        return true;
-    if (!_folder)
-        return false;
-
-#ifndef OWNCLOUD_TEST
-    if (_folder->isFileExcludedAbsolute(path) && !Utility::isConflictFile(path)) {
-        qCDebug(lcFolderWatcher) << "* Ignoring file" << path;
-        return true;
-    }
-#endif
-    return false;
+    return path.isEmpty();
 }
 
 bool FolderWatcher::isReliable() const
index 3403fabbda032dc86c85ee6139c04fda5bd22917..0e7b50cee641f08fd9ebf8d1109c570989cc0cb3 100644 (file)
@@ -60,9 +60,6 @@ public:
      */
     void init(const QString &root);
 
-    /* Check if the path is ignored. */
-    bool pathIsIgnored(const QString &path);
-
     /**
      * Returns false if the folder watcher can't be trusted to capture all
      * notifications.
@@ -135,6 +132,9 @@ private:
     QString possiblyAddUnlockedFilePath(const QString &path);
     QString findMatchingUnlockedFileInDir(const QString &dirPath, const QString &lockFileName);
 
+    /* Check if the path should be igored by the FolderWatcher. */
+    [[nodiscard]] bool pathIsIgnored(const QString &path) const;
+
     /** Path of the expected test notification */
     QString _testNotificationPath;
 
index 8045c61487a0d925664facfea1149abe6bb51f56..1849deb74bed2b8d45b7bfe18d8dd5ec71fc708e 100644 (file)
@@ -292,6 +292,8 @@ OCC::PinState cfPinStateToPinState(CF_PIN_STATE state)
         return OCC::PinState::OnlineOnly;
     case CF_PIN_STATE_INHERIT:
         return OCC::PinState::Inherited;
+    case CF_PIN_STATE_EXCLUDED:
+        return OCC::PinState::Excluded;
     default:
         Q_UNREACHABLE();
         return OCC::PinState::Inherited;
@@ -309,6 +311,8 @@ CF_PIN_STATE pinStateToCfPinState(OCC::PinState state)
         return CF_PIN_STATE_UNPINNED;
     case OCC::PinState::Unspecified:
         return CF_PIN_STATE_UNSPECIFIED;
+    case OCC::PinState::Excluded:
+        return CF_PIN_STATE_EXCLUDED;
     default:
         Q_UNREACHABLE();
         return CF_PIN_STATE_UNSPECIFIED;
index a259ef9222be93d49e0f3dc8f95ca7f95856647c..9c32cc82937b1c1a59f073fe262f0a9331a72e11 100644 (file)
@@ -224,12 +224,16 @@ Result<void, QString> VfsCfApi::dehydratePlaceholder(const SyncFileItem &item)
 
 Result<Vfs::ConvertToPlaceholderResult, QString> VfsCfApi::convertToPlaceholder(const QString &filename, const SyncFileItem &item, const QString &replacesFile)
 {
+    const auto localPath = QDir::toNativeSeparators(filename);
+
     if (item._type != ItemTypeDirectory && OCC::FileSystem::isLnkFile(filename)) {
         qCInfo(lcCfApi) << "File \"" << filename << "\" is a Windows shortcut. Not converting it to a placeholder.";
+        const auto pinState = pinStateLocal(localPath);
+        if (!pinState || *pinState != PinState::Excluded)
+            setPinStateLocal(localPath, PinState::Excluded);
         return Vfs::ConvertToPlaceholderResult::Ok;
     }
 
-    const auto localPath = QDir::toNativeSeparators(filename);
     const auto replacesPath = QDir::toNativeSeparators(replacesFile);
 
     if (cfapi::findPlaceholderInfo(localPath)) {
@@ -293,6 +297,11 @@ bool VfsCfApi::setPinState(const QString &folderPath, PinState state)
 
     const auto localPath = QDir::toNativeSeparators(params().filesystemPath + folderPath);
 
+    return setPinStateLocal(localPath, state);
+}
+
+bool VfsCfApi::setPinStateLocal(const QString &localPath, PinState state)
+{
     if (cfapi::setPinState(localPath, state, cfapi::Recurse)) {
         return true;
     } else {
@@ -304,6 +313,11 @@ Optional<PinState> VfsCfApi::pinState(const QString &folderPath)
 {
     const auto localPath = QDir::toNativeSeparators(params().filesystemPath + folderPath);
 
+    return pinStateLocal(localPath);
+}
+
+Optional<PinState> VfsCfApi::pinStateLocal(const QString &localPath) const
+{
     const auto info = cfapi::findPlaceholderInfo(localPath);
     if (!info) {
         qCWarning(lcCfApi) << "Couldn't find pin state for regular non-placeholder file" << localPath;
index 3803bf14852213870c167600f7f752882b63d556..b675ae389f0e7b9947fd5b4638f292bcaae18b54 100644 (file)
@@ -76,6 +76,9 @@ private:
     void onHydrationJobFinished(HydrationJob *job);
     HydrationJob *findHydrationJob(const QString &requestId) const;
 
+    bool setPinStateLocal(const QString &localPath, PinState state);
+    [[nodiscard]] Optional<PinState> pinStateLocal(const QString &localPath) const;
+
     struct HasHydratedDehydrated {
         bool hasHydrated = false;
         bool hasDehydrated = false;