webview.cpp
上传用户:huahtool
上传日期:2015-12-10
资源大小:1089k
文件大小:10k
源码类别:

浏览器

开发平台:

Visual C++

  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2008 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. ** Commercial Usage
  9. ** Licensees holding valid Qt Commercial licenses may use this file in
  10. ** accordance with the Qt Commercial License Agreement provided with the
  11. ** Software or, alternatively, in accordance with the terms contained in
  12. ** a written agreement between you and Nokia.
  13. **
  14. **
  15. ** GNU General Public License Usage
  16. ** Alternatively, this file may be used under the terms of the GNU
  17. ** General Public License versions 2.0 or 3.0 as published by the Free
  18. ** Software Foundation and appearing in the file LICENSE.GPL included in
  19. ** the packaging of this file.  Please review the following information
  20. ** to ensure GNU General Public Licensing requirements will be met:
  21. ** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
  22. ** http://www.gnu.org/copyleft/gpl.html.  In addition, as a special
  23. ** exception, Nokia gives you certain additional rights. These rights
  24. ** are described in the Nokia Qt GPL Exception version 1.3, included in
  25. ** the file GPL_EXCEPTION.txt in this package.
  26. **
  27. ** Qt for Windows(R) Licensees
  28. ** As a special exception, Nokia, as the sole copyright holder for Qt
  29. ** Designer, grants users of the Qt/Eclipse Integration plug-in the
  30. ** right for the Qt/Eclipse Integration to link to functionality
  31. ** provided by Qt Designer and its related libraries.
  32. **
  33. ** If you are unsure which license is appropriate for your use, please
  34. ** contact the sales department at qt-sales@nokia.com.
  35. **
  36. ****************************************************************************/
  37. #include "browserapplication.h"
  38. #include "browsermainwindow.h"
  39. #include "cookiejar.h"
  40. #include "downloadmanager.h"
  41. #include "networkaccessmanager.h"
  42. #include "tabwidget.h"
  43. #include "webview.h"
  44. #include <QtGui/QClipboard>
  45. #include <QtGui/QMenu>
  46. #include <QtGui/QMessageBox>
  47. #include <QtGui/QMouseEvent>
  48. #include <QtWebKit/QWebHitTestResult>
  49. #include <QtUiTools/QUiLoader>
  50. #include <QtCore/QDebug>
  51. #include <QtCore/QBuffer>
  52. WebPage::WebPage(QObject *parent)
  53.     : QWebPage(parent)
  54.     , m_keyboardModifiers(Qt::NoModifier)
  55.     , m_pressedButtons(Qt::NoButton)
  56.     , m_openInNewTab(false)
  57. {
  58.     setNetworkAccessManager(BrowserApplication::networkAccessManager());
  59.     connect(this, SIGNAL(unsupportedContent(QNetworkReply *)),
  60.             this, SLOT(handleUnsupportedContent(QNetworkReply *)));
  61. }
  62. BrowserMainWindow *WebPage::mainWindow()
  63. {
  64.     QObject *w = this->parent();
  65.     while (w) {
  66.         if (BrowserMainWindow *mw = qobject_cast<BrowserMainWindow*>(w))
  67.             return mw;
  68.         w = w->parent();
  69.     }
  70.     return BrowserApplication::instance()->mainWindow();
  71. }
  72. bool WebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type)
  73. {
  74.     // ctrl open in new tab
  75.     // ctrl-shift open in new tab and select
  76.     // ctrl-alt open in new window
  77.     if (type == QWebPage::NavigationTypeLinkClicked
  78.         && (m_keyboardModifiers & Qt::ControlModifier
  79.             || m_pressedButtons == Qt::MidButton)) {
  80.         bool newWindow = (m_keyboardModifiers & Qt::AltModifier);
  81.         WebView *webView;
  82.         if (newWindow) {
  83.             BrowserApplication::instance()->newMainWindow();
  84.             BrowserMainWindow *newMainWindow = BrowserApplication::instance()->mainWindow();
  85.             webView = newMainWindow->currentTab();
  86.             newMainWindow->raise();
  87.             newMainWindow->activateWindow();
  88.             webView->setFocus();
  89.         } else {
  90.             bool selectNewTab = (m_keyboardModifiers & Qt::ShiftModifier);
  91.             webView = mainWindow()->tabWidget()->newTab(selectNewTab);
  92.         }
  93.         webView->load(request);
  94.         m_keyboardModifiers = Qt::NoModifier;
  95.         m_pressedButtons = Qt::NoButton;
  96.         return false;
  97.     }
  98.     if (frame == mainFrame()) {
  99.         m_loadingUrl = request.url();
  100.         emit loadingUrl(m_loadingUrl);
  101.     }
  102.     return QWebPage::acceptNavigationRequest(frame, request, type);
  103. }
  104. QWebPage *WebPage::createWindow(QWebPage::WebWindowType type)
  105. {
  106.     Q_UNUSED(type);
  107.     if (m_keyboardModifiers & Qt::ControlModifier || m_pressedButtons == Qt::MidButton)
  108.         m_openInNewTab = true;
  109.     if (m_openInNewTab) {
  110.         m_openInNewTab = false;
  111.         return mainWindow()->tabWidget()->newTab()->page();
  112.     }
  113.     BrowserApplication::instance()->newMainWindow();
  114.     BrowserMainWindow *mainWindow = BrowserApplication::instance()->mainWindow();
  115.     return mainWindow->currentTab()->page();
  116. }
  117. #if !defined(QT_NO_UITOOLS)
  118. QObject *WebPage::createPlugin(const QString &classId, const QUrl &url, const QStringList &paramNames, const QStringList &paramValues)
  119. {
  120.     Q_UNUSED(url);
  121.     Q_UNUSED(paramNames);
  122.     Q_UNUSED(paramValues);
  123.     QUiLoader loader;
  124.     return loader.createWidget(classId, view());
  125. }
  126. #endif // !defined(QT_NO_UITOOLS)
  127. void WebPage::handleUnsupportedContent(QNetworkReply *reply)
  128. {
  129.     if (reply->error() == QNetworkReply::NoError) {
  130.         BrowserApplication::downloadManager()->handleUnsupportedContent(reply);
  131.         return;
  132.     }
  133.     QFile file(QLatin1String(":/notfound.html"));
  134.     bool isOpened = file.open(QIODevice::ReadOnly);
  135.     Q_ASSERT(isOpened);
  136.     QString title = tr("Error loading page: %1").arg(reply->url().toString());
  137.     QString html = QString(QLatin1String(file.readAll()))
  138.                         .arg(title)
  139.                         .arg(reply->errorString())
  140.                         .arg(reply->url().toString());
  141.     QBuffer imageBuffer;
  142.     imageBuffer.open(QBuffer::ReadWrite);
  143.     QIcon icon = view()->style()->standardIcon(QStyle::SP_MessageBoxWarning, 0, view());
  144.     QPixmap pixmap = icon.pixmap(QSize(32,32));
  145.     if (pixmap.save(&imageBuffer, "PNG")) {
  146.         html.replace(QLatin1String("IMAGE_BINARY_DATA_HERE"),
  147.                      QString(QLatin1String(imageBuffer.buffer().toBase64())));
  148.     }
  149.     QList<QWebFrame*> frames;
  150.     frames.append(mainFrame());
  151.     while (!frames.isEmpty()) {
  152.         QWebFrame *frame = frames.takeFirst();
  153.         if (frame->url() == reply->url()) {
  154.             frame->setHtml(html, reply->url());
  155.             return;
  156.         }
  157.         QList<QWebFrame *> children = frame->childFrames();
  158.         foreach(QWebFrame *frame, children)
  159.             frames.append(frame);
  160.     }
  161.     if (m_loadingUrl == reply->url()) {
  162.         mainFrame()->setHtml(html, reply->url());
  163.     }
  164. }
  165. WebView::WebView(QWidget* parent)
  166.     : QWebView(parent)
  167.     , m_progress(0)
  168.     , m_page(new WebPage(this))
  169. {
  170.     setPage(m_page);
  171.     connect(page(), SIGNAL(statusBarMessage(const QString&)),
  172.             SLOT(setStatusBarText(const QString&)));
  173.     connect(this, SIGNAL(loadProgress(int)),
  174.             this, SLOT(setProgress(int)));
  175.     connect(this, SIGNAL(loadFinished(bool)),
  176.             this, SLOT(loadFinished()));
  177.     connect(page(), SIGNAL(loadingUrl(const QUrl&)),
  178.             this, SIGNAL(urlChanged(const QUrl &)));
  179.     connect(page(), SIGNAL(downloadRequested(const QNetworkRequest &)),
  180.             this, SLOT(downloadRequested(const QNetworkRequest &)));
  181.     page()->setForwardUnsupportedContent(true);
  182. }
  183. void WebView::contextMenuEvent(QContextMenuEvent *event)
  184. {
  185.     QWebHitTestResult r = page()->mainFrame()->hitTestContent(event->pos());
  186.     if (!r.linkUrl().isEmpty()) {
  187.         QMenu menu(this);
  188.         menu.addAction(pageAction(QWebPage::OpenLinkInNewWindow));
  189.         menu.addAction(tr("Open in New Tab"), this, SLOT(openLinkInNewTab()));
  190.         menu.addSeparator();
  191.         menu.addAction(pageAction(QWebPage::DownloadLinkToDisk));
  192.         // Add link to bookmarks...
  193.         menu.addSeparator();
  194.         menu.addAction(pageAction(QWebPage::CopyLinkToClipboard));
  195.         if (page()->settings()->testAttribute(QWebSettings::DeveloperExtrasEnabled))
  196.             menu.addAction(pageAction(QWebPage::InspectElement));
  197.         menu.exec(mapToGlobal(event->pos()));
  198.         return;
  199.     }
  200.     QWebView::contextMenuEvent(event);
  201. }
  202. void WebView::wheelEvent(QWheelEvent *event)
  203. {
  204.     if (QApplication::keyboardModifiers() & Qt::ControlModifier) {
  205.         int numDegrees = event->delta() / 8;
  206.         int numSteps = numDegrees / 15;
  207.         setTextSizeMultiplier(textSizeMultiplier() + numSteps * 0.1);
  208.         event->accept();
  209.         return;
  210.     }
  211.     QWebView::wheelEvent(event);
  212. }
  213. void WebView::openLinkInNewTab()
  214. {
  215.     m_page->m_openInNewTab = true;
  216.     pageAction(QWebPage::OpenLinkInNewWindow)->trigger();
  217. }
  218. void WebView::setProgress(int progress)
  219. {
  220.     m_progress = progress;
  221. }
  222. void WebView::loadFinished()
  223. {
  224.     if (100 != m_progress) {
  225.         qWarning() << "Recieved finished signal while progress is still:" << progress()
  226.                    << "Url:" << url();
  227.     }
  228.     m_progress = 0;
  229. }
  230. void WebView::loadUrl(const QUrl &url)
  231. {
  232.     m_initialUrl = url;
  233.     load(url);
  234. }
  235. QString WebView::lastStatusBarText() const
  236. {
  237.     return m_statusBarText;
  238. }
  239. QUrl WebView::url() const
  240. {
  241.     QUrl url = QWebView::url();
  242.     if (!url.isEmpty())
  243.         return url;
  244.     return m_initialUrl;
  245. }
  246. void WebView::mousePressEvent(QMouseEvent *event)
  247. {
  248.     m_page->m_pressedButtons = event->buttons();
  249.     m_page->m_keyboardModifiers = event->modifiers();
  250.     QWebView::mousePressEvent(event);
  251. }
  252. void WebView::mouseReleaseEvent(QMouseEvent *event)
  253. {
  254.     QWebView::mouseReleaseEvent(event);
  255.     if (!event->isAccepted() && (m_page->m_pressedButtons & Qt::MidButton)) {
  256.         QUrl url(QApplication::clipboard()->text(QClipboard::Selection));
  257.         if (!url.isEmpty() && url.isValid() && !url.scheme().isEmpty()) {
  258.             setUrl(url);
  259.         }
  260.     }
  261. }
  262. void WebView::setStatusBarText(const QString &string)
  263. {
  264.     m_statusBarText = string;
  265. }
  266. void WebView::downloadRequested(const QNetworkRequest &request)
  267. {
  268.     BrowserApplication::downloadManager()->download(request);
  269. }