Mercurial > projects > qtd
comparison demos/browser/webview.d @ 73:7bfd46c330dc
more porting
author | mandel |
---|---|
date | Fri, 22 May 2009 10:59:00 +0000 |
parents | 71b382c10ef6 |
children | 37caa90ce503 |
comparison
equal
deleted
inserted
replaced
72:b149ef2cb18b | 73:7bfd46c330dc |
---|---|
36 ** If you are unsure which license is appropriate for your use, please | 36 ** If you are unsure which license is appropriate for your use, please |
37 ** contact the sales department at qt-sales@nokia.com. | 37 ** contact the sales department at qt-sales@nokia.com. |
38 ** $QT_END_LICENSE$ | 38 ** $QT_END_LICENSE$ |
39 ** | 39 ** |
40 ****************************************************************************/ | 40 ****************************************************************************/ |
41 module webview; | |
42 | |
43 import qt.gui.QClipboard; | |
44 import qt.gui.QMenu; | |
45 import qt.gui.QMessageBox; | |
46 import qt.gui.QMouseEvent; | |
47 | |
48 import qt.core.QDebug; | |
49 import qt.core.QBuffer; | |
41 | 50 |
42 import QtWebKit.QWebView; | 51 import QtWebKit.QWebView; |
52 import QtWebKit.QWebHitTestResult; | |
53 import QtUiTools.QUiLoader; | |
43 | 54 |
44 import browserapplication; | 55 import browserapplication; |
45 import browsermainwindow; | 56 import browsermainwindow; |
46 import cookiejar; | 57 import cookiejar; |
47 import downloadmanager; | 58 import downloadmanager; |
48 import networkaccessmanager; | 59 import networkaccessmanager; |
49 import tabwidget; | 60 import tabwidget; |
50 import webview; | 61 |
51 | 62 |
52 import QtGui.QClipboard; | 63 class WebPage : public QWebPage |
53 import QtGui.QMenu; | 64 { |
54 import QtGui.QMessageBox; | 65 mixin Signal!("loadingUrl", QUrl url); |
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 | 66 |
82 public: | 67 public: |
83 this(QObject *parent = null) | 68 |
69 this(QObject parent = null) | |
70 { | |
71 super(parent); | |
72 m_keyboardModifiers = Qt.NoModifier; | |
73 m_pressedButtons = Qt.NoButton; | |
74 m_openInNewTab = false; | |
75 setNetworkAccessManager(BrowserApplication.networkAccessManager()); | |
76 this.unsupportedContent.connect(&this.handleUnsupportedContent); | |
77 } | |
78 | |
79 BrowserMainWindow mainWindow() | |
80 { | |
81 QObject w = this.parent(); | |
82 while (w) { | |
83 if (BrowserMainWindow mw = qobject_cast<BrowserMainWindow>(w)) | |
84 return mw; | |
85 w = w.parent(); | |
86 } | |
87 return BrowserApplication.instance().mainWindow(); | |
88 } | |
89 | |
90 protected: | |
91 | |
92 bool acceptNavigationRequest(QWebFrame frame, QNetworkRequest request, NavigationType type); | |
93 { | |
94 // ctrl open in new tab | |
95 // ctrl-shift open in new tab and select | |
96 // ctrl-alt open in new window | |
97 if (type == QWebPage.NavigationTypeLinkClicked | |
98 && (m_keyboardModifiers & Qt.ControlModifier | |
99 || m_pressedButtons == Qt.MidButton)) { | |
100 bool newWindow = (m_keyboardModifiers & Qt.AltModifier); | |
101 WebView webView; | |
102 if (newWindow) { | |
103 BrowserApplication.instance().newMainWindow(); | |
104 BrowserMainWindow newMainWindow = BrowserApplication.instance().mainWindow(); | |
105 webView = newMainWindow.currentTab(); | |
106 newMainWindow.raise(); | |
107 newMainWindow.activateWindow(); | |
108 webView.setFocus(); | |
109 } else { | |
110 bool selectNewTab = (m_keyboardModifiers & Qt.ShiftModifier); | |
111 webView = mainWindow().tabWidget().newTab(selectNewTab); | |
112 } | |
113 webView.load(request); | |
114 m_keyboardModifiers = Qt.NoModifier; | |
115 m_pressedButtons = Qt.NoButton; | |
116 return false; | |
117 } | |
118 if (frame == mainFrame()) { | |
119 m_loadingUrl = request.url(); | |
120 emit loadingUrl(m_loadingUrl); | |
121 } | |
122 return QWebPage.acceptNavigationRequest(frame, request, type); | |
123 } | |
124 | |
125 QWebPage createWindow(QWebPage.WebWindowType type) | |
126 { | |
127 //Q_UNUSED(type); | |
128 if (m_keyboardModifiers & Qt.ControlModifier || m_pressedButtons == Qt.MidButton) | |
129 m_openInNewTab = true; | |
130 if (m_openInNewTab) { | |
131 m_openInNewTab = false; | |
132 return mainWindow().tabWidget().newTab().page(); | |
133 } | |
134 BrowserApplication.instance().newMainWindow(); | |
135 BrowserMainWindow mainWindow = BrowserApplication.instance().mainWindow(); | |
136 return mainWindow.currentTab().page(); | |
137 } | |
138 | |
139 version(QT_NO_UITOOLS) {} else | |
140 { | |
141 QObject createPlugin(const QString &classId, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues); | |
142 { | |
143 //Q_UNUSED(url); | |
144 //Q_UNUSED(paramNames); | |
145 //Q_UNUSED(paramValues); | |
146 QUiLoader loader; | |
147 return loader.createWidget(classId, view()); | |
148 } | |
149 } | |
150 | |
151 private: | |
152 | |
153 void handleUnsupportedContent(QNetworkReply reply) | |
154 { | |
155 if (reply.error() == QNetworkReply.NoError) { | |
156 BrowserApplication.downloadManager().handleUnsupportedContent(reply); | |
157 return; | |
158 } | |
159 | |
160 QFile file(QLatin1String(":/notfound.html")); | |
161 bool isOpened = file.open(QIODevice.ReadOnly); | |
162 Q_ASSERT(isOpened); | |
163 QString title = tr("Error loading page: %1").arg(reply.url().toString()); | |
164 QString html = QString(QLatin1String(file.readAll())) | |
165 .arg(title) | |
166 .arg(reply.errorString()) | |
167 .arg(reply.url().toString()); | |
168 | |
169 QBuffer imageBuffer; | |
170 imageBuffer.open(QBuffer.ReadWrite); | |
171 QIcon icon = view().style().standardIcon(QStyle.SP_MessageBoxWarning, 0, view()); | |
172 QPixmap pixmap = icon.pixmap(QSize(32,32)); | |
173 if (pixmap.save(&imageBuffer, "PNG")) { | |
174 html.replace(QLatin1String("IMAGE_BINARY_DATA_HERE"), | |
175 QString(QLatin1String(imageBuffer.buffer().toBase64()))); | |
176 } | |
177 | |
178 QList<QWebFrame*> frames; | |
179 frames.append(mainFrame()); | |
180 while (!frames.isEmpty()) { | |
181 QWebFrame frame = frames.takeFirst(); | |
182 if (frame.url() == reply.url()) { | |
183 frame.setHtml(html, reply.url()); | |
184 return; | |
185 } | |
186 QList<QWebFrame > children = frame.childFrames(); | |
187 foreach(QWebFrame frame, children) | |
188 frames.append(frame); | |
189 } | |
190 if (m_loadingUrl == reply.url()) { | |
191 mainFrame().setHtml(html, reply.url()); | |
192 } | |
193 } | |
194 | |
195 private: | |
196 | |
197 // set the webview mousepressedevent | |
198 Qt.KeyboardModifiers m_keyboardModifiers; | |
199 Qt.MouseButtons m_pressedButtons; | |
200 bool m_openInNewTab; | |
201 QUrl m_loadingUrl; | |
202 }; | |
203 | |
204 class WebView : public QWebView | |
84 { | 205 { |
85 super(parent); | 206 public: |
86 m_keyboardModifiers = Qt.NoModifier; | 207 |
87 m_pressedButtons = Qt.NoButton; | 208 WebView(QWidget parent = null) |
88 m_openInNewTab = false; | 209 { |
89 setNetworkAccessManager(BrowserApplication::networkAccessManager()); | 210 super(parent); |
90 connect(this, SIGNAL(unsupportedContent(QNetworkReply *)), | 211 m_progress = 0; |
91 this, SLOT(handleUnsupportedContent(QNetworkReply *))); | 212 m_page = new WebPage(this); |
213 setPage(m_page); | |
214 page().statusBarMessage.connect(&setStatusBarText); | |
215 this.loadProgress.connect(&this.setProgress); | |
216 this.loadFinished.connect(&this.loadFinished); | |
217 page().loadingUrl.connect(&this.urlChanged); | |
218 page().downloadRequested.connect(&this.downloadRequested); | |
219 page().setForwardUnsupportedContent(true); | |
220 } | |
221 | |
222 WebPage webPage() { return m_page; } | |
223 | |
224 void loadUrl(QUrl url) | |
225 { | |
226 m_initialUrl = url; | |
227 load(url); | |
228 } | |
229 | |
230 QUrl url() const | |
231 { | |
232 QUrl url = QWebView.url(); | |
233 if (!url.isEmpty()) | |
234 return url; | |
235 return m_initialUrl; | |
236 } | |
237 | |
238 QString lastStatusBarText() | |
239 { | |
240 return m_statusBarText; | |
241 } | |
242 | |
243 int progress() const { return m_progress; } | |
244 | |
245 protected: | |
246 | |
247 void mousePressEvent(QMouseEvent event); | |
248 { | |
249 m_page.m_pressedButtons = event.buttons(); | |
250 m_page.m_keyboardModifiers = event.modifiers(); | |
251 QWebView.mousePressEvent(event); | |
252 } | |
253 | |
254 void mouseReleaseEvent(QMouseEvent event) | |
255 { | |
256 QWebView.mouseReleaseEvent(event); | |
257 if (!event.isAccepted() && (m_page.m_pressedButtons & Qt.MidButton)) { | |
258 QUrl url(QApplication.clipboard().text(QClipboard.Selection)); | |
259 if (!url.isEmpty() && url.isValid() && !url.scheme().isEmpty()) { | |
260 setUrl(url); | |
261 } | |
262 } | |
263 } | |
264 | |
265 void contextMenuEvent(QContextMenuEvent event) | |
266 { | |
267 QWebHitTestResult r = page().mainFrame().hitTestContent(event.pos()); | |
268 if (!r.linkUrl().isEmpty()) { | |
269 QMenu menu(this); | |
270 menu.addAction(pageAction(QWebPage.OpenLinkInNewWindow)); | |
271 menu.addAction(tr("Open in New Tab"), this, SLOT(openLinkInNewTab())); | |
272 menu.addSeparator(); | |
273 menu.addAction(pageAction(QWebPage.DownloadLinkToDisk)); | |
274 // Add link to bookmarks... | |
275 menu.addSeparator(); | |
276 menu.addAction(pageAction(QWebPage.CopyLinkToClipboard)); | |
277 if (page().settings().testAttribute(QWebSettings.DeveloperExtrasEnabled)) | |
278 menu.addAction(pageAction(QWebPage.InspectElement)); | |
279 menu.exec(mapToGlobal(event.pos())); | |
280 return; | |
281 } | |
282 QWebView.contextMenuEvent(event); | |
283 } | |
284 | |
285 void wheelEvent(QWheelEvent event) | |
286 { | |
287 if (QApplication.keyboardModifiers() & Qt.ControlModifier) { | |
288 int numDegrees = event.delta() / 8; | |
289 int numSteps = numDegrees / 15; | |
290 setTextSizeMultiplier(textSizeMultiplier() + numSteps * 0.1); | |
291 event.accept(); | |
292 return; | |
293 } | |
294 QWebView.wheelEvent(event); | |
295 } | |
296 | |
297 | |
298 private: | |
299 | |
300 void setProgress(int progress) | |
301 { | |
302 m_progress = progress; | |
303 } | |
304 | |
305 void loadFinished() | |
306 { | |
307 if (100 != m_progress) { | |
308 qWarning() << "Received finished signal while progress is still:" << progress() << "Url:" << url(); | |
309 } | |
310 m_progress = 0; | |
311 } | |
312 | |
313 void setStatusBarText(QString string) | |
314 { | |
315 m_statusBarText = string; | |
316 } | |
317 | |
318 void downloadRequested(QNetworkRequest request) | |
319 { | |
320 BrowserApplication.downloadManager().download(request); | |
321 } | |
322 | |
323 void openLinkInNewTab() | |
324 { | |
325 m_page.m_openInNewTab = true; | |
326 pageAction(QWebPage.OpenLinkInNewWindow).trigger(); | |
327 } | |
328 | |
329 private: | |
330 | |
331 QString m_statusBarText; | |
332 QUrl m_initialUrl; | |
333 int m_progress; | |
334 WebPage m_page; | |
92 } | 335 } |
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 } |