diff options
-rw-r--r-- | src/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/application.cpp | 49 | ||||
-rw-r--r-- | src/autosaver.cpp (renamed from src/history/autosaver.cpp) | 0 | ||||
-rw-r--r-- | src/autosaver.h (renamed from src/history/autosaver.h) | 0 | ||||
-rw-r--r-- | src/main.cpp | 8 | ||||
-rw-r--r-- | src/session/sessionmanager.cpp | 331 | ||||
-rw-r--r-- | src/session/sessionmanager.h | 104 |
7 files changed, 465 insertions, 30 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a15e2c62..12d19a2b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,6 +16,8 @@ set(rekonq_KDEINIT_SRCS history/historymanager.cpp history/historymodels.cpp #---------------------------------------- + session/sessionmanager.cpp + #---------------------------------------- tabwindow/tabbar.cpp tabwindow/tabhighlighteffect.cpp tabwindow/tabpreviewpopup.cpp @@ -31,6 +33,7 @@ set(rekonq_KDEINIT_SRCS INCLUDE_DIRECTORIES ( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/history + ${CMAKE_CURRENT_SOURCE_DIR}/session ${CMAKE_CURRENT_SOURCE_DIR}/tabwindow ${CMAKE_CURRENT_SOURCE_DIR}/webwindow ${CMAKE_CURRENT_BINARY_DIR} diff --git a/src/application.cpp b/src/application.cpp index 2434eeaa..286f113f 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -32,12 +32,14 @@ #include "rekonq.h" // Local Includes +#include "searchengine.h" #include "tabwindow.h" #include "webwindow.h" #include "urlresolver.h" // Local Manager(s) Includes #include "historymanager.h" +#include "sessionmanager.h" // // KDE Includes #include <KCmdLineArgs> @@ -120,10 +122,10 @@ int Application::newInstance() } } -// if (isFirstLoad && (ReKonfig::startupBehaviour() == 2)) // && sessionManager()->restoreSessionFromScratch()) -// { -// isFirstLoad = false; -// } + if (isFirstLoad && (ReKonfig::startupBehaviour() == 2) && SessionManager::self()->restoreSessionFromScratch()) + { + isFirstLoad = false; + } // first argument: 99% of the time we have just that... if (isFirstLoad) @@ -178,11 +180,11 @@ int Application::newInstance() case 1: // open new tab page loadUrl(KUrl("about:home"), Rekonq::NewWindow); break; - case 2: // restore session FIXME -// if (sessionManager()->restoreSessionFromScratch()) -// { -// break; -// } + case 2: // restore session + if (SessionManager::self()->restoreSessionFromScratch()) + { + break; + } default: newTabWindow()->newCleanTab(); break; @@ -208,20 +210,19 @@ int Application::newInstance() } } // !isSessionRestored() -// if (isFirstLoad) -// { -// FIXME -// if (hasToBeRecovered) -// { -// QTimer::singleShot(1000, tabWindow()->currentTab(), SLOT(showMessageBar())); -// } -// else -// { -// sessionManager()->setSessionManagementEnabled(true); -// } -// -// if (ReKonfig::checkDefaultSearchEngine() && !hasToBeRecovered && SearchEngine::defaultEngine().isNull()) -// QTimer::singleShot(2000, tabWindow()->currentTab(), SLOT(showSearchEngineBar())); + if (isFirstLoad) + { + if (hasToBeRecovered) + { + QTimer::singleShot(1000, tabWindow()->currentWebWindow(), SLOT(showMessageBar())); + } + else + { + SessionManager::self()->setSessionManagementEnabled(true); + } + + if (ReKonfig::checkDefaultSearchEngine() && !hasToBeRecovered && SearchEngine::defaultEngine().isNull()) + QTimer::singleShot(2000, tabWindow()->currentWebWindow(), SLOT(showSearchEngineBar())); // updating rekonq configuration updateConfiguration(); @@ -233,7 +234,7 @@ int Application::newInstance() ReKonfig::setRecoverOnCrash(ReKonfig::recoverOnCrash() + 1); saveConfiguration(); -// } + } KStartupInfo::appStarted(); isFirstLoad = false; diff --git a/src/history/autosaver.cpp b/src/autosaver.cpp index ee84e299..ee84e299 100644 --- a/src/history/autosaver.cpp +++ b/src/autosaver.cpp diff --git a/src/history/autosaver.h b/src/autosaver.h index cb1add2f..cb1add2f 100644 --- a/src/history/autosaver.h +++ b/src/autosaver.h diff --git a/src/main.cpp b/src/main.cpp index c5759d84..5ed5dc08 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -75,6 +75,8 @@ extern "C" KDE_EXPORT int kdemain(int argc, char **argv) QApplication::setGraphicsSystem(QLatin1String("raster")); #endif + KCmdLineArgs::setCwd(QDir::currentPath().toUtf8()); + Application app; QWebSettings::setIconDatabasePath("/tmp/iconcache"); @@ -83,11 +85,5 @@ extern "C" KDE_EXPORT int kdemain(int argc, char **argv) QCoreApplication::setApplicationName(QLatin1String("rekonq")); QCoreApplication::setApplicationVersion(REKONQ_VERSION); - KCmdLineArgs::setCwd(QDir::currentPath().toUtf8()); - -// if (app.isSessionRestored()) -// for (int i = 1; MainWindow::canBeRestored(i); i++) -// app.newMainWindow(false)->restore(i); - return app.exec(); } diff --git a/src/session/sessionmanager.cpp b/src/session/sessionmanager.cpp new file mode 100644 index 00000000..1ea5c133 --- /dev/null +++ b/src/session/sessionmanager.cpp @@ -0,0 +1,331 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009-2012 by Andrea Diamantini <adjam7 at gmail dot com> +* Copyright (C) 2009 by Yoram Bar-Haim <<yoram.b at zend dot com> +* Copyright (C) 2009-2011 by Lionel Chauvin <megabigbug@yahoo.fr> +* +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + + +// Self Includes +#include "sessionmanager.h" +#include "sessionmanager.moc" + +// Local Includes +#include "application.h" +#include "autosaver.h" +#include "tabhistory.h" +#include "tabwindow.h" +#include "webwindow.h" +#include "webpage.h" + +// KDE Includes +#include <KStandardDirs> +#include <KUrl> + +// Qt Includes +#include <QFile> +#include <QDomDocument> + + +// Only used internally +bool readSessionDocument(QDomDocument & document, const QString & sessionFilePath) +{ + QFile sessionFile(sessionFilePath); + + if (!sessionFile.exists()) + return false; + + if (!sessionFile.open(QFile::ReadOnly)) + { + kDebug() << "Unable to open session file" << sessionFile.fileName(); + return false; + } + + if (!document.setContent(&sessionFile, false)) + { + kDebug() << "Unable to parse session file" << sessionFile.fileName(); + return false; + } + + return true; +} + + +int loadTabs(TabWindow *tw, QDomElement & window, bool useFirstTab) +{ + int currentTab = 0; + + for (unsigned int tabNo = 0; tabNo < window.elementsByTagName("tab").length(); tabNo++) + { + QDomElement tab = window.elementsByTagName("tab").at(tabNo).toElement(); + if (tab.hasAttribute("currentTab")) + currentTab = tabNo; + + KUrl u = KUrl(tab.attribute("url")); + + TabHistory tabHistory; + tabHistory.title = tab.attribute("title"); + tabHistory.url = tab.attribute("url"); + QDomCDATASection historySection = tab.firstChild().toCDATASection(); + tabHistory.history = QByteArray::fromBase64(historySection.data().toAscii()); + + if (tabNo == 0 && useFirstTab) + { + tw->loadUrl(u, Rekonq::CurrentTab, &tabHistory); + } + else + { + tw->loadUrl(u, Rekonq::NewTab, &tabHistory); + } + } + + return currentTab; +} + + +// ------------------------------------------------------------------------------------------------- + + +QWeakPointer<SessionManager> SessionManager::s_sessionyManager; + + +SessionManager *SessionManager::self() +{ + if (s_sessionyManager.isNull()) + { + s_sessionyManager = new SessionManager(qApp); + } + return s_sessionyManager.data(); +} + + +// ---------------------------------------------------------------------------------------------- + + +SessionManager::SessionManager(QObject *parent) + : QObject(parent) + , m_safe(true) + , m_isSessionEnabled(false) + , m_saveTimer(new AutoSaver(this)) +{ + // AutoSaver. Save your hd from frying... + connect(m_saveTimer, SIGNAL(saveNeeded()), this, SLOT(save())); + + m_sessionFilePath = KStandardDirs::locateLocal("appdata" , "session"); +} + + +void SessionManager::saveSession() +{ + if (!m_isSessionEnabled) + return; + + m_saveTimer->changeOccurred(); +} + + +void SessionManager::save() +{ + if (!m_isSessionEnabled || !m_safe) + return; + + m_safe = false; + + kDebug() << "SAVING SESSION..."; + + QFile sessionFile(m_sessionFilePath); + if (!sessionFile.open(QFile::WriteOnly | QFile::Truncate)) + { + kDebug() << "Unable to open session file" << sessionFile.fileName(); + return; + } + TabWindowList wl = rApp->tabWindowList(); + QDomDocument document("session"); + QDomElement session = document.createElement("session"); + document.appendChild(session); + + Q_FOREACH(const QWeakPointer<TabWindow> &w, wl) + { + QDomElement window = document.createElement("window"); + int tabInserted = 0; + + window.setAttribute("name", w.data()->objectName()); + + for (signed int tabNo = 0; tabNo < w.data()->count(); tabNo++) + { + KUrl u = w.data()->webWindow(tabNo)->url(); + + tabInserted++; + QDomElement tab = document.createElement("tab"); + tab.setAttribute("title", w.data()->webWindow(tabNo)->title()); // redundant, but needed for closedSites() + // as there's not way to read out the historyData + tab.setAttribute("url", u.url()); + if (w.data()->currentIndex() == tabNo) + { + tab.setAttribute("currentTab", 1); + } + QByteArray history; + QDataStream historyStream(&history, QIODevice::ReadWrite); + historyStream << *(w.data()->webWindow(tabNo)->page()->history()); + QDomCDATASection historySection = document.createCDATASection(history.toBase64()); + + tab.appendChild(historySection); + window.appendChild(tab); + } + if (tabInserted > 0) + session.appendChild(window); + } + + QTextStream TextStream(&sessionFile); + document.save(TextStream, 2); + sessionFile.close(); + + m_safe = true; + return; +} + + +bool SessionManager::restoreSessionFromScratch() +{ + QDomDocument document("session"); + + if (!readSessionDocument(document, m_sessionFilePath)) + return false; + + for (unsigned int winNo = 0; winNo < document.elementsByTagName("window").length(); winNo++) + { + QDomElement window = document.elementsByTagName("window").at(winNo).toElement(); + + TabWindow *tw = rApp->newTabWindow(); + + int currentTab = loadTabs(tw, window, false); + + tw->setCurrentIndex(currentTab); + } + + return true; +} + + +void SessionManager::restoreCrashedSession() +{ + QDomDocument document("session"); + + if (!readSessionDocument(document, m_sessionFilePath)) + return; + + for (unsigned int winNo = 0; winNo < document.elementsByTagName("window").length(); winNo++) + { + QDomElement window = document.elementsByTagName("window").at(winNo).toElement(); + + TabWindow *tw = (winNo == 0) + ? rApp->tabWindow() + : rApp->newTabWindow(); + + KUrl u = tw->currentWebWindow()->url(); + bool useCurrentTab = (u.isEmpty() || u.protocol() == QL1S("about")); + int currentTab = loadTabs(tw, window, useCurrentTab); + + tw->setCurrentIndex(currentTab); + } + + setSessionManagementEnabled(true); +} + + +int SessionManager::restoreSavedSession() +{ + QDomDocument document("session"); + + if (!readSessionDocument(document, m_sessionFilePath)) + return 0; + + unsigned int winNo; + + for (winNo = 0; winNo < document.elementsByTagName("window").length(); winNo++) + { + QDomElement window = document.elementsByTagName("window").at(winNo).toElement(); + + TabWindow *tw = rApp->newTabWindow(); + + int currentTab = loadTabs(tw, window, true); + + tw->setCurrentIndex(currentTab); + } + + return winNo; +} + + +bool SessionManager::restoreTabWindow(TabWindow* window) +{ + QDomDocument document("session"); + + if (!readSessionDocument(document, m_sessionFilePath)) + return false; + + unsigned int winNo; + + for (winNo = 0; winNo < document.elementsByTagName("window").length(); winNo++) + { + QDomElement savedWindowElement = document.elementsByTagName("window").at(winNo).toElement(); + + if (window->objectName() != savedWindowElement.attribute("name", "")) + continue; + + int currentTab = loadTabs(window, savedWindowElement, false); + + window->setCurrentIndex(currentTab); + + return true; + } + + return false; +} + + +QList<TabHistory> SessionManager::closedSites() +{ + QList<TabHistory> list; + QDomDocument document("session"); + + if (!readSessionDocument(document, m_sessionFilePath)) + return list; + + for (unsigned int tabNo = 0; tabNo < document.elementsByTagName("tab").length(); tabNo++) + { + QDomElement tab = document.elementsByTagName("tab").at(tabNo).toElement(); + + TabHistory tabHistory; + + tabHistory.title = tab.attribute("title"); + tabHistory.url = tab.attribute("url"); + + QDomCDATASection historySection = tab.firstChild().toCDATASection(); + tabHistory.history = QByteArray::fromBase64(historySection.data().toAscii()); + + list << tabHistory; + } + + return list; +} diff --git a/src/session/sessionmanager.h b/src/session/sessionmanager.h new file mode 100644 index 00000000..31afea82 --- /dev/null +++ b/src/session/sessionmanager.h @@ -0,0 +1,104 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009-2012 by Andrea Diamantini <adjam7 at gmail dot com> +* Copyright (C) 2009 by Yoram Bar-Haim <<yoram.b at zend dot com> +* Copyright (C) 2009-2011 by Lionel Chauvin <megabigbug@yahoo.fr> +* +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation; either version 2 of +* the License or (at your option) version 3 or any later version +* accepted by the membership of KDE e.V. (or its successor approved +* by the membership of KDE e.V.), which shall act as a proxy +* defined in Section 14 of version 3 of the license. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* ============================================================ */ + + +#ifndef SESSION_MANAGER_H +#define SESSION_MANAGER_H + + +// Rekonq Includes +#include "rekonq_defines.h" + +// Qt Includes +#include <QObject> +#include <QString> +#include <QWeakPointer> + +// Forward Declarations +class AutoSaver; +class TabHistory; +class TabWindow; + + +/** + * Session Management: Needs clean up :) + * + */ +class REKONQ_TESTS_EXPORT SessionManager : public QObject +{ + Q_OBJECT + +public: + /** + * Entry point. + * Access to SessionManager class by using + * SessionyManager::self()->thePublicMethodYouNeed() + */ + static SessionManager *self(); + + inline void setSessionManagementEnabled(bool on) + { + m_isSessionEnabled = on; + } + + QList<TabHistory> closedSites(); + + // This method restores session + // while turning back from Private mode + int restoreSavedSession(); + + // This method restores a single TabWindow + bool restoreTabWindow(TabWindow * window); + +private: + SessionManager(QObject *parent = 0); + +public Q_SLOTS: + // This method restores session + // on restart when restore at startup is chosen + bool restoreSessionFromScratch(); + +private Q_SLOTS: + void saveSession(); + void save(); + + // This method restores session + // after a crash + void restoreCrashedSession(); + +private: + QString m_sessionFilePath; + + bool m_safe; + bool m_isSessionEnabled; + AutoSaver *m_saveTimer; + + static QWeakPointer<SessionManager> s_sessionyManager; +}; + + +#endif // SESSION_MANAGER_H |