From 7504b595fea9924a4a397cea3dc69fa2e0fd0119 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20E=2E=20Narv=C3=A1ez?= Date: Thu, 12 Jan 2012 23:11:33 -0500 Subject: Implement (User) Session Restore This patch implements session management. Most of the ideas are taken from Konsole, which is also a KUniqueApplication but manages session restoring correctly. REVIEW: 103658 --- src/application.cpp | 11 ++++++++- src/main.cpp | 5 ++++ src/mainwindow.cpp | 6 +++++ src/mainwindow.h | 1 + src/sessionmanager.cpp | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/sessionmanager.h | 5 +++- 6 files changed, 90 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/application.cpp b/src/application.cpp index a09fc26e..e868116d 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -183,7 +183,7 @@ int Application::newInstance() // 2) Are there arguments? // 3) Is rekonq recovering from crash? // so, we have 8 possible cases... - bool isFirstLoad = m_mainWindows.isEmpty(); + static bool isFirstLoad = true; bool areThereArguments = (args->count() > 0); bool isRekonqCrashed = (ReKonfig::recoverOnCrash() > 0); // note that isRekonqCrashed is always true if it is not the first load @@ -195,6 +195,13 @@ int Application::newInstance() int exitValue = 1 * isFirstLoad + 2 * areThereArguments + 4 * isRekonqCrashed; + if (isFirstLoad && isSessionRestored()) + { + isFirstLoad = false; + + return exitValue; + } + if (isRekonqCrashed && isFirstLoad) { loadUrl(KUrl("about:closedTabs"), Rekonq::NewWindow); @@ -312,6 +319,8 @@ int Application::newInstance() } KStartupInfo::appStarted(); + isFirstLoad = false; + return exitValue; } diff --git a/src/main.cpp b/src/main.cpp index a9082d7a..d9c9968f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -29,6 +29,7 @@ // Local Includes #include "application.h" +#include "mainwindow.h" // KDE Includes #include @@ -212,5 +213,9 @@ extern "C" KDE_EXPORT int kdemain(int argc, char **argv) Application app; + if (app.isSessionRestored()) + for (int i = 1; MainWindow::canBeRestored(i); i++) + app.newMainWindow()->restore(i); + return app.exec(); } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 98936e96..feeb0383 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -650,6 +650,12 @@ void MainWindow::finalizeGUI(KXMLGUIClient* client) << " ====================== "; } +void MainWindow::readProperties(const KConfigGroup& config) +{ + Q_UNUSED(config) + + Application::instance()->sessionManager()->restoreMainWindow(this); +} void MainWindow::openLocation() { diff --git a/src/mainwindow.h b/src/mainwindow.h index 04a59a14..abdf903a 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -142,6 +142,7 @@ protected: bool event(QEvent *event); + void readProperties(const KConfigGroup & config); void finalizeGUI(KXMLGUIClient *client); private Q_SLOTS: diff --git a/src/sessionmanager.cpp b/src/sessionmanager.cpp index 20b35016..1bb96b54 100644 --- a/src/sessionmanager.cpp +++ b/src/sessionmanager.cpp @@ -78,6 +78,9 @@ void SessionManager::saveSession() MainView *mv = w.data()->mainView(); QDomElement window = document.createElement("window"); int tabInserted = 0; + + window.setAttribute("name", w.data()->objectName()); + for (signed int tabNo = 0; tabNo < mv->count(); tabNo++) { // IGNORE about urls @@ -278,6 +281,67 @@ int SessionManager::restoreSavedSession() return winNo; } +bool SessionManager::restoreMainWindow(MainWindow* window) +{ + QFile sessionFile(m_sessionFilePath); + if (!sessionFile.exists()) + { + kDebug() << "Unable to find session file" << sessionFile.fileName(); + return 0; + } + + if (!sessionFile.open(QFile::ReadOnly)) + { + kDebug() << "Unable to open session file" << sessionFile.fileName(); + return 0; + } + + QDomDocument document("session"); + if (!document.setContent(&sessionFile, false)) + { + kDebug() << "Unable to parse session file" << sessionFile.fileName(); + return 0; + } + + unsigned int winNo; + + for (winNo = 0; winNo < document.elementsByTagName("window").length(); winNo++) + { + QDomElement savedWindowElement = document.elementsByTagName("window").at(winNo).toElement(); + int currentTab = 0; + + if (window->objectName() != savedWindowElement.attribute("name", "")) + continue; + + MainView *mv = window->mainView(); + + for (unsigned int tabNo = 0; tabNo < savedWindowElement.elementsByTagName("tab").length(); tabNo++) + { + QDomElement tab = savedWindowElement.elementsByTagName("tab").at(tabNo).toElement(); + if (tab.hasAttribute("currentTab")) + currentTab = tabNo; + + WebView *view = (tabNo == 0) ? mv->webTab(0)->view() : mv->newWebTab()->view(); + + QDomCDATASection historySection = tab.firstChild().toCDATASection(); + QByteArray history = QByteArray::fromBase64(historySection.data().toAscii()); + + QDataStream readingStream(&history, QIODevice::ReadOnly); + readingStream >> *(view->history()); + + // Get sure about urls are loaded + KUrl u = KUrl(tab.attribute("url")); + if (u.protocol() == QL1S("about")) + view->load(u); + } + + mv->tabBar()->setCurrentIndex(currentTab); + + return true; + } + + return false; +} QList SessionManager::closedSites() { diff --git a/src/sessionmanager.h b/src/sessionmanager.h index d0d7efde..a8560b41 100644 --- a/src/sessionmanager.h +++ b/src/sessionmanager.h @@ -39,7 +39,7 @@ // Forward Declarations class QString; class TabHistory; - +class MainWindow; /** * Session Management: Needs clean up :) @@ -61,6 +61,9 @@ public: // while turning back from Private mode int restoreSavedSession(); + // This method restores a single MainWindow + bool restoreMainWindow(MainWindow * window); + public Q_SLOTS: // This method restores session // on restart when restore at startup is chosen -- cgit v1.2.1