diff options
Diffstat (limited to 'examples/webenginewidgets/simplebrowser/tabwidget.cpp')
-rw-r--r-- | examples/webenginewidgets/simplebrowser/tabwidget.cpp | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/examples/webenginewidgets/simplebrowser/tabwidget.cpp b/examples/webenginewidgets/simplebrowser/tabwidget.cpp new file mode 100644 index 000000000..d9e0dea1b --- /dev/null +++ b/examples/webenginewidgets/simplebrowser/tabwidget.cpp @@ -0,0 +1,277 @@ +/**************************************************************************** +** +** 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 "tabwidget.h" +#include "webpage.h" +#include "webview.h" +#include <QMenu> +#include <QTabBar> +#include <QWebEngineProfile> + +TabWidget::TabWidget(QWidget *parent) + : QTabWidget(parent) +{ + QTabBar *tabBar = this->tabBar(); + tabBar->setTabsClosable(true); + tabBar->setSelectionBehaviorOnRemove(QTabBar::SelectPreviousTab); + tabBar->setMovable(true); + tabBar->setContextMenuPolicy(Qt::CustomContextMenu); + connect(tabBar, &QTabBar::customContextMenuRequested, this, &TabWidget::handleContextMenuRequested); + connect(tabBar, &QTabBar::tabCloseRequested, this, &TabWidget::closeTab); + connect(tabBar, &QTabBar::tabBarDoubleClicked, [this](int index) { + if (index != -1) + return; + createTab(); + }); + + setDocumentMode(true); + setElideMode(Qt::ElideRight); + + connect(this, &QTabWidget::currentChanged, this, &TabWidget::handleCurrentChanged); +} + +TabWidget::~TabWidget() +{ +} + +void TabWidget::handleCurrentChanged(int index) +{ + if (index != -1) { + WebView *view = webView(index); + if (!view->url().isEmpty()) + view->setFocus(); + emit titleChanged(view->title()); + emit loadProgress(view->loadProgress()); + emit urlChanged(view->url()); + emit iconChanged(view->icon()); + emit webActionEnabledChanged(QWebEnginePage::Back, view->isWebActionEnabled(QWebEnginePage::Back)); + emit webActionEnabledChanged(QWebEnginePage::Forward, view->isWebActionEnabled(QWebEnginePage::Forward)); + emit webActionEnabledChanged(QWebEnginePage::Stop, view->isWebActionEnabled(QWebEnginePage::Stop)); + emit webActionEnabledChanged(QWebEnginePage::Reload,view->isWebActionEnabled(QWebEnginePage::Reload)); + } else { + emit titleChanged(QString()); + emit loadProgress(0); + emit urlChanged(QUrl()); + emit iconChanged(QIcon()); + emit webActionEnabledChanged(QWebEnginePage::Back, false); + emit webActionEnabledChanged(QWebEnginePage::Forward, false); + emit webActionEnabledChanged(QWebEnginePage::Stop, false); + emit webActionEnabledChanged(QWebEnginePage::Reload, true); + } +} + +void TabWidget::handleContextMenuRequested(const QPoint &pos) +{ + QMenu menu; + menu.addAction(tr("New &Tab"), this, &TabWidget::createTab, QKeySequence::AddTab); + int index = tabBar()->tabAt(pos); + if (index != -1) { + QAction *action = menu.addAction(tr("Clone Tab")); + connect(action, &QAction::triggered, this, [this,index]() { + cloneTab(index); + }); + menu.addSeparator(); + action = menu.addAction(tr("&Close Tab")); + action->setShortcut(QKeySequence::Close); + connect(action, &QAction::triggered, this, [this,index]() { + closeTab(index); + }); + action = menu.addAction(tr("Close &Other Tabs")); + connect(action, &QAction::triggered, this, [this,index]() { + closeOtherTabs(index); + }); + menu.addSeparator(); + action = menu.addAction(tr("Reload Tab")); + action->setShortcut(QKeySequence::Refresh); + connect(action, &QAction::triggered, this, [this,index]() { + reloadTab(index); + }); + } else { + menu.addSeparator(); + } + menu.addAction(tr("Reload All Tabs"), this, &TabWidget::reloadAllTabs); + menu.exec(QCursor::pos()); +} + +WebView *TabWidget::currentWebView() const +{ + return webView(currentIndex()); +} + +WebView *TabWidget::webView(int index) const +{ + return qobject_cast<WebView*>(widget(index)); +} + +void TabWidget::setupView(WebView *webView) +{ + QWebEnginePage *webPage = webView->page(); + + connect(webView, &QWebEngineView::titleChanged, [this, webView](const QString &title) { + int index = indexOf(webView); + if (index != -1) + setTabText(index, title); + if (currentIndex() == index) + emit titleChanged(title); + }); + connect(webView, &QWebEngineView::urlChanged, [this, webView](const QUrl &url) { + int index = indexOf(webView); + if (index != -1) + tabBar()->setTabData(index, url); + if (currentIndex() == index) + emit urlChanged(url); + }); + connect(webView, &QWebEngineView::loadProgress, [this, webView](int progress) { + if (currentIndex() == indexOf(webView)) + emit loadProgress(progress); + }); + connect(webPage, &QWebEnginePage::linkHovered, [this, webView](const QString &url) { + if (currentIndex() == indexOf(webView)) + emit linkHovered(url); + }); + connect(webView, &WebView::iconChanged, [this, webView](const QIcon& icon) { + int index = indexOf(webView); + if (index != -1) + setTabIcon(index, icon); + if (currentIndex() == index) + emit iconChanged(icon); + }); + connect(webView, &WebView::webActionEnabledChanged, [this, webView](QWebEnginePage::WebAction action, bool enabled) { + if (currentIndex() == indexOf(webView)) + emit webActionEnabledChanged(action,enabled); + }); + connect(webView, &QWebEngineView::loadStarted, [this, webView]() { + int index = indexOf(webView); + if (index != -1) { + QIcon icon(QLatin1String(":loading.gif")); + setTabIcon(index, icon); + } + }); + connect(webPage, &QWebEnginePage::windowCloseRequested, [this, webView]() { + int index = indexOf(webView); + if (index >= 0) + closeTab(index); + }); +} + +WebView *TabWidget::createTab(bool makeCurrent) +{ + WebView *webView = new WebView; + WebPage *webPage = new WebPage(QWebEngineProfile::defaultProfile(), webView); + webView->setPage(webPage); + setupView(webView); + addTab(webView, tr("(Untitled)")); + if (makeCurrent) + setCurrentWidget(webView); + return webView; +} + +void TabWidget::reloadAllTabs() +{ + for (int i = 0; i < count(); ++i) + webView(i)->reload(); +} + +void TabWidget::closeOtherTabs(int index) +{ + for (int i = count() - 1; i > index; --i) + closeTab(i); + for (int i = index - 1; i >= 0; --i) + closeTab(i); +} + +void TabWidget::closeTab(int index) +{ + if (WebView *view = webView(index)) { + bool hasFocus = view->hasFocus(); + removeTab(index); + if (hasFocus && count() > 0) + currentWebView()->setFocus(); + if (count() == 0) + createTab(); + view->deleteLater(); + } +} + +void TabWidget::cloneTab(int index) +{ + if (WebView *view = webView(index)) { + WebView *tab = createTab(false); + tab->setUrl(view->url()); + } +} + +void TabWidget::setUrl(const QUrl &url) +{ + if (WebView *view = currentWebView()) { + view->setUrl(url); + view->setFocus(); + } +} + +void TabWidget::triggerWebPageAction(QWebEnginePage::WebAction action) +{ + if (WebView *webView = currentWebView()) { + webView->triggerPageAction(action); + webView->setFocus(); + } +} + +void TabWidget::nextTab() +{ + int next = currentIndex() + 1; + if (next == count()) + next = 0; + setCurrentIndex(next); +} + +void TabWidget::previousTab() +{ + int next = currentIndex() - 1; + if (next < 0) + next = count() - 1; + setCurrentIndex(next); +} + +void TabWidget::reloadTab(int index) +{ + if (WebView *view = webView(index)) + view->reload(); +} |