]> cloud.milkyroute.net Git - dolphin.git/commitdiff
DolphinMainWindow: autosave session
authorAmol Godbole <amolagodbole@gmail.com>
Thu, 9 Nov 2023 17:05:48 +0000 (11:05 -0600)
committerMéven Car <meven.car@kdemail.net>
Sun, 14 Jan 2024 08:34:58 +0000 (08:34 +0000)
Currently, the session is saved only when the app quits normally. Save
the session after a fixed time interval from the last state change i.e.
anytime the url is changed, or a tab is opened or closed, or the active
view is changed.

BUG: 425627

src/dolphinmainwindow.cpp
src/dolphinmainwindow.h
src/dolphintabwidget.cpp
src/dolphintabwidget.h
src/main.cpp

index 745fa97cc8ddd1f5e9691a65f7267cf8974ce3d5..d73cc4866d9472964df0693b84ed71f756a3877c 100644 (file)
@@ -79,6 +79,7 @@
 #include <QStandardPaths>
 #include <QTimer>
 #include <QToolButton>
+#include <QtConcurrentRun>
 
 #include <algorithm>
 
@@ -114,6 +115,9 @@ DolphinMainWindow::DolphinMainWindow()
     , m_tearDownFromPlacesRequested(false)
     , m_backAction(nullptr)
     , m_forwardAction(nullptr)
+    , m_sessionSaveTimer(nullptr)
+    , m_sessionSaveWatcher(nullptr)
+    , m_sessionSaveScheduled(false)
 {
     Q_INIT_RESOURCE(dolphin);
 
@@ -676,18 +680,74 @@ void DolphinMainWindow::closeEvent(QCloseEvent *event)
         }
     }
 
-    if (GeneralSettings::rememberOpenedTabs()) {
+    if (m_sessionSaveTimer && (m_sessionSaveTimer->isActive() || m_sessionSaveWatcher->isRunning())) {
+        const bool sessionSaveTimerActive = m_sessionSaveTimer->isActive();
+
+        m_sessionSaveTimer->stop();
+        m_sessionSaveWatcher->disconnect();
+        m_sessionSaveWatcher->waitForFinished();
+
+        if (sessionSaveTimerActive || m_sessionSaveScheduled) {
+            slotSaveSession();
+        }
+    }
+
+    GeneralSettings::setVersion(CurrentDolphinVersion);
+    GeneralSettings::self()->save();
+
+    KXmlGuiWindow::closeEvent(event);
+}
+
+void DolphinMainWindow::slotSaveSession()
+{
+    m_sessionSaveScheduled = false;
+
+    if (m_sessionSaveWatcher->isRunning()) {
+        // The previous session is still being saved - schedule another save.
+        m_sessionSaveWatcher->disconnect();
+        connect(m_sessionSaveWatcher, &QFutureWatcher<void>::finished, this, &DolphinMainWindow::slotSaveSession, Qt::SingleShotConnection);
+        m_sessionSaveScheduled = true;
+    } else if (!m_sessionSaveTimer->isActive()) {
+        // No point in saving the session if the timer is running (since it will save the session again when it times out).
         KConfigGui::setSessionConfig(QStringLiteral("dolphin"), QStringLiteral("dolphin"));
         KConfig *config = KConfigGui::sessionConfig();
         saveGlobalProperties(config);
         savePropertiesInternal(config, 1);
-        config->sync();
+
+        auto future = QtConcurrent::run([config]() {
+            config->sync();
+        });
+        m_sessionSaveWatcher->setFuture(future);
     }
+}
 
-    GeneralSettings::setVersion(CurrentDolphinVersion);
-    GeneralSettings::self()->save();
+void DolphinMainWindow::setSessionAutoSaveEnabled(bool enable)
+{
+    if (enable) {
+        if (!m_sessionSaveTimer) {
+            m_sessionSaveTimer = new QTimer(this);
+            m_sessionSaveWatcher = new QFutureWatcher<void>(this);
+            m_sessionSaveTimer->setSingleShot(true);
+            m_sessionSaveTimer->setInterval(22000);
 
-    KXmlGuiWindow::closeEvent(event);
+            connect(m_sessionSaveTimer, &QTimer::timeout, this, &DolphinMainWindow::slotSaveSession);
+        }
+
+        connect(m_tabWidget, &DolphinTabWidget::urlChanged, m_sessionSaveTimer, qOverload<>(&QTimer::start), Qt::UniqueConnection);
+        connect(m_tabWidget, &DolphinTabWidget::tabCountChanged, m_sessionSaveTimer, qOverload<>(&QTimer::start), Qt::UniqueConnection);
+        connect(m_tabWidget, &DolphinTabWidget::activeViewChanged, m_sessionSaveTimer, qOverload<>(&QTimer::start), Qt::UniqueConnection);
+    } else if (m_sessionSaveTimer) {
+        m_sessionSaveTimer->stop();
+        m_sessionSaveWatcher->disconnect();
+        m_sessionSaveScheduled = false;
+
+        m_sessionSaveWatcher->waitForFinished();
+
+        m_sessionSaveTimer->deleteLater();
+        m_sessionSaveWatcher->deleteLater();
+        m_sessionSaveTimer = nullptr;
+        m_sessionSaveWatcher = nullptr;
+    }
 }
 
 void DolphinMainWindow::saveProperties(KConfigGroup &group)
index 551e28192700373103edce3709b39675e2f9ebdc..bff0ef4de8cac5d60908bc07ef80036832db98c7 100644 (file)
@@ -20,6 +20,7 @@
 #include "panels/information/informationpanel.h"
 #endif
 
+#include <QFutureWatcher>
 #include <QIcon>
 #include <QList>
 #include <QMenu>
@@ -116,6 +117,14 @@ public:
      */
     void setViewsToHomeIfMountPathOpen(const QString &mountPath);
 
+    /**
+     * Enables or disables the session autosaving feature.
+     *
+     * @param enable If true, saves the session automatically after a fixed
+     *               time interval from the last state change.
+     */
+    void setSessionAutoSaveEnabled(bool enable);
+
     bool isFoldersPanelEnabled() const;
     bool isInformationPanelEnabled() const;
     bool isSplitViewEnabledInCurrentTab() const;
@@ -619,6 +628,11 @@ private Q_SLOTS:
      */
     void slotKeyBindings();
 
+    /**
+     * Saves the session.
+     */
+    void slotSaveSession();
+
 private:
     /**
      * Sets up the various menus and actions and connects them.
@@ -718,6 +732,10 @@ private:
     QMenu m_searchTools;
     KFileItemActions m_fileItemActions;
 
+    QTimer *m_sessionSaveTimer;
+    QFutureWatcher<void> *m_sessionSaveWatcher;
+    bool m_sessionSaveScheduled;
+
     friend class DolphinMainWindowTest;
 };
 
index 35921647ed243e1a3234ef9f8b08076bb930ecc1..f274ffa2abbb4b7f64555ae9daa329a4b4e6bee7 100644 (file)
@@ -426,6 +426,8 @@ void DolphinTabWidget::tabUrlChanged(const QUrl &url)
         if (index == currentIndex()) {
             Q_EMIT currentUrlChanged(url);
         }
+
+        Q_EMIT urlChanged(url);
     }
 }
 
index 1bdb6c9a187f3daee8dcc7fd0cf72e143d908387..22f65b634c634510af0ad6bc058403e94c0aea64 100644 (file)
@@ -111,6 +111,11 @@ Q_SIGNALS:
      */
     void currentUrlChanged(const QUrl &url);
 
+    /**
+     * Is emitted when the url of any tab has been changed (including the current tab).
+     */
+    void urlChanged(const QUrl &url);
+
 public Q_SLOTS:
     /**
      * Opens a new view with the current URL that is part of a tab and activates
index 4c4d790bcfa97e0f94d072f17f1658cad041c826..e93ee43bc96535148e25bbee9ff0047c6f48d041 100644 (file)
@@ -245,6 +245,8 @@ int main(int argc, char **argv)
         }
     }
 
+    mainWindow->setSessionAutoSaveEnabled(GeneralSettings::rememberOpenedTabs());
+
 #if HAVE_KUSERFEEDBACK
     auto feedbackProvider = DolphinFeedbackProvider::instance();
     Q_UNUSED(feedbackProvider)