Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/common/vfs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ QString Utility::enumToString(Vfs::Mode mode)
}
}

Result<void, QString> Vfs::checkAvailability(const QString &path, Vfs::Mode mode)
QString Vfs::pathSupportDetail(const QString &path, Vfs::Mode mode)
{
#ifdef Q_OS_WIN
if (mode == Mode::WindowsCfApi) {
Expand Down
12 changes: 11 additions & 1 deletion src/common/vfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,17 @@ class OCSYNC_EXPORT Vfs : public QObject

static Mode modeFromString(const QString &str);

static Result<void, QString> checkAvailability(const QString &path, OCC::Vfs::Mode mode);
/**
* @brief pathSupportDetail - needs a better name but the concept is that this function checks to see if the path is supported for vfs.
* if it is not supported the return string contains the "reason" it's not supported.
* @param path to check to for support
* @param mode which we want to check - note that the only arg that makes sense here at all is Vfs::WindowsCfApi
* @return empty string if the mode is supported on the given path. If the string is not empty, it contains a string explaining the
* reason the mode is not supported.
*
* as of this writing, the possible root reasons are: path is a drive, path is on a network drive, path fs is not ntfs.
*/
static QString pathSupportDetail(const QString &path, OCC::Vfs::Mode mode);

enum class AvailabilityError
{
Expand Down
238 changes: 89 additions & 149 deletions src/gui/FoldersGui/accountfolderscontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ AccountFoldersController::AccountFoldersController(AccountState *state, AccountF
_sortModel = weightedModel;
*/

_view->setItemModel(model);
_view->setItemModels(model, modelController->selectionModel());

buildMenuActions();

connect(_view, &AccountFoldersView::addFolderTriggered, this, &AccountFoldersController::slotAddFolder);
// ui->quickWidget->engine()->addImageProvider(QStringLiteral("space"), new Spaces::SpaceImageProvider(_accountState->account()->spacesManager()));
Expand Down Expand Up @@ -123,140 +125,79 @@ void AccountFoldersController::slotFolderWizardAccepted(OCC::FolderMan::SyncConn

void AccountFoldersController::buildMenuActions()
{
QList<QAction *> itemActions;

// show in finder
_showInSystemFolder = new QAction(CommonStrings::showInFileBrowser(), this);
itemActions.push_back(_showInSystemFolder);
connect(_showInSystemFolder, &QAction::triggered, this, &AccountFoldersController::onShowInSystemFolder);

if (_accountState->account()->capabilities().privateLinkPropertyAvailable()) {
_showInBrowser = new QAction(CommonStrings::showInWebBrowser(), this);
itemActions.push_back(_showInBrowser);
connect(_showInBrowser, &QAction::triggered, this, &AccountFoldersController::onShowInBrowser);
}

QAction *separator = new QAction(this);
separator->setSeparator(true);
itemActions.push_back(separator);

_forceSync = new QAction(tr("Force sync now"), this);
itemActions.push_back(_forceSync);
connect(_forceSync, &QAction::triggered, this, &AccountFoldersController::onForceSync);

_pauseSync = new QAction(this);
itemActions.push_back(_pauseSync);
connect(_pauseSync, &QAction::triggered, this, &AccountFoldersController::onTogglePauseSync);

_removeSync = new QAction(tr("Remove folder sync connection"), this);
itemActions.push_back(_removeSync);
connect(_removeSync, &QAction::triggered, this, &AccountFoldersController::onRemoveSync);

// we may want to treat this similar to the enable vfs option, because choose sync can only be activated
// if the folder is not using vfs. So the idea is if force vfs is on the user will never be able to choose
// so showing the option at all is probably not great
_chooseSync = new QAction(tr("Choose what to sync"), this);
itemActions.push_back(_chooseSync);
connect(_chooseSync, &QAction::triggered, this, &AccountFoldersController::onChooseSync);


// Only show "Enable VFS" if a VFS mode is available
/* const auto mode = VfsPluginManager::instance().bestAvailableVfsMode();
if (mode == Vfs::WindowsCfApi) {
_enableVfs = new QAction(tr("Enable virtual file support"), this);

if (FolderMan::instance()->checkVfsAvailability(folder->path(), mode)) {
if (mode == Vfs::WindowsCfApi) {
QAction *enableVfsAction = menu->addAction(tr("Enable virtual file support"));
connect(enableVfsAction, &QAction::triggered, this, [folder, this] { slotEnableVfsCurrentFolder(folder); });
}
}
};

if (Theme::instance()->showVirtualFilesOption()) {
if (Theme::instance()->forceVirtualFilesOption()) {
if (!folder->virtualFilesEnabled()) {
// VFS is currently disabled, but is forced on by theming (e.g. due to a theme change)
maybeShowEnableVfs();
/* auto maybeShowEnableVfs = [folder, menu, this]() {
// Only show "Enable VFS" if a VFS mode is available
const auto mode = VfsPluginManager::instance().bestAvailableVfsMode();
if (mode == Vfs::WindowsCfApi) {
_enableVfs = new QAction(tr("Enable virtual file support"), this);

if (FolderMan::instance()->checkVfsAvailability(folder->path(), mode)) {
if (mode == Vfs::WindowsCfApi) {
QAction *enableVfsAction = menu->addAction(tr("Enable virtual file support"));
connect(enableVfsAction, &QAction::triggered, this, [folder, this] { slotEnableVfsCurrentFolder(folder); });
}
}
} else {
if (folder->virtualFilesEnabled()) {
menu->addAction(tr("Disable virtual file support"), this, [folder, this] { slotDisableVfsCurrentFolder(folder); });
};

if (Theme::instance()->showVirtualFilesOption()) {
if (Theme::instance()->forceVirtualFilesOption()) {
if (!folder->virtualFilesEnabled()) {
// VFS is currently disabled, but is forced on by theming (e.g. due to a theme change)
maybeShowEnableVfs();
}
} else {
maybeShowEnableVfs();
if (folder->virtualFilesEnabled()) {
menu->addAction(tr("Disable virtual file support"), this, [folder, this] { slotDisableVfsCurrentFolder(folder); });
} else {
maybeShowEnableVfs();
}
}
}
_enableVfs = new QAction(this);
*/
_enableVfs = new QAction(this);
*/

connect(_view, &AccountFoldersView::requestActionsUpdate, this, &AccountFoldersController::updateActions);
_view->setFolderActions(itemActions);
}


/*void AccountView::slotCustomContextMenuRequested(Folder *folder)
{
// Refactoring todo: we need to eval defensive handling of the account state QPointer in more depth, and I
// am not able to easily determine what should happen in this handler if the state is null. For now we just assert
// to make the "source" of the nullptr obvious before it trickles down into sub-areas and causes a crash that's harder
// to id
Q_ASSERT(_accountState && _accountState->account());

// qpointer for async calls
const auto isDeployed = folder->isDeployed();
const auto addRemoveFolderAction = [isDeployed, folder, this](QMenu *menu) {
Q_ASSERT(!isDeployed);
return menu->addAction(tr("Remove folder sync connection"), this, [folder, this] { slotRemoveCurrentFolder(folder); });
};


auto *menu = new QMenu(ui->accountFoldersView);
menu->setAccessibleName(tr("Sync options menu"));
menu->setAttribute(Qt::WA_DeleteOnClose);
connect(folder, &OCC::Folder::destroyed, menu, &QMenu::close);
// Only allow removal if the item isn't in "ready" state.
if (!folder->isReady() && !isDeployed) {
if (Theme::instance()->syncNewlyDiscoveredSpaces()) {
menu->addAction(tr("Folder is not ready yet"))->setEnabled(false);
} else {
addRemoveFolderAction(menu);
}
menu->popup(QCursor::pos());
// accessibility
menu->setFocus();
return;
}
// Add an action to open the folder in the system's file browser:
QAction *showInFileManagerAction = menu->addAction(CommonStrings::showInFileBrowser(), [folder]() {
qCInfo(lcAccountView) << "Opening local folder" << folder->path();
if (QFileInfo::exists(folder->path())) {
showInFileManager(folder->path());
}
});

if (!QFile::exists(folder->path())) {
showInFileManagerAction->setEnabled(false);
}

// Add an action to open the folder on the server in a webbrowser:
// Refactoring todo: why are we using the folder accountState AND the local member? shouldn't the folder have the same account state
// as this settings panel?!
if (folder->accountState()->account()->capabilities().privateLinkPropertyAvailable()) {
QString path = folder->remotePathTrailingSlash();
menu->addAction(CommonStrings::showInWebBrowser(), [path, davUrl = folder->webDavUrl(), this] {
fetchPrivateLinkUrl(_accountState->account(), davUrl, path, this, [](const QUrl &url) { Utility::openBrowser(url, nullptr); });
});
}


// Root-folder specific actions:
menu->addSeparator();

// qpointer for the async context menu
if (OC_ENSURE(folder->isReady())) {
const bool folderPaused = folder->syncPaused();

if (!folderPaused) {
QAction *forceSyncAction = menu->addAction(tr("Force sync now"));
if (folder->isSyncRunning()) {
forceSyncAction->setText(tr("Restart sync"));
}
forceSyncAction->setEnabled(folder->accountState()->isConnected());
connect(forceSyncAction, &QAction::triggered, this, [folder, this] { slotForceSyncCurrentFolder(folder); });
}

QAction *resumeAction = menu->addAction(folderPaused ? tr("Resume sync") : tr("Pause sync"));
connect(resumeAction, &QAction::triggered, this, [folder, this] { slotEnableCurrentFolder(folder, true); });

if (!isDeployed) {
if (!Theme::instance()->syncNewlyDiscoveredSpaces()) {
addRemoveFolderAction(menu);
}

auto maybeShowEnableVfs = [folder, menu, this]() {
// Only show "Enable VFS" if a VFS mode is available
Expand All @@ -283,76 +224,76 @@ void AccountFoldersController::buildMenuActions()
}
}
}
if (!folder->virtualFilesEnabled()) {
menu->addAction(tr("Choose what to sync"), this, [folder, this] { showSelectiveSyncDialog(folder); });
}
menu->popup(QCursor::pos());
menu->setFocus(); // for accassebility (keyboard navigation)
} else {
menu->deleteLater();
}

}
}
}*/


/*void AccountFoldersController::slotEnableVfsCurrentFolder(Folder *folder)
void AccountFoldersController::onEnableVfs()
{
if (OC_ENSURE(VfsPluginManager::instance().bestAvailableVfsMode() == Vfs::WindowsCfApi)) {
if (!folder) {
return;
}
qCInfo(lcAccountView) << "Enabling vfs support for folder" << folder->path();
if (!_currentFolder || _currentFolder->virtualFilesEnabled() || VfsPluginManager::instance().bestAvailableVfsMode() != Vfs::WindowsCfApi)
return;

// Change the folder vfs mode and load the plugin
folder->setVirtualFilesEnabled(true);
}
}*/
qCInfo(lcAccountFoldersController) << "Enabling vfs support for folder" << _currentFolder->path();

/*void AccountFoldersController::slotDisableVfsCurrentFolder(Folder *folder)
// Change the folder vfs mode and load the plugin
_currentFolder->setVirtualFilesEnabled(true);
}

void AccountFoldersController::onDisableVfs()
{
auto msgBox = new QMessageBox(QMessageBox::Question, tr("Disable virtual file support?"),
if (!_currentFolder)
return;

QMessageBox msgBox(QMessageBox::Question, tr("Disable virtual file support?"),
tr("This action will disable virtual file support. As a consequence contents of folders that "
"are currently marked as 'available online only' will be downloaded."
"\n\n"
"The only advantage of disabling virtual file support is that the selective sync feature "
"will become available again."
"\n\n"
"This action will abort any currently running synchronization."));
auto acceptButton = msgBox->addButton(tr("Disable support"), QMessageBox::AcceptRole);
msgBox->addButton(tr("Cancel"), QMessageBox::RejectRole);
connect(msgBox, &QMessageBox::finished, msgBox, [msgBox, folder, acceptButton] {
msgBox->deleteLater();
if (msgBox->clickedButton() != acceptButton || !folder) {
return;
}
msgBox.button(QMessageBox::Yes)->setText(tr("Disable support"));
msgBox.button(QMessageBox::No)->setText(tr("Cancel"));

qCInfo(lcAccountView) << "Disabling vfs support for folder" << folder->path();
int result = msgBox.exec();
if (result == QDialog::Rejected)
return;

// Also wipes virtual files, schedules remote discovery
folder->setVirtualFilesEnabled(false);
});
msgBox->open();
}*/
qCInfo(lcAccountFoldersController) << "Disabling vfs support for folder" << _currentFolder->path();

// Also wipes virtual files, schedules remote discovery
_currentFolder->setVirtualFilesEnabled(false);
}


void AccountFoldersController::updateActions()
{
if (!_currentFolder)
return;

_showInSystemFolder->setEnabled(QFileInfo::exists(_currentFolder->path()));
// the checks for _currentFolder are twofold:
// obvs we don't want to try to access values that aren't there
// furthermore, we do need to disable if the current folder selection
// is empty so it's actually a key part of the evaluation for action state here
_showInSystemFolder->setEnabled(_currentFolder && QFileInfo::exists(_currentFolder->path()));

if (_showInBrowser)
_showInBrowser->setEnabled(_currentFolder->isAvailable());
_showInBrowser->setEnabled(_currentFolder && _currentFolder->isAvailable());

_forceSync->setEnabled(!_currentFolder->isSyncRunning() && _currentFolder->canSync());
_forceSync->setEnabled(_currentFolder && _currentFolder->canSync());
_forceSync->setText(_currentFolder && _currentFolder->isSyncRunning() ? tr("Restart sync") : tr("Force sync now"));

_pauseSync->setText(_currentFolder->syncPaused() ? tr("Resume sync") : tr("Pause sync"));
_pauseSync->setText(_currentFolder && _currentFolder->syncPaused() ? tr("Resume sync") : tr("Pause sync"));
// is this enough? I think we need to keep it enabled even if sync is running so the user can effectively cancel it + pause. as who knows. maybe
// they made a mistake when adding the folder or whatever
_pauseSync->setEnabled(_currentFolder->isAvailable());
_pauseSync->setEnabled(_currentFolder && _currentFolder->isAvailable());

_removeSync->setEnabled(_currentFolder);

if (_enableVfs) {
_enableVfs->setText(_currentFolder && _currentFolder->virtualFilesEnabled() ? tr("Disable virtual file support") : tr("Enable virtual file support"));
_enableVfs->setEnabled(_currentFolder->canSync());
}

_chooseSync->setEnabled(!_currentFolder->virtualFilesEnabled());
_chooseSync->setEnabled(_currentFolder && _currentFolder->isAvailable() && !_currentFolder->virtualFilesEnabled());
}

void OCC::AccountFoldersController::onShowInSystemFolder()
Expand All @@ -369,7 +310,7 @@ void AccountFoldersController::onShowInBrowser()
if (!_currentFolder)
return;

QString path = _currentFolder->path();
QString path = _currentFolder->remotePathTrailingSlash();
QUrl davUrl = _currentFolder->webDavUrl();
fetchPrivateLinkUrl(_accountState->account(), davUrl, path, this, [](const QUrl &url) { Utility::openBrowser(url, nullptr); });
}
Expand All @@ -384,7 +325,6 @@ void AccountFoldersController::onForceSync()
tr("Synchronization is paused because the Internet connection is a metered connection"
"<p>Do you really want to force a Synchronization now?"),
QMessageBox::Yes | QMessageBox::No, ocApp()->gui()->settingsDialog());
messageBox.setAttribute(Qt::WA_DeleteOnClose);
int result = messageBox.exec();
if (result == QDialog::Rejected)
return;
Expand Down Expand Up @@ -443,7 +383,7 @@ void AccountFoldersController::onRemoveSync()

void AccountFoldersController::onChooseSync()
{
if (!_currentFolder || _accountState || !_accountState->account()) {
if (!_currentFolder || !_accountState || !_accountState->account()) {
return;
}

Expand Down
5 changes: 4 additions & 1 deletion src/gui/FoldersGui/accountfolderscontroller.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ protected slots:
QPointer<Folder> _currentFolder = nullptr;
AccountFoldersView *_view = nullptr;
FolderModelController *_modelController = nullptr;

void buildMenuActions();
void updateActions();

// menu actions:
QAction *_showInSystemFolder = nullptr;
Expand All @@ -73,6 +75,7 @@ protected slots:
void onTogglePauseSync();
void onRemoveSync();
void onChooseSync();
void updateActions();
void onDisableVfs();
void onEnableVfs();
};
}
Loading