| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the examples of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:BSD$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** BSD License Usage |
| ** Alternatively, you may use this file under the terms of the BSD license |
| ** as follows: |
| ** |
| ** "Redistribution and use in source and binary forms, with or without |
| ** modification, are permitted provided that the following conditions are |
| ** met: |
| ** * Redistributions of source code must retain the above copyright |
| ** notice, this list of conditions and the following disclaimer. |
| ** * Redistributions in binary form must reproduce the above copyright |
| ** notice, this list of conditions and the following disclaimer in |
| ** the documentation and/or other materials provided with the |
| ** distribution. |
| ** * Neither the name of The Qt Company Ltd nor the names of its |
| ** contributors may be used to endorse or promote products derived |
| ** from this software without specific prior written permission. |
| ** |
| ** |
| ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| #include "browser.h" |
| #include "browserwindow.h" |
| #include "downloadmanagerwidget.h" |
| #include "tabwidget.h" |
| #include "webview.h" |
| #include <QApplication> |
| #include <QCloseEvent> |
| #include <QDesktopWidget> |
| #include <QEvent> |
| #include <QFileDialog> |
| #include <QInputDialog> |
| #include <QMenuBar> |
| #include <QMessageBox> |
| #include <QProgressBar> |
| #include <QScreen> |
| #include <QStatusBar> |
| #include <QToolBar> |
| #include <QVBoxLayout> |
| #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) |
| #include <QWebEngineFindTextResult> |
| #endif |
| #include <QWebEngineProfile> |
| |
| BrowserWindow::BrowserWindow(Browser *browser, QWebEngineProfile *profile, bool forDevTools) |
| : m_browser(browser) |
| , m_profile(profile) |
| , m_tabWidget(new TabWidget(profile, this)) |
| , m_progressBar(nullptr) |
| , m_historyBackAction(nullptr) |
| , m_historyForwardAction(nullptr) |
| , m_stopAction(nullptr) |
| , m_reloadAction(nullptr) |
| , m_stopReloadAction(nullptr) |
| , m_urlLineEdit(nullptr) |
| , m_favAction(nullptr) |
| { |
| setAttribute(Qt::WA_DeleteOnClose, true); |
| setFocusPolicy(Qt::ClickFocus); |
| |
| if (!forDevTools) { |
| m_progressBar = new QProgressBar(this); |
| |
| QToolBar *toolbar = createToolBar(); |
| addToolBar(toolbar); |
| menuBar()->addMenu(createFileMenu(m_tabWidget)); |
| menuBar()->addMenu(createEditMenu()); |
| menuBar()->addMenu(createViewMenu(toolbar)); |
| menuBar()->addMenu(createWindowMenu(m_tabWidget)); |
| menuBar()->addMenu(createHelpMenu()); |
| } |
| |
| QWidget *centralWidget = new QWidget(this); |
| QVBoxLayout *layout = new QVBoxLayout; |
| layout->setSpacing(0); |
| layout->setContentsMargins(0, 0, 0, 0); |
| if (!forDevTools) { |
| addToolBarBreak(); |
| |
| m_progressBar->setMaximumHeight(1); |
| m_progressBar->setTextVisible(false); |
| m_progressBar->setStyleSheet(QStringLiteral("QProgressBar {border: 0px} QProgressBar::chunk {background-color: #da4453}")); |
| |
| layout->addWidget(m_progressBar); |
| } |
| |
| layout->addWidget(m_tabWidget); |
| centralWidget->setLayout(layout); |
| setCentralWidget(centralWidget); |
| |
| connect(m_tabWidget, &TabWidget::titleChanged, this, &BrowserWindow::handleWebViewTitleChanged); |
| if (!forDevTools) { |
| connect(m_tabWidget, &TabWidget::linkHovered, [this](const QString& url) { |
| statusBar()->showMessage(url); |
| }); |
| connect(m_tabWidget, &TabWidget::loadProgress, this, &BrowserWindow::handleWebViewLoadProgress); |
| connect(m_tabWidget, &TabWidget::webActionEnabledChanged, this, &BrowserWindow::handleWebActionEnabledChanged); |
| connect(m_tabWidget, &TabWidget::urlChanged, [this](const QUrl &url) { |
| m_urlLineEdit->setText(url.toDisplayString()); |
| }); |
| connect(m_tabWidget, &TabWidget::favIconChanged, m_favAction, &QAction::setIcon); |
| connect(m_tabWidget, &TabWidget::devToolsRequested, this, &BrowserWindow::handleDevToolsRequested); |
| connect(m_urlLineEdit, &QLineEdit::returnPressed, [this]() { |
| m_tabWidget->setUrl(QUrl::fromUserInput(m_urlLineEdit->text())); |
| }); |
| #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) |
| connect(m_tabWidget, &TabWidget::findTextFinished, this, &BrowserWindow::handleFindTextFinished); |
| #endif |
| |
| QAction *focusUrlLineEditAction = new QAction(this); |
| addAction(focusUrlLineEditAction); |
| focusUrlLineEditAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_L)); |
| connect(focusUrlLineEditAction, &QAction::triggered, this, [this] () { |
| m_urlLineEdit->setFocus(Qt::ShortcutFocusReason); |
| }); |
| } |
| |
| handleWebViewTitleChanged(QString()); |
| m_tabWidget->createTab(); |
| } |
| |
| QSize BrowserWindow::sizeHint() const |
| { |
| QRect desktopRect = QApplication::primaryScreen()->geometry(); |
| QSize size = desktopRect.size() * qreal(0.9); |
| return size; |
| } |
| |
| QMenu *BrowserWindow::createFileMenu(TabWidget *tabWidget) |
| { |
| QMenu *fileMenu = new QMenu(tr("&File")); |
| fileMenu->addAction(tr("&New Window"), this, &BrowserWindow::handleNewWindowTriggered, QKeySequence::New); |
| fileMenu->addAction(tr("New &Incognito Window"), this, &BrowserWindow::handleNewIncognitoWindowTriggered); |
| |
| QAction *newTabAction = new QAction(tr("New &Tab"), this); |
| newTabAction->setShortcuts(QKeySequence::AddTab); |
| connect(newTabAction, &QAction::triggered, this, [this]() { |
| m_tabWidget->createTab(); |
| m_urlLineEdit->setFocus(); |
| }); |
| fileMenu->addAction(newTabAction); |
| |
| fileMenu->addAction(tr("&Open File..."), this, &BrowserWindow::handleFileOpenTriggered, QKeySequence::Open); |
| fileMenu->addSeparator(); |
| |
| QAction *closeTabAction = new QAction(tr("&Close Tab"), this); |
| closeTabAction->setShortcuts(QKeySequence::Close); |
| connect(closeTabAction, &QAction::triggered, [tabWidget]() { |
| tabWidget->closeTab(tabWidget->currentIndex()); |
| }); |
| fileMenu->addAction(closeTabAction); |
| |
| QAction *closeAction = new QAction(tr("&Quit"),this); |
| closeAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q)); |
| connect(closeAction, &QAction::triggered, this, &QWidget::close); |
| fileMenu->addAction(closeAction); |
| |
| connect(fileMenu, &QMenu::aboutToShow, [this, closeAction]() { |
| if (m_browser->windows().count() == 1) |
| closeAction->setText(tr("&Quit")); |
| else |
| closeAction->setText(tr("&Close Window")); |
| }); |
| return fileMenu; |
| } |
| |
| QMenu *BrowserWindow::createEditMenu() |
| { |
| QMenu *editMenu = new QMenu(tr("&Edit")); |
| QAction *findAction = editMenu->addAction(tr("&Find")); |
| findAction->setShortcuts(QKeySequence::Find); |
| connect(findAction, &QAction::triggered, this, &BrowserWindow::handleFindActionTriggered); |
| |
| QAction *findNextAction = editMenu->addAction(tr("Find &Next")); |
| findNextAction->setShortcut(QKeySequence::FindNext); |
| connect(findNextAction, &QAction::triggered, [this]() { |
| if (!currentTab() || m_lastSearch.isEmpty()) |
| return; |
| currentTab()->findText(m_lastSearch); |
| }); |
| |
| QAction *findPreviousAction = editMenu->addAction(tr("Find &Previous")); |
| findPreviousAction->setShortcut(QKeySequence::FindPrevious); |
| connect(findPreviousAction, &QAction::triggered, [this]() { |
| if (!currentTab() || m_lastSearch.isEmpty()) |
| return; |
| currentTab()->findText(m_lastSearch, QWebEnginePage::FindBackward); |
| }); |
| |
| return editMenu; |
| } |
| |
| QMenu *BrowserWindow::createViewMenu(QToolBar *toolbar) |
| { |
| QMenu *viewMenu = new QMenu(tr("&View")); |
| m_stopAction = viewMenu->addAction(tr("&Stop")); |
| QList<QKeySequence> shortcuts; |
| shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Period)); |
| shortcuts.append(Qt::Key_Escape); |
| m_stopAction->setShortcuts(shortcuts); |
| connect(m_stopAction, &QAction::triggered, [this]() { |
| m_tabWidget->triggerWebPageAction(QWebEnginePage::Stop); |
| }); |
| |
| m_reloadAction = viewMenu->addAction(tr("Reload Page")); |
| m_reloadAction->setShortcuts(QKeySequence::Refresh); |
| connect(m_reloadAction, &QAction::triggered, [this]() { |
| m_tabWidget->triggerWebPageAction(QWebEnginePage::Reload); |
| }); |
| |
| QAction *zoomIn = viewMenu->addAction(tr("Zoom &In")); |
| zoomIn->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Plus)); |
| connect(zoomIn, &QAction::triggered, [this]() { |
| if (currentTab()) |
| currentTab()->setZoomFactor(currentTab()->zoomFactor() + 0.1); |
| }); |
| |
| QAction *zoomOut = viewMenu->addAction(tr("Zoom &Out")); |
| zoomOut->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Minus)); |
| connect(zoomOut, &QAction::triggered, [this]() { |
| if (currentTab()) |
| currentTab()->setZoomFactor(currentTab()->zoomFactor() - 0.1); |
| }); |
| |
| QAction *resetZoom = viewMenu->addAction(tr("Reset &Zoom")); |
| resetZoom->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_0)); |
| connect(resetZoom, &QAction::triggered, [this]() { |
| if (currentTab()) |
| currentTab()->setZoomFactor(1.0); |
| }); |
| |
| |
| viewMenu->addSeparator(); |
| QAction *viewToolbarAction = new QAction(tr("Hide Toolbar"),this); |
| viewToolbarAction->setShortcut(tr("Ctrl+|")); |
| connect(viewToolbarAction, &QAction::triggered, [toolbar,viewToolbarAction]() { |
| if (toolbar->isVisible()) { |
| viewToolbarAction->setText(tr("Show Toolbar")); |
| toolbar->close(); |
| } else { |
| viewToolbarAction->setText(tr("Hide Toolbar")); |
| toolbar->show(); |
| } |
| }); |
| viewMenu->addAction(viewToolbarAction); |
| |
| QAction *viewStatusbarAction = new QAction(tr("Hide Status Bar"), this); |
| viewStatusbarAction->setShortcut(tr("Ctrl+/")); |
| connect(viewStatusbarAction, &QAction::triggered, [this, viewStatusbarAction]() { |
| if (statusBar()->isVisible()) { |
| viewStatusbarAction->setText(tr("Show Status Bar")); |
| statusBar()->close(); |
| } else { |
| viewStatusbarAction->setText(tr("Hide Status Bar")); |
| statusBar()->show(); |
| } |
| }); |
| viewMenu->addAction(viewStatusbarAction); |
| return viewMenu; |
| } |
| |
| QMenu *BrowserWindow::createWindowMenu(TabWidget *tabWidget) |
| { |
| QMenu *menu = new QMenu(tr("&Window")); |
| |
| QAction *nextTabAction = new QAction(tr("Show Next Tab"), this); |
| QList<QKeySequence> shortcuts; |
| shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BraceRight)); |
| shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_PageDown)); |
| shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BracketRight)); |
| shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Less)); |
| nextTabAction->setShortcuts(shortcuts); |
| connect(nextTabAction, &QAction::triggered, tabWidget, &TabWidget::nextTab); |
| |
| QAction *previousTabAction = new QAction(tr("Show Previous Tab"), this); |
| shortcuts.clear(); |
| shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BraceLeft)); |
| shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_PageUp)); |
| shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BracketLeft)); |
| shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Greater)); |
| previousTabAction->setShortcuts(shortcuts); |
| connect(previousTabAction, &QAction::triggered, tabWidget, &TabWidget::previousTab); |
| |
| connect(menu, &QMenu::aboutToShow, [this, menu, nextTabAction, previousTabAction]() { |
| menu->clear(); |
| menu->addAction(nextTabAction); |
| menu->addAction(previousTabAction); |
| menu->addSeparator(); |
| |
| QVector<BrowserWindow*> windows = m_browser->windows(); |
| int index(-1); |
| for (auto window : windows) { |
| QAction *action = menu->addAction(window->windowTitle(), this, &BrowserWindow::handleShowWindowTriggered); |
| action->setData(++index); |
| action->setCheckable(true); |
| if (window == this) |
| action->setChecked(true); |
| } |
| }); |
| return menu; |
| } |
| |
| QMenu *BrowserWindow::createHelpMenu() |
| { |
| QMenu *helpMenu = new QMenu(tr("&Help")); |
| helpMenu->addAction(tr("About &Qt"), qApp, QApplication::aboutQt); |
| return helpMenu; |
| } |
| |
| QToolBar *BrowserWindow::createToolBar() |
| { |
| QToolBar *navigationBar = new QToolBar(tr("Navigation")); |
| navigationBar->setMovable(false); |
| navigationBar->toggleViewAction()->setEnabled(false); |
| |
| m_historyBackAction = new QAction(this); |
| QList<QKeySequence> backShortcuts = QKeySequence::keyBindings(QKeySequence::Back); |
| for (auto it = backShortcuts.begin(); it != backShortcuts.end();) { |
| // Chromium already handles navigate on backspace when appropriate. |
| if ((*it)[0] == Qt::Key_Backspace) |
| it = backShortcuts.erase(it); |
| else |
| ++it; |
| } |
| // For some reason Qt doesn't bind the dedicated Back key to Back. |
| backShortcuts.append(QKeySequence(Qt::Key_Back)); |
| m_historyBackAction->setShortcuts(backShortcuts); |
| m_historyBackAction->setIconVisibleInMenu(false); |
| m_historyBackAction->setIcon(QIcon(QStringLiteral(":go-previous.png"))); |
| m_historyBackAction->setToolTip(tr("Go back in history")); |
| connect(m_historyBackAction, &QAction::triggered, [this]() { |
| m_tabWidget->triggerWebPageAction(QWebEnginePage::Back); |
| }); |
| navigationBar->addAction(m_historyBackAction); |
| |
| m_historyForwardAction = new QAction(this); |
| QList<QKeySequence> fwdShortcuts = QKeySequence::keyBindings(QKeySequence::Forward); |
| for (auto it = fwdShortcuts.begin(); it != fwdShortcuts.end();) { |
| if (((*it)[0] & Qt::Key_unknown) == Qt::Key_Backspace) |
| it = fwdShortcuts.erase(it); |
| else |
| ++it; |
| } |
| fwdShortcuts.append(QKeySequence(Qt::Key_Forward)); |
| m_historyForwardAction->setShortcuts(fwdShortcuts); |
| m_historyForwardAction->setIconVisibleInMenu(false); |
| m_historyForwardAction->setIcon(QIcon(QStringLiteral(":go-next.png"))); |
| m_historyForwardAction->setToolTip(tr("Go forward in history")); |
| connect(m_historyForwardAction, &QAction::triggered, [this]() { |
| m_tabWidget->triggerWebPageAction(QWebEnginePage::Forward); |
| }); |
| navigationBar->addAction(m_historyForwardAction); |
| |
| m_stopReloadAction = new QAction(this); |
| connect(m_stopReloadAction, &QAction::triggered, [this]() { |
| m_tabWidget->triggerWebPageAction(QWebEnginePage::WebAction(m_stopReloadAction->data().toInt())); |
| }); |
| navigationBar->addAction(m_stopReloadAction); |
| |
| m_urlLineEdit = new QLineEdit(this); |
| m_favAction = new QAction(this); |
| m_urlLineEdit->addAction(m_favAction, QLineEdit::LeadingPosition); |
| m_urlLineEdit->setClearButtonEnabled(true); |
| navigationBar->addWidget(m_urlLineEdit); |
| |
| auto downloadsAction = new QAction(this); |
| downloadsAction->setIcon(QIcon(QStringLiteral(":go-bottom.png"))); |
| downloadsAction->setToolTip(tr("Show downloads")); |
| navigationBar->addAction(downloadsAction); |
| connect(downloadsAction, &QAction::triggered, [this]() { |
| m_browser->downloadManagerWidget().show(); |
| }); |
| |
| return navigationBar; |
| } |
| |
| void BrowserWindow::handleWebActionEnabledChanged(QWebEnginePage::WebAction action, bool enabled) |
| { |
| switch (action) { |
| case QWebEnginePage::Back: |
| m_historyBackAction->setEnabled(enabled); |
| break; |
| case QWebEnginePage::Forward: |
| m_historyForwardAction->setEnabled(enabled); |
| break; |
| case QWebEnginePage::Reload: |
| m_reloadAction->setEnabled(enabled); |
| break; |
| case QWebEnginePage::Stop: |
| m_stopAction->setEnabled(enabled); |
| break; |
| default: |
| qWarning("Unhandled webActionChanged signal"); |
| } |
| } |
| |
| void BrowserWindow::handleWebViewTitleChanged(const QString &title) |
| { |
| QString suffix = m_profile->isOffTheRecord() |
| ? tr("Qt Simple Browser (Incognito)") |
| : tr("Qt Simple Browser"); |
| |
| if (title.isEmpty()) |
| setWindowTitle(suffix); |
| else |
| setWindowTitle(title + " - " + suffix); |
| } |
| |
| void BrowserWindow::handleNewWindowTriggered() |
| { |
| BrowserWindow *window = m_browser->createWindow(); |
| window->m_urlLineEdit->setFocus(); |
| } |
| |
| void BrowserWindow::handleNewIncognitoWindowTriggered() |
| { |
| BrowserWindow *window = m_browser->createWindow(/* offTheRecord: */ true); |
| window->m_urlLineEdit->setFocus(); |
| } |
| |
| void BrowserWindow::handleFileOpenTriggered() |
| { |
| QUrl url = QFileDialog::getOpenFileUrl(this, tr("Open Web Resource"), QString(), |
| tr("Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*)")); |
| if (url.isEmpty()) |
| return; |
| currentTab()->setUrl(url); |
| } |
| |
| void BrowserWindow::handleFindActionTriggered() |
| { |
| if (!currentTab()) |
| return; |
| bool ok = false; |
| QString search = QInputDialog::getText(this, tr("Find"), |
| tr("Find:"), QLineEdit::Normal, |
| m_lastSearch, &ok); |
| if (ok && !search.isEmpty()) { |
| m_lastSearch = search; |
| #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) |
| currentTab()->findText(m_lastSearch); |
| #else |
| currentTab()->findText(m_lastSearch, 0, [this](bool found) { |
| if (!found) |
| statusBar()->showMessage(tr("\"%1\" not found.").arg(m_lastSearch)); |
| }); |
| #endif |
| } |
| } |
| |
| void BrowserWindow::closeEvent(QCloseEvent *event) |
| { |
| if (m_tabWidget->count() > 1) { |
| int ret = QMessageBox::warning(this, tr("Confirm close"), |
| tr("Are you sure you want to close the window ?\n" |
| "There are %1 tabs open.").arg(m_tabWidget->count()), |
| QMessageBox::Yes | QMessageBox::No, QMessageBox::No); |
| if (ret == QMessageBox::No) { |
| event->ignore(); |
| return; |
| } |
| } |
| event->accept(); |
| deleteLater(); |
| } |
| |
| TabWidget *BrowserWindow::tabWidget() const |
| { |
| return m_tabWidget; |
| } |
| |
| WebView *BrowserWindow::currentTab() const |
| { |
| return m_tabWidget->currentWebView(); |
| } |
| |
| void BrowserWindow::handleWebViewLoadProgress(int progress) |
| { |
| static QIcon stopIcon(QStringLiteral(":process-stop.png")); |
| static QIcon reloadIcon(QStringLiteral(":view-refresh.png")); |
| |
| if (0 < progress && progress < 100) { |
| m_stopReloadAction->setData(QWebEnginePage::Stop); |
| m_stopReloadAction->setIcon(stopIcon); |
| m_stopReloadAction->setToolTip(tr("Stop loading the current page")); |
| m_progressBar->setValue(progress); |
| } else { |
| m_stopReloadAction->setData(QWebEnginePage::Reload); |
| m_stopReloadAction->setIcon(reloadIcon); |
| m_stopReloadAction->setToolTip(tr("Reload the current page")); |
| m_progressBar->setValue(0); |
| } |
| } |
| |
| void BrowserWindow::handleShowWindowTriggered() |
| { |
| if (QAction *action = qobject_cast<QAction*>(sender())) { |
| int offset = action->data().toInt(); |
| QVector<BrowserWindow*> windows = m_browser->windows(); |
| windows.at(offset)->activateWindow(); |
| windows.at(offset)->currentTab()->setFocus(); |
| } |
| } |
| |
| void BrowserWindow::handleDevToolsRequested(QWebEnginePage *source) |
| { |
| source->setDevToolsPage(m_browser->createDevToolsWindow()->currentTab()->page()); |
| source->triggerAction(QWebEnginePage::InspectElement); |
| } |
| |
| #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) |
| void BrowserWindow::handleFindTextFinished(const QWebEngineFindTextResult &result) |
| { |
| if (result.numberOfMatches() == 0) { |
| statusBar()->showMessage(tr("\"%1\" not found.").arg(m_lastSearch)); |
| } else { |
| statusBar()->showMessage(tr("\"%1\" found: %2/%3").arg(m_lastSearch, |
| QString::number(result.activeMatch()), |
| QString::number(result.numberOfMatches()))); |
| } |
| } |
| #endif |