Falkon Develop
Cross-platform Qt-based web browser
historymenu.cpp
Go to the documentation of this file.
1/* ============================================================
2* Falkon - Qt web browser
3* Copyright (C) 2014-2018 David Rosca <nowrep@gmail.com>
4*
5* This program is free software: you can redistribute it and/or modify
6* it under the terms of the GNU General Public License as published by
7* the Free Software Foundation, either version 3 of the License, or
8* (at your option) any later version.
9*
10* This program is distributed in the hope that it will be useful,
11* but WITHOUT ANY WARRANTY; without even the implied warranty of
12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13* GNU General Public License for more details.
14*
15* You should have received a copy of the GNU General Public License
16* along with this program. If not, see <http://www.gnu.org/licenses/>.
17* ============================================================ */
18#include "historymenu.h"
19#include "iconprovider.h"
20#include "browserwindow.h"
21#include "tabbedwebview.h"
22#include "mainapplication.h"
23#include "closedtabsmanager.h"
24#include "tabwidget.h"
25#include "qztools.h"
26#include "history.h"
27#include "qzsettings.h"
28#include "sqldatabase.h"
30
31#include <QApplication>
32#include <QWebEngineHistory>
33
35 : Menu(parent)
36{
37 init();
38}
39
41{
42 m_window = window;
43}
44
45void HistoryMenu::goBack()
46{
47 if (m_window) {
48 m_window->goBack();
49 }
50}
51
52void HistoryMenu::goForward()
53{
54 if (m_window) {
55 m_window->goForward();
56 }
57}
58
59void HistoryMenu::goHome()
60{
61 if (m_window) {
62 m_window->goHome();
63 }
64}
65
66void HistoryMenu::showHistoryManager()
67{
68 if (m_window) {
69 m_window->showHistoryManager();
70 }
71}
72
73void HistoryMenu::aboutToShow()
74{
75 // Set enabled states for Back/Forward actions according to current WebView
76 TabbedWebView* view = m_window ? m_window->weView() : nullptr;
77
78 if (view) {
79 actions().at(0)->setEnabled(view->history()->canGoBack());
80 actions().at(1)->setEnabled(view->history()->canGoForward());
81 }
82
83 while (actions().count() != 8) {
84 QAction* act = actions().at(8);
85 if (act->menu()) {
86 act->menu()->clear();
87 }
88 removeAction(act);
89 delete act;
90 }
91
92 addSeparator();
93
94 QSqlQuery query(SqlDatabase::instance()->database());
95 query.exec(QSL("SELECT title, url FROM history ORDER BY date DESC LIMIT 10"));
96
97 while (query.next()) {
98 const QUrl url = query.value(1).toUrl();
99 const QString title = QzTools::truncatedText(query.value(0).toString(), 40);
100
101 auto* act = new Action(title);
102 act->setData(url);
103 act->setIcon(IconProvider::iconForUrl(url));
104 connect(act, &QAction::triggered, this, &HistoryMenu::historyEntryActivated);
105 connect(act, &Action::ctrlTriggered, this, &HistoryMenu::historyEntryCtrlActivated);
106 connect(act, &Action::shiftTriggered, this, &HistoryMenu::historyEntryShiftActivated);
107 addAction(act);
108 }
109}
110
111void HistoryMenu::aboutToHide()
112{
113 // Enable Back/Forward actions to ensure shortcuts are working
114 actions().at(0)->setEnabled(true);
115 actions().at(1)->setEnabled(true);
116}
117
118void HistoryMenu::aboutToShowMostVisited()
119{
120 m_menuMostVisited->clear();
121
122 const QVector<HistoryEntry> mostVisited = mApp->history()->mostVisited(10);
123
124 for (const HistoryEntry &entry : mostVisited) {
125 auto* act = new Action(QzTools::truncatedText(entry.title, 40));
126 act->setData(entry.url);
127 act->setIcon(IconProvider::iconForUrl(entry.url));
128 connect(act, &QAction::triggered, this, &HistoryMenu::historyEntryActivated);
129 connect(act, &Action::ctrlTriggered, this, &HistoryMenu::historyEntryCtrlActivated);
130 connect(act, &Action::shiftTriggered, this, &HistoryMenu::historyEntryShiftActivated);
131 m_menuMostVisited->addAction(act);
132 }
133
134 if (m_menuMostVisited->isEmpty()) {
135 m_menuMostVisited->addAction(tr("Empty"))->setEnabled(false);
136 }
137}
138
139void HistoryMenu::aboutToShowClosedTabs()
140{
141 m_menuClosedTabs->clear();
142
143 if (!m_window) {
144 return;
145 }
146
147 TabWidget* tabWidget = m_window->tabWidget();
148
149 const auto closedTabs = tabWidget->closedTabsManager()->closedTabs();
150 for (int i = 0; i < closedTabs.count(); ++i) {
151 const ClosedTabsManager::Tab tab = closedTabs.at(i);
152 const QString title = QzTools::truncatedText(tab.tabState.title, 40);
153 m_menuClosedTabs->addAction(tab.tabState.icon, title, tabWidget, SLOT(restoreClosedTab()))->setData(i);
154 }
155
156 if (m_menuClosedTabs->isEmpty()) {
157 m_menuClosedTabs->addAction(tr("Empty"))->setEnabled(false);
158 }
159 else {
160 m_menuClosedTabs->addSeparator();
161 m_menuClosedTabs->addAction(tr("Restore All Closed Tabs"), tabWidget, &TabWidget::restoreAllClosedTabs);
162 m_menuClosedTabs->addAction(QIcon::fromTheme(QSL("edit-clear")), tr("Clear list"), tabWidget, &TabWidget::clearClosedTabsList);
163 }
164}
165
166void HistoryMenu::aboutToShowClosedWindows()
167{
168 m_menuClosedWindows->clear();
169
170 ClosedWindowsManager *manager = mApp->closedWindowsManager();
171
172 const auto closedWindows = manager->closedWindows();
173 for (int i = 0; i < closedWindows.count(); ++i) {
174 const ClosedWindowsManager::Window window = closedWindows.at(i);
175 const QString title = QzTools::truncatedText(window.title, 40);
176 QAction *act = m_menuClosedWindows->addAction(window.icon, title, manager, &ClosedWindowsManager::restoreClosedWindow);
177 if (i == 0) {
178 act->setShortcut(QKeySequence(QSL("Ctrl+Shift+N")));
179 act->setShortcutContext(Qt::WidgetShortcut);
180 } else {
181 act->setData(i);
182 }
183 }
184
185 if (m_menuClosedWindows->isEmpty()) {
186 m_menuClosedWindows->addAction(tr("Empty"))->setEnabled(false);
187 } else {
188 m_menuClosedWindows->addSeparator();
189 m_menuClosedWindows->addAction(tr("Restore All Closed Windows"), manager, &ClosedWindowsManager::restoreAllClosedWindows);
190 m_menuClosedWindows->addAction(QIcon::fromTheme(QSL("edit-clear")), tr("Clear list"), manager, &ClosedWindowsManager::clearClosedWindows);
191 }
192}
193
194void HistoryMenu::historyEntryActivated()
195{
196 if (auto* action = qobject_cast<QAction*>(sender())) {
197 openUrl(action->data().toUrl());
198 }
199}
200
201void HistoryMenu::historyEntryCtrlActivated()
202{
203 if (auto* action = qobject_cast<QAction*>(sender())) {
204 openUrlInNewTab(action->data().toUrl());
205 }
206}
207
208void HistoryMenu::historyEntryShiftActivated()
209{
210 if (auto* action = qobject_cast<QAction*>(sender())) {
211 openUrlInNewWindow(action->data().toUrl());
212 }
213}
214
215void HistoryMenu::openUrl(const QUrl &url)
216{
217 if (m_window) {
218 m_window->loadAddress(url);
219 }
220}
221
222void HistoryMenu::openUrlInNewTab(const QUrl &url)
223{
224 if (m_window) {
225 m_window->tabWidget()->addView(url, qzSettings->newTabPosition);
226 }
227}
228
229void HistoryMenu::openUrlInNewWindow(const QUrl &url)
230{
231 mApp->createWindow(Qz::BW_NewWindow, url);
232}
233
234void HistoryMenu::init()
235{
236 setTitle(tr("Hi&story"));
237
238 QAction* act = addAction(IconProvider::standardIcon(QStyle::SP_ArrowBack), tr("&Back"), this, &HistoryMenu::goBack);
239 act->setShortcut(QzTools::actionShortcut(QKeySequence::Back, Qt::ALT | Qt::Key_Left, QKeySequence::Forward, Qt::ALT | Qt::Key_Right));
240
241 act = addAction(IconProvider::standardIcon(QStyle::SP_ArrowForward), tr("&Forward"), this, &HistoryMenu::goForward);
242 act->setShortcut(QzTools::actionShortcut(QKeySequence::Forward, Qt::ALT | Qt::Key_Right, QKeySequence::Back, Qt::ALT | Qt::Key_Left));
243
244 act = addAction(QIcon::fromTheme(QSL("go-home")), tr("&Home"), this, &HistoryMenu::goHome);
245 act->setShortcut(QKeySequence(Qt::ALT | Qt::Key_Home));
246
247 act = addAction(QIcon::fromTheme(QSL("deep-history"), QIcon(QSL(":/icons/menu/history.svg"))), tr("Show &All History"), this, &HistoryMenu::showHistoryManager);
248 act->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_H));
249
250 addSeparator();
251
252 connect(this, SIGNAL(aboutToShow()), this, SLOT(aboutToShow()));
253 connect(this, SIGNAL(aboutToHide()), this, SLOT(aboutToHide()));
254
255 m_menuMostVisited = new Menu(tr("Most Visited"), this);
256 connect(m_menuMostVisited, &QMenu::aboutToShow, this, &HistoryMenu::aboutToShowMostVisited);
257
258 m_menuClosedTabs = new Menu(tr("Closed Tabs"));
259 connect(m_menuClosedTabs, &QMenu::aboutToShow, this, &HistoryMenu::aboutToShowClosedTabs);
260
261 m_menuClosedWindows = new Menu(tr("Closed Windows"));
262 connect(m_menuClosedWindows, &QMenu::aboutToShow, this, &HistoryMenu::aboutToShowClosedWindows);
263
264 addMenu(m_menuMostVisited);
265 addMenu(m_menuClosedTabs);
266 addMenu(m_menuClosedWindows);
267}
void shiftTriggered()
void ctrlTriggered()
QVector< Tab > closedTabs() const
QVector< Window > closedWindows() const
HistoryMenu(QWidget *parent=nullptr)
Definition: historymenu.cpp:34
void setMainWindow(BrowserWindow *window)
Definition: historymenu.cpp:40
static QIcon iconForUrl(const QUrl &url, bool allowNull=false)
static QIcon standardIcon(QStyle::StandardPixmap icon)
Menu(QWidget *parent=nullptr)
static QKeySequence actionShortcut(const QKeySequence &shortcut, const QKeySequence &fallBack, const QKeySequence &shortcutRtl=QKeySequence(), const QKeySequence &fallbackRtl=QKeySequence())
Definition: qztools.cpp:752
static QString truncatedText(const QString &text, int size)
Definition: qztools.cpp:458
static SqlDatabase * instance()
void restoreAllClosedTabs()
Definition: tabwidget.cpp:790
void clearClosedTabsList()
Definition: tabwidget.cpp:807
ClosedTabsManager * closedTabsManager() const
Definition: tabwidget.cpp:585
#define mApp
@ BW_NewWindow
Definition: qzcommon.h:67
i
Definition: i18n.py:23
#define QSL(x)
Definition: qzcommon.h:40
#define qzSettings
Definition: qzsettings.h:69
WebTab::SavedTab tabState
Definition: history.h:39
QString title
Definition: webtab.h:44
QIcon icon
Definition: webtab.h:46