Просмотр исходного кода

Merge pull request #5904 from nextcloud/backport/5853/stable-3.9

[stable-3.9] Set VFS PinState to Excluded for ignored files.
Matthieu Gallien 2 лет назад
Родитель
Сommit
f8dae64020

+ 7 - 0
src/common/pinstate.h

@@ -75,6 +75,13 @@ enum class PinState {
      * dehydrated (which is an arbitrary decision).
      * dehydrated (which is an arbitrary decision).
      */
      */
     Unspecified = 3,
     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)
 Q_ENUM_NS(PinState)
 
 

+ 32 - 0
src/gui/folder.cpp

@@ -561,6 +561,23 @@ void Folder::slotWatchedPathChanged(const QString &path, ChangeReason reason)
 
 
     auto relativePath = path.midRef(this->path().size());
     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
     // Add to list of locally modified paths
     //
     //
     // We do this before checking for our own sync-related changes to make
     // We do this before checking for our own sync-related changes to make
@@ -806,6 +823,21 @@ void Folder::removeFromSettings() const
     settings->remove(FolderMan::escapeAlias(_definition.alias));
     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
 bool Folder::isFileExcludedAbsolute(const QString &fullPath) const
 {
 {
     return _engine->excludedFiles().isExcluded(fullPath, path(), _definition.ignoreHiddenFiles);
     return _engine->excludedFiles().isExcluded(fullPath, path(), _definition.ignoreHiddenFiles);

+ 3 - 0
src/gui/folder.h

@@ -233,6 +233,9 @@ public:
     /// Removes the folder from the account's settings.
     /// Removes the folder from the account's settings.
     void removeFromSettings() const;
     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.
       * Returns whether a file inside this folder should be excluded.
       */
       */

+ 2 - 13
src/gui/folderwatcher.cpp

@@ -66,20 +66,9 @@ void FolderWatcher::init(const QString &root)
     _timer.start();
     _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
 bool FolderWatcher::isReliable() const

+ 3 - 3
src/gui/folderwatcher.h

@@ -60,9 +60,6 @@ public:
      */
      */
     void init(const QString &root);
     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
      * Returns false if the folder watcher can't be trusted to capture all
      * notifications.
      * notifications.
@@ -135,6 +132,9 @@ private:
     QString possiblyAddUnlockedFilePath(const QString &path);
     QString possiblyAddUnlockedFilePath(const QString &path);
     QString findMatchingUnlockedFileInDir(const QString &dirPath, const QString &lockFileName);
     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 */
     /** Path of the expected test notification */
     QString _testNotificationPath;
     QString _testNotificationPath;
 
 

+ 4 - 0
src/libsync/vfs/cfapi/cfapiwrapper.cpp

@@ -292,6 +292,8 @@ OCC::PinState cfPinStateToPinState(CF_PIN_STATE state)
         return OCC::PinState::OnlineOnly;
         return OCC::PinState::OnlineOnly;
     case CF_PIN_STATE_INHERIT:
     case CF_PIN_STATE_INHERIT:
         return OCC::PinState::Inherited;
         return OCC::PinState::Inherited;
+    case CF_PIN_STATE_EXCLUDED:
+        return OCC::PinState::Excluded;
     default:
     default:
         Q_UNREACHABLE();
         Q_UNREACHABLE();
         return OCC::PinState::Inherited;
         return OCC::PinState::Inherited;
@@ -309,6 +311,8 @@ CF_PIN_STATE pinStateToCfPinState(OCC::PinState state)
         return CF_PIN_STATE_UNPINNED;
         return CF_PIN_STATE_UNPINNED;
     case OCC::PinState::Unspecified:
     case OCC::PinState::Unspecified:
         return CF_PIN_STATE_UNSPECIFIED;
         return CF_PIN_STATE_UNSPECIFIED;
+    case OCC::PinState::Excluded:
+        return CF_PIN_STATE_EXCLUDED;
     default:
     default:
         Q_UNREACHABLE();
         Q_UNREACHABLE();
         return CF_PIN_STATE_UNSPECIFIED;
         return CF_PIN_STATE_UNSPECIFIED;

+ 17 - 2
src/libsync/vfs/cfapi/vfs_cfapi.cpp

@@ -224,12 +224,17 @@ Result<void, QString> VfsCfApi::dehydratePlaceholder(const SyncFileItem &item)
 
 
 Result<Vfs::ConvertToPlaceholderResult, QString> VfsCfApi::convertToPlaceholder(const QString &filename, const SyncFileItem &item, const QString &replacesFile)
 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)) {
     if (item._type != ItemTypeDirectory && OCC::FileSystem::isLnkFile(filename)) {
         qCInfo(lcCfApi) << "File \"" << filename << "\" is a Windows shortcut. Not converting it to a placeholder.";
         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;
         return Vfs::ConvertToPlaceholderResult::Ok;
     }
     }
 
 
-    const auto localPath = QDir::toNativeSeparators(filename);
     const auto replacesPath = QDir::toNativeSeparators(replacesFile);
     const auto replacesPath = QDir::toNativeSeparators(replacesFile);
 
 
     if (cfapi::findPlaceholderInfo(localPath)) {
     if (cfapi::findPlaceholderInfo(localPath)) {
@@ -293,6 +298,11 @@ bool VfsCfApi::setPinState(const QString &folderPath, PinState state)
 
 
     const auto localPath = QDir::toNativeSeparators(params().filesystemPath + folderPath);
     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)) {
     if (cfapi::setPinState(localPath, state, cfapi::Recurse)) {
         return true;
         return true;
     } else {
     } else {
@@ -304,9 +314,14 @@ Optional<PinState> VfsCfApi::pinState(const QString &folderPath)
 {
 {
     const auto localPath = QDir::toNativeSeparators(params().filesystemPath + 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);
     const auto info = cfapi::findPlaceholderInfo(localPath);
     if (!info) {
     if (!info) {
-        qCWarning(lcCfApi) << "Couldn't find pin state for regular non-placeholder file" << localPath;
+        qCDebug(lcCfApi) << "Couldn't find pin state for regular non-placeholder file" << localPath;
         return {};
         return {};
     }
     }
 
 

+ 3 - 0
src/libsync/vfs/cfapi/vfs_cfapi.h

@@ -76,6 +76,9 @@ private:
     void onHydrationJobFinished(HydrationJob *job);
     void onHydrationJobFinished(HydrationJob *job);
     HydrationJob *findHydrationJob(const QString &requestId) const;
     HydrationJob *findHydrationJob(const QString &requestId) const;
 
 
+    bool setPinStateLocal(const QString &localPath, PinState state);
+    [[nodiscard]] Optional<PinState> pinStateLocal(const QString &localPath) const;
+
     struct HasHydratedDehydrated {
     struct HasHydratedDehydrated {
         bool hasHydrated = false;
         bool hasHydrated = false;
         bool hasDehydrated = false;
         bool hasDehydrated = false;