Mercurial > projects > qtd
view demos/browser/webview.d @ 46:fd6eb3a1759d
license
author | eldar |
---|---|
date | Sun, 17 May 2009 21:50:06 +0000 |
parents | 71b382c10ef6 |
children | 7bfd46c330dc |
line wrap: on
line source
/**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** ** This file is part of the demonstration applications of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial Usage ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Commercial License Agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain ** additional rights. These rights are described in the Nokia Qt LGPL ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this ** package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ import QtWebKit.QWebView; import browserapplication; import browsermainwindow; import cookiejar; import downloadmanager; import networkaccessmanager; import tabwidget; import webview; import QtGui.QClipboard; import QtGui.QMenu; import QtGui.QMessageBox; import QtGui.QMouseEvent; import QtWebKit.QWebHitTestResult; import QtUiTools.QUiLoader; import QtCore.QDebug; import QtCore.QBuffer; /* QT_BEGIN_NAMESPACE class QAuthenticator; class QMouseEvent; class QNetworkProxy; class QNetworkReply; class QSslError; QT_END_NAMESPACE class BrowserMainWindow; */ class WebPage : public QWebPage { Q_OBJECT signals: void loadingUrl(const QUrl &url); public: this(QObject *parent = null) { super(parent); m_keyboardModifiers = Qt.NoModifier; m_pressedButtons = Qt.NoButton; m_openInNewTab = false; setNetworkAccessManager(BrowserApplication::networkAccessManager()); connect(this, SIGNAL(unsupportedContent(QNetworkReply *)), this, SLOT(handleUnsupportedContent(QNetworkReply *))); } BrowserMainWindow *mainWindow() { QObject *w = this.parent(); while (w) { if (BrowserMainWindow *mw = qobject_cast<BrowserMainWindow*>(w)) return mw; w = w.parent(); } return BrowserApplication::instance().mainWindow(); } protected: bool acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type); { // ctrl open in new tab // ctrl-shift open in new tab and select // ctrl-alt open in new window if (type == QWebPage::NavigationTypeLinkClicked && (m_keyboardModifiers & Qt.ControlModifier || m_pressedButtons == Qt.MidButton)) { bool newWindow = (m_keyboardModifiers & Qt.AltModifier); WebView *webView; if (newWindow) { BrowserApplication::instance().newMainWindow(); BrowserMainWindow *newMainWindow = BrowserApplication::instance().mainWindow(); webView = newMainWindow.currentTab(); newMainWindow.raise(); newMainWindow.activateWindow(); webView.setFocus(); } else { bool selectNewTab = (m_keyboardModifiers & Qt.ShiftModifier); webView = mainWindow().tabWidget().newTab(selectNewTab); } webView.load(request); m_keyboardModifiers = Qt.NoModifier; m_pressedButtons = Qt.NoButton; return false; } if (frame == mainFrame()) { m_loadingUrl = request.url(); emit loadingUrl(m_loadingUrl); } return QWebPage::acceptNavigationRequest(frame, request, type); } QWebPage *createWindow(QWebPage::WebWindowType type) { Q_UNUSED(type); if (m_keyboardModifiers & Qt.ControlModifier || m_pressedButtons == Qt.MidButton) m_openInNewTab = true; if (m_openInNewTab) { m_openInNewTab = false; return mainWindow().tabWidget().newTab().page(); } BrowserApplication::instance().newMainWindow(); BrowserMainWindow *mainWindow = BrowserApplication::instance().mainWindow(); return mainWindow.currentTab().page(); } version(QT_NO_UITOOLS) {} else { QObject *createPlugin(const QString &classId, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues); { Q_UNUSED(url); Q_UNUSED(paramNames); Q_UNUSED(paramValues); QUiLoader loader; return loader.createWidget(classId, view()); } } private slots: void handleUnsupportedContent(QNetworkReply *reply) { if (reply.error() == QNetworkReply::NoError) { BrowserApplication::downloadManager().handleUnsupportedContent(reply); return; } QFile file(QLatin1String(":/notfound.html")); bool isOpened = file.open(QIODevice::ReadOnly); Q_ASSERT(isOpened); QString title = tr("Error loading page: %1").arg(reply.url().toString()); QString html = QString(QLatin1String(file.readAll())) .arg(title) .arg(reply.errorString()) .arg(reply.url().toString()); QBuffer imageBuffer; imageBuffer.open(QBuffer::ReadWrite); QIcon icon = view().style().standardIcon(QStyle::SP_MessageBoxWarning, 0, view()); QPixmap pixmap = icon.pixmap(QSize(32,32)); if (pixmap.save(&imageBuffer, "PNG")) { html.replace(QLatin1String("IMAGE_BINARY_DATA_HERE"), QString(QLatin1String(imageBuffer.buffer().toBase64()))); } QList<QWebFrame*> frames; frames.append(mainFrame()); while (!frames.isEmpty()) { QWebFrame *frame = frames.takeFirst(); if (frame.url() == reply.url()) { frame.setHtml(html, reply.url()); return; } QList<QWebFrame *> children = frame.childFrames(); foreach(QWebFrame *frame, children) frames.append(frame); } if (m_loadingUrl == reply.url()) { mainFrame().setHtml(html, reply.url()); } } private: friend class WebView; // set the webview mousepressedevent Qt.KeyboardModifiers m_keyboardModifiers; Qt.MouseButtons m_pressedButtons; bool m_openInNewTab; QUrl m_loadingUrl; }; class WebView : public QWebView { Q_OBJECT public: WebView(QWidget *parent = null) : QWebView(parent) , m_progress(0) , m_page(new WebPage(this)) { setPage(m_page); connect(page(), SIGNAL(statusBarMessage(const QString&)), SLOT(setStatusBarText(const QString&))); connect(this, SIGNAL(loadProgress(int)), this, SLOT(setProgress(int))); connect(this, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished())); connect(page(), SIGNAL(loadingUrl(const QUrl&)), this, SIGNAL(urlChanged(const QUrl &))); connect(page(), SIGNAL(downloadRequested(const QNetworkRequest &)), this, SLOT(downloadRequested(const QNetworkRequest &))); page().setForwardUnsupportedContent(true); } WebPage *webPage() const { return m_page; } void loadUrl(const QUrl &url) { m_initialUrl = url; load(url); } QUrl url() const { QUrl url = QWebView::url(); if (!url.isEmpty()) return url; return m_initialUrl; } QString lastStatusBarText() const { return m_statusBarText; } inline int progress() const { return m_progress; } protected: void mousePressEvent(QMouseEvent *event); { m_page.m_pressedButtons = event.buttons(); m_page.m_keyboardModifiers = event.modifiers(); QWebView::mousePressEvent(event); } void mouseReleaseEvent(QMouseEvent *event) { QWebView::mouseReleaseEvent(event); if (!event.isAccepted() && (m_page.m_pressedButtons & Qt.MidButton)) { QUrl url(QApplication::clipboard().text(QClipboard::Selection)); if (!url.isEmpty() && url.isValid() && !url.scheme().isEmpty()) { setUrl(url); } } } void contextMenuEvent(QContextMenuEvent *event) { QWebHitTestResult r = page().mainFrame().hitTestContent(event.pos()); if (!r.linkUrl().isEmpty()) { QMenu menu(this); menu.addAction(pageAction(QWebPage::OpenLinkInNewWindow)); menu.addAction(tr("Open in New Tab"), this, SLOT(openLinkInNewTab())); menu.addSeparator(); menu.addAction(pageAction(QWebPage::DownloadLinkToDisk)); // Add link to bookmarks... menu.addSeparator(); menu.addAction(pageAction(QWebPage::CopyLinkToClipboard)); if (page().settings().testAttribute(QWebSettings::DeveloperExtrasEnabled)) menu.addAction(pageAction(QWebPage::InspectElement)); menu.exec(mapToGlobal(event.pos())); return; } QWebView::contextMenuEvent(event); } void wheelEvent(QWheelEvent *event) { if (QApplication::keyboardModifiers() & Qt.ControlModifier) { int numDegrees = event.delta() / 8; int numSteps = numDegrees / 15; setTextSizeMultiplier(textSizeMultiplier() + numSteps * 0.1); event.accept(); return; } QWebView::wheelEvent(event); } private slots: void setProgress(int progress) { m_progress = progress; } void loadFinished() { if (100 != m_progress) { qWarning() << "Recieved finished signal while progress is still:" << progress() << "Url:" << url(); } m_progress = 0; } void setStatusBarText(const QString &string) { m_statusBarText = string; } void downloadRequested(const QNetworkRequest &request) { BrowserApplication::downloadManager().download(request); } void openLinkInNewTab() { m_page.m_openInNewTab = true; pageAction(QWebPage::OpenLinkInNewWindow).trigger(); } private: QString m_statusBarText; QUrl m_initialUrl; int m_progress; WebPage *m_page; }