Home | History | Annotate | Download | only in Api
      1 /*
      2     Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
      3     Copyright (C) 2009 Girish Ramakrishnan <girish (at) forwardbias.in>
      4 
      5     This library is free software; you can redistribute it and/or
      6     modify it under the terms of the GNU Library General Public
      7     License as published by the Free Software Foundation; either
      8     version 2 of the License, or (at your option) any later version.
      9 
     10     This library is distributed in the hope that it will be useful,
     11     but WITHOUT ANY WARRANTY; without even the implied warranty of
     12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13     Library General Public License for more details.
     14 
     15     You should have received a copy of the GNU Library General Public License
     16     along with this library; see the file COPYING.LIB.  If not, write to
     17     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     18     Boston, MA 02110-1301, USA.
     19 */
     20 
     21 #include "config.h"
     22 #include "qgraphicswebview.h"
     23 
     24 #if !defined(QT_NO_GRAPHICSVIEW)
     25 
     26 #include "qwebframe.h"
     27 #include "qwebframe_p.h"
     28 #include "qwebpage.h"
     29 #include "qwebpage_p.h"
     30 #include "PageClientQt.h"
     31 #include "FrameView.h"
     32 #include "GraphicsContext.h"
     33 #include "IntRect.h"
     34 #include "TiledBackingStore.h"
     35 #include <QtCore/qmetaobject.h>
     36 #include <QtCore/qsharedpointer.h>
     37 #include <QtCore/qtimer.h>
     38 #include <QtGui/qapplication.h>
     39 #include <QtGui/qgraphicsscene.h>
     40 #include <QtGui/qgraphicssceneevent.h>
     41 #include <QtGui/qgraphicsview.h>
     42 #include <QtGui/qpixmapcache.h>
     43 #include <QtGui/qscrollbar.h>
     44 #include <QtGui/qstyleoption.h>
     45 #include <QtGui/qinputcontext.h>
     46 #if defined(Q_WS_X11)
     47 #include <QX11Info>
     48 #endif
     49 #include <Settings.h>
     50 
     51 using namespace WebCore;
     52 
     53 class QGraphicsWebViewPrivate {
     54 public:
     55     QGraphicsWebViewPrivate(QGraphicsWebView* parent)
     56         : q(parent)
     57         , page(0)
     58         , resizesToContents(false)
     59         , renderHints(QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform) {}
     60 
     61     virtual ~QGraphicsWebViewPrivate();
     62 
     63     void syncLayers();
     64 
     65     void updateResizesToContentsForPage();
     66 
     67     void detachCurrentPage();
     68 
     69     void _q_doLoadFinished(bool success);
     70     void _q_contentsSizeChanged(const QSize&);
     71     void _q_scaleChanged();
     72 
     73     void _q_pageDestroyed();
     74 
     75     QGraphicsWebView* q;
     76     QWebPage* page;
     77     bool resizesToContents;
     78     QPainter::RenderHints renderHints;
     79 
     80     QGraphicsItemOverlay* overlay() const
     81     {
     82         if (!page || !page->d->client)
     83             return 0;
     84         return pageClient()->overlay;
     85     }
     86 
     87     PageClientQGraphicsWidget* pageClient() const
     88     {
     89         return static_cast<WebCore::PageClientQGraphicsWidget*> (page->d->client.get());
     90     }
     91 };
     92 
     93 QGraphicsWebViewPrivate::~QGraphicsWebViewPrivate()
     94 {
     95     detachCurrentPage();
     96 }
     97 
     98 void QGraphicsWebViewPrivate::syncLayers()
     99 {
    100 #if USE(ACCELERATED_COMPOSITING)
    101     pageClient()->syncLayers();
    102 #endif
    103 }
    104 
    105 void QGraphicsWebViewPrivate::_q_doLoadFinished(bool success)
    106 {
    107     // If the page had no title, still make sure it gets the signal
    108     if (q->title().isEmpty())
    109         emit q->urlChanged(q->url());
    110 
    111     emit q->loadFinished(success);
    112 }
    113 
    114 void QGraphicsWebViewPrivate::_q_pageDestroyed()
    115 {
    116     page = 0;
    117     q->setPage(0);
    118 }
    119 
    120 void QGraphicsWebViewPrivate::updateResizesToContentsForPage()
    121 {
    122     ASSERT(page);
    123     pageClient()->viewResizesToContents = resizesToContents;
    124     if (resizesToContents) {
    125         // resizes to contents mode requires preferred contents size to be set
    126         if (!page->preferredContentsSize().isValid())
    127             page->setPreferredContentsSize(QSize(960, 800));
    128 
    129         QObject::connect(page->mainFrame(), SIGNAL(contentsSizeChanged(QSize)),
    130             q, SLOT(_q_contentsSizeChanged(const QSize&)), Qt::UniqueConnection);
    131     } else {
    132         QObject::disconnect(page->mainFrame(), SIGNAL(contentsSizeChanged(QSize)),
    133                          q, SLOT(_q_contentsSizeChanged(const QSize&)));
    134     }
    135     page->d->page->mainFrame()->view()->setPaintsEntireContents(resizesToContents);
    136     page->d->page->mainFrame()->view()->setDelegatesScrolling(resizesToContents);
    137 }
    138 
    139 void QGraphicsWebViewPrivate::_q_contentsSizeChanged(const QSize& size)
    140 {
    141     if (!resizesToContents)
    142         return;
    143     q->setGeometry(QRectF(q->geometry().topLeft(), size));
    144 }
    145 
    146 void QGraphicsWebViewPrivate::_q_scaleChanged()
    147 {
    148 #if ENABLE(TILED_BACKING_STORE)
    149     if (!page)
    150         return;
    151     pageClient()->updateTiledBackingStoreScale();
    152 #endif
    153 }
    154 
    155 /*!
    156     \class QGraphicsWebView
    157     \brief The QGraphicsWebView class allows Web content to be added to a GraphicsView.
    158     \since 4.6
    159 
    160     An instance of this class renders Web content from a URL or supplied as data, using
    161     features of the QtWebKit module.
    162 
    163     If the width and height of the item are not set, they will default to 800 and 600,
    164     respectively. If the Web page contents is larger than that, scrollbars will be shown
    165     if not disabled explicitly.
    166 
    167     \section1 Browser Features
    168 
    169     Many of the functions, signals and properties provided by QWebView are also available
    170     for this item, making it simple to adapt existing code to use QGraphicsWebView instead
    171     of QWebView.
    172 
    173     The item uses a QWebPage object to perform the rendering of Web content, and this can
    174     be obtained with the page() function, enabling the document itself to be accessed and
    175     modified.
    176 
    177     As with QWebView, the item records the browsing history using a QWebHistory object,
    178     accessible using the history() function. The QWebSettings object that defines the
    179     configuration of the browser can be obtained with the settings() function, enabling
    180     features like plugin support to be customized for each item.
    181 
    182     \sa QWebView, QGraphicsTextItem
    183 */
    184 
    185 /*!
    186     \fn void QGraphicsWebView::titleChanged(const QString &title)
    187 
    188     This signal is emitted whenever the \a title of the main frame changes.
    189 
    190     \sa title()
    191 */
    192 
    193 /*!
    194     \fn void QGraphicsWebView::urlChanged(const QUrl &url)
    195 
    196     This signal is emitted when the \a url of the view changes.
    197 
    198     \sa url(), load()
    199 */
    200 
    201 /*!
    202     \fn void QGraphicsWebView::iconChanged()
    203 
    204     This signal is emitted whenever the icon of the page is loaded or changes.
    205 
    206     In order for icons to be loaded, you will need to set an icon database path
    207     using QWebSettings::setIconDatabasePath().
    208 
    209     \sa icon(), QWebSettings::setIconDatabasePath()
    210 */
    211 
    212 /*!
    213     \fn void QGraphicsWebView::loadStarted()
    214 
    215     This signal is emitted when a new load of the page is started.
    216 
    217     \sa loadProgress(), loadFinished()
    218 */
    219 
    220 /*!
    221     \fn void QGraphicsWebView::loadFinished(bool ok)
    222 
    223     This signal is emitted when a load of the page is finished.
    224     \a ok will indicate whether the load was successful or any error occurred.
    225 
    226     \sa loadStarted()
    227 */
    228 
    229 /*!
    230     Constructs an empty QGraphicsWebView with parent \a parent.
    231 
    232     \sa load()
    233 */
    234 QGraphicsWebView::QGraphicsWebView(QGraphicsItem* parent)
    235     : QGraphicsWidget(parent)
    236     , d(new QGraphicsWebViewPrivate(this))
    237 {
    238     setFlag(QGraphicsItem::ItemUsesExtendedStyleOption, true);
    239     setAcceptDrops(true);
    240     setAcceptHoverEvents(true);
    241     setAcceptTouchEvents(true);
    242     setFocusPolicy(Qt::StrongFocus);
    243     setFlag(QGraphicsItem::ItemClipsChildrenToShape, true);
    244 #if ENABLE(TILED_BACKING_STORE)
    245     QObject::connect(this, SIGNAL(scaleChanged()), this, SLOT(_q_scaleChanged()));
    246 #endif
    247 }
    248 
    249 /*!
    250     Destroys the item.
    251 */
    252 QGraphicsWebView::~QGraphicsWebView()
    253 {
    254     delete d;
    255 }
    256 
    257 /*!
    258     Returns a pointer to the underlying web page.
    259 
    260     \sa setPage()
    261 */
    262 QWebPage* QGraphicsWebView::page() const
    263 {
    264     if (!d->page) {
    265         QGraphicsWebView* that = const_cast<QGraphicsWebView*>(this);
    266         QWebPage* page = new QWebPage(that);
    267 
    268         // Default to not having a background, in the case
    269         // the page doesn't provide one.
    270         QPalette palette = QApplication::palette();
    271         palette.setBrush(QPalette::Base, QColor::fromRgbF(0, 0, 0, 0));
    272         page->setPalette(palette);
    273 
    274         that->setPage(page);
    275     }
    276 
    277     return d->page;
    278 }
    279 
    280 /*! \reimp
    281 */
    282 void QGraphicsWebView::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget*)
    283 {
    284     QPainter::RenderHints oldHints = painter->renderHints();
    285     painter->setRenderHints(oldHints | d->renderHints);
    286 #if ENABLE(TILED_BACKING_STORE)
    287     if (WebCore::TiledBackingStore* backingStore = QWebFramePrivate::core(page()->mainFrame())->tiledBackingStore()) {
    288         // FIXME: We should set the backing store viewport earlier than in paint
    289         backingStore->adjustVisibleRect();
    290         // QWebFrame::render is a public API, bypass it for tiled rendering so behavior does not need to change.
    291         WebCore::GraphicsContext context(painter);
    292         page()->mainFrame()->d->renderFromTiledBackingStore(&context, option->exposedRect.toAlignedRect());
    293         painter->setRenderHints(oldHints);
    294         return;
    295     }
    296 #endif
    297 #if USE(ACCELERATED_COMPOSITING) && !USE(TEXTURE_MAPPER)
    298     page()->mainFrame()->render(painter, d->overlay() ? QWebFrame::ContentsLayer : QWebFrame::AllLayers, option->exposedRect.toAlignedRect());
    299 #else
    300     page()->mainFrame()->render(painter, QWebFrame::AllLayers, option->exposedRect.toRect());
    301 #endif
    302     painter->setRenderHints(oldHints);
    303 }
    304 
    305 /*! \reimp
    306 */
    307 bool QGraphicsWebView::sceneEvent(QEvent* event)
    308 {
    309     // Re-implemented in order to allows fixing event-related bugs in patch releases.
    310 
    311     if (d->page && (event->type() == QEvent::TouchBegin
    312                 || event->type() == QEvent::TouchEnd
    313                 || event->type() == QEvent::TouchUpdate)) {
    314         d->page->event(event);
    315 
    316         // Always return true so that we'll receive also TouchUpdate and TouchEnd events
    317         return true;
    318     }
    319 
    320     return QGraphicsWidget::sceneEvent(event);
    321 }
    322 
    323 /*! \reimp
    324 */
    325 QVariant QGraphicsWebView::itemChange(GraphicsItemChange change, const QVariant& value)
    326 {
    327     switch (change) {
    328     // Differently from QWebView, it is interesting to QGraphicsWebView to handle
    329     // post mouse cursor change notifications. Reason: 'ItemCursorChange' is sent
    330     // as the first action in QGraphicsItem::setCursor implementation, and at that
    331     // item widget's cursor has not been effectively changed yet.
    332     // After cursor is properly set (at 'ItemCursorHasChanged' emission time), we
    333     // fire 'CursorChange'.
    334     case ItemCursorChange:
    335         return value;
    336     case ItemCursorHasChanged: {
    337             QEvent event(QEvent::CursorChange);
    338             QApplication::sendEvent(this, &event);
    339             return value;
    340         }
    341     default:
    342         break;
    343     }
    344 
    345     return QGraphicsWidget::itemChange(change, value);
    346 }
    347 
    348 /*! \reimp
    349 */
    350 QSizeF QGraphicsWebView::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
    351 {
    352     if (which == Qt::PreferredSize)
    353         return QSizeF(800, 600); // ###
    354     return QGraphicsWidget::sizeHint(which, constraint);
    355 }
    356 
    357 /*! \reimp
    358 */
    359 QVariant QGraphicsWebView::inputMethodQuery(Qt::InputMethodQuery query) const
    360 {
    361     if (d->page)
    362         return d->page->inputMethodQuery(query);
    363     return QVariant();
    364 }
    365 
    366 /*!
    367     \property QGraphicsWebView::renderHints
    368     \since 4.8
    369     \brief the default render hints for the view
    370 
    371     These hints are used to initialize QPainter before painting the Web page.
    372 
    373     QPainter::TextAntialiasing and QPainter::SmoothPixmapTransform are enabled by default and will be
    374     used to render the item in addition of what has been set on the painter given by QGraphicsScene.
    375 
    376     \note This property is not available on Symbian. However, the getter and
    377     setter functions can still be used directly.
    378 
    379     \sa QPainter::renderHints()
    380 */
    381 
    382 /*!
    383     \since 4.8
    384     Returns the render hints used by the view to render content.
    385 
    386     \sa QPainter::renderHints()
    387 */
    388 QPainter::RenderHints QGraphicsWebView::renderHints() const
    389 {
    390     return d->renderHints;
    391 }
    392 
    393 /*!
    394     \since 4.8
    395     Sets the render hints used by the view to the specified \a hints.
    396 
    397     \sa QPainter::setRenderHints()
    398 */
    399 void QGraphicsWebView::setRenderHints(QPainter::RenderHints hints)
    400 {
    401     if (hints == d->renderHints)
    402         return;
    403     d->renderHints = hints;
    404     update();
    405 }
    406 
    407 /*!
    408     \since 4.8
    409     If \a enabled is true, enables the specified render \a hint; otherwise
    410     disables it.
    411 
    412     \sa renderHints, QPainter::renderHints()
    413 */
    414 void QGraphicsWebView::setRenderHint(QPainter::RenderHint hint, bool enabled)
    415 {
    416     QPainter::RenderHints oldHints = d->renderHints;
    417     if (enabled)
    418         d->renderHints |= hint;
    419     else
    420         d->renderHints &= ~hint;
    421     if (oldHints != d->renderHints)
    422         update();
    423 }
    424 
    425 /*! \reimp
    426 */
    427 bool QGraphicsWebView::event(QEvent* event)
    428 {
    429     // Re-implemented in order to allows fixing event-related bugs in patch releases.
    430 
    431     if (d->page) {
    432         if (event->type() == QEvent::PaletteChange)
    433             d->page->setPalette(palette());
    434 #ifndef QT_NO_CONTEXTMENU
    435         if (event->type() == QEvent::GraphicsSceneContextMenu) {
    436             if (!isEnabled())
    437                 return false;
    438 
    439             QGraphicsSceneContextMenuEvent* ev = static_cast<QGraphicsSceneContextMenuEvent*>(event);
    440             QContextMenuEvent fakeEvent(QContextMenuEvent::Reason(ev->reason()), ev->pos().toPoint());
    441             if (d->page->swallowContextMenuEvent(&fakeEvent)) {
    442                 event->accept();
    443                 return true;
    444             }
    445             d->page->updatePositionDependentActions(fakeEvent.pos());
    446         } else
    447 #endif // QT_NO_CONTEXTMENU
    448         {
    449 #ifndef QT_NO_CURSOR
    450             if (event->type() == QEvent::CursorChange) {
    451                 // An unsetCursor will set the cursor to Qt::ArrowCursor.
    452                 // Thus this cursor change might be a QWidget::unsetCursor()
    453                 // If this is not the case and it came from WebCore, the
    454                 // QWebPageClient already has set its cursor internally
    455                 // to Qt::ArrowCursor, so updating the cursor is always
    456                 // right, as it falls back to the last cursor set by
    457                 // WebCore.
    458                 // FIXME: Add a QEvent::CursorUnset or similar to Qt.
    459                 if (cursor().shape() == Qt::ArrowCursor)
    460                     d->page->d->client->resetCursor();
    461             }
    462 #endif
    463         }
    464     }
    465     return QGraphicsWidget::event(event);
    466 }
    467 
    468 void QGraphicsWebViewPrivate::detachCurrentPage()
    469 {
    470     if (!page)
    471         return;
    472 
    473     page->d->view.clear();
    474     page->d->client = 0;
    475 
    476     // if the page was created by us, we own it and need to
    477     // destroy it as well.
    478 
    479     if (page->parent() == q)
    480         delete page;
    481     else
    482         page->disconnect(q);
    483 
    484     page = 0;
    485 }
    486 
    487 /*!
    488     Makes \a page the new web page of the web graphicsitem.
    489 
    490     The parent QObject of the provided page remains the owner
    491     of the object. If the current document is a child of the web
    492     view, it will be deleted.
    493 
    494     \sa page()
    495 */
    496 void QGraphicsWebView::setPage(QWebPage* page)
    497 {
    498     if (d->page == page)
    499         return;
    500 
    501     d->detachCurrentPage();
    502     d->page = page;
    503 
    504     if (!d->page)
    505         return;
    506 
    507     d->page->d->client = new PageClientQGraphicsWidget(this, page); // set the page client
    508 
    509     if (d->overlay())
    510         d->overlay()->prepareGraphicsItemGeometryChange();
    511 
    512     QSize size = geometry().size().toSize();
    513     page->setViewportSize(size);
    514 
    515     if (d->resizesToContents)
    516         d->updateResizesToContentsForPage();
    517 
    518     QWebFrame* mainFrame = d->page->mainFrame();
    519 
    520     connect(mainFrame, SIGNAL(titleChanged(QString)),
    521             this, SIGNAL(titleChanged(QString)));
    522     connect(mainFrame, SIGNAL(iconChanged()),
    523             this, SIGNAL(iconChanged()));
    524     connect(mainFrame, SIGNAL(urlChanged(QUrl)),
    525             this, SIGNAL(urlChanged(QUrl)));
    526     connect(d->page, SIGNAL(loadStarted()),
    527             this, SIGNAL(loadStarted()));
    528     connect(d->page, SIGNAL(loadProgress(int)),
    529             this, SIGNAL(loadProgress(int)));
    530     connect(d->page, SIGNAL(loadFinished(bool)),
    531             this, SLOT(_q_doLoadFinished(bool)));
    532     connect(d->page, SIGNAL(statusBarMessage(QString)),
    533             this, SIGNAL(statusBarMessage(QString)));
    534     connect(d->page, SIGNAL(linkClicked(QUrl)),
    535             this, SIGNAL(linkClicked(QUrl)));
    536     connect(d->page, SIGNAL(destroyed()),
    537             this, SLOT(_q_pageDestroyed()));
    538 #if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN))
    539     connect(d->page, SIGNAL(microFocusChanged()),
    540             this, SLOT(updateMicroFocus()));
    541 #endif
    542 }
    543 
    544 /*!
    545     \property QGraphicsWebView::url
    546     \brief the url of the web page currently viewed
    547 
    548     Setting this property clears the view and loads the URL.
    549 
    550     By default, this property contains an empty, invalid URL.
    551 
    552     \sa load(), urlChanged()
    553 */
    554 
    555 void QGraphicsWebView::setUrl(const QUrl &url)
    556 {
    557     page()->mainFrame()->setUrl(url);
    558 }
    559 
    560 QUrl QGraphicsWebView::url() const
    561 {
    562     if (d->page)
    563         return d->page->mainFrame()->url();
    564 
    565     return QUrl();
    566 }
    567 
    568 /*!
    569     \property QGraphicsWebView::title
    570     \brief the title of the web page currently viewed
    571 
    572     By default, this property contains an empty string.
    573 
    574     \sa titleChanged()
    575 */
    576 QString QGraphicsWebView::title() const
    577 {
    578     if (d->page)
    579         return d->page->mainFrame()->title();
    580 
    581     return QString();
    582 }
    583 
    584 /*!
    585     \property QGraphicsWebView::icon
    586     \brief the icon associated with the web page currently viewed
    587 
    588     By default, this property contains a null icon.
    589 
    590     \sa iconChanged(), QWebSettings::iconForUrl()
    591 */
    592 QIcon QGraphicsWebView::icon() const
    593 {
    594     if (d->page)
    595         return d->page->mainFrame()->icon();
    596 
    597     return QIcon();
    598 }
    599 
    600 /*!
    601     \property QGraphicsWebView::zoomFactor
    602     \brief the zoom factor for the view
    603 */
    604 
    605 void QGraphicsWebView::setZoomFactor(qreal factor)
    606 {
    607     if (factor == page()->mainFrame()->zoomFactor())
    608         return;
    609 
    610     page()->mainFrame()->setZoomFactor(factor);
    611 }
    612 
    613 qreal QGraphicsWebView::zoomFactor() const
    614 {
    615     return page()->mainFrame()->zoomFactor();
    616 }
    617 
    618 /*! \reimp
    619 */
    620 void QGraphicsWebView::updateGeometry()
    621 {
    622     if (d->overlay())
    623         d->overlay()->prepareGraphicsItemGeometryChange();
    624 
    625     QGraphicsWidget::updateGeometry();
    626 
    627     if (!d->page)
    628         return;
    629 
    630     QSize size = geometry().size().toSize();
    631     d->page->setViewportSize(size);
    632 }
    633 
    634 /*! \reimp
    635 */
    636 void QGraphicsWebView::setGeometry(const QRectF& rect)
    637 {
    638     QGraphicsWidget::setGeometry(rect);
    639 
    640     if (d->overlay())
    641         d->overlay()->prepareGraphicsItemGeometryChange();
    642 
    643     if (!d->page)
    644         return;
    645 
    646     // NOTE: call geometry() as setGeometry ensures that
    647     // the geometry is within legal bounds (minimumSize, maximumSize)
    648     QSize size = geometry().size().toSize();
    649     d->page->setViewportSize(size);
    650 }
    651 
    652 /*!
    653     Convenience slot that stops loading the document.
    654 
    655     \sa reload(), loadFinished()
    656 */
    657 void QGraphicsWebView::stop()
    658 {
    659     if (d->page)
    660         d->page->triggerAction(QWebPage::Stop);
    661 }
    662 
    663 /*!
    664     Convenience slot that loads the previous document in the list of documents
    665     built by navigating links. Does nothing if there is no previous document.
    666 
    667     \sa forward()
    668 */
    669 void QGraphicsWebView::back()
    670 {
    671     if (d->page)
    672         d->page->triggerAction(QWebPage::Back);
    673 }
    674 
    675 /*!
    676     Convenience slot that loads the next document in the list of documents
    677     built by navigating links. Does nothing if there is no next document.
    678 
    679     \sa back()
    680 */
    681 void QGraphicsWebView::forward()
    682 {
    683     if (d->page)
    684         d->page->triggerAction(QWebPage::Forward);
    685 }
    686 
    687 /*!
    688     Reloads the current document.
    689 
    690     \sa stop(), loadStarted()
    691 */
    692 void QGraphicsWebView::reload()
    693 {
    694     if (d->page)
    695         d->page->triggerAction(QWebPage::Reload);
    696 }
    697 
    698 /*!
    699     Loads the specified \a url and displays it.
    700 
    701     \note The view remains the same until enough data has arrived to display the new \a url.
    702 
    703     \sa setUrl(), url(), urlChanged()
    704 */
    705 void QGraphicsWebView::load(const QUrl& url)
    706 {
    707     page()->mainFrame()->load(url);
    708 }
    709 
    710 /*!
    711     \fn void QGraphicsWebView::load(const QNetworkRequest &request, QNetworkAccessManager::Operation operation, const QByteArray &body)
    712 
    713     Loads a network request, \a request, using the method specified in \a operation.
    714 
    715     \a body is optional and is only used for POST operations.
    716 
    717     \note The view remains the same until enough data has arrived to display the new url.
    718 
    719     \sa url(), urlChanged()
    720 */
    721 
    722 void QGraphicsWebView::load(const QNetworkRequest& request,
    723                     QNetworkAccessManager::Operation operation,
    724                     const QByteArray& body)
    725 {
    726     page()->mainFrame()->load(request, operation, body);
    727 }
    728 
    729 /*!
    730     Sets the content of the web view to the specified \a html.
    731 
    732     External objects such as stylesheets or images referenced in the HTML
    733     document are located relative to \a baseUrl.
    734 
    735     The \a html is loaded immediately; external objects are loaded asynchronously.
    736 
    737     When using this method, WebKit assumes that external resources such as
    738     JavaScript programs or style sheets are encoded in UTF-8 unless otherwise
    739     specified. For example, the encoding of an external script can be specified
    740     through the charset attribute of the HTML script tag. Alternatively, the
    741     encoding can also be specified by the web server.
    742 
    743     This is a convenience function equivalent to setContent(html, "text/html", baseUrl).
    744 
    745     \warning This function works only for HTML, for other mime types (i.e. XHTML, SVG)
    746     setContent() should be used instead.
    747 
    748     \sa load(), setContent(), QWebFrame::toHtml(), QWebFrame::setContent()
    749 */
    750 void QGraphicsWebView::setHtml(const QString& html, const QUrl& baseUrl)
    751 {
    752     page()->mainFrame()->setHtml(html, baseUrl);
    753 }
    754 
    755 /*!
    756     Sets the content of the web graphicsitem to the specified content \a data. If the \a mimeType argument
    757     is empty it is currently assumed that the content is HTML but in future versions we may introduce
    758     auto-detection.
    759 
    760     External objects referenced in the content are located relative to \a baseUrl.
    761 
    762     The \a data is loaded immediately; external objects are loaded asynchronously.
    763 
    764     \sa load(), setHtml(), QWebFrame::toHtml()
    765 */
    766 void QGraphicsWebView::setContent(const QByteArray& data, const QString& mimeType, const QUrl& baseUrl)
    767 {
    768     page()->mainFrame()->setContent(data, mimeType, baseUrl);
    769 }
    770 
    771 /*!
    772     Returns a pointer to the view's history of navigated web pages.
    773 
    774     It is equivalent to
    775 
    776     \snippet webkitsnippets/qtwebkit_qwebview_snippet.cpp 0
    777 */
    778 QWebHistory* QGraphicsWebView::history() const
    779 {
    780     return page()->history();
    781 }
    782 
    783 /*!
    784     \property QGraphicsWebView::modified
    785     \brief whether the document was modified by the user
    786 
    787     Parts of HTML documents can be editable for example through the
    788     \c{contenteditable} attribute on HTML elements.
    789 
    790     By default, this property is false.
    791 */
    792 bool QGraphicsWebView::isModified() const
    793 {
    794     if (d->page)
    795         return d->page->isModified();
    796     return false;
    797 }
    798 
    799 /*!
    800     Returns a pointer to the view/page specific settings object.
    801 
    802     It is equivalent to
    803 
    804     \snippet webkitsnippets/qtwebkit_qwebview_snippet.cpp 1
    805 
    806     \sa QWebSettings::globalSettings()
    807 */
    808 QWebSettings* QGraphicsWebView::settings() const
    809 {
    810     return page()->settings();
    811 }
    812 
    813 /*!
    814     Returns a pointer to a QAction that encapsulates the specified web action \a action.
    815 */
    816 QAction *QGraphicsWebView::pageAction(QWebPage::WebAction action) const
    817 {
    818 #ifdef QT_NO_ACTION
    819     Q_UNUSED(action)
    820     return 0;
    821 #else
    822     return page()->action(action);
    823 #endif
    824 }
    825 
    826 /*!
    827     Triggers the specified \a action. If it is a checkable action the specified
    828     \a checked state is assumed.
    829 
    830     \sa pageAction()
    831 */
    832 void QGraphicsWebView::triggerPageAction(QWebPage::WebAction action, bool checked)
    833 {
    834     page()->triggerAction(action, checked);
    835 }
    836 
    837 /*!
    838     Finds the specified string, \a subString, in the page, using the given \a options.
    839 
    840     If the HighlightAllOccurrences flag is passed, the function will highlight all occurrences
    841     that exist in the page. All subsequent calls will extend the highlight, rather than
    842     replace it, with occurrences of the new string.
    843 
    844     If the HighlightAllOccurrences flag is not passed, the function will select an occurrence
    845     and all subsequent calls will replace the current occurrence with the next one.
    846 
    847     To clear the selection, just pass an empty string.
    848 
    849     Returns true if \a subString was found; otherwise returns false.
    850 
    851     \sa QWebPage::selectedText(), QWebPage::selectionChanged()
    852 */
    853 bool QGraphicsWebView::findText(const QString &subString, QWebPage::FindFlags options)
    854 {
    855     if (d->page)
    856         return d->page->findText(subString, options);
    857     return false;
    858 }
    859 
    860 /*!
    861     \property QGraphicsWebView::resizesToContents
    862     \brief whether the size of the QGraphicsWebView and its viewport changes to match the contents size
    863     \since 4.7
    864 
    865     If this property is set, the QGraphicsWebView will automatically change its
    866     size to match the size of the main frame contents. As a result the top level frame
    867     will never have scrollbars. It will also make CSS fixed positioning to behave like absolute positioning
    868     with elements positioned relative to the document instead of the viewport.
    869 
    870     This property should be used in conjunction with the QWebPage::preferredContentsSize property.
    871     If not explicitly set, the preferredContentsSize is automatically set to a reasonable value.
    872 
    873     \sa QWebPage::setPreferredContentsSize()
    874 */
    875 void QGraphicsWebView::setResizesToContents(bool enabled)
    876 {
    877     if (d->resizesToContents == enabled)
    878         return;
    879     d->resizesToContents = enabled;
    880     if (d->page)
    881         d->updateResizesToContentsForPage();
    882 }
    883 
    884 bool QGraphicsWebView::resizesToContents() const
    885 {
    886     return d->resizesToContents;
    887 }
    888 
    889 /*!
    890     \property QGraphicsWebView::tiledBackingStoreFrozen
    891     \brief whether the tiled backing store updates its contents
    892     \since 4.7
    893 
    894     If the tiled backing store is enabled using QWebSettings::TiledBackingStoreEnabled attribute, this property
    895     can be used to disable backing store updates temporarily. This can be useful for example for running
    896     a smooth animation that changes the scale of the QGraphicsWebView.
    897 
    898     When the backing store is unfrozen, its contents will be automatically updated to match the current
    899     state of the document. If the QGraphicsWebView scale was changed, the backing store is also
    900     re-rendered using the new scale.
    901 
    902     If the tiled backing store is not enabled, this property does nothing.
    903 
    904     \sa QWebSettings::TiledBackingStoreEnabled
    905     \sa QGraphicsObject::scale
    906 */
    907 bool QGraphicsWebView::isTiledBackingStoreFrozen() const
    908 {
    909 #if ENABLE(TILED_BACKING_STORE)
    910     WebCore::TiledBackingStore* backingStore = QWebFramePrivate::core(page()->mainFrame())->tiledBackingStore();
    911     if (!backingStore)
    912         return false;
    913     return backingStore->contentsFrozen();
    914 #else
    915     return false;
    916 #endif
    917 }
    918 
    919 void QGraphicsWebView::setTiledBackingStoreFrozen(bool frozen)
    920 {
    921 #if ENABLE(TILED_BACKING_STORE)
    922     WebCore::TiledBackingStore* backingStore = QWebFramePrivate::core(page()->mainFrame())->tiledBackingStore();
    923     if (!backingStore)
    924         return;
    925     backingStore->setContentsFrozen(frozen);
    926 #else
    927     UNUSED_PARAM(frozen);
    928 #endif
    929 }
    930 
    931 /*! \reimp
    932 */
    933 void QGraphicsWebView::hoverMoveEvent(QGraphicsSceneHoverEvent* ev)
    934 {
    935     if (d->page) {
    936         const bool accepted = ev->isAccepted();
    937         QMouseEvent me = QMouseEvent(QEvent::MouseMove,
    938                 ev->pos().toPoint(), Qt::NoButton,
    939                 Qt::NoButton, Qt::NoModifier);
    940         d->page->event(&me);
    941         ev->setAccepted(accepted);
    942     }
    943 
    944     if (!ev->isAccepted())
    945         QGraphicsItem::hoverMoveEvent(ev);
    946 }
    947 
    948 /*! \reimp
    949 */
    950 void QGraphicsWebView::hoverLeaveEvent(QGraphicsSceneHoverEvent* ev)
    951 {
    952     Q_UNUSED(ev);
    953 }
    954 
    955 /*! \reimp
    956 */
    957 void QGraphicsWebView::mouseMoveEvent(QGraphicsSceneMouseEvent* ev)
    958 {
    959     if (d->page) {
    960         const bool accepted = ev->isAccepted();
    961         d->page->event(ev);
    962         ev->setAccepted(accepted);
    963     }
    964 
    965     if (!ev->isAccepted())
    966         QGraphicsItem::mouseMoveEvent(ev);
    967 }
    968 
    969 /*! \reimp
    970 */
    971 void QGraphicsWebView::mousePressEvent(QGraphicsSceneMouseEvent* ev)
    972 {
    973     if (d->page) {
    974         const bool accepted = ev->isAccepted();
    975         d->page->event(ev);
    976         ev->setAccepted(accepted);
    977     }
    978 
    979     if (!ev->isAccepted())
    980         QGraphicsItem::mousePressEvent(ev);
    981 }
    982 
    983 /*! \reimp
    984 */
    985 void QGraphicsWebView::mouseReleaseEvent(QGraphicsSceneMouseEvent* ev)
    986 {
    987     if (d->page) {
    988         const bool accepted = ev->isAccepted();
    989         d->page->event(ev);
    990         ev->setAccepted(accepted);
    991     }
    992 
    993     if (!ev->isAccepted())
    994         QGraphicsItem::mouseReleaseEvent(ev);
    995 }
    996 
    997 /*! \reimp
    998 */
    999 void QGraphicsWebView::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* ev)
   1000 {
   1001     if (d->page) {
   1002         const bool accepted = ev->isAccepted();
   1003         d->page->event(ev);
   1004         ev->setAccepted(accepted);
   1005     }
   1006 
   1007     if (!ev->isAccepted())
   1008         QGraphicsItem::mouseDoubleClickEvent(ev);
   1009 }
   1010 
   1011 /*! \reimp
   1012 */
   1013 void QGraphicsWebView::keyPressEvent(QKeyEvent* ev)
   1014 {
   1015     if (d->page)
   1016         d->page->event(ev);
   1017 
   1018     if (!ev->isAccepted())
   1019         QGraphicsItem::keyPressEvent(ev);
   1020 }
   1021 
   1022 /*! \reimp
   1023 */
   1024 void QGraphicsWebView::keyReleaseEvent(QKeyEvent* ev)
   1025 {
   1026     if (d->page)
   1027         d->page->event(ev);
   1028 
   1029     if (!ev->isAccepted())
   1030         QGraphicsItem::keyReleaseEvent(ev);
   1031 }
   1032 
   1033 /*! \reimp
   1034 */
   1035 void QGraphicsWebView::focusInEvent(QFocusEvent* ev)
   1036 {
   1037     if (d->page)
   1038         d->page->event(ev);
   1039     else
   1040         QGraphicsItem::focusInEvent(ev);
   1041 }
   1042 
   1043 /*! \reimp
   1044 */
   1045 void QGraphicsWebView::focusOutEvent(QFocusEvent* ev)
   1046 {
   1047     if (d->page)
   1048         d->page->event(ev);
   1049     else
   1050         QGraphicsItem::focusOutEvent(ev);
   1051 }
   1052 
   1053 /*! \reimp
   1054 */
   1055 bool QGraphicsWebView::focusNextPrevChild(bool next)
   1056 {
   1057     if (d->page)
   1058         return d->page->focusNextPrevChild(next);
   1059 
   1060     return QGraphicsWidget::focusNextPrevChild(next);
   1061 }
   1062 
   1063 /*! \reimp
   1064 */
   1065 void QGraphicsWebView::dragEnterEvent(QGraphicsSceneDragDropEvent* ev)
   1066 {
   1067 #ifndef QT_NO_DRAGANDDROP
   1068     if (d->page)
   1069         d->page->event(ev);
   1070 #else
   1071     Q_UNUSED(ev);
   1072 #endif
   1073 }
   1074 
   1075 /*! \reimp
   1076 */
   1077 void QGraphicsWebView::dragLeaveEvent(QGraphicsSceneDragDropEvent* ev)
   1078 {
   1079 #ifndef QT_NO_DRAGANDDROP
   1080     if (d->page) {
   1081         const bool accepted = ev->isAccepted();
   1082         d->page->event(ev);
   1083         ev->setAccepted(accepted);
   1084     }
   1085 
   1086     if (!ev->isAccepted())
   1087         QGraphicsWidget::dragLeaveEvent(ev);
   1088 #else
   1089     Q_UNUSED(ev);
   1090 #endif
   1091 }
   1092 
   1093 /*! \reimp
   1094 */
   1095 void QGraphicsWebView::dragMoveEvent(QGraphicsSceneDragDropEvent* ev)
   1096 {
   1097 #ifndef QT_NO_DRAGANDDROP
   1098     if (d->page) {
   1099         const bool accepted = ev->isAccepted();
   1100         d->page->event(ev);
   1101         ev->setAccepted(accepted);
   1102     }
   1103 
   1104     if (!ev->isAccepted())
   1105         QGraphicsWidget::dragMoveEvent(ev);
   1106 #else
   1107     Q_UNUSED(ev);
   1108 #endif
   1109 }
   1110 
   1111 /*! \reimp
   1112 */
   1113 void QGraphicsWebView::dropEvent(QGraphicsSceneDragDropEvent* ev)
   1114 {
   1115 #ifndef QT_NO_DRAGANDDROP
   1116     if (d->page) {
   1117         const bool accepted = ev->isAccepted();
   1118         d->page->event(ev);
   1119         ev->setAccepted(accepted);
   1120     }
   1121 
   1122     if (!ev->isAccepted())
   1123         QGraphicsWidget::dropEvent(ev);
   1124 #else
   1125     Q_UNUSED(ev);
   1126 #endif
   1127 }
   1128 
   1129 #ifndef QT_NO_CONTEXTMENU
   1130 /*! \reimp
   1131 */
   1132 void QGraphicsWebView::contextMenuEvent(QGraphicsSceneContextMenuEvent* ev)
   1133 {
   1134     if (d->page) {
   1135         const bool accepted = ev->isAccepted();
   1136         d->page->event(ev);
   1137         ev->setAccepted(accepted);
   1138     }
   1139 }
   1140 #endif // QT_NO_CONTEXTMENU
   1141 
   1142 #ifndef QT_NO_WHEELEVENT
   1143 /*! \reimp
   1144 */
   1145 void QGraphicsWebView::wheelEvent(QGraphicsSceneWheelEvent* ev)
   1146 {
   1147     if (d->page) {
   1148         const bool accepted = ev->isAccepted();
   1149         d->page->event(ev);
   1150         ev->setAccepted(accepted);
   1151     }
   1152 
   1153     if (!ev->isAccepted())
   1154         QGraphicsItem::wheelEvent(ev);
   1155 }
   1156 #endif // QT_NO_WHEELEVENT
   1157 
   1158 /*! \reimp
   1159 */
   1160 void QGraphicsWebView::inputMethodEvent(QInputMethodEvent* ev)
   1161 {
   1162     if (d->page)
   1163         d->page->event(ev);
   1164 
   1165     if (!ev->isAccepted())
   1166         QGraphicsItem::inputMethodEvent(ev);
   1167 }
   1168 
   1169 /*!
   1170     \fn void QGraphicsWebView::statusBarMessage(const QString& text)
   1171 
   1172     This signal is emitted when the statusbar \a text is changed by the page.
   1173 */
   1174 
   1175 /*!
   1176     \fn void QGraphicsWebView::loadProgress(int progress)
   1177 
   1178     This signal is emitted every time an element in the web page
   1179     completes loading and the overall loading progress advances.
   1180 
   1181     This signal tracks the progress of all child frames.
   1182 
   1183     The current value is provided by \a progress and scales from 0 to 100,
   1184     which is the default range of QProgressBar.
   1185 
   1186     \sa loadStarted(), loadFinished()
   1187 */
   1188 
   1189 /*!
   1190     \fn void QGraphicsWebView::linkClicked(const QUrl &url)
   1191 
   1192     This signal is emitted whenever the user clicks on a link and the page's linkDelegationPolicy
   1193     property is set to delegate the link handling for the specified \a url.
   1194 
   1195     \sa QWebPage::linkDelegationPolicy()
   1196 */
   1197 
   1198 #endif // QT_NO_GRAPHICSVIEW
   1199 
   1200 #include "moc_qgraphicswebview.cpp"
   1201