Skip to content

Commit

Permalink
Rename a folder's navigationPaneClsid to uuid
Browse files Browse the repository at this point in the history
So we can use it not only on Windows, but also on macOS.

`WinVfsSettingsVersion` has been removed, and for VFS and non-VFS cases
the `SettingsVersion` is used.
  • Loading branch information
erikjv committed Dec 2, 2021
1 parent 136e0d6 commit b8d9aa9
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 63 deletions.
2 changes: 1 addition & 1 deletion src/gui/accountsettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ void AccountSettings::slotFolderWizardAccepted()

#ifdef Q_OS_WIN
if (folderMan->navigationPaneHelper().showInExplorerNavigationPane())
definition.navigationPaneClsid = QUuid::createUuid();
definition.isInNavigationPane = true;
#endif

auto selectiveSyncBlackList = folderWizard->property("selectiveSyncBlackList").toStringList();
Expand Down
91 changes: 58 additions & 33 deletions src/gui/folder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,22 @@ namespace {
* 1\Folders\4\version=2
* 1\FoldersWithPlaceholders\3\version=3
*/
auto versionC()
{
return QStringLiteral("version");
}

constexpr int WinVfsSettingsVersion = 4;
constexpr int SettingsVersion = 2;
}
const QLatin1String versionC("version");

constexpr int SettingsVersion = 5;

// Settings keys:
const QLatin1String localPathC("localPath");
const QLatin1String journalPathC("journalPath");
const QLatin1String targetPathC("targetPath");
const QLatin1String pausedC("paused");
const QLatin1String ignoreHiddenFilesC("ignoreHiddenFiles");
const QLatin1String virtualFilesModeC("virtualFilesMode");
const QLatin1String navigationPaneClsidC("navigationPaneClsid");
const QLatin1String uuidC("uuid");
const QLatin1String isInNavigationPaneC("isInNavigationPane");
const QLatin1String usePlaceholdersC("usePlaceholders");
} // anonymous namespace

namespace OCC {

Expand Down Expand Up @@ -1306,47 +1314,64 @@ void Folder::slotAboutToRemoveAllFiles(SyncFileItem::Direction dir, std::functio

void FolderDefinition::save(QSettings &settings, const FolderDefinition &folder)
{
settings.setValue(QLatin1String("localPath"), folder.localPath);
settings.setValue(QLatin1String("journalPath"), folder.journalPath);
settings.setValue(QLatin1String("targetPath"), folder.targetPath);
settings.setValue(QLatin1String("paused"), folder.paused);
settings.setValue(QLatin1String("ignoreHiddenFiles"), folder.ignoreHiddenFiles);
settings.setValue(localPathC, folder.localPath);
settings.setValue(journalPathC, folder.journalPath);
settings.setValue(targetPathC, folder.targetPath);
settings.setValue(pausedC, folder.paused);
settings.setValue(ignoreHiddenFilesC, folder.ignoreHiddenFiles);
settings.setValue(uuidC, folder.uuid);
settings.setValue(virtualFilesModeC, Vfs::modeToString(folder.virtualFilesMode));

settings.setValue(QStringLiteral("virtualFilesMode"), Vfs::modeToString(folder.virtualFilesMode));
Q_ASSERT(SettingsVersion <= maxSettingsVersion());
settings.setValue(versionC, SettingsVersion);

// Ensure new vfs modes won't be attempted by older clients
const int version = folder.virtualFilesMode == Vfs::WindowsCfApi ? WinVfsSettingsVersion : SettingsVersion;
Q_ASSERT(version <= maxSettingsVersion());
settings.setValue(versionC(), version);
if (settings.contains(navigationPaneClsidC)) {
// Migrate old navigationPaneClsid to new uuid
settings.remove(navigationPaneClsidC);
}

// Happens only on Windows when the explorer integration is enabled.
if (!folder.navigationPaneClsid.isNull())
settings.setValue(QLatin1String("navigationPaneClsid"), folder.navigationPaneClsid);
else
settings.remove(QLatin1String("navigationPaneClsid"));
if (folder.isInNavigationPane) {
settings.setValue(isInNavigationPaneC, true);
} else {
settings.remove(isInNavigationPaneC);
}
}

bool FolderDefinition::load(QSettings &settings, const QString &alias,
FolderDefinition *folder)
bool FolderDefinition::load(const QSettings &settings, const QString &alias, FolderDefinition *folder)
{
folder->alias = FolderMan::unescapeAlias(alias);
folder->localPath = settings.value(QLatin1String("localPath")).toString();
folder->journalPath = settings.value(QLatin1String("journalPath")).toString();
folder->targetPath = settings.value(QLatin1String("targetPath")).toString();
folder->paused = settings.value(QLatin1String("paused")).toBool();
folder->ignoreHiddenFiles = settings.value(QLatin1String("ignoreHiddenFiles"), QVariant(true)).toBool();
folder->navigationPaneClsid = settings.value(QLatin1String("navigationPaneClsid")).toUuid();
folder->localPath = settings.value(localPathC).toString();
folder->journalPath = settings.value(journalPathC).toString();
folder->targetPath = settings.value(targetPathC).toString();
folder->paused = settings.value(pausedC).toBool();
folder->ignoreHiddenFiles = settings.value(ignoreHiddenFilesC, QVariant(true)).toBool();
folder->isInNavigationPane = settings.value(isInNavigationPaneC, QVariant(true)).toBool();

if (settings.contains(uuidC)) {
folder->uuid = settings.value(uuidC).toUuid();
} else if (settings.contains(navigationPaneClsidC)) {
// For backwards compatibility, will be changed when saved:
folder->uuid = settings.value(navigationPaneClsidC).toUuid();
if (!folder->isInNavigationPane) {
folder->isInNavigationPane = true;
}
}

// Sanity check:
if (folder->uuid.isNull()) {
folder->uuid = QUuid::createUuid();
}

folder->virtualFilesMode = Vfs::Off;
QString vfsModeString = settings.value(QStringLiteral("virtualFilesMode")).toString();
QString vfsModeString = settings.value(virtualFilesModeC).toString();
if (!vfsModeString.isEmpty()) {
if (auto mode = Vfs::modeFromString(vfsModeString)) {
folder->virtualFilesMode = *mode;
} else {
qCWarning(lcFolder) << "Unknown virtualFilesMode:" << vfsModeString << "assuming 'off'";
}
} else {
if (settings.value(QLatin1String("usePlaceholders")).toBool()) {
if (settings.value(usePlaceholdersC).toBool()) {
folder->virtualFilesMode = Vfs::WithSuffix;
folder->upgradeVfsMode = true; // maybe winvfs is available?
}
Expand Down
33 changes: 27 additions & 6 deletions src/gui/folder.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,12 @@ class FolderDefinition
bool ignoreHiddenFiles;
/// Which virtual files setting the folder uses
Vfs::Mode virtualFilesMode = Vfs::Off;
/// The CLSID where this folder appears in registry for the Explorer navigation pane entry.
QUuid navigationPaneClsid;

/// The (always valid) UUID for the folder. This can be overwritten when read from the settings.
QUuid uuid = QUuid::createUuid();

/// Is shown in Windows Explorer navigation pane
bool isInNavigationPane = false;

/// Whether the vfs mode shall silently be updated if possible
bool upgradeVfsMode = false;
Expand All @@ -81,7 +85,7 @@ class FolderDefinition
static void save(QSettings &settings, const FolderDefinition &folder);

/// Reads a folder definition from the current settings group.
static bool load(QSettings &settings, const QString &alias,
static bool load(const QSettings &settings, const QString &alias,
FolderDefinition *folder);

/** The highest version in the settings that load() can read
Expand All @@ -91,8 +95,9 @@ class FolderDefinition
* (version remains readable by 2.5.1)
* Version 3: introduction of new windows vfs mode in 2.6.0
* Version 4: until 2.9.1 windows vfs tried to unregister folders with a different id from windows.
* Version 5: renamed navigationPaneClsid to uuid in the settings for FolderDefinition
*/
static int maxSettingsVersion() { return 4; }
static int maxSettingsVersion() { return 5; }

/// Ensure / as separator and trailing /.
static QString prepareLocalPath(const QString &path);
Expand Down Expand Up @@ -163,8 +168,24 @@ class Folder : public QObject
*/
QString remotePathTrailingSlash() const;

void setNavigationPaneClsid(const QUuid &clsid) { _definition.navigationPaneClsid = clsid; }
QUuid navigationPaneClsid() const { return _definition.navigationPaneClsid; }
/**
* UUID for the folder
*/
QUuid uuid() const { return _definition.uuid; }

/**
* Currently only used on Windows.
*
* @return true is the folder is shown in the Windows Explorer navigation pane, false otherwise
*/
bool isInNavigationPane() const { return _definition.isInNavigationPane; }

/**
* Currently only used on Windows.
*
* @param yesno true is the folder shold be shown in the Windows Explorer navigation pane, false otherwise
*/
void setIsInNavigationPane(bool yesno) { _definition.isInNavigationPane = yesno; }

/**
* remote folder path with server url
Expand Down
13 changes: 5 additions & 8 deletions src/gui/folderman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,7 @@ namespace {
* [Accounts]
* 0\version=1
*/
auto versionC()
{
return QStringLiteral("version");
}
const QLatin1String versionC("version");

/*
* Folders with a version > maxFoldersVersion will be removed
Expand All @@ -71,7 +68,7 @@ QString makeLegacyDbName(const OCC::FolderDefinition &def, const OCC::AccountPtr
const QString key = QStringLiteral("%1@%2:%3").arg(account->credentials()->user(), legacyUrl.toString(), def.targetPath);
return OCC::SyncJournalDb::makeDbName(def.localPath, QString::fromUtf8(QCryptographicHash::hash(key.toUtf8(), QCryptographicHash::Md5).left(6).toHex()));
}
}
} // anonymous namespace

namespace OCC {
Q_LOGGING_CATEGORY(lcFolderMan, "gui.folder.manager", QtInfoMsg)
Expand Down Expand Up @@ -362,7 +359,7 @@ void FolderMan::setupFoldersHelper(QSettings &settings, AccountStatePtr account,
Folder *f = addFolderInternal(std::move(folderDefinition), account.data(), std::move(vfs));
if (f) {
// Migrate the old "usePlaceholders" setting to the root folder pin state
if (settings.value(versionC(), 1).toInt() == 1
if (settings.value(versionC, 1).toInt() == 1
&& settings.value(QLatin1String("usePlaceholders"), false).toBool()) {
qCInfo(lcFolderMan) << "Migrate: From usePlaceholders to PinState::OnlineOnly";
f->setRootPinState(PinState::OnlineOnly);
Expand Down Expand Up @@ -418,12 +415,12 @@ void FolderMan::backwardMigrationSettingsKeys(QStringList *deleteKeys, QStringLi

auto processSubgroup = [&](const QString &name) {
settings->beginGroup(name);
const int foldersVersion = settings->value(versionC(), 1).toInt();
const int foldersVersion = settings->value(versionC, 1).toInt();
if (foldersVersion <= maxFoldersVersion) {
const auto &childGroups = settings->childGroups();
for (const auto &folderAlias : childGroups) {
settings->beginGroup(folderAlias);
const int folderVersion = settings->value(versionC(), 1).toInt();
const int folderVersion = settings->value(versionC, 1).toInt();
if (folderVersion > FolderDefinition::maxSettingsVersion()) {
ignoreKeys->append(settings->group());
}
Expand Down
25 changes: 12 additions & 13 deletions src/gui/navigationpanehelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,26 @@ NavigationPaneHelper::NavigationPaneHelper(FolderMan *folderMan)

void NavigationPaneHelper::setShowInExplorerNavigationPane(bool show)
{
if (_showInExplorerNavigationPane == show)
if (_showInExplorerNavigationPane == show) {
return;
}

_showInExplorerNavigationPane = show;
// Re-generate a new CLSID when enabling, possibly throwing away the old one.
// updateCloudStorageRegistry will take care of removing any unknown CLSID our application owns from the registry.
for (auto *folder : _folderMan->map())
folder->setNavigationPaneClsid(show ? QUuid::createUuid() : QUuid());
// When we remove it from the side-bar, updateCloudStorageRegistry will take care of removing any
// unknown CLSID our application owns from the registry.
for (auto *folder : _folderMan->map()) {
folder->setIsInNavigationPane(show);
}

scheduleUpdateCloudStorageRegistry();
}

void NavigationPaneHelper::scheduleUpdateCloudStorageRegistry()
{
// Schedule the update to happen a bit later to avoid doing the update multiple times in a row.
if (!_updateCloudStorageRegistryTimer.isActive())
if (!_updateCloudStorageRegistryTimer.isActive()) {
_updateCloudStorageRegistryTimer.start(500);
}
}

void NavigationPaneHelper::updateCloudStorageRegistry()
Expand All @@ -76,15 +79,11 @@ void NavigationPaneHelper::updateCloudStorageRegistry()
// We currently don't distinguish between new and existing CLSIDs, if it's there we just
// save over it. We at least need to update the tile in case we are suddently using multiple accounts.
for (auto *folder : _folderMan->map()) {
if (folder->vfs().mode() == Vfs::WindowsCfApi)
{
continue;
}
if (!folder->navigationPaneClsid().isNull()) {
if (folder->vfs().mode() != Vfs::WindowsCfApi && folder->isInNavigationPane()) {
// If it already exists, unmark it for removal, this is a valid sync root.
entriesToRemove.removeOne(folder->navigationPaneClsid());
entriesToRemove.removeOne(folder->uuid());

QString clsidStr = folder->navigationPaneClsid().toString();
QString clsidStr = folder->uuid().toString();
QString clsidPath = QString() % "Software\\Classes\\CLSID\\" % clsidStr;
QString clsidPathWow64 = QString() % "Software\\Classes\\Wow6432Node\\CLSID\\" % clsidStr;
QString namespacePath = QString() % "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Desktop\\NameSpace\\" % clsidStr;
Expand Down
3 changes: 1 addition & 2 deletions src/gui/owncloudsetupwizard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,8 +405,7 @@ void OwncloudSetupWizard::slotAssistantFinished(int result)
folderDefinition.virtualFilesMode = bestAvailableVfsMode();
}
#ifdef Q_OS_WIN
if (folderMan->navigationPaneHelper().showInExplorerNavigationPane())
folderDefinition.navigationPaneClsid = QUuid::createUuid();
folderDefinition.isInNavigationPane = folderMan->navigationPaneHelper().showInExplorerNavigationPane();
#endif

auto f = folderMan->addFolder(account, folderDefinition);
Expand Down

0 comments on commit b8d9aa9

Please sign in to comment.