From 6181e316ce8cfc1bef05c466a2470427ceb2deac Mon Sep 17 00:00:00 2001 From: Pierre Rossi Date: Wed, 15 Sep 2010 21:21:33 +0200 Subject: Prompt user before restoring session after a crash. Shows the about:closedTabs page in the background. Task: https://bugs.kde.org/show_bug.cgi?id=249228 --- src/CMakeLists.txt | 1 + src/application.cpp | 55 ++++++++++---------- src/messagebar.cpp | 122 +++++++++++++++++++++++++++++++++++++++++++++ src/messagebar.h | 78 +++++++++++++++++++++++++++++ src/notificationbar.cpp | 51 +++++-------------- src/notificationbar.h | 42 +++++++++++++++- src/previewselectorbar.cpp | 12 +---- src/previewselectorbar.h | 2 - src/sessionmanager.cpp | 14 ++++-- src/sessionmanager.h | 5 +- src/urlbar/urlbar.cpp | 1 - src/urlbar/urlbar.h | 2 +- src/walletbar.cpp | 9 ---- src/walletbar.h | 1 - src/webtab.cpp | 5 ++ src/webtab.h | 2 + 16 files changed, 302 insertions(+), 100 deletions(-) create mode 100644 src/messagebar.cpp create mode 100644 src/messagebar.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 861126f5..b786bcdd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -14,6 +14,7 @@ SET( rekonq_KDEINIT_SRCS iconmanager.cpp mainview.cpp mainwindow.cpp + messagebar.cpp networkaccessmanager.cpp newtabpage.cpp notificationbar.cpp diff --git a/src/application.cpp b/src/application.cpp index ce353912..7e949220 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -41,6 +41,7 @@ #include "iconmanager.h" #include "mainview.h" #include "mainwindow.h" +#include "messagebar.h" #include "opensearchmanager.h" #include "sessionmanager.h" #include "stackedurlbar.h" @@ -50,10 +51,13 @@ // KDE Includes #include -#include +#include #include +#include #include +// Qt Includes +#include QWeakPointer Application::s_adblockManager; QWeakPointer Application::s_bookmarkProvider; @@ -115,7 +119,7 @@ int Application::newInstance() // so, we have 8 possible cases... bool isFirstLoad = m_mainWindows.isEmpty(); bool areThereArguments = (args->count() > 0); - bool isRekonqCrashed = (ReKonfig::recoverOnCrash() == 1); + bool isRekonqCrashed = ReKonfig::recoverOnCrash(); kDebug() << "is first load? " << isFirstLoad; kDebug() << "are there arguments? " << areThereArguments; @@ -123,26 +127,19 @@ int Application::newInstance() int exitValue = 1 * isFirstLoad + 2 * areThereArguments + 4 * isRekonqCrashed; - if(isRekonqCrashed) - { - if( isFirstLoad && sessionManager()->restoreSession() ) - { - kDebug() << "session restored from crash"; - } - } - else - { - if( isFirstLoad && ReKonfig::startupBehaviour() == 2 ) - { - sessionManager()->restoreSession(); - kDebug() << "session restored following settings"; - if(areThereArguments) - loadUrl( KUrl("about:blank"), Rekonq::NewFocusedTab); - } + if (isRekonqCrashed && isFirstLoad) { + loadUrl(KUrl("about:closedTabs")); + MessageBar *msgBar = new MessageBar(i18n("It seems rekonq wasn't closed properly, do you want " + "to restore the last saved session ?") + , mainWindow()->currentTab() + , QMessageBox::Warning + , MessageBar::Yes | MessageBar::No ); + + connect(msgBar, SIGNAL(accepted()), sessionManager(), SLOT(restoreSession())); + mainWindow()->currentTab()->insertBar(msgBar); } - if(areThereArguments) - { + if (areThereArguments) { KUrl::List urlList; for(int i = 0; i < args->count(); ++i) { @@ -153,8 +150,7 @@ int Application::newInstance() urlList += KUrl( args->arg(i) ); // "rekonq kde.org" || "rekonq kde:kdialog" case } - if (isFirstLoad) - { + if (isFirstLoad && !isRekonqCrashed) { // No windows in the current desktop? No windows at all? // Create a new one and load there sites... loadUrl(urlList.at(0), Rekonq::CurrentTab); @@ -169,9 +165,9 @@ int Application::newInstance() for (int i = 1; i < urlList.count(); ++i) loadUrl( urlList.at(i), Rekonq::NewTab); - } - else - { + + } else if (!isRekonqCrashed) { + if (isFirstLoad) // we are starting rekonq, for the first time with no args: use startup behaviour { switch (ReKonfig::startupBehaviour()) @@ -183,7 +179,8 @@ int Application::newInstance() loadUrl(KUrl("about:home")); break; case 2: // restore session - // NOTE: this has just been considered + sessionManager()->restoreSession(); + kDebug() << "session restored following settings"; break; default: mainWindow()->homePage(); @@ -235,15 +232,14 @@ void Application::postLaunch() setWindowIcon(KIcon("rekonq")); Application::historyManager(); - Application::sessionManager(); + Application::sessionManager()->setSessionManagementEnabled(true); // bookmarks loading connect(Application::bookmarkProvider(), SIGNAL(openUrl(const KUrl&, const Rekonq::OpenType&)), Application::instance(), SLOT(loadUrl(const KUrl&, const Rekonq::OpenType&))); // crash recovering - int n = ReKonfig::recoverOnCrash(); - ReKonfig::setRecoverOnCrash(++n); + ReKonfig::setRecoverOnCrash(ReKonfig::recoverOnCrash() + 1); saveConfiguration(); } @@ -367,6 +363,7 @@ void Application::loadUrl(const KUrl& url, const Rekonq::OpenType& type) int tabIndex = w->mainView()->indexOf(tab); Q_ASSERT( tabIndex != -1 ); UrlBar *barForTab = qobject_cast(w->mainView()->widgetBar()->widget(tabIndex)); + barForTab->activateSuggestions(false); barForTab->setQUrl(url); WebView *view = tab->view(); diff --git a/src/messagebar.cpp b/src/messagebar.cpp new file mode 100644 index 00000000..34a04f6b --- /dev/null +++ b/src/messagebar.cpp @@ -0,0 +1,122 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2010 by Pierre Rossi +* +* +* 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 . +* +* ============================================================ */ + +// Self Includes +#include "messagebar.h" +#include "messagebar.moc" + +// KDE Includes +#include +#include +#include + +// Qt Includes +#include +#include +#include +#include + +MessageBar::MessageBar(const QString &message, QWidget *parent, QMessageBox::Icon icon, StandardButtons buttons) + : NotificationBar(parent) + , m_icon(0) + , m_text(0) +{ + QToolButton *closeButton = new QToolButton(this); + closeButton->setAutoRaise(true); + closeButton->setIcon(KIcon("dialog-close")); + connect(closeButton, SIGNAL(clicked()), this, SLOT(destroy())); + + m_text = new QLabel(message, this); + m_text->setWordWrap(true); + + m_icon = new QLabel; + QString icon_name; + switch (icon) { + case QMessageBox::NoIcon: + break; + case QMessageBox::Information: + icon_name = "dialog-information"; + break; + case QMessageBox::Warning: + icon_name = "dialog-warning"; + break; + case QMessageBox::Critical: + icon_name = "dialog-error"; + break; + default: + break; + } + if (!icon_name.isEmpty()) + m_icon->setPixmap(KIcon(icon_name).pixmap(int(KIconLoader::SizeSmallMedium))); + + QPushButton *button; + if (buttons & Ok) { + button = new QPushButton(KIcon("dialog-ok"), i18n("Ok")); + connect(button, SIGNAL(clicked()), this, SIGNAL(accepted())); + connect(button, SIGNAL(clicked()), this, SLOT(destroy())); + m_buttons.append(button); + } + if (buttons & Cancel) { + button = new QPushButton(KIcon("dialog-cancel"), i18n("Cancel")); + connect(button, SIGNAL(clicked()), this, SIGNAL(rejected())); + connect(button, SIGNAL(clicked()), this, SLOT(destroy())); + m_buttons.append(button); + } + if (buttons & Yes) { + button = new QPushButton(i18n("Yes")); + connect(button, SIGNAL(clicked()), this, SIGNAL(accepted())); + connect(button, SIGNAL(clicked()), this, SLOT(destroy())); + m_buttons.append(button); + } + if (buttons & No) { + button = new QPushButton(i18n("No")); + connect(button, SIGNAL(clicked()), this, SIGNAL(rejected())); + connect(button, SIGNAL(clicked()), this, SLOT(destroy())); + m_buttons.append(button); + } + if (buttons & Continue) { + button = new QPushButton(i18n("Continue")); + connect(button, SIGNAL(clicked()), this, SIGNAL(accepted())); + connect(button, SIGNAL(clicked()), this, SLOT(destroy())); + m_buttons.append(button); + } + + QHBoxLayout *layout = new QHBoxLayout(this); + layout->setContentsMargins(2, 0, 2, 0); + layout->addWidget(closeButton); + layout->addWidget(m_icon); + layout->addWidget(m_text); + foreach(QPushButton *button, m_buttons) + layout->addWidget(button, 2); + layout->setStretch(2,20); + + setLayout(layout); + +} + +MessageBar::~MessageBar() +{ + qDeleteAll(m_buttons); +} diff --git a/src/messagebar.h b/src/messagebar.h new file mode 100644 index 00000000..28b63e87 --- /dev/null +++ b/src/messagebar.h @@ -0,0 +1,78 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2010 by Pierre Rossi +* +* +* 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 . +* +* ============================================================ */ + +#ifndef MESSAGEBAR_H +#define MESSAGEBAR_H + +// Rekonq Includes +#include "rekonq_defines.h" +#include "notificationbar.h" + +// Qt Includes +#include + +// Forward Declarations +class QLabel; +class QPushButton; + + +class REKONQ_TESTS_EXPORT MessageBar : public NotificationBar +{ + Q_OBJECT + + Q_FLAGS(StandardButtons); + +public: + + enum StandardButton { + NoButton = 0x00000000, + Ok = 0x00000001, + Cancel = 0x00000002, + Yes = 0x00000004, + No = 0x00000008, + Continue = 0x00000010 + }; + + Q_DECLARE_FLAGS(StandardButtons, StandardButton) + + explicit MessageBar(const QString & message, QWidget *parent + , QMessageBox::Icon icon = QMessageBox::NoIcon + , StandardButtons buttons = NoButton); + ~MessageBar(); + +Q_SIGNALS: + void accepted(); + void rejected(); + +private: + QLabel *m_icon; + QLabel *m_text; + QList m_buttons; + +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(MessageBar::StandardButtons) + +#endif // MESSAGEBAR_H diff --git a/src/notificationbar.cpp b/src/notificationbar.cpp index 94c5cba8..e3d9c6b0 100644 --- a/src/notificationbar.cpp +++ b/src/notificationbar.cpp @@ -22,47 +22,14 @@ * along with this program. If not, see . * * ============================================================ */ +// Self includes #include "notificationbar.h" +#include "notificationbar.moc" -#include -#include -#include -#include -#include - - -class BlinkEffect : public QGraphicsEffect -{ - Q_OBJECT - Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity) - -public: - BlinkEffect(QObject *parent = 0) - : QGraphicsEffect(parent) - , m_opacity(0) - , m_backgroundColor(QApplication::palette().highlight().color().lighter()) - {} - - qreal opacity() const { return m_opacity; } - void setOpacity(qreal opacity) - { - m_opacity = opacity; - update(); - } - -protected: - void draw(QPainter *painter) - { - painter->drawPixmap(QPoint(0,0), sourcePixmap()); - painter->setOpacity(m_opacity); - painter->fillRect(boundingRect(), m_backgroundColor); - } - -private: - double m_opacity; - QColor m_backgroundColor; +// Qt Includes -}; +#include +#include NotificationBar::NotificationBar(QWidget *parent) @@ -89,4 +56,10 @@ void NotificationBar::notifyUser(int animationDuration) } -#include "notificationbar.moc" +void NotificationBar::destroy() +{ + qDebug() << Q_FUNC_INFO << "deleting the bar" << this; + if (parentWidget() && parentWidget()->layout()) + parentWidget()->layout()->removeWidget(this); + deleteLater(); +} diff --git a/src/notificationbar.h b/src/notificationbar.h index 858fac80..74372f0a 100644 --- a/src/notificationbar.h +++ b/src/notificationbar.h @@ -27,14 +27,52 @@ #define NOTIFICATIONBAR_H // Qt Includes +#include +#include +#include +#include +#include #include // Forward Declarations class QPropertyAnimation; -class BlinkEffect; + +class BlinkEffect : public QGraphicsEffect +{ + Q_OBJECT + Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity) + +public: + BlinkEffect(QObject *parent = 0) + : QGraphicsEffect(parent) + , m_opacity(0) + , m_backgroundColor(QApplication::palette().highlight().color().lighter()) + {} + + qreal opacity() const { return m_opacity; } + void setOpacity(qreal opacity) + { + m_opacity = opacity; + update(); + } + +protected: + void draw(QPainter *painter) + { + painter->drawPixmap(QPoint(0,0), sourcePixmap()); + painter->setOpacity(m_opacity); + painter->fillRect(boundingRect(), m_backgroundColor); + } + +private: + double m_opacity; + QColor m_backgroundColor; + +}; class NotificationBar : public QWidget { + Q_OBJECT public: explicit NotificationBar(QWidget *parent = 0); ~NotificationBar(); @@ -44,6 +82,8 @@ public: private: BlinkEffect *m_blinkEffect; QPropertyAnimation *m_opacityAnimation; +protected slots: + void destroy(); }; diff --git a/src/previewselectorbar.cpp b/src/previewselectorbar.cpp index 1b3d3380..a53d2831 100644 --- a/src/previewselectorbar.cpp +++ b/src/previewselectorbar.cpp @@ -146,14 +146,4 @@ void PreviewSelectorBar::clicked() } destroy(); -} - - -void PreviewSelectorBar::destroy() -{ - if (parentWidget() && parentWidget()->layout()) - { - parentWidget()->layout()->removeWidget(this); - } - this->deleteLater(); -} +} \ No newline at end of file diff --git a/src/previewselectorbar.h b/src/previewselectorbar.h index 9f8c78cc..9684a012 100644 --- a/src/previewselectorbar.h +++ b/src/previewselectorbar.h @@ -55,8 +55,6 @@ private slots: void verifyUrl(); - void destroy(); - private: QPushButton *m_button; QLabel *m_label; diff --git a/src/sessionmanager.cpp b/src/sessionmanager.cpp index 736dd76c..87f25f43 100644 --- a/src/sessionmanager.cpp +++ b/src/sessionmanager.cpp @@ -46,7 +46,7 @@ SessionManager::SessionManager(QObject *parent) : QObject(parent) - , m_safe(true) + , m_safe(false) { m_sessionFilePath = KStandardDirs::locateLocal("appdata" , "session"); } @@ -59,12 +59,10 @@ SessionManager::~SessionManager() void SessionManager::saveSession() { - if (!m_safe) + if (!m_safe || QWebSettings::globalSettings()->testAttribute(QWebSettings::PrivateBrowsingEnabled)) return; m_safe = false; - if( QWebSettings::globalSettings()->testAttribute(QWebSettings::PrivateBrowsingEnabled) ) - return; QFile sessionFile(m_sessionFilePath); if (!sessionFile.open(QFile::WriteOnly | QFile::Truncate)) @@ -106,13 +104,19 @@ bool SessionManager::restoreSession() QTextStream in(&sessionFile); QString line; + bool windowAlreadyOpen = Application::instance()->mainWindowList().count(); do { line = in.readLine(); if (line == QL1S("window")) { line = in.readLine(); - Application::instance()->loadUrl( KUrl(line), Rekonq::NewWindow); + if (windowAlreadyOpen) { + Application::instance()->loadUrl( KUrl(line), Rekonq::CurrentTab); + windowAlreadyOpen = false; + } else { + Application::instance()->loadUrl( KUrl(line), Rekonq::NewWindow); + } } else { diff --git a/src/sessionmanager.h b/src/sessionmanager.h index 63b33572..7e7875a1 100644 --- a/src/sessionmanager.h +++ b/src/sessionmanager.h @@ -49,10 +49,13 @@ class REKONQ_TESTS_EXPORT SessionManager : public QObject public: SessionManager(QObject *parent = 0); ~SessionManager(); - bool restoreSession(); + inline void setSessionManagementEnabled(bool on) { m_safe = on; } QStringList closedSites(); +public slots: + bool restoreSession(); + private slots: void saveSession(); diff --git a/src/urlbar/urlbar.cpp b/src/urlbar/urlbar.cpp index 61c44907..4746ed1d 100644 --- a/src/urlbar/urlbar.cpp +++ b/src/urlbar/urlbar.cpp @@ -148,7 +148,6 @@ void UrlBar::setQUrl(const QUrl& url) void UrlBar::activated(const KUrl& url, Rekonq::OpenType type) { activateSuggestions(false); - clearFocus(); setUrl(url); Application::instance()->loadUrl(url, type); diff --git a/src/urlbar/urlbar.h b/src/urlbar/urlbar.h index 6e05ea7e..dcd0ba5b 100644 --- a/src/urlbar/urlbar.h +++ b/src/urlbar/urlbar.h @@ -90,6 +90,7 @@ public: ~UrlBar(); void setPrivateMode(bool on); + void activateSuggestions(bool); public slots: void setQUrl(const QUrl &url); @@ -120,7 +121,6 @@ protected: private: IconButton *addRightIcon(UrlBar::icon); - void activateSuggestions(bool); QWeakPointer _box; WebTab *_tab; diff --git a/src/walletbar.cpp b/src/walletbar.cpp index c2397da9..5a6badef 100644 --- a/src/walletbar.cpp +++ b/src/walletbar.cpp @@ -104,15 +104,6 @@ void WalletBar::notNowRememberData() } -void WalletBar::destroy() -{ - if (parentWidget() && parentWidget()->layout()) - { - parentWidget()->layout()->removeWidget(this); - } - this->deleteLater(); -} - void WalletBar::onSaveFormData(const QString &key, const QUrl &url) { diff --git a/src/walletbar.h b/src/walletbar.h index afd657f4..3659d592 100644 --- a/src/walletbar.h +++ b/src/walletbar.h @@ -59,7 +59,6 @@ signals: void saveFormDataRejected(const QString &); private: - void destroy(); QString m_key; QUrl m_url; diff --git a/src/webtab.cpp b/src/webtab.cpp index c525ac00..3b97e2db 100644 --- a/src/webtab.cpp +++ b/src/webtab.cpp @@ -165,6 +165,11 @@ void WebTab::createPreviewSelectorBar(int index) connect(page()->mainFrame(), SIGNAL(urlChanged(QUrl)), _previewSelectorBar.data(), SLOT(verifyUrl()), Qt::UniqueConnection); } +void WebTab::insertBar(NotificationBar *bar) +{ + qobject_cast(layout())->insertWidget(0, bar); +} + bool WebTab::hasRSSInfo() { diff --git a/src/webtab.h b/src/webtab.h index d9213983..66eec447 100644 --- a/src/webtab.h +++ b/src/webtab.h @@ -42,6 +42,7 @@ class UrlBar; class PreviewSelectorBar; class WalletBar; +class NotificationBar; class REKONQ_TESTS_EXPORT WebTab : public QWidget @@ -59,6 +60,7 @@ public: KUrl url(); void createPreviewSelectorBar(int index); + void insertBar(NotificationBar* bar); bool hasRSSInfo(); -- cgit v1.2.1