1*4882a593Smuzhiyun /****************************************************************************
2*4882a593Smuzhiyun **
3*4882a593Smuzhiyun ** Copyright (C) 2016 The Qt Company Ltd.
4*4882a593Smuzhiyun ** Contact: https://www.qt.io/licensing/
5*4882a593Smuzhiyun **
6*4882a593Smuzhiyun ** This file is part of the examples of the Qt Toolkit.
7*4882a593Smuzhiyun **
8*4882a593Smuzhiyun ** $QT_BEGIN_LICENSE:BSD$
9*4882a593Smuzhiyun ** Commercial License Usage
10*4882a593Smuzhiyun ** Licensees holding valid commercial Qt licenses may use this file in
11*4882a593Smuzhiyun ** accordance with the commercial license agreement provided with the
12*4882a593Smuzhiyun ** Software or, alternatively, in accordance with the terms contained in
13*4882a593Smuzhiyun ** a written agreement between you and The Qt Company. For licensing terms
14*4882a593Smuzhiyun ** and conditions see https://www.qt.io/terms-conditions. For further
15*4882a593Smuzhiyun ** information use the contact form at https://www.qt.io/contact-us.
16*4882a593Smuzhiyun **
17*4882a593Smuzhiyun ** BSD License Usage
18*4882a593Smuzhiyun ** Alternatively, you may use this file under the terms of the BSD license
19*4882a593Smuzhiyun ** as follows:
20*4882a593Smuzhiyun **
21*4882a593Smuzhiyun ** "Redistribution and use in source and binary forms, with or without
22*4882a593Smuzhiyun ** modification, are permitted provided that the following conditions are
23*4882a593Smuzhiyun ** met:
24*4882a593Smuzhiyun ** * Redistributions of source code must retain the above copyright
25*4882a593Smuzhiyun ** notice, this list of conditions and the following disclaimer.
26*4882a593Smuzhiyun ** * Redistributions in binary form must reproduce the above copyright
27*4882a593Smuzhiyun ** notice, this list of conditions and the following disclaimer in
28*4882a593Smuzhiyun ** the documentation and/or other materials provided with the
29*4882a593Smuzhiyun ** distribution.
30*4882a593Smuzhiyun ** * Neither the name of The Qt Company Ltd nor the names of its
31*4882a593Smuzhiyun ** contributors may be used to endorse or promote products derived
32*4882a593Smuzhiyun ** from this software without specific prior written permission.
33*4882a593Smuzhiyun **
34*4882a593Smuzhiyun **
35*4882a593Smuzhiyun ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36*4882a593Smuzhiyun ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37*4882a593Smuzhiyun ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38*4882a593Smuzhiyun ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39*4882a593Smuzhiyun ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40*4882a593Smuzhiyun ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41*4882a593Smuzhiyun ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42*4882a593Smuzhiyun ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43*4882a593Smuzhiyun ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44*4882a593Smuzhiyun ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45*4882a593Smuzhiyun ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
46*4882a593Smuzhiyun **
47*4882a593Smuzhiyun ** $QT_END_LICENSE$
48*4882a593Smuzhiyun **
49*4882a593Smuzhiyun ****************************************************************************/
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun #include "browserwindow.h"
52*4882a593Smuzhiyun #include "tabwidget.h"
53*4882a593Smuzhiyun #include "ui_certificateerrordialog.h"
54*4882a593Smuzhiyun #include "ui_passworddialog.h"
55*4882a593Smuzhiyun #include "webpage.h"
56*4882a593Smuzhiyun #include "webview.h"
57*4882a593Smuzhiyun #include <QAuthenticator>
58*4882a593Smuzhiyun #include <QMessageBox>
59*4882a593Smuzhiyun #include <QStyle>
60*4882a593Smuzhiyun #include <QWebEngineCertificateError>
61*4882a593Smuzhiyun
WebPage(QWebEngineProfile * profile,QObject * parent)62*4882a593Smuzhiyun WebPage::WebPage(QWebEngineProfile *profile, QObject *parent)
63*4882a593Smuzhiyun : QWebEnginePage(profile, parent)
64*4882a593Smuzhiyun {
65*4882a593Smuzhiyun connect(this, &QWebEnginePage::authenticationRequired, this, &WebPage::handleAuthenticationRequired);
66*4882a593Smuzhiyun connect(this, &QWebEnginePage::featurePermissionRequested, this, &WebPage::handleFeaturePermissionRequested);
67*4882a593Smuzhiyun connect(this, &QWebEnginePage::proxyAuthenticationRequired, this, &WebPage::handleProxyAuthenticationRequired);
68*4882a593Smuzhiyun connect(this, &QWebEnginePage::registerProtocolHandlerRequested, this, &WebPage::handleRegisterProtocolHandlerRequested);
69*4882a593Smuzhiyun #if !defined(QT_NO_SSL) || QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
70*4882a593Smuzhiyun connect(this, &QWebEnginePage::selectClientCertificate, this, &WebPage::handleSelectClientCertificate);
71*4882a593Smuzhiyun #endif
72*4882a593Smuzhiyun }
73*4882a593Smuzhiyun
certificateError(const QWebEngineCertificateError & error)74*4882a593Smuzhiyun bool WebPage::certificateError(const QWebEngineCertificateError &error)
75*4882a593Smuzhiyun {
76*4882a593Smuzhiyun QWidget *mainWindow = view()->window();
77*4882a593Smuzhiyun if (error.isOverridable()) {
78*4882a593Smuzhiyun QDialog dialog(mainWindow);
79*4882a593Smuzhiyun dialog.setModal(true);
80*4882a593Smuzhiyun dialog.setWindowFlags(dialog.windowFlags() & ~Qt::WindowContextHelpButtonHint);
81*4882a593Smuzhiyun Ui::CertificateErrorDialog certificateDialog;
82*4882a593Smuzhiyun certificateDialog.setupUi(&dialog);
83*4882a593Smuzhiyun certificateDialog.m_iconLabel->setText(QString());
84*4882a593Smuzhiyun QIcon icon(mainWindow->style()->standardIcon(QStyle::SP_MessageBoxWarning, 0, mainWindow));
85*4882a593Smuzhiyun certificateDialog.m_iconLabel->setPixmap(icon.pixmap(32, 32));
86*4882a593Smuzhiyun certificateDialog.m_errorLabel->setText(error.errorDescription());
87*4882a593Smuzhiyun dialog.setWindowTitle(tr("Certificate Error"));
88*4882a593Smuzhiyun return dialog.exec() == QDialog::Accepted;
89*4882a593Smuzhiyun }
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun QMessageBox::critical(mainWindow, tr("Certificate Error"), error.errorDescription());
92*4882a593Smuzhiyun return false;
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun
handleAuthenticationRequired(const QUrl & requestUrl,QAuthenticator * auth)95*4882a593Smuzhiyun void WebPage::handleAuthenticationRequired(const QUrl &requestUrl, QAuthenticator *auth)
96*4882a593Smuzhiyun {
97*4882a593Smuzhiyun QWidget *mainWindow = view()->window();
98*4882a593Smuzhiyun QDialog dialog(mainWindow);
99*4882a593Smuzhiyun dialog.setModal(true);
100*4882a593Smuzhiyun dialog.setWindowFlags(dialog.windowFlags() & ~Qt::WindowContextHelpButtonHint);
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun Ui::PasswordDialog passwordDialog;
103*4882a593Smuzhiyun passwordDialog.setupUi(&dialog);
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun passwordDialog.m_iconLabel->setText(QString());
106*4882a593Smuzhiyun QIcon icon(mainWindow->style()->standardIcon(QStyle::SP_MessageBoxQuestion, 0, mainWindow));
107*4882a593Smuzhiyun passwordDialog.m_iconLabel->setPixmap(icon.pixmap(32, 32));
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun QString introMessage(tr("Enter username and password for \"%1\" at %2")
110*4882a593Smuzhiyun .arg(auth->realm()).arg(requestUrl.toString().toHtmlEscaped()));
111*4882a593Smuzhiyun passwordDialog.m_infoLabel->setText(introMessage);
112*4882a593Smuzhiyun passwordDialog.m_infoLabel->setWordWrap(true);
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun if (dialog.exec() == QDialog::Accepted) {
115*4882a593Smuzhiyun auth->setUser(passwordDialog.m_userNameLineEdit->text());
116*4882a593Smuzhiyun auth->setPassword(passwordDialog.m_passwordLineEdit->text());
117*4882a593Smuzhiyun } else {
118*4882a593Smuzhiyun // Set authenticator null if dialog is cancelled
119*4882a593Smuzhiyun *auth = QAuthenticator();
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun }
122*4882a593Smuzhiyun
questionForFeature(QWebEnginePage::Feature feature)123*4882a593Smuzhiyun inline QString questionForFeature(QWebEnginePage::Feature feature)
124*4882a593Smuzhiyun {
125*4882a593Smuzhiyun switch (feature) {
126*4882a593Smuzhiyun case QWebEnginePage::Geolocation:
127*4882a593Smuzhiyun return WebPage::tr("Allow %1 to access your location information?");
128*4882a593Smuzhiyun case QWebEnginePage::MediaAudioCapture:
129*4882a593Smuzhiyun return WebPage::tr("Allow %1 to access your microphone?");
130*4882a593Smuzhiyun case QWebEnginePage::MediaVideoCapture:
131*4882a593Smuzhiyun return WebPage::tr("Allow %1 to access your webcam?");
132*4882a593Smuzhiyun case QWebEnginePage::MediaAudioVideoCapture:
133*4882a593Smuzhiyun return WebPage::tr("Allow %1 to access your microphone and webcam?");
134*4882a593Smuzhiyun case QWebEnginePage::MouseLock:
135*4882a593Smuzhiyun return WebPage::tr("Allow %1 to lock your mouse cursor?");
136*4882a593Smuzhiyun case QWebEnginePage::DesktopVideoCapture:
137*4882a593Smuzhiyun return WebPage::tr("Allow %1 to capture video of your desktop?");
138*4882a593Smuzhiyun case QWebEnginePage::DesktopAudioVideoCapture:
139*4882a593Smuzhiyun return WebPage::tr("Allow %1 to capture audio and video of your desktop?");
140*4882a593Smuzhiyun case QWebEnginePage::Notifications:
141*4882a593Smuzhiyun return QString();
142*4882a593Smuzhiyun }
143*4882a593Smuzhiyun return QString();
144*4882a593Smuzhiyun }
145*4882a593Smuzhiyun
handleFeaturePermissionRequested(const QUrl & securityOrigin,Feature feature)146*4882a593Smuzhiyun void WebPage::handleFeaturePermissionRequested(const QUrl &securityOrigin, Feature feature)
147*4882a593Smuzhiyun {
148*4882a593Smuzhiyun QString title = tr("Permission Request");
149*4882a593Smuzhiyun QString question = questionForFeature(feature).arg(securityOrigin.host());
150*4882a593Smuzhiyun if (!question.isEmpty() && QMessageBox::question(view()->window(), title, question) == QMessageBox::Yes)
151*4882a593Smuzhiyun setFeaturePermission(securityOrigin, feature, PermissionGrantedByUser);
152*4882a593Smuzhiyun else
153*4882a593Smuzhiyun setFeaturePermission(securityOrigin, feature, PermissionDeniedByUser);
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun
handleProxyAuthenticationRequired(const QUrl &,QAuthenticator * auth,const QString & proxyHost)156*4882a593Smuzhiyun void WebPage::handleProxyAuthenticationRequired(const QUrl &, QAuthenticator *auth, const QString &proxyHost)
157*4882a593Smuzhiyun {
158*4882a593Smuzhiyun QWidget *mainWindow = view()->window();
159*4882a593Smuzhiyun QDialog dialog(mainWindow);
160*4882a593Smuzhiyun dialog.setModal(true);
161*4882a593Smuzhiyun dialog.setWindowFlags(dialog.windowFlags() & ~Qt::WindowContextHelpButtonHint);
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun Ui::PasswordDialog passwordDialog;
164*4882a593Smuzhiyun passwordDialog.setupUi(&dialog);
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun passwordDialog.m_iconLabel->setText(QString());
167*4882a593Smuzhiyun QIcon icon(mainWindow->style()->standardIcon(QStyle::SP_MessageBoxQuestion, 0, mainWindow));
168*4882a593Smuzhiyun passwordDialog.m_iconLabel->setPixmap(icon.pixmap(32, 32));
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun QString introMessage = tr("Connect to proxy \"%1\" using:");
171*4882a593Smuzhiyun introMessage = introMessage.arg(proxyHost.toHtmlEscaped());
172*4882a593Smuzhiyun passwordDialog.m_infoLabel->setText(introMessage);
173*4882a593Smuzhiyun passwordDialog.m_infoLabel->setWordWrap(true);
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun if (dialog.exec() == QDialog::Accepted) {
176*4882a593Smuzhiyun auth->setUser(passwordDialog.m_userNameLineEdit->text());
177*4882a593Smuzhiyun auth->setPassword(passwordDialog.m_passwordLineEdit->text());
178*4882a593Smuzhiyun } else {
179*4882a593Smuzhiyun // Set authenticator null if dialog is cancelled
180*4882a593Smuzhiyun *auth = QAuthenticator();
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun }
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun //! [registerProtocolHandlerRequested]
handleRegisterProtocolHandlerRequested(QWebEngineRegisterProtocolHandlerRequest request)185*4882a593Smuzhiyun void WebPage::handleRegisterProtocolHandlerRequested(QWebEngineRegisterProtocolHandlerRequest request)
186*4882a593Smuzhiyun {
187*4882a593Smuzhiyun auto answer = QMessageBox::question(
188*4882a593Smuzhiyun view()->window(),
189*4882a593Smuzhiyun tr("Permission Request"),
190*4882a593Smuzhiyun tr("Allow %1 to open all %2 links?")
191*4882a593Smuzhiyun .arg(request.origin().host())
192*4882a593Smuzhiyun .arg(request.scheme()));
193*4882a593Smuzhiyun if (answer == QMessageBox::Yes)
194*4882a593Smuzhiyun request.accept();
195*4882a593Smuzhiyun else
196*4882a593Smuzhiyun request.reject();
197*4882a593Smuzhiyun }
198*4882a593Smuzhiyun //! [registerProtocolHandlerRequested]
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun #if !defined(QT_NO_SSL) || QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
handleSelectClientCertificate(QWebEngineClientCertificateSelection selection)201*4882a593Smuzhiyun void WebPage::handleSelectClientCertificate(QWebEngineClientCertificateSelection selection)
202*4882a593Smuzhiyun {
203*4882a593Smuzhiyun // Just select one.
204*4882a593Smuzhiyun selection.select(selection.certificates().at(0));
205*4882a593Smuzhiyun }
206*4882a593Smuzhiyun #endif
207