diff options
Diffstat (limited to 'examples/webenginewidgets/simplebrowser/browserwindow.cpp')
-rw-r--r-- | examples/webenginewidgets/simplebrowser/browserwindow.cpp | 437 |
1 files changed, 437 insertions, 0 deletions
diff --git a/examples/webenginewidgets/simplebrowser/browserwindow.cpp b/examples/webenginewidgets/simplebrowser/browserwindow.cpp new file mode 100644 index 000000000..e7d5fd129 --- /dev/null +++ b/examples/webenginewidgets/simplebrowser/browserwindow.cpp @@ -0,0 +1,437 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** 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 "tabwidget.h" +#include "urllineedit.h" +#include "webview.h" +#include <QApplication> +#include <QCloseEvent> +#include <QDesktopWidget> +#include <QFileDialog> +#include <QMenuBar> +#include <QMessageBox> +#include <QProgressBar> +#include <QStatusBar> +#include <QToolBar> +#include <QVBoxLayout> + +BrowserWindow::BrowserWindow(QWidget *parent, Qt::WindowFlags flags) + : QMainWindow(parent, flags) + , m_tabWidget(new TabWidget(this)) + , m_progressBar(new QProgressBar(this)) + , m_historyBackAction(nullptr) + , m_historyForwardAction(nullptr) + , m_stopAction(nullptr) + , m_reloadAction(nullptr) + , m_stopReloadAction(nullptr) + , m_urlLineEdit(new UrlLineEdit(this)) +{ + setToolButtonStyle(Qt::ToolButtonFollowStyle); + setAttribute(Qt::WA_DeleteOnClose, true); + + QToolBar *toolbar = createToolBar(); + addToolBar(toolbar); + menuBar()->addMenu(createFileMenu(m_tabWidget)); + 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->setMargin(0); + addToolBarBreak(); + + m_progressBar->setMaximumHeight(1); + m_progressBar->setTextVisible(false); + m_progressBar->setStyleSheet(QStringLiteral("QProgressBar {border: 0px } QProgressBar::chunk { background-color: red; }")); + + layout->addWidget(m_progressBar); + layout->addWidget(m_tabWidget); + centralWidget->setLayout(layout); + setCentralWidget(centralWidget); + + connect(m_tabWidget, &TabWidget::titleChanged, this, &BrowserWindow::handleWebViewTitleChanged); + connect(m_tabWidget, &TabWidget::linkHovered, [this](const QString& url) { + statusBar()->showMessage(url); + }); + connect(m_tabWidget, &TabWidget::loadProgress, this, &BrowserWindow::handleWebViewLoadProgress); + connect(m_tabWidget, &TabWidget::urlChanged, this, &BrowserWindow::handleWebViewUrlChanged); + connect(m_tabWidget, &TabWidget::iconChanged, this, &BrowserWindow::handleWebViewIconChanged); + connect(m_tabWidget, &TabWidget::webActionEnabledChanged, this, &BrowserWindow::handleWebActionEnabledChanged); + connect(m_urlLineEdit, &QLineEdit::returnPressed, this, [this]() { + m_urlLineEdit->setFavIcon(QIcon(QStringLiteral(":defaulticon.png"))); + loadPage(m_urlLineEdit->url()); + }); + + m_urlLineEdit->setFavIcon(QIcon(QStringLiteral(":defaulticon.png"))); + + handleWebViewTitleChanged(tr("Qt Simple Browser")); + m_tabWidget->createTab(); +} + +BrowserWindow::~BrowserWindow() +{ +} + +QSize BrowserWindow::sizeHint() const +{ + QRect desktopRect = QApplication::desktop()->screenGeometry(); + 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); + + QAction *newTabAction = new QAction(QIcon(QLatin1String(":addtab.png")), tr("New &Tab"), this); + newTabAction->setShortcuts(QKeySequence::AddTab); + newTabAction->setIconVisibleInMenu(false); + connect(newTabAction, &QAction::triggered, tabWidget, &TabWidget::createTab); + fileMenu->addAction(newTabAction); + + fileMenu->addAction(tr("&Open File..."), this, &BrowserWindow::handleFileOpenTriggered, QKeySequence::Open); + fileMenu->addSeparator(); + + QAction *closeTabAction = new QAction(QIcon(QLatin1String(":closetab.png")), tr("&Close Tab"), this); + closeTabAction->setShortcuts(QKeySequence::Close); + closeTabAction->setIconVisibleInMenu(false); + 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, [closeAction]() { + if (Browser::instance().windows().count() == 1) + closeAction->setText(tr("&Quit")); + else + closeAction->setText(tr("&Close Window")); + }); + return fileMenu; +} + +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 = Browser::instance().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->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea); + navigationBar->toggleViewAction()->setEnabled(false); + + m_historyBackAction = new QAction(this); + m_historyBackAction->setShortcuts(QKeySequence::Back); + m_historyBackAction->setIconVisibleInMenu(false); + m_historyBackAction->setIcon(QIcon(QStringLiteral(":go-previous.png"))); + connect(m_historyBackAction, &QAction::triggered, [this]() { + m_tabWidget->triggerWebPageAction(QWebEnginePage::Back); + }); + navigationBar->addAction(m_historyBackAction); + + m_historyForwardAction = new QAction(this); + m_historyForwardAction->setShortcuts(QKeySequence::Forward); + m_historyForwardAction->setIconVisibleInMenu(false); + m_historyForwardAction->setIcon(QIcon(QStringLiteral(":go-next.png"))); + 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); + navigationBar->addWidget(m_urlLineEdit); + int size = m_urlLineEdit->sizeHint().height(); + navigationBar->setIconSize(QSize(size, size)); + return navigationBar; +} + +void BrowserWindow::handleWebViewIconChanged(const QIcon &icon) +{ + m_urlLineEdit->setFavIcon(icon); +} + +void BrowserWindow::handleWebViewUrlChanged(const QUrl &url) +{ + m_urlLineEdit->setUrl(url); + if (url.isEmpty()) + m_urlLineEdit->setFocus(); +} + +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 singal"); + } +} + +void BrowserWindow::handleWebViewTitleChanged(const QString &title) +{ + if (title.isEmpty()) + setWindowTitle(tr("Qt Simple Browser")); + else + setWindowTitle(tr("%1 - Qt Simple Browser").arg(title)); +} + +void BrowserWindow::handleNewWindowTriggered() +{ + BrowserWindow *window = new BrowserWindow(); + Browser::instance().addWindow(window); + window->loadHomePage(); +} + +void BrowserWindow::handleFileOpenTriggered() +{ + QString file = QFileDialog::getOpenFileName(this, tr("Open Web Resource"), QString(), + tr("Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*)")); + if (file.isEmpty()) + return; + loadPage(file); +} + +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(); +} + + +void BrowserWindow::loadHomePage() +{ + loadPage(QStringLiteral("http://www.qt.io")); +} + +void BrowserWindow::loadPage(const QString &page) +{ + loadPage(QUrl::fromUserInput(page)); +} + +void BrowserWindow::loadPage(const QUrl &url) +{ + if (url.isValid()) { + m_urlLineEdit->setUrl(url); + m_tabWidget->setUrl(url); + } +} + +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 (progress < 100 && progress > 0) { + m_stopReloadAction->setData(QWebEnginePage::Stop); + m_stopReloadAction->setIcon(stopIcon); + m_stopReloadAction->setToolTip(tr("Stop loading the current page")); + } else { + m_stopReloadAction->setData(QWebEnginePage::Reload); + m_stopReloadAction->setIcon(reloadIcon); + m_stopReloadAction->setToolTip(tr("Reload the current page")); + } + m_progressBar->setValue(progress < 100 ? progress : 0); +} + +void BrowserWindow::handleShowWindowTriggered() +{ + if (QAction *action = qobject_cast<QAction*>(sender())) { + int offset = action->data().toInt(); + QVector<BrowserWindow*> windows = Browser::instance().windows(); + windows.at(offset)->activateWindow(); + windows.at(offset)->currentTab()->setFocus(); + } +} |