File indexing completed on 2024-05-12 04:58:06

0001 /* ============================================================
0002 * Falkon - Qt web browser
0003 * Copyright (C) 2014-2018 David Rosca <nowrep@gmail.com>
0004 *
0005 * This program is free software: you can redistribute it and/or modify
0006 * it under the terms of the GNU General Public License as published by
0007 * the Free Software Foundation, either version 3 of the License, or
0008 * (at your option) any later version.
0009 *
0010 * This program is distributed in the hope that it will be useful,
0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013 * GNU General Public License for more details.
0014 *
0015 * You should have received a copy of the GNU General Public License
0016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0017 * ============================================================ */
0018 #include "historymenu.h"
0019 #include "iconprovider.h"
0020 #include "browserwindow.h"
0021 #include "tabbedwebview.h"
0022 #include "mainapplication.h"
0023 #include "closedtabsmanager.h"
0024 #include "tabwidget.h"
0025 #include "qztools.h"
0026 #include "history.h"
0027 #include "qzsettings.h"
0028 #include "sqldatabase.h"
0029 #include "closedwindowsmanager.h"
0030 
0031 #include <QApplication>
0032 #include <QWebEngineHistory>
0033 
0034 HistoryMenu::HistoryMenu(QWidget* parent)
0035     : Menu(parent)
0036 {
0037     init();
0038 }
0039 
0040 void HistoryMenu::setMainWindow(BrowserWindow* window)
0041 {
0042     m_window = window;
0043 }
0044 
0045 void HistoryMenu::goBack()
0046 {
0047     if (m_window) {
0048         m_window->goBack();
0049     }
0050 }
0051 
0052 void HistoryMenu::goForward()
0053 {
0054     if (m_window) {
0055         m_window->goForward();
0056     }
0057 }
0058 
0059 void HistoryMenu::goHome()
0060 {
0061     if (m_window) {
0062         m_window->goHome();
0063     }
0064 }
0065 
0066 void HistoryMenu::showHistoryManager()
0067 {
0068     if (m_window) {
0069         m_window->showHistoryManager();
0070     }
0071 }
0072 
0073 void HistoryMenu::aboutToShow()
0074 {
0075     // Set enabled states for Back/Forward actions according to current WebView
0076     TabbedWebView* view = m_window ? m_window->weView() : nullptr;
0077 
0078     if (view) {
0079         actions().at(0)->setEnabled(view->history()->canGoBack());
0080         actions().at(1)->setEnabled(view->history()->canGoForward());
0081     }
0082 
0083     while (actions().count() != 8) {
0084         QAction* act = actions().at(8);
0085         if (act->menu()) {
0086             act->menu()->clear();
0087         }
0088         removeAction(act);
0089         delete act;
0090     }
0091 
0092     addSeparator();
0093 
0094     QSqlQuery query(SqlDatabase::instance()->database());
0095     query.exec(QSL("SELECT title, url FROM history ORDER BY date DESC LIMIT 10"));
0096 
0097     while (query.next()) {
0098         const QUrl url = query.value(1).toUrl();
0099         const QString title = QzTools::truncatedText(query.value(0).toString(), 40);
0100 
0101         auto* act = new Action(title);
0102         act->setData(url);
0103         act->setIcon(IconProvider::iconForUrl(url));
0104         connect(act, &QAction::triggered, this, &HistoryMenu::historyEntryActivated);
0105         connect(act, &Action::ctrlTriggered, this, &HistoryMenu::historyEntryCtrlActivated);
0106         connect(act, &Action::shiftTriggered, this, &HistoryMenu::historyEntryShiftActivated);
0107         addAction(act);
0108     }
0109 }
0110 
0111 void HistoryMenu::aboutToHide()
0112 {
0113     // Enable Back/Forward actions to ensure shortcuts are working
0114     actions().at(0)->setEnabled(true);
0115     actions().at(1)->setEnabled(true);
0116 }
0117 
0118 void HistoryMenu::aboutToShowMostVisited()
0119 {
0120     m_menuMostVisited->clear();
0121 
0122     const QVector<HistoryEntry> mostVisited = mApp->history()->mostVisited(10);
0123 
0124     for (const HistoryEntry &entry : mostVisited) {
0125         auto* act = new Action(QzTools::truncatedText(entry.title, 40));
0126         act->setData(entry.url);
0127         act->setIcon(IconProvider::iconForUrl(entry.url));
0128         connect(act, &QAction::triggered, this, &HistoryMenu::historyEntryActivated);
0129         connect(act, &Action::ctrlTriggered, this, &HistoryMenu::historyEntryCtrlActivated);
0130         connect(act, &Action::shiftTriggered, this, &HistoryMenu::historyEntryShiftActivated);
0131         m_menuMostVisited->addAction(act);
0132     }
0133 
0134     if (m_menuMostVisited->isEmpty()) {
0135         m_menuMostVisited->addAction(tr("Empty"))->setEnabled(false);
0136     }
0137 }
0138 
0139 void HistoryMenu::aboutToShowClosedTabs()
0140 {
0141     m_menuClosedTabs->clear();
0142 
0143     if (!m_window) {
0144         return;
0145     }
0146 
0147     TabWidget* tabWidget = m_window->tabWidget();
0148 
0149     const auto closedTabs = tabWidget->closedTabsManager()->closedTabs();
0150     for (int i = 0; i < closedTabs.count(); ++i) {
0151         const ClosedTabsManager::Tab tab = closedTabs.at(i);
0152         const QString title = QzTools::truncatedText(tab.tabState.title, 40);
0153         m_menuClosedTabs->addAction(tab.tabState.icon, title, tabWidget, SLOT(restoreClosedTab()))->setData(i);
0154     }
0155 
0156     if (m_menuClosedTabs->isEmpty()) {
0157         m_menuClosedTabs->addAction(tr("Empty"))->setEnabled(false);
0158     }
0159     else {
0160         m_menuClosedTabs->addSeparator();
0161         m_menuClosedTabs->addAction(tr("Restore All Closed Tabs"), tabWidget, &TabWidget::restoreAllClosedTabs);
0162         m_menuClosedTabs->addAction(QIcon::fromTheme(QSL("edit-clear")), tr("Clear list"), tabWidget, &TabWidget::clearClosedTabsList);
0163     }
0164 }
0165 
0166 void HistoryMenu::aboutToShowClosedWindows()
0167 {
0168     m_menuClosedWindows->clear();
0169 
0170     ClosedWindowsManager *manager = mApp->closedWindowsManager();
0171 
0172     const auto closedWindows = manager->closedWindows();
0173     for (int i = 0; i < closedWindows.count(); ++i) {
0174         const ClosedWindowsManager::Window window = closedWindows.at(i);
0175         const QString title = QzTools::truncatedText(window.title, 40);
0176         QAction *act = m_menuClosedWindows->addAction(window.icon, title, manager, &ClosedWindowsManager::restoreClosedWindow);
0177         if (i == 0) {
0178             act->setShortcut(QKeySequence(QSL("Ctrl+Shift+N")));
0179             act->setShortcutContext(Qt::WidgetShortcut);
0180         } else {
0181             act->setData(i);
0182         }
0183     }
0184 
0185     if (m_menuClosedWindows->isEmpty()) {
0186         m_menuClosedWindows->addAction(tr("Empty"))->setEnabled(false);
0187     } else {
0188         m_menuClosedWindows->addSeparator();
0189         m_menuClosedWindows->addAction(tr("Restore All Closed Windows"), manager, &ClosedWindowsManager::restoreAllClosedWindows);
0190         m_menuClosedWindows->addAction(QIcon::fromTheme(QSL("edit-clear")), tr("Clear list"), manager, &ClosedWindowsManager::clearClosedWindows);
0191     }
0192 }
0193 
0194 void HistoryMenu::historyEntryActivated()
0195 {
0196     if (auto* action = qobject_cast<QAction*>(sender())) {
0197         openUrl(action->data().toUrl());
0198     }
0199 }
0200 
0201 void HistoryMenu::historyEntryCtrlActivated()
0202 {
0203     if (auto* action = qobject_cast<QAction*>(sender())) {
0204         openUrlInNewTab(action->data().toUrl());
0205     }
0206 }
0207 
0208 void HistoryMenu::historyEntryShiftActivated()
0209 {
0210     if (auto* action = qobject_cast<QAction*>(sender())) {
0211         openUrlInNewWindow(action->data().toUrl());
0212     }
0213 }
0214 
0215 void HistoryMenu::openUrl(const QUrl &url)
0216 {
0217     if (m_window) {
0218         m_window->loadAddress(url);
0219     }
0220 }
0221 
0222 void HistoryMenu::openUrlInNewTab(const QUrl &url)
0223 {
0224     if (m_window) {
0225         m_window->tabWidget()->addView(url, qzSettings->newTabPosition);
0226     }
0227 }
0228 
0229 void HistoryMenu::openUrlInNewWindow(const QUrl &url)
0230 {
0231     mApp->createWindow(Qz::BW_NewWindow, url);
0232 }
0233 
0234 void HistoryMenu::init()
0235 {
0236     setTitle(tr("Hi&story"));
0237 
0238     QAction* act = addAction(IconProvider::standardIcon(QStyle::SP_ArrowBack), tr("&Back"), this, &HistoryMenu::goBack);
0239     act->setShortcut(QzTools::actionShortcut(QKeySequence::Back, Qt::ALT | Qt::Key_Left, QKeySequence::Forward, Qt::ALT | Qt::Key_Right));
0240 
0241     act = addAction(IconProvider::standardIcon(QStyle::SP_ArrowForward), tr("&Forward"), this, &HistoryMenu::goForward);
0242     act->setShortcut(QzTools::actionShortcut(QKeySequence::Forward, Qt::ALT | Qt::Key_Right, QKeySequence::Back, Qt::ALT | Qt::Key_Left));
0243 
0244     act = addAction(QIcon::fromTheme(QSL("go-home")), tr("&Home"), this, &HistoryMenu::goHome);
0245     act->setShortcut(QKeySequence(Qt::ALT | Qt::Key_Home));
0246 
0247     act = addAction(QIcon::fromTheme(QSL("deep-history"), QIcon(QSL(":/icons/menu/history.svg"))), tr("Show &All History"), this, &HistoryMenu::showHistoryManager);
0248     act->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_H));
0249 
0250     addSeparator();
0251 
0252     connect(this, SIGNAL(aboutToShow()), this, SLOT(aboutToShow()));
0253     connect(this, SIGNAL(aboutToHide()), this, SLOT(aboutToHide()));
0254 
0255     m_menuMostVisited = new Menu(tr("Most Visited"), this);
0256     connect(m_menuMostVisited, &QMenu::aboutToShow, this, &HistoryMenu::aboutToShowMostVisited);
0257 
0258     m_menuClosedTabs = new Menu(tr("Closed Tabs"));
0259     connect(m_menuClosedTabs, &QMenu::aboutToShow, this, &HistoryMenu::aboutToShowClosedTabs);
0260 
0261     m_menuClosedWindows = new Menu(tr("Closed Windows"));
0262     connect(m_menuClosedWindows, &QMenu::aboutToShow, this, &HistoryMenu::aboutToShowClosedWindows);
0263 
0264     addMenu(m_menuMostVisited);
0265     addMenu(m_menuClosedTabs);
0266     addMenu(m_menuClosedWindows);
0267 }