fix(folder): rename VFS folders using same pattern of sync folders.

- Migrate vfs mode from config and load cfapi plugin for the folder.
- Move rename logic to Utility class.

Signed-off-by: Camila Ayres <hello@camilasan.com>
This commit is contained in:
Camila Ayres 2025-07-19 19:42:53 +02:00
parent 1cc9f689c4
commit ec74f8d274
No known key found for this signature in database
GPG Key ID: 7A4A6121E88E2AD4
4 changed files with 27 additions and 13 deletions

View File

@ -63,9 +63,8 @@ namespace Utility {
* @brief Migrate favorite link for sync folder with new application name and icon
*
* @param folder absolute file path to folder
* @param lnkName the new name of the lnk file
*/
OCSYNC_EXPORT void migrateFavLink(const QString &folder, const QString &lnkName = QString());
OCSYNC_EXPORT void migrateFavLink(const QString &folder);
/**
* @brief Creates or overwrite the Desktop.ini file to use new folder IconResource shown as a favorite link
*
@ -79,6 +78,14 @@ namespace Utility {
* @param folder absolute file path to folder
*/
OCSYNC_EXPORT void removeFavLink(const QString &folder);
/**
* @brief Return the display name of a folder - to be used in fav links and sync root name (VFS).x
* e.g. Nextcloud1 will become NewAppName1, NewAppName2 or FolderName will be kept as is.
*
* @param currentDisplayName current folder display name string
* @param newName new name to be used for the folder
*/
OCSYNC_EXPORT QString syncFolderDisplayName(const QString &currentDisplayName, const QString &newName);
// convenience system path to links folder
OCSYNC_EXPORT QString systemPathToLinks();

View File

@ -514,9 +514,13 @@ void Folder::startVfs()
return;
}
const auto displayName = QStringLiteral("%1 - %2").arg(Utility::syncFolderDisplayName(shortGuiLocalPath(),
Theme::instance()->appNameGUI()),
accountState()->account()->shortcutName());
qCDebug(lcFolder) << "Display name for VFS folder will be:" << displayName;
VfsSetupParams vfsParams;
vfsParams.filesystemPath = path();
vfsParams.displayName = shortGuiRemotePathOrAppName();
vfsParams.displayName = displayName;
vfsParams.alias = alias();
vfsParams.navigationPaneClsid = navigationPaneClsid().toString();
vfsParams.remotePath = remotePathTrailingSlash();

View File

@ -60,14 +60,15 @@ void NavigationPaneHelper::updateCloudStorageRegistry()
// Start by looking at every registered namespace extension for the sidebar, and look for an "ApplicationName" value
// that matches ours when we saved.
QVector<QUuid> entriesToRemove;
const auto currentAppName = QLatin1String(APPLICATION_NAME);
#ifdef Q_OS_WIN
const auto nameSpaceKey = QStringLiteral(R"(Software\Microsoft\Windows\CurrentVersion\Explorer\Desktop\NameSpace)");
if (Utility::registryKeyExists(HKEY_CURRENT_USER, nameSpaceKey)) {
Utility::registryWalkSubKeys(HKEY_CURRENT_USER, nameSpaceKey,
[&entriesToRemove](HKEY key, const QString &subKey) {
[&entriesToRemove, &currentAppName](HKEY key, const QString &subKey) {
const auto appName = Utility::registryGetKeyValue(key, subKey, QStringLiteral("ApplicationName"));
qCDebug(lcNavPane) << "Searching for user with subKey:" << subKey << "for appName:" << appName.toString();
if (appName.toString() == QLatin1String(APPLICATION_NAME) || appName.toString() == unbrandedApplicationName) {
if (appName.toString() == currentAppName || appName.toString() == unbrandedApplicationName) {
QUuid clsid{ subKey };
Q_ASSERT(!clsid.isNull());
entriesToRemove.append(clsid);
@ -91,17 +92,14 @@ void NavigationPaneHelper::updateCloudStorageRegistry()
const QString clsidPath = QString() % R"(Software\Classes\CLSID\)" % clsidStr;
const QString clsidPathWow64 = QString() % R"(Software\Classes\Wow6432Node\CLSID\)" % clsidStr;
const QString namespacePath = QString() % R"(Software\Microsoft\Windows\CurrentVersion\Explorer\Desktop\NameSpace\)" % clsidStr;
const auto isRemoteRoot = folder->remotePath() == QStringLiteral("/");
const auto title = QStringLiteral("%1 - %2").arg(Utility::syncFolderDisplayName(folder->shortGuiLocalPath(), currentAppName),
folder->accountState()->account()->shortcutName());
qCDebug(lcNavPane) << "Folder" << folder->cleanPath() << "will use shortcutname" << title;
auto title = isRemoteRoot ? folder->shortGuiRemotePathOrAppName() : folder->shortGuiLocalPath();
// Write the account name in the sidebar only when using more than one account.
if (AccountManager::instance()->accounts().size() > 1 && isRemoteRoot) {
title = folder->accountState()->account()->shortcutName();
}
const auto iconPath = QDir::toNativeSeparators(qApp->applicationFilePath());
const auto targetFolderPath = QDir::toNativeSeparators(folder->cleanPath());
qCInfo(lcNavPane) << "Explorer Cloud storage provider: saving path" << targetFolderPath << "to CLSID" << clsidStr;
qCDebug(lcNavPane) << "Explorer Cloud storage provider: saving path" << targetFolderPath << "to CLSID" << clsidStr;
#ifdef Q_OS_WIN
// Steps taken from: https://msdn.microsoft.com/en-us/library/windows/desktop/dn889934%28v=vs.85%29.aspx
// Step 1: Add your CLSID and name your extension

View File

@ -576,7 +576,6 @@ bool createSyncRootRegistryKeys(const QString &providerName, const QString &fold
// syncRootId should be: [storage provider ID]![Windows SID]![Account ID]![FolderAlias] (FolderAlias is a custom part added here to be able to register multiple sync folders for the same account)
// folder registry keys go like: Nextcloud!S-1-5-21-2096452760-2617351404-2281157308-1001!user@nextcloud.lan:8080!0, Nextcloud!S-1-5-21-2096452760-2617351404-2281157308-1001!user@nextcloud.lan:8080!1, etc. for each sync folder
const auto syncRootId = QStringLiteral("%1!%2!%3!%4").arg(providerName).arg(windowsSid).arg(accountDisplayName).arg(folderAlias);
const QString providerSyncRootIdRegistryKey = syncRootManagerRegKey + QStringLiteral("\\") + syncRootId;
const QString providerSyncRootIdUserSyncRootsRegistryKey = providerSyncRootIdRegistryKey + QStringLiteral(R"(\UserSyncRoots\)");
@ -589,6 +588,8 @@ bool createSyncRootRegistryKeys(const QString &providerName, const QString &fold
const auto flags = OCC::Theme::instance()->enforceVirtualFilesSyncFolder() ? syncRootFlagsNoCfApiContextMenu : syncRootFlagsFull;
qCDebug(lcCfApiWrapper) << "syncRootPath" << syncRootPath << " will use DisplayNameResource" << displayName;
const QVector<RegistryKeyInfo> registryKeysToSet = {
{ providerSyncRootIdRegistryKey, QStringLiteral("Flags"), REG_DWORD, flags },
{ providerSyncRootIdRegistryKey, QStringLiteral("DisplayNameResource"), REG_EXPAND_SZ, displayName },
@ -606,6 +607,10 @@ bool createSyncRootRegistryKeys(const QString &providerName, const QString &fold
Q_ASSERT(!deleteKeyResult);
return false;
}
qCDebug(lcCfApiWrapper) << "Registering keys - subKey:" << registryKeyToSet.subKey
<< " - valueName:" << registryKeyToSet.valueName
<< " - type:" << registryKeyToSet.type
<< " - value:" << registryKeyToSet.value.toString();
}
qCInfo(lcCfApiWrapper) << "Successfully set Registry keys for shell integration at:" << providerSyncRootIdRegistryKey << ". Progress bar will work.";