Skip to content

Commit

Permalink
Set VFS PinState to Excluded for ignored files.
Browse files Browse the repository at this point in the history
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

Signed-off-by: Dries Mys <[email protected]>
  • Loading branch information
m7913d authored and mgallien committed Jul 7, 2023
1 parent eea254b commit ae2ce45
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 16 deletions.
7 changes: 7 additions & 0 deletions src/common/pinstate.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
29 changes: 29 additions & 0 deletions src/gui/folder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,21 @@ void Folder::slotWatchedPathChanged(const QString &path, ChangeReason reason)

auto relativePath = path.midRef(this->path().size());

if (pathIsIgnored(path)) {
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 {
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
Expand Down Expand Up @@ -806,6 +821,20 @@ void Folder::removeFromSettings() const
settings->remove(FolderMan::escapeAlias(_definition.alias));
}

bool Folder::pathIsIgnored(const QString &path)
{
if (path.isEmpty())
return true;

#ifndef OWNCLOUD_TEST
if (isFileExcludedAbsolute(path) && !Utility::isConflictFile(path)) {
qCDebug(lcFolderWatcher) << "* Ignoring file" << path;
return true;
}
#endif
return false;
}

bool Folder::isFileExcludedAbsolute(const QString &fullPath) const
{
return _engine->excludedFiles().isExcluded(fullPath, path(), _definition.ignoreHiddenFiles);
Expand Down
3 changes: 3 additions & 0 deletions src/gui/folder.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,9 @@ class Folder : public QObject
/// Removes the folder from the account's settings.
void removeFromSettings() const;

/* Check if the path is ignored. */
bool pathIsIgnored(const QString &path);

/**
* Returns whether a file inside this folder should be excluded.
*/
Expand Down
13 changes: 1 addition & 12 deletions src/gui/folderwatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,7 @@ void FolderWatcher::init(const QString &root)

bool FolderWatcher::pathIsIgnored(const QString &path)
{
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
Expand Down
6 changes: 3 additions & 3 deletions src/gui/folderwatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,6 @@ class FolderWatcher : public QObject
*/
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.
Expand Down Expand Up @@ -135,6 +132,9 @@ private slots:
QString possiblyAddUnlockedFilePath(const QString &path);
QString findMatchingUnlockedFileInDir(const QString &dirPath, const QString &lockFileName);

/* Check if the path should be igored by the FolderWatcher. */
bool pathIsIgnored(const QString &path);

/** Path of the expected test notification */
QString _testNotificationPath;

Expand Down
4 changes: 4 additions & 0 deletions src/libsync/vfs/cfapi/cfapiwrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
16 changes: 15 additions & 1 deletion src/libsync/vfs/cfapi/vfs_cfapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.";
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)) {
Expand Down Expand Up @@ -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 {
Expand All @@ -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 auto info = cfapi::findPlaceholderInfo(localPath);
if (!info) {
qCWarning(lcCfApi) << "Couldn't find pin state for regular non-placeholder file" << localPath;
Expand Down
3 changes: 3 additions & 0 deletions src/libsync/vfs/cfapi/vfs_cfapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ public slots:
void onHydrationJobFinished(HydrationJob *job);
HydrationJob *findHydrationJob(const QString &requestId) const;

bool setPinStateLocal(const QString &localPath, PinState state);
Optional<PinState> pinStateLocal(const QString &localPath);

struct HasHydratedDehydrated {
bool hasHydrated = false;
bool hasDehydrated = false;
Expand Down

0 comments on commit ae2ce45

Please sign in to comment.