Bring back support for excluding tabs when restoring after crash

remotes/origin/falkon
David Rosca 11 years ago
parent a9d0e79eeb
commit de46aad181
  1. 275
      src/lib/data/html/restore.html
  2. 3
      src/lib/lib.pro
  3. 4
      src/lib/network/schemehandlers/qupzillaschemehandler.cpp
  4. 60
      src/lib/session/recoveryjsobject.cpp
  5. 5
      src/lib/session/recoveryjsobject.h
  6. 114
      src/lib/session/recoverywidget.cpp
  7. 53
      src/lib/session/recoverywidget.h
  8. 70
      src/lib/session/recoverywidget.ui
  9. 1
      src/lib/webengine/webpage.cpp

@ -7,17 +7,187 @@ html {background: #dddddd;font-family: sans-serif;color: #525c66;}
html * {font-size: 100%;line-height: 1.6;}
#box {max-width:650px;min-width:400px;overflow:auto;margin: 25px auto 10px auto;padding: 10px 40px;border-width: 20px;text-align: %LEFT_STR%;-webkit-border-image: url(%BOX-BORDER%) 25;direction: %DIRECTION%;}
hr {color: lightgray;width: 100%;}
img {float: %LEFT_STR%;margin-%LEFT_STR%: -20px;margin-top: 15px;}
img.warning {float: %LEFT_STR%;margin-%LEFT_STR%: -20px;margin-top: 15px;}
h1 {font-size: 150%;font-weight: bold;border-bottom: 1px solid #f4f4f4;margin-%LEFT_STR%: 48px;margin-%RIGHT_STR%: 50px;}
h2 {font-size: 100%;font-weight: normal;border-bottom: 1px solid #f4f4f4;margin-%LEFT_STR%: 48px;padding: 5px 0px 10px 2px;margin-%RIGHT_STR%: 50px;}
ul {font-size: 90%;padding-%LEFT_STR%: 48px;margin: 20px 0;max-width:600px;}
li {padding: 5px;}
#buttons {margin: 20px 50px;}
#restore-session-button {font-weight: bold;}
#recovery-widget
{
margin: 20px 50px;
}
#recovery-widget .button
{
margin-top: 10px;
height: 25px;
}
#restore-session-button
{
font-weight: bold;
margin-left: 5px;
}
#listview
{
width: 500px;
border-spacing: 0;
border: 1px solid #c0c2c4;
cursor: default;
-webkit-user-select: none;
}
#listview tbody,
#listview thead
{
display: block;
}
#listview thead
{
height: 30px;
background: #eff0f1;
padding-left: 5px;
}
#listview th
{
line-height: 30px;
font-weight: normal;
vertical-align: middle;
}
#listview tbody
{
height: 200px;
overflow-y: auto;
overflow-x: hidden;
}
#listview tbody
{
border-top: 1px solid #c0c2c4;
}
#listview tbody td
{
height: 26px;
width: 480px;
max-width: 480px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
#listview tbody tr:hover
{
background-color: #baddff;
}
#listview tbody tr.selected
{
color: white;
background-color: #1e90ff;
}
#listview img
{
width: 16px;
height: 16px;
margin-right: 7px;
}
#listview input
{
margin-top: 6px;
margin-left: 8px;
margin-right: 10px;
}
#listview .tab input
{
margin-left: 15px;
}
#listview .window
{
font-weight: bold;
}
#listview span
{
vertical-align: top;
}
</style>
<script type="text/javascript">
var selectedRow = null;
function selectRow(row)
{
if (selectedRow) {
selectedRow.className = selectedRow.className.replace(/\bselected\b/, "");
}
row.className = row.className + " selected";
selectedRow = row;
}
function forEachInput(f)
{
var inputs = document.getElementsByTagName("input");
for (var i = 0; i < inputs.length; ++i) {
f(inputs[i]);
}
}
function toggleWindow(e)
{
var win = e.getAttribute("data-window");
forEachInput(function(input) {
if (input.getAttribute("data-window") == win) {
input.checked = e.checked;
}
});
}
function toggleTab(e)
{
var win = e.getAttribute("data-window");
var winElement = null;
var checked = 0;
var total = 0;
forEachInput(function(input) {
if (input.getAttribute("data-window") != win) {
return;
}
if (!input.hasAttribute("data-tab")) {
winElement = input;
return;
}
if (input.checked) {
++checked;
}
++total;
});
if (checked == total) {
winElement.checked = true;
winElement.indeterminate = false;
} else if (checked > 0) {
winElement.indeterminate = true;
} else {
winElement.checked = false;
winElement.indeterminate = false;
}
}
function startNewSession()
{
document.getElementById("start-new-session-button").disabled = true;
@ -27,14 +197,93 @@ function startNewSession()
function restoreSession()
{
document.getElementById("restore-session-button").disabled = true;
external.recovery.restoreSession();
var excludeWin = [];
var excludeTab = [];
forEachInput(function(input) {
if (input.checked || input.indeterminate || !input.hasAttribute("data-tab")) {
return;
}
excludeWin.push(input.getAttribute("data-window"));
excludeTab.push(input.getAttribute("data-tab"));
});
external.recovery.restoreSession(excludeWin, excludeTab);
}
function addWindow(winId)
{
var tr = document.createElement("tr");
tr.className = "window";
tr.onclick = function() { selectRow(tr); };
var td = document.createElement("td");
var input = document.createElement("input");
input.type = "checkbox";
input.checked = true;
input.setAttribute("data-window", winId);
input.onclick = function() { toggleWindow(input); };
var span = document.createElement("span");
span.innerText = "%WINDOW% " + (winId + 1);
tr.appendChild(td);
td.appendChild(input);
td.appendChild(span);
document.getElementById("recovery-items").appendChild(tr);
}
function addTab(winId, tabId, icon, title)
{
var tr = document.createElement("tr");
tr.className = "tab";
tr.onclick = function() { selectRow(tr); };
var td = document.createElement("td");
var input = document.createElement("input");
input.type = "checkbox";
input.checked = true;
input.setAttribute("data-window", winId);
input.setAttribute("data-tab", tabId);
input.onclick = function() { toggleTab(input); };
var img = document.createElement("img");
img.src = icon;
var span = document.createElement("span");
span.innerText = title;
tr.appendChild(td);
td.appendChild(input);
td.appendChild(img);
td.appendChild(span);
document.getElementById("recovery-items").appendChild(tr);
}
function init()
{
external.recovery.restoreData(function(data) {
for (var i = 0; i < data.length; ++i) {
var win = data[i];
addWindow(win.window);
for (var j = 0; j < win.tabs.length; ++j) {
var tab = win.tabs[j];
addTab(win.window, tab.tab, tab.icon, tab.title);
}
}
});
}
// Initialize
if (window.external) {
init();
} else {
document.addEventListener("_qupzilla_external_created", init);
}
</script>
</head>
<body>
<div id="box">
<img src="data:image/png;base64,%IMAGE%" >
<img class="warning" src="data:image/png;base64,%IMAGE%" >
<h1>%OOPS%</h1>
<h2>%APOLOGIZE%</h2>
@ -43,9 +292,19 @@ function restoreSession()
<li>%START-NEW%</li>
</ul>
<div id="buttons">
<input type="button" id="start-new-session-button" value="Start New Session" onclick="startNewSession();">
<input type="button" id="restore-session-button" value=" Restore " onclick="restoreSession();">
<div id="recovery-widget">
<table id="listview">
<thead>
<tr>
<th>%WINDOWS-AND-TABS%</th>
</tr>
</thead>
<tbody id="recovery-items">
</tbody>
</table>
<input class="button" type="button" id="start-new-session-button" value="%BUTTON-START-NEW%" onclick="startNewSession();">
<input class="button" type="button" id="restore-session-button" value=" %BUTTON-RESTORE% " onclick="restoreSession();">
</div>
</div>
</body></html>

@ -180,7 +180,6 @@ SOURCES += \
preferences/sslmanager.cpp \
preferences/thememanager.cpp \
preferences/useragentdialog.cpp \
session/recoverywidget.cpp \
session/recoveryjsobject.cpp \
session/restoremanager.cpp \
sidebar/bookmarkssidebar.cpp \
@ -380,7 +379,6 @@ HEADERS += \
preferences/sslmanager.h \
preferences/thememanager.h \
preferences/useragentdialog.h \
session/recoverywidget.h \
session/recoveryjsobject.h \
session/restoremanager.h \
sidebar/bookmarkssidebar.h \
@ -478,7 +476,6 @@ FORMS += \
preferences/sslmanager.ui \
preferences/thememanager.ui \
preferences/useragentdialog.ui \
session/recoverywidget.ui \
sidebar/bookmarkssidebar.ui \
sidebar/historysidebar.ui \
tools/certificateinfowidget.ui \

@ -335,6 +335,10 @@ QString QupZillaSchemeReply::restorePage()
rPage.replace(QLatin1String("%APOLOGIZE%"), tr("We apologize for this. Would you like to restore the last saved state?"));
rPage.replace(QLatin1String("%TRY-REMOVING%"), tr("Try removing one or more tabs that you think cause troubles"));
rPage.replace(QLatin1String("%START-NEW%"), tr("Or you can start completely new session"));
rPage.replace(QLatin1String("%WINDOW%"), tr("Window"));
rPage.replace(QLatin1String("%WINDOWS-AND-TABS%"), tr("Windows and Tabs"));
rPage.replace(QLatin1String("%BUTTON-START-NEW%"), tr("Start New Session"));
rPage.replace(QLatin1String("%BUTTON-RESTORE%"), tr("Restore"));
rPage = QzTools::applyDirectionToPage(rPage);
}

@ -21,6 +21,9 @@
#include "webpage.h"
#include "tabbedwebview.h"
#include "browserwindow.h"
#include "qztools.h"
#include <QJsonObject>
RecoveryJsObject::RecoveryJsObject(RestoreManager *manager)
: QObject()
@ -36,6 +39,31 @@ void RecoveryJsObject::setPage(WebPage *page)
m_page = page;
}
QJsonArray RecoveryJsObject::restoreData() const
{
QJsonArray out;
int i = 0;
Q_FOREACH (const RestoreManager::WindowData &w, m_manager->restoreData()) {
int j = 0;
QJsonArray tabs;
Q_FOREACH (const WebTab::SavedTab &t, w.tabsState) {
QJsonObject tab;
tab[QSL("tab")] = j++;
tab[QSL("icon")] = QString(QSL("data:image/png;base64,") + QzTools::pixmapToByteArray(t.icon.pixmap(16)));
tab[QSL("title")] = t.title;
tabs.append(tab);
}
QJsonObject window;
window[QSL("window")] = i++;
window[QSL("tabs")] = tabs;
out.append(window);
}
return out;
}
void RecoveryJsObject::startNewSession()
{
BrowserWindow *window = getBrowserWindow();
@ -47,15 +75,39 @@ void RecoveryJsObject::startNewSession()
mApp->destroyRestoreManager();
}
void RecoveryJsObject::restoreSession()
void RecoveryJsObject::restoreSession(const QStringList &excludeWin, const QStringList &excludeTab)
{
Q_ASSERT(excludeWin.size() == excludeTab.size());
RestoreData data = m_manager->restoreData();
for (int i = 0; i < excludeWin.size(); ++i) {
int win = excludeWin.at(i).toInt();
int tab = excludeTab.at(i).toInt();
if (!QzTools::containsIndex(data, win) || !QzTools::containsIndex(data.at(win).tabsState, tab))
continue;
RestoreManager::WindowData &wd = data[win];
wd.tabsState.remove(tab);
if (wd.currentTab >= tab)
--wd.currentTab;
if (wd.tabsState.isEmpty()) {
data.remove(win);
continue;
}
if (wd.currentTab < 0)
wd.currentTab = wd.tabsState.size() - 1;
}
BrowserWindow *window = getBrowserWindow();
if (!window)
return;
bool ok = mApp->restoreSession(window , m_manager->restoreData());
if (!ok)
if (!mApp->restoreSession(window , data))
startNewSession();
}

@ -20,6 +20,7 @@
#define RECOVERYJSOBJECT_H
#include <QObject>
#include <QJsonArray>
class WebPage;
class BrowserWindow;
@ -34,8 +35,10 @@ public:
void setPage(WebPage *page);
public slots:
QJsonArray restoreData() const;
void startNewSession();
void restoreSession();
void restoreSession(const QStringList &excludeWin, const QStringList &excludeTab);
private:
BrowserWindow *getBrowserWindow() const;

@ -1,114 +0,0 @@
/* ============================================================
* QupZilla - WebKit based browser
* Copyright (C) 2010-2014 Franz Fellner <alpine.art.de@googlemail.com>
* David Rosca <nowrep@gmail.com>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* 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/>.
* ============================================================ */
#include "recoverywidget.h"
#include "ui_recoverywidget.h"
#include "restoremanager.h"
#include "mainapplication.h"
#include "webview.h"
#include "browserwindow.h"
RecoveryWidget::RecoveryWidget(WebView* view, BrowserWindow* window)
: QWidget()
, ui(new Ui::RecoveryWidget)
, m_view(view)
, m_window(window)
{
ui->setupUi(this);
setCursor(Qt::ArrowCursor);
const RestoreData data = mApp->restoreManager()->restoreData();
for (int i = 0; i < data.size(); ++i) {
const RestoreManager::WindowData wd = data.at(i);
QTreeWidgetItem* root = new QTreeWidgetItem(ui->treeWidget);
root->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsTristate);
root->setText(0, tr("Window %1").arg((i + 1)));
root->setCheckState(0, Qt::Checked);
for (int tab = 0; tab < wd.tabsState.size(); ++tab) {
const WebTab::SavedTab st = wd.tabsState.at(tab);
QTreeWidgetItem* child = new QTreeWidgetItem(root);
child->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
child->setCheckState(0, Qt::Checked);
child->setIcon(0, st.icon);
child->setText(0, st.title);
}
}
ui->treeWidget->expandAll();
connect(ui->restoreSession, SIGNAL(clicked()), this, SLOT(restoreSession()));
connect(ui->newSession, SIGNAL(clicked()), this, SLOT(newSession()));
}
void RecoveryWidget::restoreSession()
{
RestoreManager* manager = mApp->restoreManager();
if (!manager) {
return;
}
RestoreData data = manager->restoreData();
for (int win = ui->treeWidget->topLevelItemCount() - 1; win >= 0; --win) {
QTreeWidgetItem* root = ui->treeWidget->topLevelItem(win);
if (root->checkState(0) == Qt::Unchecked) {
data.remove(win);
continue;
}
RestoreManager::WindowData &wd = data[win];
for (int tab = root->childCount() - 1; tab >= 0; --tab) {
if (root->child(tab)->checkState(0) == Qt::Unchecked) {
wd.tabsState.remove(tab);
if (wd.currentTab >= tab) {
wd.currentTab--;
}
}
}
if (wd.tabsState.isEmpty()) {
data.remove(win);
continue;
}
if (wd.currentTab < 0) {
wd.currentTab = wd.tabsState.size() - 1;
}
}
if (!mApp->restoreSession(m_window, data)) {
newSession();
}
}
void RecoveryWidget::newSession()
{
m_view->load(m_window->homepageUrl());
mApp->destroyRestoreManager();
}
RecoveryWidget::~RecoveryWidget()
{
delete ui;
}

@ -1,53 +0,0 @@
/* ============================================================
* QupZilla - WebKit based browser
* Copyright (C) 2010-2014 Franz Fellner <alpine.art.de@googlemail.com>
* David Rosca <nowrep@gmail.com>
*
* 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 3 of the License, or
* (at your option) any later version.
*
* 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 RECOVERYWIDGET_H
#define RECOVERYWIDGET_H
#include <QWidget>
namespace Ui
{
class RecoveryWidget;
}
class QTreeWidgetItem;
class WebView;
class BrowserWindow;
class RecoveryWidget : public QWidget
{
Q_OBJECT
public:
explicit RecoveryWidget(WebView* view, BrowserWindow* window);
~RecoveryWidget();
private slots:
void restoreSession();
void newSession();
private:
Ui::RecoveryWidget* ui;
WebView* m_view;
BrowserWindow* m_window;
};
#endif // RECOVERYWIDGET_H

@ -1,70 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>RecoveryWidget</class>
<widget class="QWidget" name="RecoveryWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>500</width>
<height>300</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTreeWidget" name="treeWidget">
<column>
<property name="text">
<string>Windows and Tabs</string>
</property>
</column>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="newSession">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Start New Session</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="restoreSession">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="text">
<string>Restore</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

@ -36,7 +36,6 @@
#include "qzsettings.h"
#include "useragentmanager.h"
#include "delayedfilewatcher.h"
#include "recoverywidget.h"
#include "searchenginesmanager.h"
#include "html5permissions/html5permissionsmanager.h"
#include "schemehandlers/fileschemehandler.h"

Loading…
Cancel
Save