File indexing completed on 2024-05-19 04:58:37

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 "mainmenu.h"
0019 #include "siteinfo.h"
0020 #include "tabwidget.h"
0021 #include "historymenu.h"
0022 #include "aboutdialog.h"
0023 #include "preferences.h"
0024 #include "iconprovider.h"
0025 #include "cookiemanager.h"
0026 #include "bookmarksmenu.h"
0027 #include "tabbedwebview.h"
0028 #include "browserwindow.h"
0029 #include "downloadmanager.h"
0030 #include "mainapplication.h"
0031 #include "clearprivatedata.h"
0032 #include "qzsettings.h"
0033 #include "pluginproxy.h"
0034 #include "webinspector.h"
0035 #include "sessionmanager.h"
0036 #include "statusbar.h"
0037 
0038 #include <QApplication>
0039 #include <QMetaObject>
0040 #include <QWebEnginePage>
0041 #include <QMenuBar>
0042 #include <QDesktopServices>
0043 
0044 #ifdef Q_OS_MACOS
0045 extern void qt_mac_set_dock_menu(QMenu* menu);
0046 #endif
0047 
0048 MainMenu::MainMenu(BrowserWindow* window, QWidget* parent)
0049     : QMenu(parent)
0050     , m_window(window)
0051 {
0052     Q_ASSERT(m_window);
0053 
0054     init();
0055 }
0056 
0057 void MainMenu::setWindow(BrowserWindow* window)
0058 {
0059     Q_ASSERT(window);
0060 
0061     m_window = window;
0062     addActionsToWindow();
0063 }
0064 
0065 void MainMenu::initMenuBar(QMenuBar* menuBar) const
0066 {
0067     menuBar->addMenu(m_menuFile);
0068     menuBar->addMenu(m_menuEdit);
0069     menuBar->addMenu(m_menuView);
0070     menuBar->addMenu(m_menuHistory);
0071     menuBar->addMenu(m_menuBookmarks);
0072     menuBar->addMenu(m_menuTools);
0073     menuBar->addMenu(m_menuHelp);
0074 }
0075 
0076 void MainMenu::initSuperMenu(QMenu* superMenu) const
0077 {
0078     superMenu->addAction(m_actions[QSL("File/NewTab")]);
0079     superMenu->addAction(m_actions[QSL("File/NewWindow")]);
0080     superMenu->addAction(m_actions[QSL("File/NewPrivateWindow")]);
0081     superMenu->addAction(m_actions[QSL("File/OpenFile")]);
0082     if (mApp->sessionManager()) {
0083         superMenu->addSeparator();
0084         auto* sessionsSubmenu = new QMenu(tr("Sessions"));
0085         connect(sessionsSubmenu, SIGNAL(aboutToShow()), mApp->sessionManager(), SLOT(aboutToShowSessionsMenu()));
0086         superMenu->addMenu(sessionsSubmenu);
0087         superMenu->addAction(m_actions[QSL("File/SessionManager")]);
0088     }
0089     superMenu->addSeparator();
0090     superMenu->addAction(m_actions[QSL("File/SendLink")]);
0091     superMenu->addAction(m_actions[QSL("File/Print")]);
0092     superMenu->addSeparator();
0093     superMenu->addAction(m_actions[QSL("Edit/SelectAll")]);
0094     superMenu->addAction(m_actions[QSL("Edit/Find")]);
0095     superMenu->addSeparator();
0096     superMenu->addAction(m_menuHistory->actions().at(3));
0097     superMenu->addAction(m_menuBookmarks->actions().at(2));
0098     superMenu->addSeparator();
0099     superMenu->addMenu(m_menuView);
0100     superMenu->addMenu(m_menuHistory);
0101     superMenu->addMenu(m_menuBookmarks);
0102     superMenu->addMenu(m_menuTools);
0103     superMenu->addMenu(m_menuHelp);
0104     superMenu->addSeparator();
0105     superMenu->addAction(m_actions[QSL("Standard/Preferences")]);
0106     superMenu->addAction(m_actions[QSL("Standard/About")]);
0107     superMenu->addSeparator();
0108     superMenu->addAction(m_actions[QSL("Standard/Quit")]);
0109 
0110     connect(superMenu, &QMenu::aboutToShow, this, &MainMenu::aboutToShowSuperMenu);
0111 }
0112 
0113 QAction* MainMenu::action(const QString &name) const
0114 {
0115     Q_ASSERT(m_actions.value(name));
0116 
0117     return m_actions.value(name);
0118 }
0119 
0120 void MainMenu::showAboutDialog()
0121 {
0122     auto* dialog = new AboutDialog(m_window);
0123     dialog->open();
0124 }
0125 
0126 void MainMenu::showPreferences()
0127 {
0128     if (!m_preferences)
0129         m_preferences = new Preferences(m_window);
0130 
0131     m_preferences->show();
0132     m_preferences->raise();
0133     m_preferences->activateWindow();
0134 }
0135 
0136 void MainMenu::quitApplication()
0137 {
0138     mApp->quitApplication();
0139 }
0140 
0141 void MainMenu::newTab()
0142 {
0143     callSlot("addTab");
0144 }
0145 
0146 void MainMenu::newWindow()
0147 {
0148     mApp->createWindow(Qz::BW_NewWindow);
0149 }
0150 
0151 void MainMenu::newPrivateWindow()
0152 {
0153     mApp->startPrivateBrowsing();
0154 }
0155 
0156 void MainMenu::openLocation()
0157 {
0158     callSlot("openLocation");
0159 }
0160 
0161 void MainMenu::openFile()
0162 {
0163     callSlot("openFile");
0164 }
0165 
0166 void MainMenu::closeWindow()
0167 {
0168     callSlot("closeWindow");
0169 }
0170 
0171 void MainMenu::savePageAs()
0172 {
0173     if (m_window) {
0174         QMetaObject::invokeMethod(m_window->weView(), "savePageAs");
0175     }
0176 }
0177 
0178 void MainMenu::sendLink()
0179 {
0180     const QUrl mailUrl = QUrl::fromEncoded(QByteArray(
0181         "mailto:%20?body=" +
0182         QUrl::toPercentEncoding(
0183             QString::fromUtf8(m_window->weView()->url().toEncoded())) +
0184         "&subject=" + QUrl::toPercentEncoding(m_window->weView()->title())));
0185     QDesktopServices::openUrl(mailUrl);
0186 }
0187 
0188 void MainMenu::printPage()
0189 {
0190     callSlot("printPage");
0191 }
0192 
0193 void MainMenu::editUndo()
0194 {
0195     if (m_window) {
0196         m_window->weView()->editUndo();
0197     }
0198 }
0199 
0200 void MainMenu::editRedo()
0201 {
0202     if (m_window) {
0203         m_window->weView()->editRedo();
0204     }
0205 }
0206 
0207 void MainMenu::editCut()
0208 {
0209     if (m_window) {
0210         m_window->weView()->editCut();
0211     }
0212 }
0213 
0214 void MainMenu::editCopy()
0215 {
0216     if (m_window) {
0217         m_window->weView()->editCopy();
0218     }
0219 }
0220 
0221 void MainMenu::editPaste()
0222 {
0223     if (m_window) {
0224         m_window->weView()->editPaste();
0225     }
0226 }
0227 
0228 void MainMenu::editSelectAll()
0229 {
0230     if (m_window) {
0231         m_window->weView()->editSelectAll();
0232     }
0233 }
0234 
0235 void MainMenu::editFind()
0236 {
0237     callSlot("searchOnPage");
0238 }
0239 
0240 void MainMenu::showStatusBar()
0241 {
0242     if (m_window) {
0243         m_window->toggleShowStatusBar();
0244     }
0245 }
0246 
0247 void MainMenu::stop()
0248 {
0249     if (m_window) {
0250         m_window->weView()->stop();
0251     }
0252 }
0253 
0254 void MainMenu::reload()
0255 {
0256     if (m_window) {
0257         m_window->weView()->reload();
0258     }
0259 }
0260 
0261 void MainMenu::zoomIn()
0262 {
0263     if (m_window) {
0264         m_window->weView()->zoomIn();
0265     }
0266 }
0267 
0268 void MainMenu::zoomOut()
0269 {
0270     if (m_window) {
0271         m_window->weView()->zoomOut();
0272     }
0273 }
0274 
0275 void MainMenu::zoomReset()
0276 {
0277     if (m_window) {
0278         m_window->weView()->zoomReset();
0279     }
0280 }
0281 
0282 void MainMenu::showPageSource()
0283 {
0284     callSlot("showSource");
0285 }
0286 
0287 void MainMenu::showFullScreen()
0288 {
0289     if (m_window) {
0290         m_window->toggleFullScreen();
0291     }
0292 }
0293 
0294 void MainMenu::webSearch()
0295 {
0296     callSlot("webSearch");
0297 }
0298 
0299 void MainMenu::showSiteInfo()
0300 {
0301     if (m_window && SiteInfo::canShowSiteInfo(m_window->weView()->url())) {
0302         auto* info = new SiteInfo(m_window->weView());
0303         info->show();
0304     }
0305 }
0306 
0307 void MainMenu::showDownloadManager()
0308 {
0309     DownloadManager* m = mApp->downloadManager();
0310     m->show();
0311     m->raise();
0312 }
0313 
0314 void MainMenu::showCookieManager()
0315 {
0316     auto* m = new CookieManager(m_window);
0317     m->show();
0318     m->raise();
0319 }
0320 
0321 void MainMenu::toggleWebInspector()
0322 {
0323     callSlot("toggleWebInspector");
0324 }
0325 
0326 void MainMenu::showClearRecentHistoryDialog()
0327 {
0328     auto* dialog = new ClearPrivateData(m_window);
0329     dialog->open();
0330 }
0331 
0332 void MainMenu::aboutQt()
0333 {
0334     QApplication::aboutQt();
0335 }
0336 
0337 void MainMenu::showInfoAboutApp()
0338 {
0339     if (m_window) {
0340         m_window->tabWidget()->addView(QUrl(QSL("falkon:about")), Qz::NT_CleanSelectedTab);
0341     }
0342 }
0343 
0344 void MainMenu::showConfigInfo()
0345 {
0346     if (m_window) {
0347         m_window->tabWidget()->addView(QUrl(QSL("falkon:config")), Qz::NT_CleanSelectedTab);
0348     }
0349 }
0350 
0351 void MainMenu::reportIssue()
0352 {
0353     if (m_window) {
0354         m_window->tabWidget()->addView(QUrl(QSL("falkon:reportbug")), Qz::NT_CleanSelectedTab);
0355     }
0356 }
0357 
0358 void MainMenu::restoreClosedTab()
0359 {
0360     if (m_window) {
0361         m_window->tabWidget()->restoreClosedTab();
0362     }
0363 }
0364 
0365 void MainMenu::aboutToShowFileMenu()
0366 {
0367 #ifndef Q_OS_MACOS
0368     m_actions[QSL("File/CloseWindow")]->setEnabled(mApp->windowCount() > 1);
0369 #endif
0370 }
0371 
0372 void MainMenu::aboutToShowViewMenu()
0373 {
0374     if (!m_window) {
0375         return;
0376     }
0377 
0378     m_actions[QSL("View/ShowStatusBar")]->setChecked(m_window->statusBar()->isVisible());
0379     m_actions[QSL("View/FullScreen")]->setChecked(m_window->isFullScreen());
0380 }
0381 
0382 void MainMenu::aboutToShowEditMenu()
0383 {
0384     if (!m_window) {
0385         return;
0386     }
0387 
0388     WebView* view = m_window->weView();
0389 
0390     m_actions[QSL("Edit/Undo")]->setEnabled(view->pageAction(QWebEnginePage::Undo)->isEnabled());
0391     m_actions[QSL("Edit/Redo")]->setEnabled(view->pageAction(QWebEnginePage::Redo)->isEnabled());
0392     m_actions[QSL("Edit/Cut")]->setEnabled(view->pageAction(QWebEnginePage::Cut)->isEnabled());
0393     m_actions[QSL("Edit/Copy")]->setEnabled(view->pageAction(QWebEnginePage::Copy)->isEnabled());
0394     m_actions[QSL("Edit/Paste")]->setEnabled(view->pageAction(QWebEnginePage::Paste)->isEnabled());
0395     m_actions[QSL("Edit/SelectAll")]->setEnabled(view->pageAction(QWebEnginePage::SelectAll)->isEnabled());
0396 }
0397 
0398 void MainMenu::aboutToShowToolsMenu()
0399 {
0400     if (!m_window)
0401         return;
0402 
0403     m_actions[QSL("Tools/SiteInfo")]->setEnabled(SiteInfo::canShowSiteInfo(m_window->weView()->url()));
0404 
0405     m_submenuExtensions->clear();
0406     mApp->plugins()->populateExtensionsMenu(m_submenuExtensions);
0407 
0408     m_submenuExtensions->menuAction()->setVisible(!m_submenuExtensions->actions().isEmpty());
0409 }
0410 
0411 void MainMenu::aboutToShowSuperMenu()
0412 {
0413     if (!m_window) {
0414         return;
0415     }
0416 
0417     WebView* view = m_window->weView();
0418 
0419     m_actions[QSL("Edit/Find")]->setEnabled(true);
0420     m_actions[QSL("Edit/SelectAll")]->setEnabled(view->pageAction(QWebEnginePage::SelectAll)->isEnabled());
0421 }
0422 
0423 void MainMenu::aboutToShowToolbarsMenu()
0424 {
0425     auto* menu = qobject_cast<QMenu*>(sender());
0426     Q_ASSERT(menu);
0427 
0428     if (m_window) {
0429         menu->clear();
0430         m_window->createToolbarsMenu(menu);
0431     }
0432 }
0433 
0434 void MainMenu::aboutToShowSidebarsMenu()
0435 {
0436     auto* menu = qobject_cast<QMenu*>(sender());
0437     Q_ASSERT(menu);
0438 
0439     if (m_window) {
0440         m_window->createSidebarsMenu(menu);
0441     }
0442 }
0443 
0444 void MainMenu::aboutToShowEncodingMenu()
0445 {
0446     auto* menu = qobject_cast<QMenu*>(sender());
0447     Q_ASSERT(menu);
0448 
0449     if (m_window) {
0450         menu->clear();
0451         m_window->createEncodingMenu(menu);
0452     }
0453 }
0454 
0455 void MainMenu::init()
0456 {
0457 #define ADD_ACTION(name, menu, icon, trName, slot, shortcut) \
0458     action = menu->addAction(icon, trName); \
0459     action->setShortcut(QKeySequence(QSL(shortcut))); \
0460     connect(action, SIGNAL(triggered()), this, slot); \
0461     m_actions[QSL(name)] = action
0462 
0463 #define ADD_CHECKABLE_ACTION(name, menu, icon, trName, slot, shortcut) \
0464     action = menu->addAction(icon, trName); \
0465     action->setShortcut(QKeySequence(QSL(shortcut))); \
0466     action->setCheckable(true); \
0467     connect(action, SIGNAL(triggered(bool)), this, slot); \
0468     m_actions[QSL(name)] = action
0469 
0470     // Standard actions - needed on Mac to be placed correctly in "application" menu
0471     auto* action = new QAction(QIcon::fromTheme(QSL("help-about")), tr("&About Falkon"), this);
0472     action->setMenuRole(QAction::AboutRole);
0473     connect(action, &QAction::triggered, this, &MainMenu::showAboutDialog);
0474     m_actions[QSL("Standard/About")] = action;
0475 
0476     action = new QAction(IconProvider::settingsIcon(), tr("Pr&eferences"), this);
0477     action->setMenuRole(QAction::PreferencesRole);
0478     action->setShortcut(QKeySequence(QKeySequence::Preferences));
0479     connect(action, &QAction::triggered, this, &MainMenu::showPreferences);
0480     m_actions[QSL("Standard/Preferences")] = action;
0481 
0482     action = new QAction(QIcon::fromTheme(QSL("application-exit")), tr("Quit"), this);
0483     action->setMenuRole(QAction::QuitRole);
0484     // shortcut set from browserwindow
0485     connect(action, &QAction::triggered, this, &MainMenu::quitApplication);
0486     m_actions[QSL("Standard/Quit")] = action;
0487 
0488     // File menu
0489     m_menuFile = new QMenu(tr("&File"));
0490     connect(m_menuFile, &QMenu::aboutToShow, this, &MainMenu::aboutToShowFileMenu);
0491 
0492     ADD_ACTION("File/NewTab", m_menuFile, IconProvider::newTabIcon(), tr("New Tab"), SLOT(newTab()), "Ctrl+T");
0493     ADD_ACTION("File/NewWindow", m_menuFile, IconProvider::newWindowIcon(), tr("&New Window"), SLOT(newWindow()), "Ctrl+N");
0494     ADD_ACTION("File/NewPrivateWindow", m_menuFile, IconProvider::privateBrowsingIcon(), tr("New &Private Window"), SLOT(newPrivateWindow()), "Ctrl+Shift+P");
0495     ADD_ACTION("File/OpenLocation", m_menuFile, QIcon::fromTheme(QSL("document-open-remote")), tr("Open Location"), SLOT(openLocation()), "Ctrl+L");
0496     ADD_ACTION("File/OpenFile", m_menuFile, QIcon::fromTheme(QSL("document-open")), tr("Open &File..."), SLOT(openFile()), "Ctrl+O");
0497     ADD_ACTION("File/CloseWindow", m_menuFile, QIcon::fromTheme(QSL("window-close")), tr("Close Window"), SLOT(closeWindow()), "Ctrl+Shift+W");
0498     m_menuFile->addSeparator();
0499 
0500     if (mApp->sessionManager()) {
0501         auto* sessionsSubmenu = new QMenu(tr("Sessions"));
0502         connect(sessionsSubmenu, SIGNAL(aboutToShow()), mApp->sessionManager(), SLOT(aboutToShowSessionsMenu()));
0503         m_menuFile->addMenu(sessionsSubmenu);
0504         action = new QAction(tr("Session Manager"), this);
0505         connect(action, &QAction::triggered, mApp->sessionManager(), &SessionManager::openSessionManagerDialog);
0506         m_actions[QSL("File/SessionManager")] = action;
0507         m_menuFile->addAction(action);
0508         m_menuFile->addSeparator();
0509     }
0510 
0511     ADD_ACTION("File/SavePageAs", m_menuFile, QIcon::fromTheme(QSL("document-save")), tr("&Save Page As..."), SLOT(savePageAs()), "Ctrl+S");
0512     ADD_ACTION("File/SendLink", m_menuFile, QIcon::fromTheme(QSL("mail-message-new")), tr("Send Link..."), SLOT(sendLink()), "");
0513     ADD_ACTION("File/Print", m_menuFile, QIcon::fromTheme(QSL("document-print")), tr("&Print..."), SLOT(printPage()), "Ctrl+P");
0514     m_menuFile->addSeparator();
0515     m_menuFile->addAction(m_actions[QSL("Standard/Quit")]);
0516 
0517     // Edit menu
0518     m_menuEdit = new QMenu(tr("&Edit"));
0519     connect(m_menuEdit, &QMenu::aboutToShow, this, &MainMenu::aboutToShowEditMenu);
0520 
0521     ADD_ACTION("Edit/Undo", m_menuEdit, QIcon::fromTheme(QSL("edit-undo")), tr("&Undo"), SLOT(editUndo()), "Ctrl+Z");
0522     action->setShortcutContext(Qt::WidgetShortcut);
0523     ADD_ACTION("Edit/Redo", m_menuEdit, QIcon::fromTheme(QSL("edit-redo")), tr("&Redo"), SLOT(editRedo()), "Ctrl+Shift+Z");
0524     action->setShortcutContext(Qt::WidgetShortcut);
0525     m_menuEdit->addSeparator();
0526     ADD_ACTION("Edit/Cut", m_menuEdit, QIcon::fromTheme(QSL("edit-cut")), tr("&Cut"), SLOT(editCut()), "Ctrl+X");
0527     action->setShortcutContext(Qt::WidgetShortcut);
0528     ADD_ACTION("Edit/Copy", m_menuEdit, QIcon::fromTheme(QSL("edit-copy")), tr("C&opy"), SLOT(editCopy()), "Ctrl+C");
0529     action->setShortcutContext(Qt::WidgetShortcut);
0530     ADD_ACTION("Edit/Paste", m_menuEdit, QIcon::fromTheme(QSL("edit-paste")), tr("&Paste"), SLOT(editPaste()), "Ctrl+V");
0531     action->setShortcutContext(Qt::WidgetShortcut);
0532     m_menuEdit->addSeparator();
0533     ADD_ACTION("Edit/SelectAll", m_menuEdit, QIcon::fromTheme(QSL("edit-select-all")), tr("Select &All"), SLOT(editSelectAll()), "Ctrl+A");
0534     action->setShortcutContext(Qt::WidgetShortcut);
0535     ADD_ACTION("Edit/Find", m_menuEdit, QIcon::fromTheme(QSL("edit-find")), tr("&Find"), SLOT(editFind()), "Ctrl+F");
0536     action->setShortcutContext(Qt::WidgetShortcut);
0537     m_menuEdit->addSeparator();
0538 
0539     // View menu
0540     m_menuView = new QMenu(tr("&View"));
0541     connect(m_menuView, &QMenu::aboutToShow, this, &MainMenu::aboutToShowViewMenu);
0542 
0543     auto* toolbarsMenu = new QMenu(tr("Toolbars"));
0544     connect(toolbarsMenu, &QMenu::aboutToShow, this, &MainMenu::aboutToShowToolbarsMenu);
0545     auto* sidebarMenu = new QMenu(tr("Sidebar"));
0546     connect(sidebarMenu, &QMenu::aboutToShow, this, &MainMenu::aboutToShowSidebarsMenu);
0547     auto* encodingMenu = new QMenu(tr("Character &Encoding"));
0548     connect(encodingMenu, &QMenu::aboutToShow, this, &MainMenu::aboutToShowEncodingMenu);
0549 
0550     // Create menus to make shortcuts available even before first showing the menu
0551     m_window->createToolbarsMenu(toolbarsMenu);
0552     m_window->createSidebarsMenu(sidebarMenu);
0553 
0554     m_menuView->addMenu(toolbarsMenu);
0555     m_menuView->addMenu(sidebarMenu);
0556     ADD_CHECKABLE_ACTION("View/ShowStatusBar", m_menuView, QIcon(), tr("Sta&tus Bar"), SLOT(showStatusBar()), "");
0557     m_menuView->addSeparator();
0558     ADD_ACTION("View/Stop", m_menuView, QIcon::fromTheme(QSL("process-stop")), tr("&Stop"), SLOT(stop()), "Esc");
0559     ADD_ACTION("View/Reload", m_menuView, QIcon::fromTheme(QSL("view-refresh")), tr("&Reload"), SLOT(reload()), "F5");
0560     m_menuView->addSeparator();
0561     ADD_ACTION("View/ZoomIn", m_menuView, QIcon::fromTheme(QSL("zoom-in")), tr("Zoom &In"), SLOT(zoomIn()), "Ctrl++");
0562     ADD_ACTION("View/ZoomOut", m_menuView, QIcon::fromTheme(QSL("zoom-out")), tr("Zoom &Out"), SLOT(zoomOut()), "Ctrl+-");
0563     ADD_ACTION("View/ZoomReset", m_menuView, QIcon::fromTheme(QSL("zoom-original")), tr("Reset"), SLOT(zoomReset()), "Ctrl+0");
0564     m_menuView->addSeparator();
0565     m_menuView->addMenu(encodingMenu);
0566     m_menuView->addSeparator();
0567     ADD_ACTION("View/PageSource", m_menuView, QIcon::fromTheme(QSL("text-html")), tr("&Page Source"), SLOT(showPageSource()), "Ctrl+U");
0568     action->setShortcutContext(Qt::WidgetShortcut);
0569     ADD_CHECKABLE_ACTION("View/FullScreen", m_menuView, QIcon::fromTheme(QSL("view-fullscreen")), tr("&FullScreen"), SLOT(showFullScreen()), "F11");
0570 
0571     // Tools menu
0572     m_menuTools = new QMenu(tr("&Tools"));
0573     connect(m_menuTools, &QMenu::aboutToShow, this, &MainMenu::aboutToShowToolsMenu);
0574 
0575     ADD_ACTION("Tools/WebSearch", m_menuTools, QIcon::fromTheme(QSL("edit-find")), tr("&Web Search"), SLOT(webSearch()), "Ctrl+K");
0576     ADD_ACTION("Tools/SiteInfo", m_menuTools, QIcon::fromTheme(QSL("dialog-information")), tr("Site &Info"), SLOT(showSiteInfo()), "Ctrl+I");
0577     action->setShortcutContext(Qt::WidgetShortcut);
0578     m_menuTools->addSeparator();
0579     ADD_ACTION("Tools/DownloadManager", m_menuTools, QIcon::fromTheme(QSL("download")), tr("&Download Manager"), SLOT(showDownloadManager()), "Ctrl+Y");
0580     ADD_ACTION("Tools/CookiesManager", m_menuTools, QIcon(), tr("&Cookies Manager"), SLOT(showCookieManager()), "");
0581     ADD_ACTION("Tools/WebInspector", m_menuTools, QIcon(), tr("Web In&spector"), SLOT(toggleWebInspector()), "Ctrl+Shift+I");
0582     ADD_ACTION("Tools/ClearRecentHistory", m_menuTools, QIcon::fromTheme(QSL("edit-clear")), tr("Clear Recent &History"), SLOT(showClearRecentHistoryDialog()), "Ctrl+Shift+Del");
0583 
0584     if (!WebInspector::isEnabled())
0585         m_actions.value(QSL("Tools/WebInspector"))->setVisible(false);
0586 
0587     m_submenuExtensions = new QMenu(tr("&Extensions"));
0588     m_submenuExtensions->menuAction()->setVisible(false);
0589     m_menuTools->addMenu(m_submenuExtensions);
0590     m_menuTools->addSeparator();
0591 
0592     // Help menu
0593     m_menuHelp = new QMenu(tr("&Help"));
0594 
0595 #ifndef Q_OS_MACOS
0596     ADD_ACTION("Help/AboutQt", m_menuHelp, QIcon(), tr("About &Qt"), SLOT(aboutQt()), "");
0597     m_menuHelp->addAction(m_actions[QSL("Standard/About")]);
0598     m_menuHelp->addSeparator();
0599 #endif
0600 
0601     ADD_ACTION("Help/InfoAboutApp", m_menuHelp, QIcon::fromTheme(QSL("help-contents")), tr("Information about application"), SLOT(showInfoAboutApp()), "");
0602     ADD_ACTION("Help/ConfigInfo", m_menuHelp, QIcon(), tr("Configuration Information"), SLOT(showConfigInfo()), "");
0603     ADD_ACTION("Help/ReportIssue", m_menuHelp, QIcon(), tr("Report &Issue"), SLOT(reportIssue()), "");
0604 
0605     m_actions[QSL("Help/InfoAboutApp")]->setShortcut(QKeySequence(QKeySequence::HelpContents));
0606 
0607     // History menu
0608     m_menuHistory = new HistoryMenu();
0609     m_menuHistory->setMainWindow(m_window);
0610 
0611     // Bookmarks menu
0612     m_menuBookmarks = new BookmarksMenu();
0613     m_menuBookmarks->setMainWindow(m_window);
0614 
0615     // Other actions
0616     action = new QAction(QIcon::fromTheme(QSL("user-trash")), tr("Restore &Closed Tab"), this);
0617     action->setShortcut(QKeySequence(QSL("Ctrl+Shift+T")));
0618     connect(action, &QAction::triggered, this, &MainMenu::restoreClosedTab);
0619     m_actions[QSL("Other/RestoreClosedTab")] = action;
0620 
0621 #ifdef Q_OS_MACOS
0622     m_actions[QSL("View/FullScreen")]->setShortcut(QKeySequence(QSL("Ctrl+Meta+F")));
0623 
0624     // Add standard actions to File Menu (as it won't be ever cleared) and Mac menubar should move them to "Application" menu
0625     m_menuFile->addAction(m_actions[QSL("Standard/About")]);
0626     m_menuFile->addAction(m_actions[QSL("Standard/Preferences")]);
0627 
0628     // Prevent ConfigInfo action to be detected as "Preferences..." action in Mac menubar
0629     m_actions[QSL("Help/ConfigInfo")]->setMenuRole(QAction::NoRole);
0630 
0631     // Create Dock menu
0632     QMenu* dockMenu = new QMenu(0);
0633     dockMenu->addAction(m_actions[QSL("File/NewTab")]);
0634     dockMenu->addAction(m_actions[QSL("File/NewWindow")]);
0635     dockMenu->addAction(m_actions[QSL("File/NewPrivateWindow")]);
0636     qt_mac_set_dock_menu(dockMenu);
0637 #endif
0638 
0639 #if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
0640     m_menuEdit->addAction(m_actions[QSL("Standard/Preferences")]);
0641 #elif !defined(Q_OS_MACOS)
0642     m_menuTools->addAction(m_actions[QSL("Standard/Preferences")]);
0643 #endif
0644 
0645     addActionsToWindow();
0646 }
0647 
0648 void MainMenu::addActionsToWindow()
0649 {
0650     // Make shortcuts available even in fullscreen (hidden menu)
0651 
0652     QList<QAction*> actions;
0653     actions << m_menuFile->actions();
0654     actions << m_menuEdit->actions();
0655     actions << m_menuView->actions();
0656     actions << m_menuTools->actions();
0657     actions << m_menuHelp->actions();
0658     actions << m_menuHistory->actions();
0659     actions << m_menuBookmarks->actions();
0660     actions << m_actions[QSL("Other/RestoreClosedTab")];
0661 
0662     for (int i = 0; i < actions.size(); ++i) {
0663         QAction* action = actions.at(i);
0664         if (action->menu()) {
0665             actions += action->menu()->actions();
0666         }
0667         m_window->addAction(action);
0668     }
0669 }
0670 
0671 void MainMenu::callSlot(const char* slot)
0672 {
0673     if (m_window) {
0674         QMetaObject::invokeMethod(m_window, slot);
0675     }
0676 }