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 &paramNames, const QStringList &paramValues);
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 &paramNames, const QStringList &paramValues);
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 }