xref: /OK3568_Linux_fs/app/forlinx/flapp/src/plugins/allwinner/browser/webview.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the demonstration applications of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL21$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** $QT_END_LICENSE$
31 **
32 ****************************************************************************/
33 
34 #include "browserapplication.h"
35 #include "browsermainwindow.h"
36 #include "cookiejar.h"
37 #include "downloadmanager.h"
38 #include "networkaccessmanager.h"
39 #include "tabwidget.h"
40 #include "webview.h"
41 
42 #include <QtGui/QClipboard>
43 #include <QtWidgets/QMenu>
44 #include <QtWidgets/QMessageBox>
45 #include <QtGui/QMouseEvent>
46 
47 #include <QWebHitTestResult>
48 
49 #ifndef QT_NO_UITOOLS
50 #include <QtUiTools/QUiLoader>
51 #endif  //QT_NO_UITOOLS
52 
53 #include <QtCore/QDebug>
54 #include <QtCore/QBuffer>
55 
WebPage(QObject * parent)56 WebPage::WebPage(QObject *parent)
57     : QWebPage(parent)
58     , m_keyboardModifiers(Qt::NoModifier)
59     , m_pressedButtons(Qt::NoButton)
60     , m_openInNewTab(false)
61 {
62     setNetworkAccessManager(BrowserApplication::networkAccessManager());
63     connect(this, SIGNAL(unsupportedContent(QNetworkReply*)),
64             this, SLOT(handleUnsupportedContent(QNetworkReply*)));
65 }
66 
mainWindow()67 BrowserMainWindow *WebPage::mainWindow()
68 {
69     QObject *w = this->parent();
70     while (w) {
71         if (BrowserMainWindow *mw = qobject_cast<BrowserMainWindow*>(w))
72             return mw;
73         w = w->parent();
74     }
75     return BrowserApplication::instance()->mainWindow();
76 }
77 
acceptNavigationRequest(QWebFrame * frame,const QNetworkRequest & request,NavigationType type)78 bool WebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type)
79 {
80     // ctrl open in new tab
81     // ctrl-shift open in new tab and select
82     // ctrl-alt open in new window
83     if (type == QWebPage::NavigationTypeLinkClicked
84         && (m_keyboardModifiers & Qt::ControlModifier
85             || m_pressedButtons == Qt::MidButton)) {
86         bool newWindow = (m_keyboardModifiers & Qt::AltModifier);
87         WebView *webView;
88         if (newWindow) {
89             BrowserApplication::instance()->newMainWindow();
90             BrowserMainWindow *newMainWindow = BrowserApplication::instance()->mainWindow();
91             webView = newMainWindow->currentTab();
92             newMainWindow->raise();
93             newMainWindow->activateWindow();
94             webView->setFocus();
95         } else {
96             bool selectNewTab = (m_keyboardModifiers & Qt::ShiftModifier);
97             webView = mainWindow()->tabWidget()->newTab(selectNewTab);
98         }
99         webView->load(request);
100         m_keyboardModifiers = Qt::NoModifier;
101         m_pressedButtons = Qt::NoButton;
102         return false;
103     }
104     if (frame == mainFrame()) {
105         m_loadingUrl = request.url();
106         emit loadingUrl(m_loadingUrl);
107     }
108     return QWebPage::acceptNavigationRequest(frame, request, type);
109 }
110 
createWindow(QWebPage::WebWindowType type)111 QWebPage *WebPage::createWindow(QWebPage::WebWindowType type)
112 {
113     Q_UNUSED(type);
114     if (m_keyboardModifiers & Qt::ControlModifier || m_pressedButtons == Qt::MidButton)
115         m_openInNewTab = true;
116     if (m_openInNewTab) {
117         m_openInNewTab = false;
118         return mainWindow()->tabWidget()->newTab()->page();
119     }
120     BrowserApplication::instance()->newMainWindow();
121     BrowserMainWindow *mainWindow = BrowserApplication::instance()->mainWindow();
122     return mainWindow->currentTab()->page();
123 }
124 
125 #if !defined(QT_NO_UITOOLS)
createPlugin(const QString & classId,const QUrl & url,const QStringList & paramNames,const QStringList & paramValues)126 QObject *WebPage::createPlugin(const QString &classId, const QUrl &url, const QStringList &paramNames, const QStringList &paramValues)
127 {
128     Q_UNUSED(url);
129     Q_UNUSED(paramNames);
130     Q_UNUSED(paramValues);
131     QUiLoader loader;
132     return loader.createWidget(classId, view());
133 }
134 #endif // !defined(QT_NO_UITOOLS)
135 
handleUnsupportedContent(QNetworkReply * reply)136 void WebPage::handleUnsupportedContent(QNetworkReply *reply)
137 {
138     QString errorString = reply->errorString();
139 
140     if (m_loadingUrl != reply->url()) {
141         // sub resource of this page
142         qWarning() << "Resource" << reply->url().toEncoded() << "has unknown Content-Type, will be ignored.";
143         reply->deleteLater();
144         return;
145     }
146 
147     if (reply->error() == QNetworkReply::NoError && !reply->header(QNetworkRequest::ContentTypeHeader).isValid()) {
148         errorString = "Unknown Content-Type";
149     }
150 
151     QFile file(QLatin1String(":/notfound.html"));
152     bool isOpened = file.open(QIODevice::ReadOnly);
153     Q_ASSERT(isOpened);
154     Q_UNUSED(isOpened)
155 
156     QString title = tr("Error loading page: %1").arg(reply->url().toString());
157     QString html = QString(QLatin1String(file.readAll()))
158                         .arg(title)
159                         .arg(errorString)
160                         .arg(reply->url().toString());
161 
162     QBuffer imageBuffer;
163     imageBuffer.open(QBuffer::ReadWrite);
164     QIcon icon = view()->style()->standardIcon(QStyle::SP_MessageBoxWarning, 0, view());
165     QPixmap pixmap = icon.pixmap(QSize(32,32));
166     if (pixmap.save(&imageBuffer, "PNG")) {
167         html.replace(QLatin1String("IMAGE_BINARY_DATA_HERE"),
168                      QString(QLatin1String(imageBuffer.buffer().toBase64())));
169     }
170 
171     QList<QWebFrame*> frames;
172     frames.append(mainFrame());
173     while (!frames.isEmpty()) {
174         QWebFrame *frame = frames.takeFirst();
175         if (frame->url() == reply->url()) {
176             frame->setHtml(html, reply->url());
177             return;
178         }
179         QList<QWebFrame *> children = frame->childFrames();
180         foreach(QWebFrame *frame, children)
181             frames.append(frame);
182     }
183     if (m_loadingUrl == reply->url()) {
184         mainFrame()->setHtml(html, reply->url());
185     }
186 }
187 
188 
WebView(QWidget * parent)189 WebView::WebView(QWidget* parent)
190     : QWebView(parent)
191     , m_progress(0)
192     , m_page(new WebPage(this))
193 {
194     setPage(m_page);
195     connect(page(), SIGNAL(statusBarMessage(QString)),
196             SLOT(setStatusBarText(QString)));
197     connect(this, SIGNAL(loadProgress(int)),
198             this, SLOT(setProgress(int)));
199     connect(this, SIGNAL(loadFinished(bool)),
200             this, SLOT(loadFinished()));
201     connect(page(), SIGNAL(loadingUrl(QUrl)),
202             this, SIGNAL(urlChanged(QUrl)));
203     connect(page(), SIGNAL(downloadRequested(QNetworkRequest)),
204             this, SLOT(downloadRequested(QNetworkRequest)));
205     page()->setForwardUnsupportedContent(true);
206 
207 }
208 
contextMenuEvent(QContextMenuEvent * event)209 void WebView::contextMenuEvent(QContextMenuEvent *event)
210 {
211     QWebHitTestResult r = page()->mainFrame()->hitTestContent(event->pos());
212     if (!r.linkUrl().isEmpty()) {
213         QMenu menu(this);
214         menu.addAction(pageAction(QWebPage::OpenLinkInNewWindow));
215         menu.addAction(tr("Open in New Tab"), this, SLOT(openLinkInNewTab()));
216         menu.addSeparator();
217         menu.addAction(pageAction(QWebPage::DownloadLinkToDisk));
218         // Add link to bookmarks...
219         menu.addSeparator();
220         menu.addAction(pageAction(QWebPage::CopyLinkToClipboard));
221         if (page()->settings()->testAttribute(QWebSettings::DeveloperExtrasEnabled))
222             menu.addAction(pageAction(QWebPage::InspectElement));
223         menu.exec(mapToGlobal(event->pos()));
224         return;
225     }
226     QWebView::contextMenuEvent(event);
227 }
228 
wheelEvent(QWheelEvent * event)229 void WebView::wheelEvent(QWheelEvent *event)
230 {
231     if (QApplication::keyboardModifiers() & Qt::ControlModifier) {
232         int numDegrees = event->delta() / 8;
233         int numSteps = numDegrees / 15;
234         setTextSizeMultiplier(textSizeMultiplier() + numSteps * 0.1);
235         event->accept();
236         return;
237     }
238     QWebView::wheelEvent(event);
239 }
240 
openLinkInNewTab()241 void WebView::openLinkInNewTab()
242 {
243     m_page->m_openInNewTab = true;
244     pageAction(QWebPage::OpenLinkInNewWindow)->trigger();
245 }
246 
setProgress(int progress)247 void WebView::setProgress(int progress)
248 {
249     m_progress = progress;
250 }
251 
loadFinished()252 void WebView::loadFinished()
253 {
254     if (100 != m_progress) {
255         qWarning() << "Received finished signal while progress is still:" << progress()
256                    << "Url:" << url();
257     }
258     m_progress = 0;
259 }
260 
loadUrl(const QUrl & url)261 void WebView::loadUrl(const QUrl &url)
262 {
263     m_initialUrl = url;
264     load(url);
265 }
266 
lastStatusBarText() const267 QString WebView::lastStatusBarText() const
268 {
269     return m_statusBarText;
270 }
271 
url() const272 QUrl WebView::url() const
273 {
274     QUrl url = QWebView::url();
275     if (!url.isEmpty())
276         return url;
277 
278     return m_initialUrl;
279 }
280 
mousePressEvent(QMouseEvent * event)281 void WebView::mousePressEvent(QMouseEvent *event)
282 {
283     m_page->m_pressedButtons = event->buttons();
284     m_page->m_keyboardModifiers = event->modifiers();
285     QWebView::mousePressEvent(event);
286 }
287 
mouseReleaseEvent(QMouseEvent * event)288 void WebView::mouseReleaseEvent(QMouseEvent *event)
289 {
290     QWebView::mouseReleaseEvent(event);
291 #ifndef QT_NO_CLIPBOARD
292     if (!event->isAccepted() && (m_page->m_pressedButtons & Qt::MidButton)) {
293         QUrl url(QApplication::clipboard()->text(QClipboard::Selection));
294         if (!url.isEmpty() && url.isValid() && !url.scheme().isEmpty()) {
295             setUrl(url);
296         }
297     }
298 #endif
299 }
300 
setStatusBarText(const QString & string)301 void WebView::setStatusBarText(const QString &string)
302 {
303     m_statusBarText = string;
304 }
305 
downloadRequested(const QNetworkRequest & request)306 void WebView::downloadRequested(const QNetworkRequest &request)
307 {
308     BrowserApplication::downloadManager()->download(request);
309 }
310 
311