Mercurial > projects > qtd
comparison demos/browser/webview.d @ 45:71b382c10ef6
add coarse and incomplete QT browser port
author | mandel |
---|---|
date | Sun, 17 May 2009 18:49:59 +0000 |
parents | |
children | 7bfd46c330dc |
comparison
equal
deleted
inserted
replaced
44:3cb15c92ac28 | 45:71b382c10ef6 |
---|---|
1 /**************************************************************************** | |
2 ** | |
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). | |
4 ** Contact: Qt Software Information (qt-info@nokia.com) | |
5 ** | |
6 ** This file is part of the demonstration applications of the Qt Toolkit. | |
7 ** | |
8 ** $QT_BEGIN_LICENSE:LGPL$ | |
9 ** Commercial Usage | |
10 ** Licensees holding valid Qt Commercial licenses may use this file in | |
11 ** accordance with the Qt Commercial License Agreement provided with the | |
12 ** Software or, alternatively, in accordance with the terms contained in | |
13 ** a written agreement between you and Nokia. | |
14 ** | |
15 ** GNU Lesser General Public License Usage | |
16 ** Alternatively, this file may be used under the terms of the GNU Lesser | |
17 ** General Public License version 2.1 as published by the Free Software | |
18 ** Foundation and appearing in the file LICENSE.LGPL included in the | |
19 ** packaging of this file. Please review the following information to | |
20 ** ensure the GNU Lesser General Public License version 2.1 requirements | |
21 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. | |
22 ** | |
23 ** In addition, as a special exception, Nokia gives you certain | |
24 ** additional rights. These rights are described in the Nokia Qt LGPL | |
25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this | |
26 ** package. | |
27 ** | |
28 ** GNU General Public License Usage | |
29 ** Alternatively, this file may be used under the terms of the GNU | |
30 ** General Public License version 3.0 as published by the Free Software | |
31 ** Foundation and appearing in the file LICENSE.GPL included in the | |
32 ** packaging of this file. Please review the following information to | |
33 ** ensure the GNU General Public License version 3.0 requirements will be | |
34 ** met: http://www.gnu.org/copyleft/gpl.html. | |
35 ** | |
36 ** If you are unsure which license is appropriate for your use, please | |
37 ** contact the sales department at qt-sales@nokia.com. | |
38 ** $QT_END_LICENSE$ | |
39 ** | |
40 ****************************************************************************/ | |
41 | |
42 import QtWebKit.QWebView; | |
43 | |
44 import browserapplication; | |
45 import browsermainwindow; | |
46 import cookiejar; | |
47 import downloadmanager; | |
48 import networkaccessmanager; | |
49 import tabwidget; | |
50 import webview; | |
51 | |
52 import QtGui.QClipboard; | |
53 import QtGui.QMenu; | |
54 import QtGui.QMessageBox; | |
55 import QtGui.QMouseEvent; | |
56 | |
57 import QtWebKit.QWebHitTestResult; | |
58 | |
59 import QtUiTools.QUiLoader; | |
60 | |
61 import QtCore.QDebug; | |
62 import QtCore.QBuffer; | |
63 | |
64 /* | |
65 QT_BEGIN_NAMESPACE | |
66 class QAuthenticator; | |
67 class QMouseEvent; | |
68 class QNetworkProxy; | |
69 class QNetworkReply; | |
70 class QSslError; | |
71 QT_END_NAMESPACE | |
72 | |
73 class BrowserMainWindow; | |
74 */ | |
75 | |
76 class WebPage : public QWebPage { | |
77 Q_OBJECT | |
78 | |
79 signals: | |
80 void loadingUrl(const QUrl &url); | |
81 | |
82 public: | |
83 this(QObject *parent = null) | |
84 { | |
85 super(parent); | |
86 m_keyboardModifiers = Qt.NoModifier; | |
87 m_pressedButtons = Qt.NoButton; | |
88 m_openInNewTab = false; | |
89 setNetworkAccessManager(BrowserApplication::networkAccessManager()); | |
90 connect(this, SIGNAL(unsupportedContent(QNetworkReply *)), | |
91 this, SLOT(handleUnsupportedContent(QNetworkReply *))); | |
92 } | |
93 BrowserMainWindow *mainWindow() | |
94 { | |
95 QObject *w = this.parent(); | |
96 while (w) { | |
97 if (BrowserMainWindow *mw = qobject_cast<BrowserMainWindow*>(w)) | |
98 return mw; | |
99 w = w.parent(); | |
100 } | |
101 return BrowserApplication::instance().mainWindow(); | |
102 } | |
103 | |
104 protected: | |
105 bool acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type); | |
106 { | |
107 // ctrl open in new tab | |
108 // ctrl-shift open in new tab and select | |
109 // ctrl-alt open in new window | |
110 if (type == QWebPage::NavigationTypeLinkClicked | |
111 && (m_keyboardModifiers & Qt.ControlModifier | |
112 || m_pressedButtons == Qt.MidButton)) { | |
113 bool newWindow = (m_keyboardModifiers & Qt.AltModifier); | |
114 WebView *webView; | |
115 if (newWindow) { | |
116 BrowserApplication::instance().newMainWindow(); | |
117 BrowserMainWindow *newMainWindow = BrowserApplication::instance().mainWindow(); | |
118 webView = newMainWindow.currentTab(); | |
119 newMainWindow.raise(); | |
120 newMainWindow.activateWindow(); | |
121 webView.setFocus(); | |
122 } else { | |
123 bool selectNewTab = (m_keyboardModifiers & Qt.ShiftModifier); | |
124 webView = mainWindow().tabWidget().newTab(selectNewTab); | |
125 } | |
126 webView.load(request); | |
127 m_keyboardModifiers = Qt.NoModifier; | |
128 m_pressedButtons = Qt.NoButton; | |
129 return false; | |
130 } | |
131 if (frame == mainFrame()) { | |
132 m_loadingUrl = request.url(); | |
133 emit loadingUrl(m_loadingUrl); | |
134 } | |
135 return QWebPage::acceptNavigationRequest(frame, request, type); | |
136 } | |
137 | |
138 QWebPage *createWindow(QWebPage::WebWindowType type) | |
139 { | |
140 Q_UNUSED(type); | |
141 if (m_keyboardModifiers & Qt.ControlModifier || m_pressedButtons == Qt.MidButton) | |
142 m_openInNewTab = true; | |
143 if (m_openInNewTab) { | |
144 m_openInNewTab = false; | |
145 return mainWindow().tabWidget().newTab().page(); | |
146 } | |
147 BrowserApplication::instance().newMainWindow(); | |
148 BrowserMainWindow *mainWindow = BrowserApplication::instance().mainWindow(); | |
149 return mainWindow.currentTab().page(); | |
150 } | |
151 | |
152 version(QT_NO_UITOOLS) {} else | |
153 { | |
154 QObject *createPlugin(const QString &classId, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues); | |
155 { | |
156 Q_UNUSED(url); | |
157 Q_UNUSED(paramNames); | |
158 Q_UNUSED(paramValues); | |
159 QUiLoader loader; | |
160 return loader.createWidget(classId, view()); | |
161 } | |
162 } | |
163 | |
164 | |
165 | |
166 private slots: | |
167 void handleUnsupportedContent(QNetworkReply *reply) | |
168 { | |
169 if (reply.error() == QNetworkReply::NoError) { | |
170 BrowserApplication::downloadManager().handleUnsupportedContent(reply); | |
171 return; | |
172 } | |
173 | |
174 QFile file(QLatin1String(":/notfound.html")); | |
175 bool isOpened = file.open(QIODevice::ReadOnly); | |
176 Q_ASSERT(isOpened); | |
177 QString title = tr("Error loading page: %1").arg(reply.url().toString()); | |
178 QString html = QString(QLatin1String(file.readAll())) | |
179 .arg(title) | |
180 .arg(reply.errorString()) | |
181 .arg(reply.url().toString()); | |
182 | |
183 QBuffer imageBuffer; | |
184 imageBuffer.open(QBuffer::ReadWrite); | |
185 QIcon icon = view().style().standardIcon(QStyle::SP_MessageBoxWarning, 0, view()); | |
186 QPixmap pixmap = icon.pixmap(QSize(32,32)); | |
187 if (pixmap.save(&imageBuffer, "PNG")) { | |
188 html.replace(QLatin1String("IMAGE_BINARY_DATA_HERE"), | |
189 QString(QLatin1String(imageBuffer.buffer().toBase64()))); | |
190 } | |
191 | |
192 QList<QWebFrame*> frames; | |
193 frames.append(mainFrame()); | |
194 while (!frames.isEmpty()) { | |
195 QWebFrame *frame = frames.takeFirst(); | |
196 if (frame.url() == reply.url()) { | |
197 frame.setHtml(html, reply.url()); | |
198 return; | |
199 } | |
200 QList<QWebFrame *> children = frame.childFrames(); | |
201 foreach(QWebFrame *frame, children) | |
202 frames.append(frame); | |
203 } | |
204 if (m_loadingUrl == reply.url()) { | |
205 mainFrame().setHtml(html, reply.url()); | |
206 } | |
207 } | |
208 | |
209 private: | |
210 friend class WebView; | |
211 | |
212 // set the webview mousepressedevent | |
213 Qt.KeyboardModifiers m_keyboardModifiers; | |
214 Qt.MouseButtons m_pressedButtons; | |
215 bool m_openInNewTab; | |
216 QUrl m_loadingUrl; | |
217 }; | |
218 | |
219 class WebView : public QWebView { | |
220 Q_OBJECT | |
221 | |
222 public: | |
223 WebView(QWidget *parent = null) | |
224 : QWebView(parent) | |
225 , m_progress(0) | |
226 , m_page(new WebPage(this)) | |
227 { | |
228 setPage(m_page); | |
229 connect(page(), SIGNAL(statusBarMessage(const QString&)), | |
230 SLOT(setStatusBarText(const QString&))); | |
231 connect(this, SIGNAL(loadProgress(int)), | |
232 this, SLOT(setProgress(int))); | |
233 connect(this, SIGNAL(loadFinished(bool)), | |
234 this, SLOT(loadFinished())); | |
235 connect(page(), SIGNAL(loadingUrl(const QUrl&)), | |
236 this, SIGNAL(urlChanged(const QUrl &))); | |
237 connect(page(), SIGNAL(downloadRequested(const QNetworkRequest &)), | |
238 this, SLOT(downloadRequested(const QNetworkRequest &))); | |
239 page().setForwardUnsupportedContent(true); | |
240 | |
241 } | |
242 | |
243 WebPage *webPage() const { return m_page; } | |
244 | |
245 void loadUrl(const QUrl &url) | |
246 { | |
247 m_initialUrl = url; | |
248 load(url); | |
249 } | |
250 | |
251 QUrl url() const | |
252 { | |
253 QUrl url = QWebView::url(); | |
254 if (!url.isEmpty()) | |
255 return url; | |
256 | |
257 return m_initialUrl; | |
258 } | |
259 | |
260 QString lastStatusBarText() const | |
261 { | |
262 return m_statusBarText; | |
263 } | |
264 | |
265 inline int progress() const { return m_progress; } | |
266 | |
267 protected: | |
268 void mousePressEvent(QMouseEvent *event); | |
269 { | |
270 m_page.m_pressedButtons = event.buttons(); | |
271 m_page.m_keyboardModifiers = event.modifiers(); | |
272 QWebView::mousePressEvent(event); | |
273 } | |
274 | |
275 void mouseReleaseEvent(QMouseEvent *event) | |
276 { | |
277 QWebView::mouseReleaseEvent(event); | |
278 if (!event.isAccepted() && (m_page.m_pressedButtons & Qt.MidButton)) { | |
279 QUrl url(QApplication::clipboard().text(QClipboard::Selection)); | |
280 if (!url.isEmpty() && url.isValid() && !url.scheme().isEmpty()) { | |
281 setUrl(url); | |
282 } | |
283 } | |
284 } | |
285 | |
286 void contextMenuEvent(QContextMenuEvent *event) | |
287 { | |
288 QWebHitTestResult r = page().mainFrame().hitTestContent(event.pos()); | |
289 if (!r.linkUrl().isEmpty()) { | |
290 QMenu menu(this); | |
291 menu.addAction(pageAction(QWebPage::OpenLinkInNewWindow)); | |
292 menu.addAction(tr("Open in New Tab"), this, SLOT(openLinkInNewTab())); | |
293 menu.addSeparator(); | |
294 menu.addAction(pageAction(QWebPage::DownloadLinkToDisk)); | |
295 // Add link to bookmarks... | |
296 menu.addSeparator(); | |
297 menu.addAction(pageAction(QWebPage::CopyLinkToClipboard)); | |
298 if (page().settings().testAttribute(QWebSettings::DeveloperExtrasEnabled)) | |
299 menu.addAction(pageAction(QWebPage::InspectElement)); | |
300 menu.exec(mapToGlobal(event.pos())); | |
301 return; | |
302 } | |
303 QWebView::contextMenuEvent(event); | |
304 } | |
305 | |
306 void wheelEvent(QWheelEvent *event) | |
307 { | |
308 if (QApplication::keyboardModifiers() & Qt.ControlModifier) { | |
309 int numDegrees = event.delta() / 8; | |
310 int numSteps = numDegrees / 15; | |
311 setTextSizeMultiplier(textSizeMultiplier() + numSteps * 0.1); | |
312 event.accept(); | |
313 return; | |
314 } | |
315 QWebView::wheelEvent(event); | |
316 } | |
317 | |
318 | |
319 private slots: | |
320 void setProgress(int progress) | |
321 { | |
322 m_progress = progress; | |
323 } | |
324 | |
325 void loadFinished() | |
326 { | |
327 if (100 != m_progress) { | |
328 qWarning() << "Recieved finished signal while progress is still:" << progress() | |
329 << "Url:" << url(); | |
330 } | |
331 m_progress = 0; | |
332 } | |
333 | |
334 void setStatusBarText(const QString &string) | |
335 { | |
336 m_statusBarText = string; | |
337 } | |
338 | |
339 void downloadRequested(const QNetworkRequest &request) | |
340 { | |
341 BrowserApplication::downloadManager().download(request); | |
342 } | |
343 | |
344 void openLinkInNewTab() | |
345 { | |
346 m_page.m_openInNewTab = true; | |
347 pageAction(QWebPage::OpenLinkInNewWindow).trigger(); | |
348 } | |
349 private: | |
350 QString m_statusBarText; | |
351 QUrl m_initialUrl; | |
352 int m_progress; | |
353 WebPage *m_page; | |
354 } |