From ef06ed567ad883273c622945556587c5b48712d3 Mon Sep 17 00:00:00 2001 From: David Rosca Date: Tue, 2 Jan 2018 14:22:24 +0100 Subject: [PATCH] Add ClosedWindowsManager allowing to restore closed windows Closes #2306 --- src/lib/CMakeLists.txt | 1 + src/lib/app/browserwindow.cpp | 6 +- src/lib/app/mainapplication.cpp | 10 +++ src/lib/app/mainapplication.h | 5 +- src/lib/history/historymenu.cpp | 37 +++++++++- src/lib/history/historymenu.h | 4 +- src/lib/tools/closedwindowsmanager.cpp | 99 ++++++++++++++++++++++++++ src/lib/tools/closedwindowsmanager.h | 63 ++++++++++++++++ 8 files changed, 220 insertions(+), 5 deletions(-) create mode 100644 src/lib/tools/closedwindowsmanager.cpp create mode 100644 src/lib/tools/closedwindowsmanager.h diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 3de6d651e..75f89e6bc 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -185,6 +185,7 @@ set(SRCS ${SRCS} tools/certificateinfowidget.cpp tools/clickablelabel.cpp tools/closedtabsmanager.cpp + tools/closedwindowsmanager.cpp tools/colors.cpp tools/delayedfilewatcher.cpp tools/docktitlebarwidget.cpp diff --git a/src/lib/app/browserwindow.cpp b/src/lib/app/browserwindow.cpp index c1651b92f..2bae84cb5 100644 --- a/src/lib/app/browserwindow.cpp +++ b/src/lib/app/browserwindow.cpp @@ -40,7 +40,7 @@ #include "iconprovider.h" #include "progressbar.h" #include "adblockicon.h" -#include "closedtabsmanager.h" +#include "closedwindowsmanager.h" #include "statusbarmessage.h" #include "browsinglibrary.h" #include "navigationbar.h" @@ -476,6 +476,9 @@ void BrowserWindow::setupMenu() QShortcut* inspectorAction = new QShortcut(QKeySequence(QSL("F12")), this); connect(inspectorAction, SIGNAL(activated()), this, SLOT(toggleWebInspector())); + + QShortcut* restoreClosedWindow = new QShortcut(QKeySequence(QSL("Ctrl+Shift+N")), this); + connect(restoreClosedWindow, &QShortcut::activated, mApp->closedWindowsManager(), &ClosedWindowsManager::restoreClosedWindow); } void BrowserWindow::updateStartupFocus() @@ -1483,6 +1486,7 @@ void BrowserWindow::closeEvent(QCloseEvent* event) } saveSettings(); + mApp->closedWindowsManager()->saveWindow(this); #ifndef Q_OS_MACOS if (mApp->windowCount() == 1) diff --git a/src/lib/app/mainapplication.cpp b/src/lib/app/mainapplication.cpp index 7eb40bea7..752f23b2f 100644 --- a/src/lib/app/mainapplication.cpp +++ b/src/lib/app/mainapplication.cpp @@ -47,6 +47,7 @@ #include "html5permissions/html5permissionsmanager.h" #include "scripts.h" #include "sessionmanager.h" +#include "closedwindowsmanager.h" #include #include @@ -96,6 +97,7 @@ MainApplication::MainApplication(int &argc, char** argv) , m_downloadManager(0) , m_userAgentManager(0) , m_searchEnginesManager(0) + , m_closedWindowsManager(0) , m_html5PermissionsManager(0) , m_desktopNotifications(0) , m_webProfile(0) @@ -577,6 +579,14 @@ SearchEnginesManager* MainApplication::searchEnginesManager() return m_searchEnginesManager; } +ClosedWindowsManager* MainApplication::closedWindowsManager() +{ + if (!m_closedWindowsManager) { + m_closedWindowsManager = new ClosedWindowsManager(this); + } + return m_closedWindowsManager; +} + HTML5PermissionsManager* MainApplication::html5PermissionsManager() { if (!m_html5PermissionsManager) { diff --git a/src/lib/app/mainapplication.h b/src/lib/app/mainapplication.h index 223f9c3d3..2bdfff6bb 100644 --- a/src/lib/app/mainapplication.h +++ b/src/lib/app/mainapplication.h @@ -1,6 +1,6 @@ /* ============================================================ * Falkon - Qt web browser -* Copyright (C) 2010-2017 David Rosca +* Copyright (C) 2010-2018 David Rosca * * 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 @@ -50,6 +50,7 @@ class RegisterQAppAssociation; class DesktopNotificationsFactory; class ProxyStyle; class SessionManager; +class ClosedWindowsManager; class FALKON_EXPORT MainApplication : public QtSingleApplication { @@ -107,6 +108,7 @@ public: DownloadManager* downloadManager(); UserAgentManager* userAgentManager(); SearchEnginesManager* searchEnginesManager(); + ClosedWindowsManager* closedWindowsManager(); HTML5PermissionsManager* html5PermissionsManager(); DesktopNotificationsFactory* desktopNotifications(); QWebEngineProfile* webProfile() const; @@ -178,6 +180,7 @@ private: DownloadManager* m_downloadManager; UserAgentManager* m_userAgentManager; SearchEnginesManager* m_searchEnginesManager; + ClosedWindowsManager* m_closedWindowsManager; HTML5PermissionsManager* m_html5PermissionsManager; DesktopNotificationsFactory* m_desktopNotifications; QWebEngineProfile* m_webProfile; diff --git a/src/lib/history/historymenu.cpp b/src/lib/history/historymenu.cpp index c6ddf2d5c..76d2fe36d 100644 --- a/src/lib/history/historymenu.cpp +++ b/src/lib/history/historymenu.cpp @@ -26,6 +26,7 @@ #include "history.h" #include "qzsettings.h" #include "sqldatabase.h" +#include "closedwindowsmanager.h" #include #include @@ -79,8 +80,8 @@ void HistoryMenu::aboutToShow() actions().at(1)->setEnabled(view->history()->canGoForward()); } - while (actions().count() != 7) { - QAction* act = actions().at(7); + while (actions().count() != 8) { + QAction* act = actions().at(8); if (act->menu()) { act->menu()->clear(); } @@ -162,6 +163,34 @@ void HistoryMenu::aboutToShowClosedTabs() } } +void HistoryMenu::aboutToShowClosedWindows() +{ + m_menuClosedWindows->clear(); + + ClosedWindowsManager *manager = mApp->closedWindowsManager(); + + const auto closedWindows = manager->closedWindows(); + for (int i = 0; i < closedWindows.count(); ++i) { + const ClosedWindowsManager::Window window = closedWindows.at(i); + const QString title = QzTools::truncatedText(window.title, 40); + QAction *act = m_menuClosedWindows->addAction(window.icon, title, manager, SLOT(restoreClosedWindow())); + if (i == 0) { + act->setShortcut(QKeySequence(QSL("Ctrl+Shift+N"))); + act->setShortcutContext(Qt::WidgetShortcut); + } else { + act->setData(i); + } + } + + if (m_menuClosedWindows->isEmpty()) { + m_menuClosedWindows->addAction(tr("Empty"))->setEnabled(false); + } else { + m_menuClosedWindows->addSeparator(); + m_menuClosedWindows->addAction(tr("Restore All Closed Windows"), manager, SLOT(restoreAllClosedWindows())); + m_menuClosedWindows->addAction(tr("Clear list"), manager, SLOT(clearClosedWindows())); + } +} + void HistoryMenu::historyEntryActivated() { if (QAction* action = qobject_cast(sender())) { @@ -229,6 +258,10 @@ void HistoryMenu::init() m_menuClosedTabs = new Menu(tr("Closed Tabs")); connect(m_menuClosedTabs, SIGNAL(aboutToShow()), this, SLOT(aboutToShowClosedTabs())); + m_menuClosedWindows = new Menu(tr("Closed Windows")); + connect(m_menuClosedWindows, &QMenu::aboutToShow, this, &HistoryMenu::aboutToShowClosedWindows); + addMenu(m_menuMostVisited); addMenu(m_menuClosedTabs); + addMenu(m_menuClosedWindows); } diff --git a/src/lib/history/historymenu.h b/src/lib/history/historymenu.h index 8e9fe25e9..fdb5a9a62 100644 --- a/src/lib/history/historymenu.h +++ b/src/lib/history/historymenu.h @@ -1,6 +1,6 @@ /* ============================================================ * Falkon - Qt web browser -* Copyright (C) 2014 David Rosca +* Copyright (C) 2014-2018 David Rosca * * 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 @@ -47,6 +47,7 @@ private slots: void aboutToShowMostVisited(); void aboutToShowClosedTabs(); + void aboutToShowClosedWindows(); void historyEntryActivated(); void historyEntryCtrlActivated(); @@ -62,6 +63,7 @@ private: QPointer m_window; Menu* m_menuMostVisited; Menu* m_menuClosedTabs; + Menu *m_menuClosedWindows; }; #endif // HISTORYMENU_H diff --git a/src/lib/tools/closedwindowsmanager.cpp b/src/lib/tools/closedwindowsmanager.cpp new file mode 100644 index 000000000..69e5baaf3 --- /dev/null +++ b/src/lib/tools/closedwindowsmanager.cpp @@ -0,0 +1,99 @@ +/* ============================================================ +* Falkon - Qt web browser +* Copyright (C) 2018 David Rosca +* +* 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 . +* ============================================================ */ +#include "closedwindowsmanager.h" +#include "mainapplication.h" +#include "tabbedwebview.h" +#include "qztools.h" + +#include + +ClosedWindowsManager::ClosedWindowsManager(QObject *parent) + : QObject(parent) +{ +} + +bool ClosedWindowsManager::isClosedWindowAvailable() const +{ + return !m_closedWindows.isEmpty(); +} + +QVector ClosedWindowsManager::closedWindows() const +{ + return m_closedWindows; +} + +void ClosedWindowsManager::saveWindow(BrowserWindow *window) +{ + if (mApp->isPrivate()) { + return; + } + + Window closedWindow; + closedWindow.icon = window->weView()->icon(); + closedWindow.title = window->weView()->title(); + closedWindow.windowState = BrowserWindow::SavedWindow(window); + m_closedWindows.prepend(closedWindow); +} + +ClosedWindowsManager::Window ClosedWindowsManager::takeLastClosedWindow() +{ + Window window; + if (!m_closedWindows.isEmpty()) { + window = m_closedWindows.takeFirst(); + } + return window; +} + +ClosedWindowsManager::Window ClosedWindowsManager::takeClosedWindowAt(int index) +{ + Window window; + if (QzTools::containsIndex(m_closedWindows, index)) { + window = m_closedWindows.takeAt(index); + } + return window; +} + +void ClosedWindowsManager::restoreClosedWindow() +{ + Window window; + QAction *act = qobject_cast(sender()); + if (act) { + window = takeClosedWindowAt(act->data().toInt()); + } else { + window = takeLastClosedWindow(); + } + + if (!window.isValid()) { + return; + } + + mApp->createWindow(Qz::BW_OtherRestoredWindow)->restoreWindow(window.windowState); +} + +void ClosedWindowsManager::restoreAllClosedWindows() +{ + const int count = m_closedWindows.count(); + for (int i = 0; i < count; ++i) { + restoreClosedWindow(); + } +} + +void ClosedWindowsManager::clearClosedWindows() +{ + m_closedWindows.clear(); +} diff --git a/src/lib/tools/closedwindowsmanager.h b/src/lib/tools/closedwindowsmanager.h new file mode 100644 index 000000000..b2088391b --- /dev/null +++ b/src/lib/tools/closedwindowsmanager.h @@ -0,0 +1,63 @@ +/* ============================================================ +* Falkon - Qt web browser +* Copyright (C) 2018 David Rosca +* +* 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 . +* ============================================================ */ +#pragma once + +#include +#include + +#include "qzcommon.h" +#include "browserwindow.h" + +class QUPZILLA_EXPORT ClosedWindowsManager : public QObject +{ + Q_OBJECT + +public: + struct Window { + QIcon icon; + QString title; + BrowserWindow::SavedWindow windowState; + + bool isValid() const { + return windowState.isValid(); + } + }; + + explicit ClosedWindowsManager(QObject *parent = nullptr); + + bool isClosedWindowAvailable() const; + QVector closedWindows() const; + + void saveWindow(BrowserWindow *window); + + // Takes window that was most recently closed + Window takeLastClosedWindow(); + // Takes window at given index + Window takeClosedWindowAt(int index); + +public slots: + void restoreClosedWindow(); + void restoreAllClosedWindows(); + void clearClosedWindows(); + +private: + QVector m_closedWindows; +}; + +// Hint to Qt to use std::realloc on item moving +Q_DECLARE_TYPEINFO(ClosedWindowsManager::Window, Q_MOVABLE_TYPE);