From a0315947c024a3be1d35b4700af7fa653272093e Mon Sep 17 00:00:00 2001 From: Anton Kreuzkamp Date: Sun, 21 Aug 2011 12:01:26 +0200 Subject: Restore tab's history when restoring a tab/session We finally have it :D CCMAIL: akreuzkamp@web.de REVIEW: 100604 REVIEWED-BY: adjam, elproxy --- src/history/historymanager.h | 36 +++++++++++ src/mainview.cpp | 47 +++++++------- src/mainview.h | 4 +- src/newtabpage.cpp | 4 +- src/sessionmanager.cpp | 145 ++++++++++++++++++++++++------------------- src/sessionmanager.h | 3 +- src/tabbar.cpp | 4 +- 7 files changed, 151 insertions(+), 92 deletions(-) diff --git a/src/history/historymanager.h b/src/history/historymanager.h index 101bc09d..bdce16d7 100644 --- a/src/history/historymanager.h +++ b/src/history/historymanager.h @@ -46,6 +46,7 @@ #include #include #include +#include #include @@ -97,6 +98,41 @@ public: }; +// --------------------------------------------------------------------------------------------------------------- + +class TabHistory +{ +public: + explicit TabHistory(QWebHistory *h = 0) + { + if (h) + { + title = h->currentItem().title(); + url = h->currentItem().url().toString(); + QDataStream stream(&history, QIODevice::ReadWrite); + stream << *h; + } + } + + inline bool operator ==(const TabHistory &other) const + { + return history == other.history; + } + + void applyHistory(QWebHistory *h) + { + if (h) + { + QDataStream stream(&history, QIODevice::ReadOnly); + stream >> *h; + } + } + + QString title; + QString url; + QByteArray history; +}; + // --------------------------------------------------------------------------------------------------------------- diff --git a/src/mainview.cpp b/src/mainview.cpp index ca5ae654..b5738944 100644 --- a/src/mainview.cpp +++ b/src/mainview.cpp @@ -100,16 +100,13 @@ MainView::MainView(MainWindow *parent) void MainView::postLaunch() { - QStringList list = rApp->sessionManager()->closedSites(); - Q_FOREACH(const QString & line, list) + QList list = rApp->sessionManager()->closedSites(); + Q_FOREACH(const TabHistory & tab, list) { - if (line.startsWith(QL1S("about"))) - break; - QString title = line; - QString url = title; - HistoryItem item(url, QDateTime(), title); - m_recentlyClosedTabs.removeAll(item); - m_recentlyClosedTabs.prepend(item); + if (tab.url.startsWith(QL1S("about"))) + continue; + m_recentlyClosedTabs.removeAll(tab); + m_recentlyClosedTabs.prepend(tab); } // Session Manager @@ -486,13 +483,12 @@ void MainView::closeTab(int index, bool del) ) { const int recentlyClosedTabsLimit = 10; - QString title = tabToClose->view()->title(); - QString url = tabToClose->url().prettyUrl(); - HistoryItem item(url, QDateTime(), title); - m_recentlyClosedTabs.removeAll(item); + TabHistory history(tabToClose->view()->history()); + + m_recentlyClosedTabs.removeAll(history); if (m_recentlyClosedTabs.count() == recentlyClosedTabsLimit) m_recentlyClosedTabs.removeLast(); - m_recentlyClosedTabs.prepend(item); + m_recentlyClosedTabs.prepend(history); } removeTab(index); @@ -652,8 +648,10 @@ void MainView::openLastClosedTab() if (m_recentlyClosedTabs.isEmpty()) return; - const HistoryItem item = m_recentlyClosedTabs.takeFirst(); - rApp->loadUrl(KUrl(item.url), Rekonq::NewTab); + TabHistory history = m_recentlyClosedTabs.takeFirst(); + WebView *view = rApp->mainWindow()->mainView()->newWebTab()->view(); + + history.applyHistory(view->history()); } @@ -662,12 +660,19 @@ void MainView::openClosedTab() KAction *action = qobject_cast(sender()); if (action) { - rApp->loadUrl(action->data().toUrl(), Rekonq::NewTab); + WebView *view = rApp->mainWindow()->mainView()->newWebTab()->view(); + TabHistory history; + Q_FOREACH(TabHistory item, m_recentlyClosedTabs) + { + if (item.history == action->data().toByteArray()) + { + history = item; + break; + } + } + history.applyHistory(view->history()); - QString title = action->text(); - title = title.remove('&'); - HistoryItem item(action->data().toString(), QDateTime(), title); - m_recentlyClosedTabs.removeAll(item); + m_recentlyClosedTabs.removeAll(history); } } diff --git a/src/mainview.h b/src/mainview.h index 2ca3e9e7..ede1d62e 100644 --- a/src/mainview.h +++ b/src/mainview.h @@ -100,7 +100,7 @@ public: */ WebTab *newWebTab(bool focused = true); - inline QList recentlyClosedTabs() + inline QList recentlyClosedTabs() { return m_recentlyClosedTabs; } @@ -199,7 +199,7 @@ private: int m_currentTabIndex; - QList m_recentlyClosedTabs; + QList m_recentlyClosedTabs; MainWindow *m_parentWindow; }; diff --git a/src/newtabpage.cpp b/src/newtabpage.cpp index 6de35038..761bccd8 100644 --- a/src/newtabpage.cpp +++ b/src/newtabpage.cpp @@ -511,7 +511,7 @@ void NewTabPage::closedTabsPage() { m_root.addClass(QL1S("closedTabs")); - QList links = rApp->mainWindow()->mainView()->recentlyClosedTabs(); + QList links = rApp->mainWindow()->mainView()->recentlyClosedTabs(); if (links.isEmpty()) { @@ -522,7 +522,7 @@ void NewTabPage::closedTabsPage() for (int i = 0; i < links.count(); ++i) { - HistoryItem item = links.at(i); + TabHistory item = links.at(i); QWebElement prev; if (item.url.isEmpty()) diff --git a/src/sessionmanager.cpp b/src/sessionmanager.cpp index d6889cff..1377132c 100644 --- a/src/sessionmanager.cpp +++ b/src/sessionmanager.cpp @@ -65,21 +65,37 @@ void SessionManager::saveSession() kDebug() << "Unable to open session file" << sessionFile.fileName(); return; } - QTextStream out(&sessionFile); MainWindowList wl = rApp->mainWindowList(); + QDomDocument document("session"); + QDomElement session = document.createElement("session"); + document.appendChild(session); + Q_FOREACH(const QWeakPointer &w, wl) { - out << "window\n"; MainView *mv = w.data()->mainView(); - for (int i = 0 ; i < mv->count() ; i++) + QDomElement window = document.createElement("window"); + for (signed int tabNo = 0; tabNo < mv->count(); tabNo++) { - out << mv->webTab(i)->url().toEncoded() << "\n"; - } + QDomElement tab = document.createElement("tab"); + tab.setAttribute("title", mv->webTab(tabNo)->view()->title()); // redundant, but needed for closedSites() + // as there's not way to read out the historyData + tab.setAttribute("url", mv->webTab(tabNo)->view()->url().toString()); + if (mv->tabBar()->currentIndex() == tabNo) + { + tab.setAttribute("currentTab", 1); + } + QByteArray history; + QDataStream historyStream(&history, QIODevice::ReadWrite); + historyStream << *(mv->webTab(tabNo)->view()->history()); + QDomCDATASection historySection = document.createCDATASection(history.toBase64()); - // Current Tab for window - out << "currenttab\n"; - out << mv->tabBar()->currentIndex() << "\n"; + tab.appendChild(historySection); + window.appendChild(tab); + } + session.appendChild(window); } + QTextStream TextStream(&sessionFile); + document.save(TextStream, 2); sessionFile.close(); m_safe = true; return; @@ -97,58 +113,56 @@ bool SessionManager::restoreSession() return false; } - QTextStream in(&sessionFile); - QString line; bool windowAlreadyOpen = rApp->mainWindowList().count(); - do + MainWindowList wl; + + QDomDocument document("session"); + if (!document.setContent(&sessionFile, false)) { - line = in.readLine(); - if (line == QL1S("window")) - { - line = in.readLine(); - if (windowAlreadyOpen) - { - rApp->loadUrl(KUrl(line), Rekonq::CurrentTab); - windowAlreadyOpen = false; - } - else - { - rApp->loadUrl(KUrl(line), Rekonq::NewWindow); - } - } + kDebug() << "Unable to parse session file" << sessionFile.fileName(); + return false; + } + + for (unsigned int winNo = 0; winNo < document.elementsByTagName("window").length(); winNo++) + { + QDomElement window = document.elementsByTagName("window").at(winNo).toElement(); + int currentTab = 0; + + if (windowAlreadyOpen) + windowAlreadyOpen = false; else + rApp->newMainWindow(false); + + wl = rApp->mainWindowList(); //get the latest windowlist + if (wl.count() == 0) + continue; + MainView *mv = wl.at(0).data()->mainView(); //last mainwindow created will be first one in mainwindow list + + for (unsigned int tabNo = 0; tabNo < window.elementsByTagName("tab").length(); tabNo++) { - if (line == QL1S("currenttab")) - { - line = in.readLine(); - bool ok; - int idx = line.toInt(&ok); - if (ok) - { - // Get last mainwindow created which will be first one in mainwindow list - MainWindowList wl = rApp->mainWindowList(); - if (wl.count() > 0) - { - MainView *mv = wl[0].data()->mainView(); - emit mv->tabBar()->setCurrentIndex(idx); - } - } - } - else - { - rApp->loadUrl(KUrl(line), Rekonq::NewFocusedTab); - } + QDomElement tab = window.elementsByTagName("tab").at(tabNo).toElement(); + if (tab.hasAttribute("currentTab")) + currentTab = tabNo; + + WebView *view = mv->newWebTab()->view(); + + QDomCDATASection historySection = tab.firstChild().toCDATASection(); + QByteArray history = QByteArray::fromBase64(historySection.data().toAscii()); + + QDataStream readingStream(&history, QIODevice::ReadOnly); + readingStream >> *(view->history()); } + + mv->tabBar()->setCurrentIndex(currentTab); } - while (!line.isEmpty()); return true; } -QStringList SessionManager::closedSites() +QList SessionManager::closedSites() { - QStringList list; + QList list; QFile sessionFile(m_sessionFilePath); if (!sessionFile.exists()) @@ -159,24 +173,27 @@ QStringList SessionManager::closedSites() return list; } - QTextStream in(&sessionFile); - QString line; - do + QDomDocument document("session"); + if (!document.setContent(&sessionFile, false)) { - line = in.readLine(); - if (line != QL1S("window")) - { - if (line == QL1S("currenttab")) - { - in.readLine(); // drop out the next field, containing the index of the current tab.. - } - else - { - list << QString(line); - } - } + kDebug() << "Unable to parse session file" << sessionFile.fileName(); + 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; } - while (!line.isEmpty()); return list; } diff --git a/src/sessionmanager.h b/src/sessionmanager.h index 22972906..fa23623e 100644 --- a/src/sessionmanager.h +++ b/src/sessionmanager.h @@ -38,6 +38,7 @@ // Forward Declarations class QString; +class TabHistory; /** @@ -54,7 +55,7 @@ public: m_safe = on; } - QStringList closedSites(); + QList closedSites(); public slots: bool restoreSession(); diff --git a/src/tabbar.cpp b/src/tabbar.cpp index 48a0ad70..2c28573f 100644 --- a/src/tabbar.cpp +++ b/src/tabbar.cpp @@ -395,10 +395,10 @@ void TabBar::setupHistoryActions() if (!isEnabled) return; - Q_FOREACH(const HistoryItem & item, mv->recentlyClosedTabs()) + Q_FOREACH(const TabHistory & item, mv->recentlyClosedTabs()) { KAction *a = new KAction(rApp->iconManager()->iconForUrl(item.url), item.title, this); - a->setData(item.url); + a->setData(item.history); connect(a, SIGNAL(triggered()), mv, SLOT(openClosedTab())); am->addAction(a); } -- cgit v1.2.1