PageRenderTime 47ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/src/webpage.cpp

https://github.com/vipw/arora
C++ | 205 lines | 161 code | 20 blank | 24 comment | 34 complexity | 46bd312c91d19cdf6b0c8a3c88f06437 MD5 | raw file
  1. /*
  2. * Copyright 2009 Benjamin C. Meyer <ben@meyerhome.net>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor,
  17. * Boston, MA 02110-1301 USA
  18. */
  19. #include "webpage.h"
  20. #include "browserapplication.h"
  21. #include "downloadmanager.h"
  22. #include "historymanager.h"
  23. #include "networkaccessmanager.h"
  24. #include "tabwidget.h"
  25. #include "webpluginfactory.h"
  26. #include "webview.h"
  27. #include <qbuffer.h>
  28. #include <qdesktopservices.h>
  29. #include <qnetworkreply.h>
  30. #include <qnetworkrequest.h>
  31. #include <qsettings.h>
  32. #include <qwebframe.h>
  33. WebPluginFactory *WebPage::s_webPluginFactory = 0;
  34. WebPage::WebPage(QObject *parent)
  35. : QWebPage(parent)
  36. , m_openTargetBlankLinksIn(TabWidget::NewWindow)
  37. {
  38. setPluginFactory(webPluginFactory());
  39. setNetworkAccessManager(BrowserApplication::networkAccessManager());
  40. connect(this, SIGNAL(unsupportedContent(QNetworkReply *)),
  41. this, SLOT(handleUnsupportedContent(QNetworkReply *)));
  42. loadSettings();
  43. }
  44. WebPluginFactory *WebPage::webPluginFactory()
  45. {
  46. if (!s_webPluginFactory)
  47. s_webPluginFactory = new WebPluginFactory(BrowserApplication::instance());
  48. return s_webPluginFactory;
  49. }
  50. bool WebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request,
  51. NavigationType type)
  52. {
  53. QString scheme = request.url().scheme();
  54. if (scheme == QLatin1String("mailto")
  55. || scheme == QLatin1String("ftp")) {
  56. QDesktopServices::openUrl(request.url());
  57. return false;
  58. }
  59. TabWidget::OpenUrlIn openIn = frame ? TabWidget::CurrentTab : TabWidget::NewWindow;
  60. // If the user just clicked on the back or forward button on the toolbar
  61. if (type == QWebPage::NavigationTypeBackOrForward) {
  62. BrowserApplication::instance()->setEventMouseButtons(qApp->mouseButtons());
  63. BrowserApplication::instance()->setEventKeyboardModifiers(qApp->keyboardModifiers());
  64. }
  65. openIn = TabWidget::modifyWithUserBehavior(openIn);
  66. // handle the case where we want to do something different then
  67. // what qwebpage would do
  68. if (openIn == TabWidget::NewSelectedTab
  69. || openIn == TabWidget::NewNotSelectedTab
  70. || (frame && openIn == TabWidget::NewWindow)) {
  71. if (WebView *webView = qobject_cast<WebView*>(view())) {
  72. TabWidget *tabWidget = webView->tabWidget();
  73. if (tabWidget) {
  74. WebView *newView = tabWidget->getView(openIn, webView);
  75. QWebPage *page = 0;
  76. if (newView)
  77. page = newView->page();
  78. if (page && page->mainFrame())
  79. page->mainFrame()->load(request);
  80. }
  81. }
  82. return false;
  83. }
  84. bool accepted = QWebPage::acceptNavigationRequest(frame, request, type);
  85. if (accepted && frame == mainFrame())
  86. emit aboutToLoadUrl(request.url());
  87. return accepted;
  88. }
  89. void WebPage::loadSettings()
  90. {
  91. QSettings settings;
  92. settings.beginGroup(QLatin1String("tabs"));
  93. m_openTargetBlankLinksIn = (TabWidget::OpenUrlIn)settings.value(QLatin1String("openTargetBlankLinksIn"),
  94. TabWidget::NewWindow).toInt();
  95. }
  96. QWebPage *WebPage::createWindow(QWebPage::WebWindowType type)
  97. {
  98. Q_UNUSED(type);
  99. if (WebView *webView = qobject_cast<WebView*>(view())) {
  100. TabWidget *tabWidget = webView->tabWidget();
  101. if (tabWidget) {
  102. TabWidget::OpenUrlIn openIn = m_openTargetBlankLinksIn;
  103. openIn = TabWidget::modifyWithUserBehavior(openIn);
  104. return tabWidget->getView(openIn, webView)->page();
  105. }
  106. }
  107. return 0;
  108. }
  109. QObject *WebPage::createPlugin(const QString &classId, const QUrl &url,
  110. const QStringList &paramNames, const QStringList &paramValues)
  111. {
  112. Q_UNUSED(classId);
  113. Q_UNUSED(url);
  114. Q_UNUSED(paramNames);
  115. Q_UNUSED(paramValues);
  116. #if !defined(QT_NO_UITOOLS)
  117. QUiLoader loader;
  118. return loader.createWidget(classId, view());
  119. #else
  120. return 0;
  121. #endif
  122. }
  123. void WebPage::handleUnsupportedContent(QNetworkReply *reply)
  124. {
  125. if (!reply)
  126. return;
  127. QUrl replyUrl = reply->url();
  128. switch (reply->error()) {
  129. case QNetworkReply::NoError:
  130. if (reply->header(QNetworkRequest::ContentTypeHeader).isValid()) {
  131. BrowserApplication::downloadManager()->handleUnsupportedContent(reply);
  132. return;
  133. }
  134. break;
  135. case QNetworkReply::ProtocolUnknownError: {
  136. QSettings settings;
  137. settings.beginGroup(QLatin1String("WebView"));
  138. QStringList externalSchemes = settings.value(QLatin1String("externalSchemes")).toStringList();
  139. if (externalSchemes.contains(replyUrl.scheme())) {
  140. QDesktopServices::openUrl(replyUrl);
  141. return;
  142. }
  143. break;
  144. }
  145. default:
  146. break;
  147. }
  148. // Find the frame that has the unsupported content
  149. QWebFrame *notFoundFrame = 0;
  150. QList<QWebFrame*> frames;
  151. frames.append(mainFrame());
  152. while (!frames.isEmpty()) {
  153. QWebFrame *frame = frames.takeFirst();
  154. if (replyUrl == frame->url()) {
  155. notFoundFrame = frame;
  156. break;
  157. }
  158. frames.append(frame->childFrames());
  159. }
  160. if (!notFoundFrame)
  161. return;
  162. // Generate translated not found error page with an image
  163. QFile notFoundErrorFile(QLatin1String(":/notfound.html"));
  164. if (!notFoundErrorFile.open(QIODevice::ReadOnly))
  165. return;
  166. QString title = tr("Error loading page: %1").arg(QString::fromUtf8(replyUrl.toEncoded()));
  167. QString html = QLatin1String(notFoundErrorFile.readAll());
  168. QPixmap pixmap = qApp->style()->standardIcon(QStyle::SP_MessageBoxWarning, 0, view()).pixmap(QSize(32, 32));
  169. QBuffer imageBuffer;
  170. imageBuffer.open(QBuffer::ReadWrite);
  171. if (pixmap.save(&imageBuffer, "PNG")) {
  172. html.replace(QLatin1String("IMAGE_BINARY_DATA_HERE"),
  173. QLatin1String(imageBuffer.buffer().toBase64()));
  174. }
  175. html = QString(html)
  176. .arg(title)
  177. .arg(reply->errorString())
  178. .arg(tr("When connecting to: %1.").arg(QString::fromUtf8(replyUrl.toEncoded())))
  179. .arg(tr("Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org"))
  180. .arg(tr("If the address is correct, try checking the network connection."))
  181. .arg(tr("If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network."));
  182. notFoundFrame->setHtml(html, replyUrl);
  183. // Don't put error pages to the history.
  184. BrowserApplication::instance()->historyManager()->removeHistoryEntry(replyUrl, notFoundFrame->title());
  185. }