Skip to content

Commit

Permalink
Merge pull request #7539 from nextcloud/backport/7375/stable-3.14
Browse files Browse the repository at this point in the history
[stable-3.14] Fix file tag fetching for files in sync folders that have non-root remote target
  • Loading branch information
mgallien authored Nov 21, 2024
2 parents 5563f9a + d9c0dc5 commit ba124c2
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 47 deletions.
46 changes: 33 additions & 13 deletions src/gui/filedetails/filedetails.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,25 +61,41 @@ void FileDetails::setLocalPath(const QString &localPath)
_fileWatcher.addPath(localPath);
connect(&_fileWatcher, &QFileSystemWatcher::fileChanged, this, &FileDetails::refreshFileDetails);

const auto folder = FolderMan::instance()->folderForPath(_localPath);
if (!folder) {
_folder = FolderMan::instance()->folderForPath(_localPath);
Q_ASSERT(_folder);
if (!_folder) {
qCWarning(lcFileDetails) << "No folder found for path:" << _localPath << "will not load file details.";
return;
}

const auto file = _localPath.mid(folder->cleanPath().length() + 1);
const auto file = _localPath.mid(_folder->cleanPath().length() + 1);

if (!folder->journalDb()->getFileRecord(file, &_fileRecord)) {
if (!_folder->journalDb()->getFileRecord(file, &_fileRecord)) {
qCWarning(lcFileDetails) << "Invalid file record for path:"
<< _localPath
<< "will not load file details.";
}

_filelockState = _fileRecord._lockstate;
updateLockExpireString();
updateFileTagModel(folder);

_sharingAvailable = folder->accountState()->account()->capabilities().shareAPI();
const auto accountState = _folder->accountState();
Q_ASSERT(accountState);
if (!accountState) {
qCWarning(lcFileDetails) << "No account state found for path:" << _localPath << "will not correctly load file details.";
return;
}

const auto account = accountState->account();
Q_ASSERT(account);
if (!account) {
qCWarning(lcFileDetails) << "No account found for path:" << _localPath << "will not correctly load file details.";
return;
}

_sharingAvailable = account->capabilities().shareAPI();

updateFileTagModel();

Q_EMIT fileChanged();
}
Expand Down Expand Up @@ -167,15 +183,19 @@ FileTagModel *FileDetails::fileTagModel() const
return _fileTagModel.get();
}

void FileDetails::updateFileTagModel(const Folder * const folder)
void FileDetails::updateFileTagModel()
{
Q_ASSERT(folder);
const auto account = folder->accountState()->account();
Q_ASSERT(account);

const auto serverRelPath = QString(folder->remotePathTrailingSlash() + name());
const auto localPath = _fileRecord.path();
const auto relPath = localPath.mid(_folder->cleanPath().length() + 1);
QString serverPath = _folder->remotePathTrailingSlash() + _fileRecord.path();

if (const auto vfsMode = _folder->vfs().mode(); _fileRecord.isVirtualFile() && vfsMode == Vfs::WithSuffix) {
if (const auto suffix = _folder->vfs().fileSuffix(); !suffix.isEmpty() && serverPath.endsWith(suffix)) {
serverPath.chop(suffix.length());
}
}

_fileTagModel = std::make_unique<FileTagModel>(serverRelPath, account);
_fileTagModel = std::make_unique<FileTagModel>(relPath, _folder->accountState()->account());
Q_EMIT fileTagModelChanged();
}

Expand Down
3 changes: 2 additions & 1 deletion src/gui/filedetails/filedetails.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,14 @@ public slots:
private slots:
void refreshFileDetails();
void updateLockExpireString();
void updateFileTagModel(const OCC::Folder * const folder);
void updateFileTagModel();

private:
QString _localPath;

QFileInfo _fileInfo;
QFileSystemWatcher _fileWatcher;
Folder *_folder = nullptr;
SyncJournalFileRecord _fileRecord;
SyncJournalFileLockInfo _filelockState;
QByteArray _numericFileId;
Expand Down
4 changes: 3 additions & 1 deletion src/gui/filetagmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ class FileTagModel : public QAbstractListModel
Q_PROPERTY(QString overflowTagsString READ overflowTagsString NOTIFY overflowTagsStringChanged)

public:
explicit FileTagModel(const QString &serverRelativePath, const AccountPtr &account, QObject * const parent = nullptr);
explicit FileTagModel(const QString &serverRelativePath,
const AccountPtr &account,
QObject *const parent = nullptr);

[[nodiscard]] int rowCount(const QModelIndex &parent = QModelIndex()) const override;
[[nodiscard]] QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
Expand Down
64 changes: 32 additions & 32 deletions src/gui/folder.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,79 +128,79 @@ class Folder : public QObject
/**
* The account the folder is configured on.
*/
AccountState *accountState() const { return _accountState.data(); }
[[nodiscard]] AccountState *accountState() const { return _accountState.data(); }

/**
* alias or nickname
*/
QString alias() const;
QString shortGuiRemotePathOrAppName() const; // since 2.0 we don't want to show aliases anymore, show the path instead
[[nodiscard]] QString alias() const;
[[nodiscard]] QString shortGuiRemotePathOrAppName() const; // since 2.0 we don't want to show aliases anymore, show the path instead

/**
* short local path to display on the GUI (native separators)
*/
QString shortGuiLocalPath() const;
[[nodiscard]] QString shortGuiLocalPath() const;

/**
* canonical local folder path, always ends with /
*/
QString path() const;
[[nodiscard]] QString path() const;

/**
* cleaned canonical folder path, like path() but never ends with a /
*
* Wrapper for QDir::cleanPath(path()) except for "Z:/",
* where it returns "Z:" instead of "Z:/".
*/
QString cleanPath() const;
[[nodiscard]] QString cleanPath() const;

/**
* remote folder path, usually without trailing /, exception "/"
*/
QString remotePath() const;
[[nodiscard]] QString remotePath() const;

/**
* remote folder path, always with a trailing /
*/
QString remotePathTrailingSlash() const;
[[nodiscard]] QString remotePathTrailingSlash() const;

[[nodiscard]] QString fulllRemotePathToPathInSyncJournalDb(const QString &fullRemotePath) const;

void setNavigationPaneClsid(const QUuid &clsid) { _definition.navigationPaneClsid = clsid; }
QUuid navigationPaneClsid() const { return _definition.navigationPaneClsid; }
[[nodiscard]] QUuid navigationPaneClsid() const { return _definition.navigationPaneClsid; }

/**
* remote folder path with server url
*/
QUrl remoteUrl() const;
[[nodiscard]] QUrl remoteUrl() const;

/**
* switch sync on or off
*/
void setSyncPaused(bool);

bool syncPaused() const;
[[nodiscard]] bool syncPaused() const;

/**
* Returns true when the folder may sync.
*/
bool canSync() const;
[[nodiscard]] bool canSync() const;

void prepareToSync();

/**
* True if the folder is busy and can't initiate
* a synchronization
*/
virtual bool isBusy() const;
[[nodiscard]] virtual bool isBusy() const;

/** True if the folder is currently synchronizing */
bool isSyncRunning() const;
[[nodiscard]] bool isSyncRunning() const;

/**
* return the last sync result with error message and status
*/
SyncResult syncResult() const;
[[nodiscard]] SyncResult syncResult() const;

/**
* This is called when the sync folder definition is removed. Do cleanups here.
Expand All @@ -219,19 +219,19 @@ class Folder : public QObject
* Ignore syncing of hidden files or not. This is defined in the
* folder definition
*/
bool ignoreHiddenFiles();
[[nodiscard]] bool ignoreHiddenFiles();
void setIgnoreHiddenFiles(bool ignore);

// Used by the Socket API
SyncJournalDb *journalDb() { return &_journal; }
SyncEngine &syncEngine() { return *_engine; }
Vfs &vfs() { return *_vfs; }
[[nodiscard]] SyncJournalDb *journalDb() const { return &_journal; }
[[nodiscard]] SyncEngine &syncEngine() const { return *_engine; }
[[nodiscard]] Vfs &vfs() const { return *_vfs; }

RequestEtagJob *etagJob() { return _requestEtagJob; }
std::chrono::milliseconds msecSinceLastSync() const { return std::chrono::milliseconds(_timeSinceLastSyncDone.elapsed()); }
std::chrono::milliseconds msecLastSyncDuration() const { return _lastSyncDuration; }
int consecutiveFollowUpSyncs() const { return _consecutiveFollowUpSyncs; }
int consecutiveFailingSyncs() const { return _consecutiveFailingSyncs; }
[[nodiscard]] RequestEtagJob *etagJob() const { return _requestEtagJob; }
[[nodiscard]] std::chrono::milliseconds msecSinceLastSync() const { return std::chrono::milliseconds(_timeSinceLastSyncDone.elapsed()); }
[[nodiscard]] std::chrono::milliseconds msecLastSyncDuration() const { return _lastSyncDuration; }
[[nodiscard]] int consecutiveFollowUpSyncs() const { return _consecutiveFollowUpSyncs; }
[[nodiscard]] int consecutiveFailingSyncs() const { return _consecutiveFailingSyncs; }

/// Saves the folder data in the account's settings.
void saveToSettings() const;
Expand All @@ -244,12 +244,12 @@ class Folder : public QObject
/**
* Returns whether a file inside this folder should be excluded.
*/
bool isFileExcludedAbsolute(const QString &fullPath) const;
[[nodiscard]] bool isFileExcludedAbsolute(const QString &fullPath) const;

/**
* Returns whether a file inside this folder should be excluded.
*/
bool isFileExcludedRelative(const QString &relativePath) const;
[[nodiscard]] bool isFileExcludedRelative(const QString &relativePath) const;

/** Calls schedules this folder on the FolderMan after a short delay.
*
Expand Down Expand Up @@ -288,23 +288,23 @@ class Folder : public QObject
* and never have an automatic virtual file. But when it's on, the shell context menu will allow
* users to make existing files virtual.
*/
bool virtualFilesEnabled() const;
[[nodiscard]] bool virtualFilesEnabled() const;
void setVirtualFilesEnabled(bool enabled);

void setRootPinState(PinState state);

/** Whether user desires a switch that couldn't be executed yet, see member */
bool isVfsOnOffSwitchPending() const { return _vfsOnOffPending; }
[[nodiscard]] bool isVfsOnOffSwitchPending() const { return _vfsOnOffPending; }
void setVfsOnOffSwitchPending(bool pending) { _vfsOnOffPending = pending; }

void switchToVirtualFiles();

void processSwitchedToVirtualFiles();

/** Whether this folder should show selective sync ui */
bool supportsSelectiveSync() const;
[[nodiscard]] bool supportsSelectiveSync() const;

QString fileFromLocalPath(const QString &localPath) const;
[[nodiscard]] QString fileFromLocalPath(const QString &localPath) const;

void whitelistPath(const QString &path);
void blacklistPath(const QString &path);
Expand Down Expand Up @@ -347,9 +347,9 @@ public slots:
void startSync(const QStringList &pathList = QStringList());

int slotDiscardDownloadProgress();
int downloadInfoCount();
[[nodiscard]] int downloadInfoCount();
int slotWipeErrorBlacklist();
int errorBlackListEntryCount();
[[nodiscard]] int errorBlackListEntryCount();

/**
* Triggered by the folder watcher when a file/dir in this folder
Expand Down

0 comments on commit ba124c2

Please sign in to comment.