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