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