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