From dd3e70b66762abc611ecb4c2715eef9bfea0eb09 Mon Sep 17 00:00:00 2001 From: Hannah von Reth Date: Wed, 21 Oct 2020 12:31:21 +0200 Subject: [PATCH] VirtualFiles: Ensure the target location supports vfs Fixes: #8131 --- src/common/vfs.cpp | 18 ++++++++++++++++++ src/common/vfs.h | 2 ++ src/gui/accountsettings.cpp | 17 +++++++++-------- src/gui/folder.cpp | 8 ++++---- src/gui/folder.h | 4 ++-- src/gui/folderstatusmodel.cpp | 4 ++-- src/gui/folderwizard.cpp | 12 +++++++++++- src/gui/socketapi.cpp | 2 +- src/gui/wizard/owncloudadvancedsetuppage.cpp | 10 ++++++++++ 9 files changed, 59 insertions(+), 18 deletions(-) diff --git a/src/common/vfs.cpp b/src/common/vfs.cpp index d97ea69cc..8c5c53d7b 100644 --- a/src/common/vfs.cpp +++ b/src/common/vfs.cpp @@ -21,6 +21,8 @@ #include "version.h" #include "syncjournaldb.h" +#include "common/filesystembase.h" + #include #include @@ -60,6 +62,22 @@ Optional Vfs::modeFromString(const QString &str) return {}; } +Result Vfs::checkAvailability(const QString &path) +{ + const auto mode = bestAvailableVfsMode(); +#ifdef Q_OS_WIN + if (mode == Mode::WindowsCfApi) { + const auto fs = FileSystem::fileSystemForPath(path); + if (fs != QLatin1String("NTFS")) { + return tr("The Virtual filesystem feature requires a NTFS file system, %1 is using %2").arg(path, fs); + } + } +#else + Q_UNUSED(path); +#endif + return true; +} + void Vfs::start(const VfsSetupParams ¶ms) { _setupParams = params; diff --git a/src/common/vfs.h b/src/common/vfs.h index 3e17a17f9..c11f59bb2 100644 --- a/src/common/vfs.h +++ b/src/common/vfs.h @@ -99,6 +99,8 @@ public: static QString modeToString(Mode mode); static Optional modeFromString(const QString &str); + static Result checkAvailability(const QString &path); + enum class AvailabilityError { // Availability can't be retrieved due to db error diff --git a/src/gui/accountsettings.cpp b/src/gui/accountsettings.cpp index 7f3b019b7..d5606ec73 100644 --- a/src/gui/accountsettings.cpp +++ b/src/gui/accountsettings.cpp @@ -445,7 +445,7 @@ void AccountSettings::slotCustomContextMenuRequested(const QPoint &pos) ac = menu->addAction(tr("Remove folder sync connection")); connect(ac, &QAction::triggered, this, &AccountSettings::slotRemoveCurrentFolder); - if (folder->supportsVirtualFiles()) { + if (folder->virtualFilesEnabled()) { auto availabilityMenu = menu->addMenu(tr("Availability")); auto availability = folder->vfs().availability(QString()); if (availability) { @@ -468,11 +468,12 @@ void AccountSettings::slotCustomContextMenuRequested(const QPoint &pos) } if (Theme::instance()->showVirtualFilesOption() - && !folder->supportsVirtualFiles() - && bestAvailableVfsMode() != Vfs::Off - && !folder->isVfsOnOffSwitchPending()) { - ac = menu->addAction(tr("Enable virtual file support%1...").arg(bestAvailableVfsMode() == Vfs::WindowsCfApi ? QString() : tr(" (experimental)"))); - connect(ac, &QAction::triggered, this, &AccountSettings::slotEnableVfsCurrentFolder); + && !folder->virtualFilesEnabled() && Vfs::checkAvailability(folder->path())) { + const auto mode = bestAvailableVfsMode(); + if (mode == Vfs::WindowsCfApi || ConfigFile().showExperimentalOptions()) { + ac = menu->addAction(tr("Enable virtual file support%1...").arg(mode == Vfs::WindowsCfApi ? QString() : tr(" (experimental)"))); + connect(ac, &QAction::triggered, this, &AccountSettings::slotEnableVfsCurrentFolder); + } } @@ -688,7 +689,7 @@ void AccountSettings::slotEnableVfsCurrentFolder() folder->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, {}); // Change the folder vfs mode and load the plugin - folder->setSupportsVirtualFiles(true); + folder->setVirtualFilesEnabled(true); folder->setVfsOnOffSwitchPending(false); // Setting to Unspecified retains existing data. @@ -754,7 +755,7 @@ void AccountSettings::slotDisableVfsCurrentFolder() qCInfo(lcAccountSettings) << "Disabling vfs support for folder" << folder->path(); // Also wipes virtual files, schedules remote discovery - folder->setSupportsVirtualFiles(false); + folder->setVirtualFilesEnabled(false); folder->setVfsOnOffSwitchPending(false); // Wipe pin states and selective sync db diff --git a/src/gui/folder.cpp b/src/gui/folder.cpp index 4a793f611..59c762ecd 100644 --- a/src/gui/folder.cpp +++ b/src/gui/folder.cpp @@ -631,7 +631,7 @@ void Folder::implicitlyHydrateFile(const QString &relativepath) slotScheduleThisFolder(); } -void Folder::setSupportsVirtualFiles(bool enabled) +void Folder::setVirtualFilesEnabled(bool enabled) { Vfs::Mode newMode = _definition.virtualFilesMode; if (enabled && _definition.virtualFilesMode == Vfs::Off) { @@ -671,7 +671,7 @@ void Folder::setRootPinState(PinState state) bool Folder::supportsSelectiveSync() const { - return !supportsVirtualFiles() && !isVfsOnOffSwitchPending(); + return !virtualFilesEnabled() && !isVfsOnOffSwitchPending(); } void Folder::saveToSettings() const @@ -688,7 +688,7 @@ void Folder::saveToSettings() const return other != this && other->cleanPath() == this->cleanPath(); }); - if (supportsVirtualFiles() || _saveInFoldersWithPlaceholders) { + if (virtualFilesEnabled() || _saveInFoldersWithPlaceholders) { // If virtual files are enabled or even were enabled at some point, // save the folder to a group that will not be read by older (<2.5.0) clients. // The name is from when virtual files were called placeholders. @@ -1221,7 +1221,7 @@ void Folder::registerFolderWatcher() _folderWatcher->startNotificatonTest(path() + QLatin1String(".owncloudsync.log")); } -bool Folder::supportsVirtualFiles() const +bool Folder::virtualFilesEnabled() const { return _definition.virtualFilesMode != Vfs::Off && !isVfsOnOffSwitchPending(); } diff --git a/src/gui/folder.h b/src/gui/folder.h index 771d9e460..811ef7e99 100644 --- a/src/gui/folder.h +++ b/src/gui/folder.h @@ -276,8 +276,8 @@ public: * 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 supportsVirtualFiles() const; - void setSupportsVirtualFiles(bool enabled); + bool virtualFilesEnabled() const; + void setVirtualFilesEnabled(bool enabled); void setRootPinState(PinState state); diff --git a/src/gui/folderstatusmodel.cpp b/src/gui/folderstatusmodel.cpp index 5839bd834..0ebab24b8 100644 --- a/src/gui/folderstatusmodel.cpp +++ b/src/gui/folderstatusmodel.cpp @@ -219,7 +219,7 @@ QVariant FolderStatusModel::data(const QModelIndex &index, int role) const case FolderStatusDelegate::FolderErrorMsg: return f->syncResult().errorStrings(); case FolderStatusDelegate::FolderInfoMsg: - return f->supportsVirtualFiles() && f->vfs().mode() != Vfs::Mode::WindowsCfApi + return f->virtualFilesEnabled() && f->vfs().mode() != Vfs::Mode::WindowsCfApi ? QStringList(tr("Virtual file support is enabled.")) : QStringList(); case FolderStatusDelegate::SyncRunning: @@ -283,7 +283,7 @@ QVariant FolderStatusModel::data(const QModelIndex &index, int role) const case FolderStatusDelegate::SyncProgressOverallString: return progress._overallSyncString; case FolderStatusDelegate::FolderSyncText: - if (f->supportsVirtualFiles()) { + if (f->virtualFilesEnabled()) { return tr("Synchronizing VirtualFiles with local folder"); } else { return tr("Synchronizing with local folder"); diff --git a/src/gui/folderwizard.cpp b/src/gui/folderwizard.cpp index fd40ef611..27345b46f 100644 --- a/src/gui/folderwizard.cpp +++ b/src/gui/folderwizard.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include @@ -520,7 +521,16 @@ void FolderWizardSelectiveSync::initializePage() bool FolderWizardSelectiveSync::validatePage() { - bool useVirtualFiles = _virtualFilesCheckBox && _virtualFilesCheckBox->isChecked(); + const bool useVirtualFiles = _virtualFilesCheckBox && _virtualFilesCheckBox->isChecked(); + if (useVirtualFiles) { + const auto availability = Vfs::checkAvailability(wizard()->field(QStringLiteral("sourceFolder")).toString()); + if (!availability) { + auto msg = new QMessageBox(QMessageBox::Warning, tr("Virtual files are not available for the selected folder"), availability.error(), QMessageBox::Ok, this); + msg->setAttribute(Qt::WA_DeleteOnClose); + msg->open(); + return false; + } + } wizard()->setProperty("selectiveSyncBlackList", useVirtualFiles ? QVariant() : QVariant(_selectiveSync->createBlackList())); wizard()->setProperty("useVirtualFiles", QVariant(useVirtualFiles)); return true; diff --git a/src/gui/socketapi.cpp b/src/gui/socketapi.cpp index e1bfcdf61..3be2d1455 100644 --- a/src/gui/socketapi.cpp +++ b/src/gui/socketapi.cpp @@ -1107,7 +1107,7 @@ void SocketApi::command_GET_MENU_ITEMS(const QString &argument, OCC::SocketListe // File availability actions if (syncFolder - && syncFolder->supportsVirtualFiles() + && syncFolder->virtualFilesEnabled() && syncFolder->vfs().socketApiPinStateActionsShown()) { ENFORCE(!files.isEmpty()); diff --git a/src/gui/wizard/owncloudadvancedsetuppage.cpp b/src/gui/wizard/owncloudadvancedsetuppage.cpp index 66686f6f2..dba276ec8 100644 --- a/src/gui/wizard/owncloudadvancedsetuppage.cpp +++ b/src/gui/wizard/owncloudadvancedsetuppage.cpp @@ -268,6 +268,16 @@ bool OwncloudAdvancedSetupPage::isConfirmBigFolderChecked() const bool OwncloudAdvancedSetupPage::validatePage() { + if (useVirtualFileSync()) { + const auto availability = Vfs::checkAvailability(localFolder()); + if (!availability) { + auto msg = new QMessageBox(QMessageBox::Warning, tr("Virtual files are not available for the selected folder"), availability.error(), QMessageBox::Ok, this); + msg->setAttribute(Qt::WA_DeleteOnClose); + msg->open(); + return false; + } + } + if (!_created) { setErrorString(QString()); _checking = true; -- 2.30.2