From a71efecbcc6f714d619a922a0eaa665a3c68a3b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCri=20Valdmann?= Date: Mon, 12 Jun 2017 15:57:31 +0200 Subject: Update Simple Browser example - Accept downloads and add a downloads list. - Fix toolbar icons being pixelated on hidpi screens by - enabling attribute AA_UseHighDpiPixmaps, and - replacing the 22x22 icons with 32x32 versions. - Move favicon selection to WebView to reduce duplication. - Replace UrlLineEdit with a standard QLineEdit using a QAction for the favicon and setClearButtonEnabled(true) for the clear button. - Fix bug where the "File -> New Tab" action would create background tabs because the QAction::triggered(bool) signal was connected to the TabWidget::createTab(bool) slot with the bool argument having a completely different meaning between the two. - Make the toolbar unmovable. Nobody wants to move the toolbar. - Add tooltips to toolbar buttons. - Add tooltips to the tab bar (page titles). - Stop adding icons to menu items only to disable them right after. Task-number: QTBUG-60655 Change-Id: I10cc0fa82dbf39281bbdbbf9ef901e1b26402f80 Reviewed-by: Leena Miettinen Reviewed-by: Michal Klocek --- .../webenginewidgets/simplebrowser/browser.cpp | 34 ++--- examples/webenginewidgets/simplebrowser/browser.h | 14 +- .../simplebrowser/browserwindow.cpp | 109 ++++++--------- .../webenginewidgets/simplebrowser/browserwindow.h | 18 ++- .../simplebrowser/data/AppLogoColor.png | Bin 0 -> 6113 bytes .../webenginewidgets/simplebrowser/data/addtab.png | Bin 469 -> 0 bytes .../simplebrowser/data/closetab.png | Bin 516 -> 0 bytes .../simplebrowser/data/defaulticon.png | Bin 1473 -> 0 bytes .../simplebrowser/data/dialog-error.png | Bin 0 -> 1645 bytes .../simplebrowser/data/edit-clear.png | Bin 0 -> 1682 bytes .../simplebrowser/data/go-bottom.png | Bin 0 -> 1263 bytes .../simplebrowser/data/go-next.png | Bin 930 -> 1219 bytes .../simplebrowser/data/go-previous.png | Bin 955 -> 1200 bytes .../simplebrowser/data/process-stop.png | Bin 1272 -> 1927 bytes .../simplebrowser/data/simplebrowser.qrc | 9 +- .../simplebrowser/data/simplebrowser.svg | 24 ---- .../simplebrowser/data/text-html.png | Bin 0 -> 1759 bytes .../simplebrowser/data/view-refresh.png | Bin 1364 -> 2024 bytes .../simplebrowser/doc/images/simplebrowser.png | Bin 70625 -> 47620 bytes .../simplebrowser/doc/src/simplebrowser.qdoc | 69 +++++++--- .../simplebrowser/downloadmanagerwidget.cpp | 86 ++++++++++++ .../simplebrowser/downloadmanagerwidget.h | 73 ++++++++++ .../simplebrowser/downloadmanagerwidget.ui | 104 ++++++++++++++ .../simplebrowser/downloadwidget.cpp | 152 +++++++++++++++++++++ .../simplebrowser/downloadwidget.h | 74 ++++++++++ .../simplebrowser/downloadwidget.ui | 80 +++++++++++ examples/webenginewidgets/simplebrowser/main.cpp | 29 ++-- .../simplebrowser/simplebrowser.pro | 18 ++- .../webenginewidgets/simplebrowser/tabwidget.cpp | 52 +++---- .../webenginewidgets/simplebrowser/tabwidget.h | 6 +- .../webenginewidgets/simplebrowser/urllineedit.cpp | 95 ------------- .../webenginewidgets/simplebrowser/urllineedit.h | 70 ---------- .../simplebrowser/webpopupwindow.cpp | 35 ++--- .../simplebrowser/webpopupwindow.h | 9 +- .../webenginewidgets/simplebrowser/webview.cpp | 44 ++++-- examples/webenginewidgets/simplebrowser/webview.h | 2 + 36 files changed, 801 insertions(+), 405 deletions(-) create mode 100644 examples/webenginewidgets/simplebrowser/data/AppLogoColor.png delete mode 100644 examples/webenginewidgets/simplebrowser/data/addtab.png delete mode 100644 examples/webenginewidgets/simplebrowser/data/closetab.png delete mode 100644 examples/webenginewidgets/simplebrowser/data/defaulticon.png create mode 100644 examples/webenginewidgets/simplebrowser/data/dialog-error.png create mode 100644 examples/webenginewidgets/simplebrowser/data/edit-clear.png create mode 100644 examples/webenginewidgets/simplebrowser/data/go-bottom.png delete mode 100644 examples/webenginewidgets/simplebrowser/data/simplebrowser.svg create mode 100644 examples/webenginewidgets/simplebrowser/data/text-html.png create mode 100644 examples/webenginewidgets/simplebrowser/downloadmanagerwidget.cpp create mode 100644 examples/webenginewidgets/simplebrowser/downloadmanagerwidget.h create mode 100644 examples/webenginewidgets/simplebrowser/downloadmanagerwidget.ui create mode 100644 examples/webenginewidgets/simplebrowser/downloadwidget.cpp create mode 100644 examples/webenginewidgets/simplebrowser/downloadwidget.h create mode 100644 examples/webenginewidgets/simplebrowser/downloadwidget.ui delete mode 100644 examples/webenginewidgets/simplebrowser/urllineedit.cpp delete mode 100644 examples/webenginewidgets/simplebrowser/urllineedit.h diff --git a/examples/webenginewidgets/simplebrowser/browser.cpp b/examples/webenginewidgets/simplebrowser/browser.cpp index f1420c2a3..5eae4f3c1 100644 --- a/examples/webenginewidgets/simplebrowser/browser.cpp +++ b/examples/webenginewidgets/simplebrowser/browser.cpp @@ -40,38 +40,26 @@ #include "browser.h" #include "browserwindow.h" -#include "webview.h" -#include -Browser::Browser() -{ -} - -Browser::~Browser() -{ - qDeleteAll(m_windows); - m_windows.clear(); -} +#include -Browser &Browser::instance() +Browser::Browser() { - static Browser browser; - return browser; -} + // Quit application if the download manager window is the only remaining window + m_downloadManagerWidget.setAttribute(Qt::WA_QuitOnClose, false); -QVector Browser::windows() -{ - return m_windows; + QObject::connect( + QWebEngineProfile::defaultProfile(), &QWebEngineProfile::downloadRequested, + &m_downloadManagerWidget, &DownloadManagerWidget::downloadRequested); } -void Browser::addWindow(BrowserWindow *mainWindow) +BrowserWindow *Browser::createWindow() { - if (m_windows.contains(mainWindow)) - return; - m_windows.prepend(mainWindow); + auto mainWindow = new BrowserWindow(this); + m_windows.append(mainWindow); QObject::connect(mainWindow, &QObject::destroyed, [this, mainWindow]() { m_windows.removeOne(mainWindow); }); mainWindow->show(); + return mainWindow; } - diff --git a/examples/webenginewidgets/simplebrowser/browser.h b/examples/webenginewidgets/simplebrowser/browser.h index 0fdbd46a7..27e2aaf43 100644 --- a/examples/webenginewidgets/simplebrowser/browser.h +++ b/examples/webenginewidgets/simplebrowser/browser.h @@ -41,6 +41,8 @@ #ifndef BROWSER_H #define BROWSER_H +#include "downloadmanagerwidget.h" + #include class BrowserWindow; @@ -48,14 +50,16 @@ class BrowserWindow; class Browser { public: - ~Browser(); + Browser(); + + QVector windows() { return m_windows; } - QVector windows(); - void addWindow(BrowserWindow* window); - static Browser &instance(); + BrowserWindow *createWindow(); + + DownloadManagerWidget &downloadManagerWidget() { return m_downloadManagerWidget; } private: - Browser(); QVector m_windows; + DownloadManagerWidget m_downloadManagerWidget; }; #endif // BROWSER_H diff --git a/examples/webenginewidgets/simplebrowser/browserwindow.cpp b/examples/webenginewidgets/simplebrowser/browserwindow.cpp index 0b85e2bb0..43c25e633 100644 --- a/examples/webenginewidgets/simplebrowser/browserwindow.cpp +++ b/examples/webenginewidgets/simplebrowser/browserwindow.cpp @@ -40,12 +40,13 @@ #include "browser.h" #include "browserwindow.h" +#include "downloadmanagerwidget.h" #include "tabwidget.h" -#include "urllineedit.h" #include "webview.h" #include #include #include +#include #include #include #include @@ -54,9 +55,10 @@ #include #include #include +#include -BrowserWindow::BrowserWindow(QWidget *parent, Qt::WindowFlags flags) - : QMainWindow(parent, flags) +BrowserWindow::BrowserWindow(Browser *browser) + : m_browser(browser) , m_tabWidget(new TabWidget(this)) , m_progressBar(new QProgressBar(this)) , m_historyBackAction(nullptr) @@ -64,10 +66,11 @@ BrowserWindow::BrowserWindow(QWidget *parent, Qt::WindowFlags flags) , m_stopAction(nullptr) , m_reloadAction(nullptr) , m_stopReloadAction(nullptr) - , m_urlLineEdit(new UrlLineEdit(this)) + , m_urlLineEdit(nullptr) + , m_favAction(nullptr) { - setToolButtonStyle(Qt::ToolButtonFollowStyle); setAttribute(Qt::WA_DeleteOnClose, true); + setFocusPolicy(Qt::ClickFocus); QToolBar *toolbar = createToolBar(); addToolBar(toolbar); @@ -85,7 +88,7 @@ BrowserWindow::BrowserWindow(QWidget *parent, Qt::WindowFlags flags) m_progressBar->setMaximumHeight(1); m_progressBar->setTextVisible(false); - m_progressBar->setStyleSheet(QStringLiteral("QProgressBar {border: 0px } QProgressBar::chunk { background-color: red; }")); + m_progressBar->setStyleSheet(QStringLiteral("QProgressBar {border: 0px} QProgressBar::chunk {background-color: #da4453}")); layout->addWidget(m_progressBar); layout->addWidget(m_tabWidget); @@ -97,15 +100,14 @@ BrowserWindow::BrowserWindow(QWidget *parent, Qt::WindowFlags flags) 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()); + 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_urlLineEdit, &QLineEdit::returnPressed, [this]() { + m_tabWidget->setUrl(QUrl::fromUserInput(m_urlLineEdit->text())); }); - - m_urlLineEdit->setFavIcon(QIcon(QStringLiteral(":defaulticon.png"))); QAction *focusUrlLineEditAction = new QAction(this); addAction(focusUrlLineEditAction); @@ -114,14 +116,10 @@ BrowserWindow::BrowserWindow(QWidget *parent, Qt::WindowFlags flags) m_urlLineEdit->setFocus(Qt::ShortcutFocusReason); }); - handleWebViewTitleChanged(tr("Qt Simple Browser")); + handleWebViewTitleChanged(QString()); m_tabWidget->createTab(); } -BrowserWindow::~BrowserWindow() -{ -} - QSize BrowserWindow::sizeHint() const { QRect desktopRect = QApplication::desktop()->screenGeometry(); @@ -134,18 +132,16 @@ 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); + QAction *newTabAction = new QAction(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); + QAction *closeTabAction = new QAction(tr("&Close Tab"), this); closeTabAction->setShortcuts(QKeySequence::Close); - closeTabAction->setIconVisibleInMenu(false); connect(closeTabAction, &QAction::triggered, [tabWidget]() { tabWidget->closeTab(tabWidget->currentIndex()); }); @@ -156,8 +152,8 @@ QMenu *BrowserWindow::createFileMenu(TabWidget *tabWidget) connect(closeAction, &QAction::triggered, this, &QWidget::close); fileMenu->addAction(closeAction); - connect(fileMenu, &QMenu::aboutToShow, [closeAction]() { - if (Browser::instance().windows().count() == 1) + connect(fileMenu, &QMenu::aboutToShow, [this, closeAction]() { + if (m_browser->windows().count() == 1) closeAction->setText(tr("&Quit")); else closeAction->setText(tr("&Close Window")); @@ -288,7 +284,7 @@ QMenu *BrowserWindow::createWindowMenu(TabWidget *tabWidget) menu->addAction(previousTabAction); menu->addSeparator(); - QVector windows = Browser::instance().windows(); + QVector windows = m_browser->windows(); int index(-1); for (auto window : windows) { QAction *action = menu->addAction(window->windowTitle(), this, &BrowserWindow::handleShowWindowTriggered); @@ -311,7 +307,7 @@ QMenu *BrowserWindow::createHelpMenu() QToolBar *BrowserWindow::createToolBar() { QToolBar *navigationBar = new QToolBar(tr("Navigation")); - navigationBar->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea); + navigationBar->setMovable(false); navigationBar->toggleViewAction()->setEnabled(false); m_historyBackAction = new QAction(this); @@ -328,6 +324,7 @@ QToolBar *BrowserWindow::createToolBar() 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); }); @@ -345,6 +342,7 @@ QToolBar *BrowserWindow::createToolBar() 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); }); @@ -355,22 +353,22 @@ QToolBar *BrowserWindow::createToolBar() 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); - int size = m_urlLineEdit->sizeHint().height(); - navigationBar->setIconSize(QSize(size, size)); - return navigationBar; -} -void BrowserWindow::handleWebViewIconChanged(const QIcon &icon) -{ - m_urlLineEdit->setFavIcon(icon); -} + 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(); + }); -void BrowserWindow::handleWebViewUrlChanged(const QUrl &url) -{ - m_urlLineEdit->setUrl(url); - if (url.isEmpty()) - m_urlLineEdit->setFocus(); + return navigationBar; } void BrowserWindow::handleWebActionEnabledChanged(QWebEnginePage::WebAction action, bool enabled) @@ -389,7 +387,7 @@ void BrowserWindow::handleWebActionEnabledChanged(QWebEnginePage::WebAction acti m_stopAction->setEnabled(enabled); break; default: - qWarning("Unhandled webActionChanged singal"); + qWarning("Unhandled webActionChanged signal"); } } @@ -403,9 +401,7 @@ void BrowserWindow::handleWebViewTitleChanged(const QString &title) void BrowserWindow::handleNewWindowTriggered() { - BrowserWindow *window = new BrowserWindow(); - Browser::instance().addWindow(window); - window->loadHomePage(); + m_browser->createWindow(); } void BrowserWindow::handleFileOpenTriggered() @@ -414,7 +410,7 @@ void BrowserWindow::handleFileOpenTriggered() tr("Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*)")); if (file.isEmpty()) return; - loadPage(file); + currentTab()->setUrl(file); } void BrowserWindow::handleFindActionTriggered() @@ -450,24 +446,6 @@ void BrowserWindow::closeEvent(QCloseEvent *event) 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; @@ -483,23 +461,24 @@ void BrowserWindow::handleWebViewLoadProgress(int progress) static QIcon stopIcon(QStringLiteral(":process-stop.png")); static QIcon reloadIcon(QStringLiteral(":view-refresh.png")); - if (progress < 100 && progress > 0) { + 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); } - m_progressBar->setValue(progress < 100 ? progress : 0); } void BrowserWindow::handleShowWindowTriggered() { if (QAction *action = qobject_cast(sender())) { int offset = action->data().toInt(); - QVector windows = Browser::instance().windows(); + QVector windows = m_browser->windows(); windows.at(offset)->activateWindow(); windows.at(offset)->currentTab()->setFocus(); } diff --git a/examples/webenginewidgets/simplebrowser/browserwindow.h b/examples/webenginewidgets/simplebrowser/browserwindow.h index 03c8d385b..745061691 100644 --- a/examples/webenginewidgets/simplebrowser/browserwindow.h +++ b/examples/webenginewidgets/simplebrowser/browserwindow.h @@ -42,14 +42,16 @@ #define BROWSERWINDOW_H #include +#include #include QT_BEGIN_NAMESPACE +class QLineEdit; class QProgressBar; QT_END_NAMESPACE +class Browser; class TabWidget; -class UrlLineEdit; class WebView; class BrowserWindow : public QMainWindow @@ -57,15 +59,11 @@ class BrowserWindow : public QMainWindow Q_OBJECT public: - BrowserWindow(QWidget *parent = nullptr, Qt::WindowFlags flags = 0); - ~BrowserWindow(); + BrowserWindow(Browser *browser); QSize sizeHint() const override; TabWidget *tabWidget() const; WebView *currentTab() const; - - void loadPage(const QString &url); - void loadPage(const QUrl &url); - void loadHomePage(); + Browser *browser() { return m_browser; } protected: void closeEvent(QCloseEvent *event) override; @@ -77,8 +75,6 @@ private slots: void handleShowWindowTriggered(); void handleWebViewLoadProgress(int); void handleWebViewTitleChanged(const QString &title); - void handleWebViewUrlChanged(const QUrl &url); - void handleWebViewIconChanged(const QIcon &icon); void handleWebActionEnabledChanged(QWebEnginePage::WebAction action, bool enabled); private: @@ -90,6 +86,7 @@ private: QToolBar *createToolBar(); private: + Browser *m_browser; TabWidget *m_tabWidget; QProgressBar *m_progressBar; QAction *m_historyBackAction; @@ -97,7 +94,8 @@ private: QAction *m_stopAction; QAction *m_reloadAction; QAction *m_stopReloadAction; - UrlLineEdit *m_urlLineEdit; + QLineEdit *m_urlLineEdit; + QAction *m_favAction; QString m_lastSearch; }; diff --git a/examples/webenginewidgets/simplebrowser/data/AppLogoColor.png b/examples/webenginewidgets/simplebrowser/data/AppLogoColor.png new file mode 100644 index 000000000..2a4971782 Binary files /dev/null and b/examples/webenginewidgets/simplebrowser/data/AppLogoColor.png differ diff --git a/examples/webenginewidgets/simplebrowser/data/addtab.png b/examples/webenginewidgets/simplebrowser/data/addtab.png deleted file mode 100644 index 20928fb40..000000000 Binary files a/examples/webenginewidgets/simplebrowser/data/addtab.png and /dev/null differ diff --git a/examples/webenginewidgets/simplebrowser/data/closetab.png b/examples/webenginewidgets/simplebrowser/data/closetab.png deleted file mode 100644 index ab9d669ee..000000000 Binary files a/examples/webenginewidgets/simplebrowser/data/closetab.png and /dev/null differ diff --git a/examples/webenginewidgets/simplebrowser/data/defaulticon.png b/examples/webenginewidgets/simplebrowser/data/defaulticon.png deleted file mode 100644 index 01a0920c9..000000000 Binary files a/examples/webenginewidgets/simplebrowser/data/defaulticon.png and /dev/null differ diff --git a/examples/webenginewidgets/simplebrowser/data/dialog-error.png b/examples/webenginewidgets/simplebrowser/data/dialog-error.png new file mode 100644 index 000000000..cdd95bade Binary files /dev/null and b/examples/webenginewidgets/simplebrowser/data/dialog-error.png differ diff --git a/examples/webenginewidgets/simplebrowser/data/edit-clear.png b/examples/webenginewidgets/simplebrowser/data/edit-clear.png new file mode 100644 index 000000000..5542948bc Binary files /dev/null and b/examples/webenginewidgets/simplebrowser/data/edit-clear.png differ diff --git a/examples/webenginewidgets/simplebrowser/data/go-bottom.png b/examples/webenginewidgets/simplebrowser/data/go-bottom.png new file mode 100644 index 000000000..bf973fedc Binary files /dev/null and b/examples/webenginewidgets/simplebrowser/data/go-bottom.png differ diff --git a/examples/webenginewidgets/simplebrowser/data/go-next.png b/examples/webenginewidgets/simplebrowser/data/go-next.png index 6f3f65d33..a68e2db77 100644 Binary files a/examples/webenginewidgets/simplebrowser/data/go-next.png and b/examples/webenginewidgets/simplebrowser/data/go-next.png differ diff --git a/examples/webenginewidgets/simplebrowser/data/go-previous.png b/examples/webenginewidgets/simplebrowser/data/go-previous.png index 93be3d1ee..c37bc0414 100644 Binary files a/examples/webenginewidgets/simplebrowser/data/go-previous.png and b/examples/webenginewidgets/simplebrowser/data/go-previous.png differ diff --git a/examples/webenginewidgets/simplebrowser/data/process-stop.png b/examples/webenginewidgets/simplebrowser/data/process-stop.png index b68290bf1..e7a8d1722 100644 Binary files a/examples/webenginewidgets/simplebrowser/data/process-stop.png and b/examples/webenginewidgets/simplebrowser/data/process-stop.png differ diff --git a/examples/webenginewidgets/simplebrowser/data/simplebrowser.qrc b/examples/webenginewidgets/simplebrowser/data/simplebrowser.qrc index 5795063ca..ec8716721 100644 --- a/examples/webenginewidgets/simplebrowser/data/simplebrowser.qrc +++ b/examples/webenginewidgets/simplebrowser/data/simplebrowser.qrc @@ -1,12 +1,13 @@ - addtab.png - defaulticon.png - closetab.png + AppLogoColor.png + dialog-error.png + edit-clear.png + go-bottom.png go-next.png go-previous.png process-stop.png - simplebrowser.svg + text-html.png view-refresh.png diff --git a/examples/webenginewidgets/simplebrowser/data/simplebrowser.svg b/examples/webenginewidgets/simplebrowser/data/simplebrowser.svg deleted file mode 100644 index 9f39deb66..000000000 --- a/examples/webenginewidgets/simplebrowser/data/simplebrowser.svg +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/examples/webenginewidgets/simplebrowser/data/text-html.png b/examples/webenginewidgets/simplebrowser/data/text-html.png new file mode 100644 index 000000000..a896697d7 Binary files /dev/null and b/examples/webenginewidgets/simplebrowser/data/text-html.png differ diff --git a/examples/webenginewidgets/simplebrowser/data/view-refresh.png b/examples/webenginewidgets/simplebrowser/data/view-refresh.png index cab4d02c7..606ea9eba 100644 Binary files a/examples/webenginewidgets/simplebrowser/data/view-refresh.png and b/examples/webenginewidgets/simplebrowser/data/view-refresh.png differ diff --git a/examples/webenginewidgets/simplebrowser/doc/images/simplebrowser.png b/examples/webenginewidgets/simplebrowser/doc/images/simplebrowser.png index 777309075..b09f7c853 100644 Binary files a/examples/webenginewidgets/simplebrowser/doc/images/simplebrowser.png and b/examples/webenginewidgets/simplebrowser/doc/images/simplebrowser.png differ diff --git a/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc b/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc index e57ec80ec..6736f8570 100644 --- a/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc +++ b/examples/webenginewidgets/simplebrowser/doc/src/simplebrowser.qdoc @@ -43,6 +43,7 @@ forward in the web page browsing history. \li Multi-tab area for displaying web content within tabs. \li Status bar for displaying hovered links. + \li A simple download manager. \endlist The web content can be opened in new tabs or separate windows. HTTP and @@ -52,13 +53,13 @@ \section1 Class Hierarchy - We start with sketching a diagram of the classes that we are going to + We start with sketching a diagram of the main classes that we are going to implement: \image simplebrowser-model.png \list - \li \c{Browser} is a singleton class managing the application windows. + \li \c{Browser} is a class managing the application windows. \li \c{BrowserWindow} is a \l QMainWindow showing the menu, a navigation bar, \c {TabWidget}, and a status bar. \li \c{TabWidget} is a \l QTabWidget and contains one or multiple @@ -68,11 +69,19 @@ \li \c{WebPage} is a \l QWebEnginePage that represents website content. \endlist + Additionally, we will implement some auxiliary classes: + + \list + \li \c{WebPopupWindow} is a \l QWidget for showing popup windows. + \li \c{DownloadManagerWidget} is a \l QWidget implementing the downloads + list. + \endlist + \section1 Creating the Browser Main Window - This example supports multiple main windows that are owned by a - \c Browser singleton object. This class could also be used for further - functionality, such as downloading files, bookmarks, and history managers. + This example supports multiple main windows that are owned by a \c Browser + object. This class also owns the \c DownloadManagerWidget and could be used + for further functionality, such as bookmarks and history managers. In \c main.cpp, we create the first \c BrowserWindow instance and add it to the \c Browser object. If no arguments are passed on the command line, @@ -104,6 +113,8 @@ \quotefromfile webenginewidgets/simplebrowser/tabwidget.cpp \skipto TabWidget::createTab( \printuntil } + \skipto TabWidget::createBackgroundTab( + \printuntil } In \c TabWidget::setupView(), we make sure that the \c TabWidget always forwards the signals of the currently selected \c WebView: @@ -225,20 +236,14 @@ \section1 Opening a Web Page - This section describes the workflow for opening a new page. - When the user enters a URL in the navigation bar and presses \uicontrol Enter, - \c QLineEdit::returnPressed is emitted, which lets \c BrowserWindow - load the requested page: + This section describes the workflow for opening a new page. When the user + enters a URL in the navigation bar and presses \uicontrol Enter, the \c + QLineEdit::returnPressed signal is emitted and the new URL is then handed + over to \c TabWidget::setUrl: \quotefromfile webenginewidgets/simplebrowser/browserwindow.cpp \skipto connect(m_urlLineEdit - \printuntil }); - - The \c loadPage() method calls the \c setUrl() method of \c TabWidget: - - \skipto void BrowserWindow::loadPage(const QUrl - \printuntil } - \printline } + \printline connect The call is forwarded to the currently selected tab: @@ -249,4 +254,36 @@ The \c setUrl() method of \c WebView just forwards the \c url to the associated \c WebPage, which in turn starts the downloading of the page's content in the background. + + \section1 Managing Downloads + + Downloads are associated with a \l QWebEngineProfile. Whenever a download is + triggered on a web page the \l QWebEngineProfile::defaultProfile signal is + emitted with a \l QWebEngineDownloadItem, which in this example is forwarded + to \c DownloadManagerWidget::downloadRequested: + + \quotefromfile webenginewidgets/simplebrowser/browser.cpp + \skipto Browser::Browser + \printuntil /^\}/ + + This method prompts the user for a file name (with a pre-filled suggestion) + and starts the download (unless the user cancels the \uicontrol {Save As} + dialog): + + \quotefromfile webenginewidgets/simplebrowser/downloadmanagerwidget.cpp + \skipto DownloadManagerWidget::downloadRequested + \printuntil /^\}/ + + The \l QWebEngineDownloadItem object will periodically emit the \l + {QWebEngineDownloadItem::}{downloadProgress} signal to notify potential + observers of the download progress and the \l + {QWebEngineDownloadItem::}{stateChanged} signal when the download is + finished or when an error occurs. See \c downloadmanagerwidget.cpp for an + example of how these signals can be handled. + + \section1 Licensing + + All icons used in the example, with the exception of \c{AppLogoColor.png}, + originate from the public domain + \l{http://tango.freedesktop.org/Tango_Icon_Library}{Tango Icon Library}. */ diff --git a/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.cpp b/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.cpp new file mode 100644 index 000000000..5f32294e8 --- /dev/null +++ b/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.cpp @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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$ +** 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 "downloadmanagerwidget.h" + +#include "browser.h" +#include "browserwindow.h" +#include "downloadwidget.h" + +#include +#include + +DownloadManagerWidget::DownloadManagerWidget(QWidget *parent) + : QWidget(parent) + , m_numDownloads(0) +{ + setupUi(this); +} + +void DownloadManagerWidget::downloadRequested(QWebEngineDownloadItem *download) +{ + Q_ASSERT(download && download->state() == QWebEngineDownloadItem::DownloadRequested); + + QString path = QFileDialog::getSaveFileName(this, tr("Save as"), download->path()); + if (path.isEmpty()) + return; + + download->setPath(path); + download->accept(); + add(new DownloadWidget(download)); + + show(); +} + +void DownloadManagerWidget::add(DownloadWidget *downloadWidget) +{ + connect(downloadWidget, &DownloadWidget::removeClicked, this, &DownloadManagerWidget::remove); + m_itemsLayout->insertWidget(0, downloadWidget, 0, Qt::AlignTop); + if (m_numDownloads++ == 0) + m_zeroItemsLabel->hide(); +} + +void DownloadManagerWidget::remove(DownloadWidget *downloadWidget) +{ + m_itemsLayout->removeWidget(downloadWidget); + downloadWidget->deleteLater(); + if (--m_numDownloads == 0) + m_zeroItemsLabel->show(); +} diff --git a/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.h b/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.h new file mode 100644 index 000000000..597e6139a --- /dev/null +++ b/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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$ +** 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$ +** +****************************************************************************/ + +#ifndef DOWNLOADMANAGERWIDGET_H +#define DOWNLOADMANAGERWIDGET_H + +#include "ui_downloadmanagerwidget.h" + +#include + +QT_BEGIN_NAMESPACE +class QWebEngineDownloadItem; +QT_END_NAMESPACE + +class DownloadWidget; + +// Displays a list of downloads. +class DownloadManagerWidget final : public QWidget, public Ui::DownloadManagerWidget +{ + Q_OBJECT +public: + explicit DownloadManagerWidget(QWidget *parent = nullptr); + + // Prompts user with a "Save As" dialog. If the user doesn't cancel it, then + // the QWebEngineDownloadItem will be accepted and the DownloadManagerWidget + // will be shown on the screen. + void downloadRequested(QWebEngineDownloadItem *webItem); + +private: + void add(DownloadWidget *downloadWidget); + void remove(DownloadWidget *downloadWidget); + + int m_numDownloads; +}; + +#endif // DOWNLOADMANAGERWIDGET_H diff --git a/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.ui b/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.ui new file mode 100644 index 000000000..b7544ac16 --- /dev/null +++ b/examples/webenginewidgets/simplebrowser/downloadmanagerwidget.ui @@ -0,0 +1,104 @@ + + + DownloadManagerWidget + + + + 0 + 0 + 400 + 212 + + + + Downloads + + + #DownloadManagerWidget { + background: palette(button) +} + + + + QLayout::SetNoConstraint + + + 0 + + + 0 + + + 0 + + + 0 + + + + + #m_scrollArea { + margin: 2px; + border: none; +} + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAlwaysOff + + + true + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + #m_items {background: palette(mid)} + + + + 2 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + + 0 + 0 + + + + color: palette(shadow) + + + No downloads + + + Qt::AlignCenter + + + + + + + + + + + + diff --git a/examples/webenginewidgets/simplebrowser/downloadwidget.cpp b/examples/webenginewidgets/simplebrowser/downloadwidget.cpp new file mode 100644 index 000000000..a80366f77 --- /dev/null +++ b/examples/webenginewidgets/simplebrowser/downloadwidget.cpp @@ -0,0 +1,152 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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$ +** 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 "downloadwidget.h" + +#include +#include +#include + +DownloadWidget::DownloadWidget(QWebEngineDownloadItem *download, QWidget *parent) + : QFrame(parent) + , m_download(download) + , m_timeAdded(QTime::currentTime()) +{ + setupUi(this); + m_dstName->setText(QFileInfo(m_download->path()).fileName()); + m_srcUrl->setText(m_download->url().toDisplayString()); + + connect(m_cancelButton, &QPushButton::clicked, + [this](bool) { + if (m_download->state() == QWebEngineDownloadItem::DownloadInProgress) + m_download->cancel(); + else + emit removeClicked(this); + }); + + connect(m_download, &QWebEngineDownloadItem::downloadProgress, + [this](qint64, qint64) { + updateWidget(); + }); + + connect(m_download, &QWebEngineDownloadItem::stateChanged, + [this](QWebEngineDownloadItem::DownloadState) { + updateWidget(); + }); + + updateWidget(); +} + +inline QString DownloadWidget::withUnit(qreal bytes) +{ + if (bytes < (1 << 10)) + return tr("%L1 B").arg(bytes); + else if (bytes < (1 << 20)) + return tr("%L1 KiB").arg(bytes / (1 << 10), 0, 'f', 2); + else if (bytes < (1 << 30)) + return tr("%L1 MiB").arg(bytes / (1 << 20), 0, 'f', 2); + else + return tr("%L1 GiB").arg(bytes / (1 << 30), 0, 'f', 2); +} + +void DownloadWidget::updateWidget() +{ + qreal totalBytes = m_download->totalBytes(); + qreal receivedBytes = m_download->receivedBytes(); + qreal bytesPerSecond = receivedBytes / m_timeAdded.elapsed() * 1000; + + auto state = m_download->state(); + switch (state) { + case QWebEngineDownloadItem::DownloadRequested: + Q_UNREACHABLE(); + break; + case QWebEngineDownloadItem::DownloadInProgress: + if (totalBytes >= 0) { + m_progressBar->setValue(qRound(100 * receivedBytes / totalBytes)); + m_progressBar->setDisabled(false); + m_progressBar->setFormat( + tr("%p% - %1 of %2 downloaded - %3/s") + .arg(withUnit(receivedBytes)) + .arg(withUnit(totalBytes)) + .arg(withUnit(bytesPerSecond))); + } else { + m_progressBar->setValue(0); + m_progressBar->setDisabled(false); + m_progressBar->setFormat( + tr("unknown size - %1 downloaded - %2/s") + .arg(withUnit(receivedBytes)) + .arg(withUnit(bytesPerSecond))); + } + break; + case QWebEngineDownloadItem::DownloadCompleted: + m_progressBar->setValue(100); + m_progressBar->setDisabled(true); + m_progressBar->setFormat( + tr("completed - %1 downloaded - %2/s") + .arg(withUnit(receivedBytes)) + .arg(withUnit(bytesPerSecond))); + break; + case QWebEngineDownloadItem::DownloadCancelled: + m_progressBar->setValue(0); + m_progressBar->setDisabled(true); + m_progressBar->setFormat( + tr("cancelled - %1 downloaded - %2/s") + .arg(withUnit(receivedBytes)) + .arg(withUnit(bytesPerSecond))); + break; + case QWebEngineDownloadItem::DownloadInterrupted: + m_progressBar->setValue(0); + m_progressBar->setDisabled(true); + m_progressBar->setFormat( + tr("interrupted: %1") + .arg(m_download->interruptReasonString())); + break; + } + + if (state == QWebEngineDownloadItem::DownloadInProgress) { + static QIcon cancelIcon(QStringLiteral(":process-stop.png")); + m_cancelButton->setIcon(cancelIcon); + m_cancelButton->setToolTip(tr("Stop downloading")); + } else { + static QIcon removeIcon(QStringLiteral(":edit-clear.png")); + m_cancelButton->setIcon(removeIcon); + m_cancelButton->setToolTip(tr("Remove from list")); + } +} diff --git a/examples/webenginewidgets/simplebrowser/downloadwidget.h b/examples/webenginewidgets/simplebrowser/downloadwidget.h new file mode 100644 index 000000000..e8cf42825 --- /dev/null +++ b/examples/webenginewidgets/simplebrowser/downloadwidget.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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$ +** 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$ +** +****************************************************************************/ + +#ifndef DOWNLOADWIDGET_H +#define DOWNLOADWIDGET_H + +#include "ui_downloadwidget.h" + +#include +#include + +QT_BEGIN_NAMESPACE +class QWebEngineDownloadItem; +QT_END_NAMESPACE + +// Displays one ongoing or finished download (QWebEngineDownloadItem). +class DownloadWidget final : public QFrame, public Ui::DownloadWidget +{ + Q_OBJECT +public: + // Precondition: The QWebEngineDownloadItem has been accepted. + explicit DownloadWidget(QWebEngineDownloadItem *download, QWidget *parent = nullptr); + +signals: + // This signal is emitted when the user indicates that they want to remove + // this download from the downloads list. + void removeClicked(DownloadWidget *self); + +private: + void updateWidget(); + QString withUnit(qreal bytes); + + QWebEngineDownloadItem *m_download; + QTime m_timeAdded; +}; + +#endif // DOWNLOADWIDGET_H diff --git a/examples/webenginewidgets/simplebrowser/downloadwidget.ui b/examples/webenginewidgets/simplebrowser/downloadwidget.ui new file mode 100644 index 000000000..ee45e0b10 --- /dev/null +++ b/examples/webenginewidgets/simplebrowser/downloadwidget.ui @@ -0,0 +1,80 @@ + + + DownloadWidget + + + #DownloadWidget { + background: palette(button); + border: 1px solid palette(dark); + margin: 0px; +} + + + + QLayout::SetMinAndMaxSize + + + + + font-weight: bold + + + + TextLabel + + + + + + + + + + QPushButton { + margin: 1px; + border: none; +} +QPushButton:pressed { + margin: none; + border: 1px solid palette(shadow); + background: palette(midlight); +} + + + false + + + + + + + + 350 + 16777215 + + + + + + + TextLabel + + + + + + + font-size: 12px + + + 24 + + + + + + + + + + diff --git a/examples/webenginewidgets/simplebrowser/main.cpp b/examples/webenginewidgets/simplebrowser/main.cpp index fa9f44c34..93dfc8a8c 100644 --- a/examples/webenginewidgets/simplebrowser/main.cpp +++ b/examples/webenginewidgets/simplebrowser/main.cpp @@ -40,38 +40,35 @@ #include "browser.h" #include "browserwindow.h" +#include "webview.h" #include #include -QString getCommandLineUrlArgument() +QUrl getCommandLineUrlArgument() { const QStringList args = QCoreApplication::arguments(); - if (args.count() > 1) { - const QString lastArg = args.last(); - const bool isValidUrl = QUrl::fromUserInput(lastArg).isValid(); - if (isValidUrl) - return lastArg; - } - return QString(); + if (args.count() > 1) + return QUrl::fromUserInput(args.last()); + return QUrl(); } int main(int argc, char **argv) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); QApplication app(argc, argv); - app.setWindowIcon(QIcon(QLatin1String(":simplebrowser.svg"))); + app.setWindowIcon(QIcon(QStringLiteral(":AppLogoColor.png"))); QWebEngineSettings::defaultSettings()->setAttribute(QWebEngineSettings::PluginsEnabled, true); - BrowserWindow *window = new BrowserWindow(); - Browser::instance().addWindow(window); + QUrl url = getCommandLineUrlArgument(); + if (!url.isValid()) + url = QStringLiteral("https://www.qt.io"); - const QString url = getCommandLineUrlArgument(); - if (!url.isEmpty()) - window->loadPage(url); - else - window->loadHomePage(); + Browser browser; + BrowserWindow *window = browser.createWindow(); + window->currentTab()->setUrl(url); return app.exec(); } diff --git a/examples/webenginewidgets/simplebrowser/simplebrowser.pro b/examples/webenginewidgets/simplebrowser/simplebrowser.pro index 197d68091..8120a2852 100644 --- a/examples/webenginewidgets/simplebrowser/simplebrowser.pro +++ b/examples/webenginewidgets/simplebrowser/simplebrowser.pro @@ -6,25 +6,29 @@ CONFIG += c++11 HEADERS += \ browser.h \ browserwindow.h \ + downloadmanagerwidget.h \ + downloadwidget.h \ tabwidget.h \ - urllineedit.h \ - webview.h \ webpage.h \ - webpopupwindow.h + webpopupwindow.h \ + webview.h SOURCES += \ browser.cpp \ browserwindow.cpp \ + downloadmanagerwidget.cpp \ + downloadwidget.cpp \ main.cpp \ tabwidget.cpp \ - urllineedit.cpp \ - webview.cpp \ webpage.cpp \ - webpopupwindow.cpp + webpopupwindow.cpp \ + webview.cpp FORMS += \ certificateerrordialog.ui \ - passworddialog.ui + passworddialog.ui \ + downloadmanagerwidget.ui \ + downloadwidget.ui RESOURCES += data/simplebrowser.qrc diff --git a/examples/webenginewidgets/simplebrowser/tabwidget.cpp b/examples/webenginewidgets/simplebrowser/tabwidget.cpp index a7f855c2a..c9fb32d83 100644 --- a/examples/webenginewidgets/simplebrowser/tabwidget.cpp +++ b/examples/webenginewidgets/simplebrowser/tabwidget.cpp @@ -56,9 +56,8 @@ TabWidget::TabWidget(QWidget *parent) 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(); + if (index == -1) + createTab(); }); setDocumentMode(true); @@ -67,10 +66,6 @@ TabWidget::TabWidget(QWidget *parent) connect(this, &QTabWidget::currentChanged, this, &TabWidget::handleCurrentChanged); } -TabWidget::~TabWidget() -{ -} - void TabWidget::handleCurrentChanged(int index) { if (index != -1) { @@ -80,11 +75,7 @@ void TabWidget::handleCurrentChanged(int index) emit titleChanged(view->title()); emit loadProgress(view->loadProgress()); emit urlChanged(view->url()); - QIcon pageIcon = view->page()->icon(); - if (!pageIcon.isNull()) - emit iconChanged(pageIcon); - else - emit iconChanged(QIcon(QStringLiteral(":defaulticon.png"))); + emit favIconChanged(view->favIcon()); emit webActionEnabledChanged(QWebEnginePage::Back, view->isWebActionEnabled(QWebEnginePage::Back)); emit webActionEnabledChanged(QWebEnginePage::Forward, view->isWebActionEnabled(QWebEnginePage::Forward)); emit webActionEnabledChanged(QWebEnginePage::Stop, view->isWebActionEnabled(QWebEnginePage::Stop)); @@ -93,7 +84,7 @@ void TabWidget::handleCurrentChanged(int index) emit titleChanged(QString()); emit loadProgress(0); emit urlChanged(QUrl()); - emit iconChanged(QIcon(QStringLiteral(":defaulticon.png"))); + emit favIconChanged(QIcon()); emit webActionEnabledChanged(QWebEnginePage::Back, false); emit webActionEnabledChanged(QWebEnginePage::Forward, false); emit webActionEnabledChanged(QWebEnginePage::Stop, false); @@ -150,8 +141,10 @@ void TabWidget::setupView(WebView *webView) connect(webView, &QWebEngineView::titleChanged, [this, webView](const QString &title) { int index = indexOf(webView); - if (index != -1) + if (index != -1) { setTabText(index, title); + setTabToolTip(index, title); + } if (currentIndex() == index) emit titleChanged(title); }); @@ -170,26 +163,17 @@ void TabWidget::setupView(WebView *webView) if (currentIndex() == indexOf(webView)) emit linkHovered(url); }); - connect(webPage, &WebPage::iconChanged, [this, webView](const QIcon &icon) { + connect(webView, &WebView::favIconChanged, [this, webView](const QIcon &icon) { int index = indexOf(webView); - QIcon ico = icon.isNull() ? QIcon(QStringLiteral(":defaulticon.png")) : icon; - if (index != -1) - setTabIcon(index, ico); + setTabIcon(index, icon); if (currentIndex() == index) - emit iconChanged(ico); + emit favIconChanged(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(":view-refresh.png")); - setTabIcon(index, icon); - } - }); connect(webPage, &QWebEnginePage::windowCloseRequested, [this, webView]() { int index = indexOf(webView); if (index >= 0) @@ -197,15 +181,21 @@ void TabWidget::setupView(WebView *webView) }); } -WebView *TabWidget::createTab(bool makeCurrent) +WebView *TabWidget::createTab() +{ + WebView *webView = createBackgroundTab(); + setCurrentWidget(webView); + return webView; +} + +WebView *TabWidget::createBackgroundTab() { WebView *webView = new WebView; WebPage *webPage = new WebPage(QWebEngineProfile::defaultProfile(), webView); webView->setPage(webPage); setupView(webView); - addTab(webView, tr("(Untitled)")); - if (makeCurrent) - setCurrentWidget(webView); + int index = addTab(webView, tr("(Untitled)")); + setTabIcon(index, webView->favIcon()); return webView; } @@ -239,7 +229,7 @@ void TabWidget::closeTab(int index) void TabWidget::cloneTab(int index) { if (WebView *view = webView(index)) { - WebView *tab = createTab(false); + WebView *tab = createTab(); tab->setUrl(view->url()); } } diff --git a/examples/webenginewidgets/simplebrowser/tabwidget.h b/examples/webenginewidgets/simplebrowser/tabwidget.h index 830effa4e..e5a1671ae 100644 --- a/examples/webenginewidgets/simplebrowser/tabwidget.h +++ b/examples/webenginewidgets/simplebrowser/tabwidget.h @@ -56,7 +56,6 @@ class TabWidget : public QTabWidget public: TabWidget(QWidget *parent = nullptr); - ~TabWidget(); WebView *currentWebView() const; @@ -66,7 +65,7 @@ signals: void loadProgress(int progress); void titleChanged(const QString &title); void urlChanged(const QUrl &url); - void iconChanged(const QIcon &icon); + void favIconChanged(const QIcon &icon); void webActionEnabledChanged(QWebEnginePage::WebAction action, bool enabled); public slots: @@ -74,7 +73,8 @@ public slots: void setUrl(const QUrl &url); void triggerWebPageAction(QWebEnginePage::WebAction action); - WebView *createTab(bool makeCurrent = true); + WebView *createTab(); + WebView *createBackgroundTab(); void closeTab(int index); void nextTab(); void previousTab(); diff --git a/examples/webenginewidgets/simplebrowser/urllineedit.cpp b/examples/webenginewidgets/simplebrowser/urllineedit.cpp deleted file mode 100644 index 7e67b635a..000000000 --- a/examples/webenginewidgets/simplebrowser/urllineedit.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** -** -** 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 "urllineedit.h" -#include -#include - -UrlLineEdit::UrlLineEdit(QWidget *parent) - : QLineEdit(parent) - , m_favButton(new QToolButton(this)) - , m_clearButton(new QToolButton(this)) -{ - m_clearButton->setIcon(QIcon(QStringLiteral(":closetab.png"))); - m_clearButton->setVisible(false); - m_clearButton->setCursor(Qt::ArrowCursor); - QString style(QStringLiteral("QToolButton { border: none; padding: 1px; }")); - m_clearButton->setStyleSheet(style); - m_favButton->setStyleSheet(style); - setStyleSheet(QStringLiteral("QLineEdit { padding-left: %1px; padding-right: %2px; } ") - .arg(m_clearButton->sizeHint().width()) - .arg(m_favButton->sizeHint().width())); - int minIconHeight = qMax(m_favButton->sizeHint().height(), m_clearButton->sizeHint().height()); - setMinimumSize(minimumSizeHint().width() + - m_favButton->sizeHint().width() + - m_clearButton->sizeHint().width(), - qMax(minimumSizeHint().height(), minIconHeight)); - - connect(m_clearButton, &QToolButton::clicked, this, &QLineEdit::clear); - connect(this, &QLineEdit::textChanged, [this](const QString &text) { - m_clearButton->setVisible(!text.isEmpty() && !isReadOnly()); - }); -} - -QUrl UrlLineEdit::url() const -{ - return QUrl::fromUserInput(text()); -} - -void UrlLineEdit::setUrl(const QUrl &url) -{ - setText(url.toString()); - setCursorPosition(0); -} - -void UrlLineEdit::setFavIcon(const QIcon &icon) -{ - QPixmap pixmap = icon.pixmap(16, 16); - m_favButton->setIcon(pixmap); -} - -void UrlLineEdit::resizeEvent(QResizeEvent *event) -{ - QLineEdit::resizeEvent(event); - QSize clearButtonSize = m_clearButton->sizeHint(); - m_clearButton->move(rect().right() - clearButtonSize.width(), - (rect().bottom() - clearButtonSize.height()) / 2); - m_favButton->move(rect().left(), (rect().bottom() - m_favButton->sizeHint().height()) / 2); -} diff --git a/examples/webenginewidgets/simplebrowser/urllineedit.h b/examples/webenginewidgets/simplebrowser/urllineedit.h deleted file mode 100644 index a01eb0e66..000000000 --- a/examples/webenginewidgets/simplebrowser/urllineedit.h +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#ifndef URLLINEEDIT_H -#define URLLINEEDIT_H - -#include - -QT_BEGIN_NAMESPACE -class QToolButton; -QT_END_NAMESPACE - -class UrlLineEdit : public QLineEdit -{ - Q_OBJECT - -public: - UrlLineEdit(QWidget *parent = nullptr); - -public: - QUrl url() const; - void setUrl(const QUrl &url); - void setFavIcon(const QIcon &icon); - -protected: - void resizeEvent(QResizeEvent *event) override; - -private: - QToolButton *m_favButton; - QToolButton *m_clearButton; -}; - -#endif // URLLINEEDIT_H diff --git a/examples/webenginewidgets/simplebrowser/webpopupwindow.cpp b/examples/webenginewidgets/simplebrowser/webpopupwindow.cpp index 8146dcfb7..63246ac1d 100644 --- a/examples/webenginewidgets/simplebrowser/webpopupwindow.cpp +++ b/examples/webenginewidgets/simplebrowser/webpopupwindow.cpp @@ -38,15 +38,17 @@ ** ****************************************************************************/ -#include "urllineedit.h" #include "webpage.h" #include "webpopupwindow.h" #include "webview.h" +#include #include +#include #include WebPopupWindow::WebPopupWindow(QWebEngineProfile *profile) - : m_addressBar(new UrlLineEdit(this)) + : m_urlLineEdit(new QLineEdit(this)) + , m_favAction(new QAction(this)) , m_view(new WebView(this)) { setAttribute(Qt::WA_DeleteOnClose); @@ -55,31 +57,29 @@ WebPopupWindow::WebPopupWindow(QWebEngineProfile *profile) QVBoxLayout *layout = new QVBoxLayout; layout->setMargin(0); setLayout(layout); - layout->addWidget(m_addressBar); + layout->addWidget(m_urlLineEdit); layout->addWidget(m_view); m_view->setPage(new WebPage(profile, m_view)); m_view->setFocus(); - m_addressBar->setReadOnly(true); - m_addressBar->setFavIcon(QIcon(QStringLiteral(":defaulticon.png"))); + + m_urlLineEdit->setReadOnly(true); + m_urlLineEdit->addAction(m_favAction, QLineEdit::LeadingPosition); connect(m_view, &WebView::titleChanged, this, &QWidget::setWindowTitle); - connect(m_view, &WebView::urlChanged, this, &WebPopupWindow::setUrl); - connect(m_view->page(), &WebPage::iconChanged, this, &WebPopupWindow::handleIconChanged); + connect(m_view, &WebView::urlChanged, [this](const QUrl &url) { + m_urlLineEdit->setText(url.toDisplayString()); + }); + connect(m_view, &WebView::favIconChanged, m_favAction, &QAction::setIcon); connect(m_view->page(), &WebPage::geometryChangeRequested, this, &WebPopupWindow::handleGeometryChangeRequested); connect(m_view->page(), &WebPage::windowCloseRequested, this, &QWidget::close); } -QWebEngineView *WebPopupWindow::view() const +WebView *WebPopupWindow::view() const { return m_view; } -void WebPopupWindow::setUrl(const QUrl &url) -{ - m_addressBar->setUrl(url); -} - void WebPopupWindow::handleGeometryChangeRequested(const QRect &newGeometry) { m_view->setMinimumSize(newGeometry.width(), newGeometry.height()); @@ -87,12 +87,5 @@ void WebPopupWindow::handleGeometryChangeRequested(const QRect &newGeometry) // let the layout do the magic resize(0, 0); show(); -} - -void WebPopupWindow::handleIconChanged(const QIcon &icon) -{ - if (icon.isNull()) - m_addressBar->setFavIcon(QIcon(QStringLiteral(":defaulticon.png"))); - else - m_addressBar->setFavIcon(icon); + m_view->setFocus(); } diff --git a/examples/webenginewidgets/simplebrowser/webpopupwindow.h b/examples/webenginewidgets/simplebrowser/webpopupwindow.h index af97ef7fc..c737b4abc 100644 --- a/examples/webenginewidgets/simplebrowser/webpopupwindow.h +++ b/examples/webenginewidgets/simplebrowser/webpopupwindow.h @@ -44,12 +44,12 @@ #include QT_BEGIN_NAMESPACE +class QLineEdit; class QWebEngineProfile; class QWebEngineView; QT_END_NAMESPACE class WebView; -class UrlLineEdit; class WebPopupWindow : public QWidget { @@ -57,15 +57,14 @@ class WebPopupWindow : public QWidget public: WebPopupWindow(QWebEngineProfile *profile); - QWebEngineView *view() const; - void setUrl(const QUrl &url); + WebView *view() const; private slots: void handleGeometryChangeRequested(const QRect &newGeometry); - void handleIconChanged(const QIcon &icon); private: - UrlLineEdit *m_addressBar; + QLineEdit *m_urlLineEdit; + QAction *m_favAction; WebView *m_view; }; #endif // WEBPOPUPWINDOW_H diff --git a/examples/webenginewidgets/simplebrowser/webview.cpp b/examples/webenginewidgets/simplebrowser/webview.cpp index e4e7f5efa..4bd5c84ac 100644 --- a/examples/webenginewidgets/simplebrowser/webview.cpp +++ b/examples/webenginewidgets/simplebrowser/webview.cpp @@ -52,15 +52,21 @@ WebView::WebView(QWidget *parent) : QWebEngineView(parent) - , m_loadProgress(0) + , m_loadProgress(100) { + connect(this, &QWebEngineView::loadStarted, [this]() { + m_loadProgress = 0; + emit favIconChanged(favIcon()); + }); connect(this, &QWebEngineView::loadProgress, [this](int progress) { m_loadProgress = progress; }); connect(this, &QWebEngineView::loadFinished, [this](bool success) { - if (!success) { - m_loadProgress = 0; - } + m_loadProgress = success ? 100 : -1; + emit favIconChanged(favIcon()); + }); + connect(this, &QWebEngineView::iconChanged, [this](const QIcon &) { + emit favIconChanged(favIcon()); }); connect(this, &QWebEngineView::renderProcessTerminated, @@ -115,21 +121,39 @@ bool WebView::isWebActionEnabled(QWebEnginePage::WebAction webAction) const return page()->action(webAction)->isEnabled(); } +QIcon WebView::favIcon() const +{ + QIcon favIcon = icon(); + if (!favIcon.isNull()) + return favIcon; + + if (m_loadProgress < 0) { + static QIcon errorIcon(QStringLiteral(":dialog-error.png")); + return errorIcon; + } else if (m_loadProgress < 100) { + static QIcon loadingIcon(QStringLiteral(":view-refresh.png")); + return loadingIcon; + } else { + static QIcon defaultIcon(QStringLiteral(":text-html.png")); + return defaultIcon; + } +} + QWebEngineView *WebView::createWindow(QWebEnginePage::WebWindowType type) { + BrowserWindow *mainWindow = qobject_cast(window()); + if (!mainWindow) + return nullptr; + switch (type) { case QWebEnginePage::WebBrowserTab: { - BrowserWindow *mainWindow = qobject_cast(window()); return mainWindow->tabWidget()->createTab(); } case QWebEnginePage::WebBrowserBackgroundTab: { - BrowserWindow *mainWindow = qobject_cast(window()); - return mainWindow->tabWidget()->createTab(false); + return mainWindow->tabWidget()->createBackgroundTab(); } case QWebEnginePage::WebBrowserWindow: { - BrowserWindow *mainWindow = new BrowserWindow(); - Browser::instance().addWindow(mainWindow); - return mainWindow->currentTab(); + return mainWindow->browser()->createWindow()->currentTab(); } case QWebEnginePage::WebDialog: { WebPopupWindow *popup = new WebPopupWindow(page()->profile()); diff --git a/examples/webenginewidgets/simplebrowser/webview.h b/examples/webenginewidgets/simplebrowser/webview.h index f06162ea3..23a9a29ee 100644 --- a/examples/webenginewidgets/simplebrowser/webview.h +++ b/examples/webenginewidgets/simplebrowser/webview.h @@ -56,6 +56,7 @@ public: int loadProgress() const; bool isWebActionEnabled(QWebEnginePage::WebAction webAction) const; + QIcon favIcon() const; protected: void contextMenuEvent(QContextMenuEvent *event) override; @@ -63,6 +64,7 @@ protected: signals: void webActionEnabledChanged(QWebEnginePage::WebAction webAction, bool enabled); + void favIconChanged(const QIcon &icon); private: void createWebActionTrigger(QWebEnginePage *page, QWebEnginePage::WebAction); -- cgit v1.2.3