vfs: Add vfs migration options to folder context menu
authorChristian Kamm <mail@ckamm.de>
Thu, 26 Nov 2020 23:57:49 +0000 (00:57 +0100)
committerKevin Ottens <kevin.ottens@nextcloud.com>
Tue, 15 Dec 2020 09:58:33 +0000 (10:58 +0100)
This allows enabling and disabling vfs.

To distinguish this operation from setting the root pin state, the
availability setting is adjusted as well to be similar to the
menu that shows in the shell extensions.

src/common/syncjournaldb.h
src/gui/accountsettings.cpp
src/gui/accountsettings.h
src/gui/folder.cpp

index 5cb785a30c095faa726f341461efdc9fa366fcb3..0e280f8cb56519fa5782f9228f435dc964456048 100644 (file)
@@ -268,6 +268,7 @@ public:
      *
      * If a path has no explicit PinState "Inherited" is returned.
      *
+     * The path should not have a trailing slash.
      * It's valid to use the root path "".
      *
      * Returns none on db error.
@@ -280,6 +281,7 @@ public:
      * If the exact path has no entry or has an Inherited state,
      * the state of the closest parent path is returned.
      *
+     * The path should not have a trailing slash.
      * It's valid to use the root path "".
      *
      * Never returns PinState::Inherited. If the root is "Inherited"
@@ -292,6 +294,7 @@ public:
     /**
      * Sets a path's pin state.
      *
+     * The path should not have a trailing slash.
      * It's valid to use the root path "".
      */
     void setPinStateForPath(const QByteArray &path, PinState state);
@@ -300,6 +303,7 @@ public:
      * Wipes pin states for a path and below.
      *
      * Used when the user asks a subtree to have a particular pin state.
+     * The path should not have a trailing slash.
      * The path "" wipes every entry.
      */
     void wipePinStateForPathAndBelow(const QByteArray &path);
@@ -308,6 +312,7 @@ public:
      * Returns list of all paths with their pin state as in the db.
      *
      * Returns nothing on db error.
+     * Note that this will have an entry for "".
      */
     Optional<QVector<QPair<QByteArray, PinState>>> rawPinStates();
 
index 20f8688f4fa9a612d9d7b24b99ce5702873d1ec0..b8f55cb7b3b13de8b3e59585dadfff9fbb7ef861 100644 (file)
@@ -439,35 +439,27 @@ void AccountSettings::slotCustomContextMenuRequested(const QPoint &pos)
     ac = menu->addAction(tr("Remove folder sync connection"));
     connect(ac, &QAction::triggered, this, &AccountSettings::slotRemoveCurrentFolder);
 
-    if ((Theme::instance()->showVirtualFilesOption() && folder->supportsVirtualFiles()) || folder->newFilesAreVirtual()) {
-        ac = menu->addAction(tr("Create virtual files for new files (Experimental)"));
+    if (folder->supportsVirtualFiles()) {
+        auto availabilityMenu = menu->addMenu(tr("Availability"));
+        ac = availabilityMenu->addAction(tr("Local"));
+        ac->setCheckable(true);
+        ac->setChecked(!folder->newFilesAreVirtual());
+        connect(ac, &QAction::triggered, this, [this]() { slotSetCurrentFolderAvailability(PinState::AlwaysLocal); });
+
+        ac = availabilityMenu->addAction(tr("Online only"));
         ac->setCheckable(true);
         ac->setChecked(folder->newFilesAreVirtual());
-        connect(ac, &QAction::toggled, this, [folder, this](bool checked) {
-            if (!checked) {
-                if (folder)
-                    folder->setNewFilesAreVirtual(false);
-                // Make sure the size is recomputed as the virtual file indicator changes
-                _ui->_folderList->doItemsLayout();
-                return;
-            }
-            OwncloudWizard::askExperimentalVirtualFilesFeature([folder, this](bool enable) {
-                if (enable && folder)
-                    folder->setNewFilesAreVirtual(enable);
-
-                // Also wipe selective sync settings
-                bool ok = false;
-                auto oldBlacklist = folder->journalDb()->getSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, &ok);
-                folder->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, {});
-                for (const auto &entry : oldBlacklist) {
-                    folder->journalDb()->avoidReadFromDbOnNextSync(entry);
-                }
-                FolderMan::instance()->scheduleFolder(folder);
+        connect(ac, &QAction::triggered, this, [this]() { slotSetCurrentFolderAvailability(PinState::OnlineOnly); });
 
-                // Make sure the size is recomputed as the virtual file indicator changes
-                _ui->_folderList->doItemsLayout();
-            });
-        });
+        ac = menu->addAction(tr("Disable virtual file support..."));
+        connect(ac, &QAction::triggered, this, &AccountSettings::slotDisableVfsCurrentFolder);
+    }
+
+    if (Theme::instance()->showVirtualFilesOption()
+        && !folder->supportsVirtualFiles()
+        && bestAvailableVfsMode() != Vfs::Off) {
+        ac = menu->addAction(tr("Enable virtual file support (experimental)..."));
+        connect(ac, &QAction::triggered, this, &AccountSettings::slotEnableVfsCurrentFolder);
     }
 
 
@@ -644,6 +636,102 @@ void AccountSettings::slotOpenCurrentLocalSubFolder()
     QDesktopServices::openUrl(url);
 }
 
+void AccountSettings::slotEnableVfsCurrentFolder()
+{
+    FolderMan *folderMan = FolderMan::instance();
+    QPointer<Folder> folder = folderMan->folder(selectedFolderAlias());
+    QModelIndex selected = _ui->_folderList->selectionModel()->currentIndex();
+    if (!selected.isValid() || !folder)
+        return;
+
+    OwncloudWizard::askExperimentalVirtualFilesFeature([folder, this](bool enable) {
+        if (!enable || !folder)
+            return;
+
+        qCInfo(lcAccountSettings) << "Enabling vfs support for folder" << folder->path();
+
+        // Wipe selective sync blacklist
+        bool ok = false;
+        auto oldBlacklist = folder->journalDb()->getSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, &ok);
+        folder->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, {});
+        for (const auto &entry : oldBlacklist) {
+            folder->journalDb()->avoidReadFromDbOnNextSync(entry);
+        }
+
+        // Change the folder vfs mode and load the plugin
+        folder->setSupportsVirtualFiles(true);
+
+        // Wipe pin states to be sure
+        folder->journalDb()->wipePinStateForPathAndBelow("");
+        folder->journalDb()->setPinStateForPath("", PinState::OnlineOnly);
+
+        FolderMan::instance()->scheduleFolder(folder);
+
+        // Update the ui: no selective sync, vfs indicator; size changed
+        _ui->_folderList->doItemsLayout();
+    });
+}
+
+void AccountSettings::slotDisableVfsCurrentFolder()
+{
+    FolderMan *folderMan = FolderMan::instance();
+    QPointer<Folder> folder = folderMan->folder(selectedFolderAlias());
+    QModelIndex selected = _ui->_folderList->selectionModel()->currentIndex();
+    if (!selected.isValid() || !folder)
+        return;
+
+    auto msgBox = new QMessageBox(
+        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."));
+    msgBox->addButton(tr("Disable support"), QMessageBox::AcceptRole);
+    msgBox->addButton(tr("Cancel"), QMessageBox::RejectRole);
+    connect(msgBox, &QMessageBox::finished, msgBox, [this, msgBox, folder](int result) {
+        msgBox->deleteLater();
+        if (result != QMessageBox::AcceptRole || !folder)
+            return;
+
+        qCInfo(lcAccountSettings) << "Disabling vfs support for folder" << folder->path();
+
+        // Also wipes virtual files, schedules remote discovery
+        folder->setSupportsVirtualFiles(false);
+
+        // Wipe pin states and selective sync db
+        folder->journalDb()->wipePinStateForPathAndBelow("");
+        folder->journalDb()->setPinStateForPath("", PinState::AlwaysLocal);
+        folder->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, {});
+
+        FolderMan::instance()->scheduleFolder(folder);
+
+        // Update the ui: no selective sync, vfs indicator; size changed
+        _ui->_folderList->doItemsLayout();
+    });
+    msgBox->open();
+}
+
+void AccountSettings::slotSetCurrentFolderAvailability(PinState state)
+{
+    FolderMan *folderMan = FolderMan::instance();
+    QPointer<Folder> folder = folderMan->folder(selectedFolderAlias());
+    QModelIndex selected = _ui->_folderList->selectionModel()->currentIndex();
+    if (!selected.isValid() || !folder)
+        return;
+
+    // similar to socket api: set pin state, wipe sub pin-states and sync
+    folder->journalDb()->wipePinStateForPathAndBelow("");
+    folder->journalDb()->setPinStateForPath("", state);
+
+    if (state == PinState::AlwaysLocal) {
+        folder->downloadVirtualFile("");
+    } else {
+        folder->dehydrateFile("");
+    }
+}
+
 void AccountSettings::showConnectionLabel(const QString &message, QStringList errors)
 {
     const QString errStyle = QLatin1String("color:#ffffff; background-color:#bb4d4d;padding:5px;"
index 60671afd275405ef388e040c20675ce625cff641..9b7529a047393f427b60a7c3db28e9955d608bc1 100644 (file)
@@ -85,6 +85,9 @@ protected slots:
     void slotOpenCurrentLocalSubFolder(); // selected subfolder in sync folder
     void slotEditCurrentIgnoredFiles();
     void slotEditCurrentLocalIgnoredFiles();
+    void slotEnableVfsCurrentFolder();
+    void slotDisableVfsCurrentFolder();
+    void slotSetCurrentFolderAvailability(PinState state);
     void slotFolderWizardAccepted();
     void slotFolderWizardRejected();
     void slotDeleteAccount();
index 5615bec7f3281010454ca01a06f9f32b48292605..d0999e11d48d553f20629ee790badb363c1e69db 100644 (file)
@@ -638,9 +638,9 @@ void Folder::setSupportsVirtualFiles(bool enabled)
         _vfs->unregisterFolder();
 
         _vfs.reset(createVfsFromPlugin(newMode).release());
-        startVfs();
 
         _definition.virtualFilesMode = newMode;
+        startVfs();
         if (newMode != Vfs::Off)
             _saveInFoldersWithPlaceholders = true;
         saveToSettings();