Mercurial > projects > qtd
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/demos/browser/webview.d Sun May 17 18:49:59 2009 +0000 @@ -0,0 +1,354 @@ +/**************************************************************************** +** +** 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; +}