summaryrefslogtreecommitdiffstats
path: root/examples/webenginewidgets/simplebrowser/browserwindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'examples/webenginewidgets/simplebrowser/browserwindow.cpp')
-rw-r--r--examples/webenginewidgets/simplebrowser/browserwindow.cpp437
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();
+ }
+}