initial import
[vuplus_webkit] / 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 <QtCore/qmetaobject.h>
38 #include <QtCore/qsharedpointer.h>
39 #include <QtCore/qtimer.h>
40 #include <QtGui/qapplication.h>
41 #include <QtGui/qgraphicsscene.h>
42 #include <QtGui/qgraphicssceneevent.h>
43 #include <QtGui/qgraphicsview.h>
44 #include <QtGui/qpixmapcache.h>
45 #include <QtGui/qscrollbar.h>
46 #include <QtGui/qstyleoption.h>
47 #include <QtGui/qinputcontext.h>
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 ENABLE(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 ENABLE(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 ENABLE(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->adjustVisibleRect();
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         d->page->event(event);
317
318         // Always return true so that we'll receive also TouchUpdate and TouchEnd events
319         return true;
320     }
321
322     return QGraphicsWidget::sceneEvent(event);
323 }
324
325 /*! \reimp
326 */
327 QVariant QGraphicsWebView::itemChange(GraphicsItemChange change, const QVariant& value)
328 {
329     switch (change) {
330     // Differently from QWebView, it is interesting to QGraphicsWebView to handle
331     // post mouse cursor change notifications. Reason: 'ItemCursorChange' is sent
332     // as the first action in QGraphicsItem::setCursor implementation, and at that
333     // item widget's cursor has not been effectively changed yet.
334     // After cursor is properly set (at 'ItemCursorHasChanged' emission time), we
335     // fire 'CursorChange'.
336     case ItemCursorChange:
337         return value;
338     case ItemCursorHasChanged: {
339             QEvent event(QEvent::CursorChange);
340             QApplication::sendEvent(this, &event);
341             return value;
342         }
343     default:
344         break;
345     }
346
347     return QGraphicsWidget::itemChange(change, value);
348 }
349
350 /*! \reimp
351 */
352 QSizeF QGraphicsWebView::sizeHint(Qt::SizeHint which, const QSizeF& constraint) const
353 {
354     if (which == Qt::PreferredSize)
355         return QSizeF(800, 600); // ###
356     return QGraphicsWidget::sizeHint(which, constraint);
357 }
358
359 /*! \reimp
360 */
361 QVariant QGraphicsWebView::inputMethodQuery(Qt::InputMethodQuery query) const
362 {
363     if (d->page)
364         return d->page->inputMethodQuery(query);
365     return QVariant();
366 }
367
368 /*!
369     \property QGraphicsWebView::renderHints
370     \since 4.8
371     \brief the default render hints for the view
372
373     These hints are used to initialize QPainter before painting the Web page.
374
375     QPainter::TextAntialiasing and QPainter::SmoothPixmapTransform are enabled by default and will be
376     used to render the item in addition of what has been set on the painter given by QGraphicsScene.
377
378     \note This property is not available on Symbian. However, the getter and
379     setter functions can still be used directly.
380
381     \sa QPainter::renderHints()
382 */
383
384 /*!
385     \since 4.8
386     Returns the render hints used by the view to render content.
387
388     \sa QPainter::renderHints()
389 */
390 QPainter::RenderHints QGraphicsWebView::renderHints() const
391 {
392     return d->renderHints;
393 }
394
395 /*!
396     \since 4.8
397     Sets the render hints used by the view to the specified \a hints.
398
399     \sa QPainter::setRenderHints()
400 */
401 void QGraphicsWebView::setRenderHints(QPainter::RenderHints hints)
402 {
403     if (hints == d->renderHints)
404         return;
405     d->renderHints = hints;
406     update();
407 }
408
409 /*!
410     \since 4.8
411     If \a enabled is true, enables the specified render \a hint; otherwise
412     disables it.
413
414     \sa renderHints, QPainter::renderHints()
415 */
416 void QGraphicsWebView::setRenderHint(QPainter::RenderHint hint, bool enabled)
417 {
418     QPainter::RenderHints oldHints = d->renderHints;
419     if (enabled)
420         d->renderHints |= hint;
421     else
422         d->renderHints &= ~hint;
423     if (oldHints != d->renderHints)
424         update();
425 }
426
427 /*! \reimp
428 */
429 bool QGraphicsWebView::event(QEvent* event)
430 {
431     // Re-implemented in order to allows fixing event-related bugs in patch releases.
432
433     if (d->page) {
434         if (event->type() == QEvent::PaletteChange)
435             d->page->setPalette(palette());
436 #ifndef QT_NO_CONTEXTMENU
437         if (event->type() == QEvent::GraphicsSceneContextMenu) {
438             if (!isEnabled())
439                 return false;
440
441             QGraphicsSceneContextMenuEvent* ev = static_cast<QGraphicsSceneContextMenuEvent*>(event);
442             QContextMenuEvent fakeEvent(QContextMenuEvent::Reason(ev->reason()), ev->pos().toPoint());
443             if (d->page->swallowContextMenuEvent(&fakeEvent)) {
444                 event->accept();
445                 return true;
446             }
447             d->page->updatePositionDependentActions(fakeEvent.pos());
448         } else
449 #endif // QT_NO_CONTEXTMENU
450         {
451 #ifndef QT_NO_CURSOR
452             if (event->type() == QEvent::CursorChange) {
453                 // An unsetCursor will set the cursor to Qt::ArrowCursor.
454                 // Thus this cursor change might be a QWidget::unsetCursor()
455                 // If this is not the case and it came from WebCore, the
456                 // QWebPageClient already has set its cursor internally
457                 // to Qt::ArrowCursor, so updating the cursor is always
458                 // right, as it falls back to the last cursor set by
459                 // WebCore.
460                 // FIXME: Add a QEvent::CursorUnset or similar to Qt.
461                 if (cursor().shape() == Qt::ArrowCursor)
462                     d->page->d->client->resetCursor();
463             }
464 #endif
465         }
466     }
467     return QGraphicsWidget::event(event);
468 }
469
470 void QGraphicsWebViewPrivate::detachCurrentPage()
471 {
472     if (!page)
473         return;
474
475     page->d->view.clear();
476     page->d->client = nullptr;
477
478     // if the page was created by us, we own it and need to
479     // destroy it as well.
480
481     if (page->parent() == q)
482         delete page;
483     else
484         page->disconnect(q);
485
486     page = 0;
487 }
488
489 /*!
490     Makes \a page the new web page of the web graphicsitem.
491
492     The parent QObject of the provided page remains the owner
493     of the object. If the current document is a child of the web
494     view, it will be deleted.
495
496     \sa page()
497 */
498 void QGraphicsWebView::setPage(QWebPage* page)
499 {
500     if (d->page == page)
501         return;
502
503     d->detachCurrentPage();
504     d->page = page;
505
506     if (!d->page)
507         return;
508
509     d->page->d->client = adoptPtr(new PageClientQGraphicsWidget(this, page));
510
511     if (d->overlay())
512         d->overlay()->prepareGraphicsItemGeometryChange();
513
514     QSize size = geometry().size().toSize();
515     page->setViewportSize(size);
516
517     if (d->resizesToContents)
518         d->updateResizesToContentsForPage();
519
520     QWebFrame* mainFrame = d->page->mainFrame();
521
522     connect(mainFrame, SIGNAL(titleChanged(QString)),
523             this, SIGNAL(titleChanged(QString)));
524     connect(mainFrame, SIGNAL(iconChanged()),
525             this, SIGNAL(iconChanged()));
526     connect(mainFrame, SIGNAL(urlChanged(QUrl)),
527             this, SIGNAL(urlChanged(QUrl)));
528     connect(d->page, SIGNAL(loadStarted()),
529             this, SIGNAL(loadStarted()));
530     connect(d->page, SIGNAL(loadProgress(int)),
531             this, SIGNAL(loadProgress(int)));
532     connect(d->page, SIGNAL(loadFinished(bool)),
533             this, SLOT(_q_doLoadFinished(bool)));
534     connect(d->page, SIGNAL(statusBarMessage(QString)),
535             this, SIGNAL(statusBarMessage(QString)));
536     connect(d->page, SIGNAL(linkClicked(QUrl)),
537             this, SIGNAL(linkClicked(QUrl)));
538     connect(d->page, SIGNAL(destroyed()),
539             this, SLOT(_q_pageDestroyed()));
540 #if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN))
541     connect(d->page, SIGNAL(microFocusChanged()),
542             this, SLOT(updateMicroFocus()));
543 #endif
544 }
545
546 /*!
547     \property QGraphicsWebView::url
548     \brief the url of the web page currently viewed
549
550     Setting this property clears the view and loads the URL.
551
552     By default, this property contains an empty, invalid URL.
553
554     \sa load(), urlChanged()
555 */
556
557 void QGraphicsWebView::setUrl(const QUrl &url)
558 {
559     page()->mainFrame()->setUrl(url);
560 }
561
562 QUrl QGraphicsWebView::url() const
563 {
564     if (d->page)
565         return d->page->mainFrame()->url();
566
567     return QUrl();
568 }
569
570 /*!
571     \property QGraphicsWebView::title
572     \brief the title of the web page currently viewed
573
574     By default, this property contains an empty string.
575
576     \sa titleChanged()
577 */
578 QString QGraphicsWebView::title() const
579 {
580     if (d->page)
581         return d->page->mainFrame()->title();
582
583     return QString();
584 }
585
586 /*!
587     \property QGraphicsWebView::icon
588     \brief the icon associated with the web page currently viewed
589
590     By default, this property contains a null icon.
591
592     \sa iconChanged(), QWebSettings::iconForUrl()
593 */
594 QIcon QGraphicsWebView::icon() const
595 {
596     if (d->page)
597         return d->page->mainFrame()->icon();
598
599     return QIcon();
600 }
601
602 /*!
603     \property QGraphicsWebView::zoomFactor
604     \brief the zoom factor for the view
605 */
606
607 void QGraphicsWebView::setZoomFactor(qreal factor)
608 {
609     if (factor == page()->mainFrame()->zoomFactor())
610         return;
611
612     page()->mainFrame()->setZoomFactor(factor);
613 }
614
615 qreal QGraphicsWebView::zoomFactor() const
616 {
617     return page()->mainFrame()->zoomFactor();
618 }
619
620 /*! \reimp
621 */
622 void QGraphicsWebView::updateGeometry()
623 {
624     if (d->overlay())
625         d->overlay()->prepareGraphicsItemGeometryChange();
626
627     QGraphicsWidget::updateGeometry();
628
629     if (!d->page)
630         return;
631
632     QSize size = geometry().size().toSize();
633     d->page->setViewportSize(size);
634 }
635
636 /*! \reimp
637 */
638 void QGraphicsWebView::setGeometry(const QRectF& rect)
639 {
640     QGraphicsWidget::setGeometry(rect);
641
642     if (d->overlay())
643         d->overlay()->prepareGraphicsItemGeometryChange();
644
645     if (!d->page)
646         return;
647
648     // NOTE: call geometry() as setGeometry ensures that
649     // the geometry is within legal bounds (minimumSize, maximumSize)
650     QSize size = geometry().size().toSize();
651     d->page->setViewportSize(size);
652 }
653
654 /*!
655     Convenience slot that stops loading the document.
656
657     \sa reload(), loadFinished()
658 */
659 void QGraphicsWebView::stop()
660 {
661     if (d->page)
662         d->page->triggerAction(QWebPage::Stop);
663 }
664
665 /*!
666     Convenience slot that loads the previous document in the list of documents
667     built by navigating links. Does nothing if there is no previous document.
668
669     \sa forward()
670 */
671 void QGraphicsWebView::back()
672 {
673     if (d->page)
674         d->page->triggerAction(QWebPage::Back);
675 }
676
677 /*!
678     Convenience slot that loads the next document in the list of documents
679     built by navigating links. Does nothing if there is no next document.
680
681     \sa back()
682 */
683 void QGraphicsWebView::forward()
684 {
685     if (d->page)
686         d->page->triggerAction(QWebPage::Forward);
687 }
688
689 /*!
690     Reloads the current document.
691
692     \sa stop(), loadStarted()
693 */
694 void QGraphicsWebView::reload()
695 {
696     if (d->page)
697         d->page->triggerAction(QWebPage::Reload);
698 }
699
700 /*!
701     Loads the specified \a url and displays it.
702
703     \note The view remains the same until enough data has arrived to display the new \a url.
704
705     \sa setUrl(), url(), urlChanged()
706 */
707 void QGraphicsWebView::load(const QUrl& url)
708 {
709     page()->mainFrame()->load(url);
710 }
711
712 /*!
713     \fn void QGraphicsWebView::load(const QNetworkRequest &request, QNetworkAccessManager::Operation operation, const QByteArray &body)
714
715     Loads a network request, \a request, using the method specified in \a operation.
716
717     \a body is optional and is only used for POST operations.
718
719     \note The view remains the same until enough data has arrived to display the new url.
720
721     \sa url(), urlChanged()
722 */
723
724 void QGraphicsWebView::load(const QNetworkRequest& request,
725                     QNetworkAccessManager::Operation operation,
726                     const QByteArray& body)
727 {
728     page()->mainFrame()->load(request, operation, body);
729 }
730
731 /*!
732     Sets the content of the web view to the specified \a html.
733
734     External objects such as stylesheets or images referenced in the HTML
735     document are located relative to \a baseUrl.
736
737     The \a html is loaded immediately; external objects are loaded asynchronously.
738
739     When using this method, WebKit assumes that external resources such as
740     JavaScript programs or style sheets are encoded in UTF-8 unless otherwise
741     specified. For example, the encoding of an external script can be specified
742     through the charset attribute of the HTML script tag. Alternatively, the
743     encoding can also be specified by the web server.
744
745     This is a convenience function equivalent to setContent(html, "text/html", baseUrl).
746
747     \warning This function works only for HTML, for other mime types (i.e. XHTML, SVG)
748     setContent() should be used instead.
749
750     \sa load(), setContent(), QWebFrame::toHtml(), QWebFrame::setContent()
751 */
752 void QGraphicsWebView::setHtml(const QString& html, const QUrl& baseUrl)
753 {
754     page()->mainFrame()->setHtml(html, baseUrl);
755 }
756
757 /*!
758     Sets the content of the web graphicsitem to the specified content \a data. If the \a mimeType argument
759     is empty it is currently assumed that the content is HTML but in future versions we may introduce
760     auto-detection.
761
762     External objects referenced in the content are located relative to \a baseUrl.
763
764     The \a data is loaded immediately; external objects are loaded asynchronously.
765
766     \sa load(), setHtml(), QWebFrame::toHtml()
767 */
768 void QGraphicsWebView::setContent(const QByteArray& data, const QString& mimeType, const QUrl& baseUrl)
769 {
770     page()->mainFrame()->setContent(data, mimeType, baseUrl);
771 }
772
773 /*!
774     Returns a pointer to the view's history of navigated web pages.
775
776     It is equivalent to
777
778     \snippet webkitsnippets/qtwebkit_qwebview_snippet.cpp 0
779 */
780 QWebHistory* QGraphicsWebView::history() const
781 {
782     return page()->history();
783 }
784
785 /*!
786     \property QGraphicsWebView::modified
787     \brief whether the document was modified by the user
788
789     Parts of HTML documents can be editable for example through the
790     \c{contenteditable} attribute on HTML elements.
791
792     By default, this property is false.
793 */
794 bool QGraphicsWebView::isModified() const
795 {
796     if (d->page)
797         return d->page->isModified();
798     return false;
799 }
800
801 /*!
802     Returns a pointer to the view/page specific settings object.
803
804     It is equivalent to
805
806     \snippet webkitsnippets/qtwebkit_qwebview_snippet.cpp 1
807
808     \sa QWebSettings::globalSettings()
809 */
810 QWebSettings* QGraphicsWebView::settings() const
811 {
812     return page()->settings();
813 }
814
815 /*!
816     Returns a pointer to a QAction that encapsulates the specified web action \a action.
817 */
818 QAction *QGraphicsWebView::pageAction(QWebPage::WebAction action) const
819 {
820 #ifdef QT_NO_ACTION
821     Q_UNUSED(action)
822     return 0;
823 #else
824     return page()->action(action);
825 #endif
826 }
827
828 /*!
829     Triggers the specified \a action. If it is a checkable action the specified
830     \a checked state is assumed.
831
832     \sa pageAction()
833 */
834 void QGraphicsWebView::triggerPageAction(QWebPage::WebAction action, bool checked)
835 {
836     page()->triggerAction(action, checked);
837 }
838
839 /*!
840     Finds the specified string, \a subString, in the page, using the given \a options.
841
842     If the HighlightAllOccurrences flag is passed, the function will highlight all occurrences
843     that exist in the page. All subsequent calls will extend the highlight, rather than
844     replace it, with occurrences of the new string.
845
846     If the HighlightAllOccurrences flag is not passed, the function will select an occurrence
847     and all subsequent calls will replace the current occurrence with the next one.
848
849     To clear the selection, just pass an empty string.
850
851     Returns true if \a subString was found; otherwise returns false.
852
853     \sa QWebPage::selectedText(), QWebPage::selectionChanged()
854 */
855 bool QGraphicsWebView::findText(const QString &subString, QWebPage::FindFlags options)
856 {
857     if (d->page)
858         return d->page->findText(subString, options);
859     return false;
860 }
861
862 /*!
863     \property QGraphicsWebView::resizesToContents
864     \brief whether the size of the QGraphicsWebView and its viewport changes to match the contents size
865     \since 4.7 
866
867     If this property is set, the QGraphicsWebView will automatically change its
868     size to match the size of the main frame contents. As a result the top level frame
869     will never have scrollbars. It will also make CSS fixed positioning to behave like absolute positioning
870     with elements positioned relative to the document instead of the viewport.
871
872     This property should be used in conjunction with the QWebPage::preferredContentsSize property.
873     If not explicitly set, the preferredContentsSize is automatically set to a reasonable value.
874
875     \sa QWebPage::setPreferredContentsSize()
876 */
877 void QGraphicsWebView::setResizesToContents(bool enabled)
878 {
879     if (d->resizesToContents == enabled)
880         return;
881     d->resizesToContents = enabled;
882     if (d->page)
883         d->updateResizesToContentsForPage();
884 }
885
886 bool QGraphicsWebView::resizesToContents() const
887 {
888     return d->resizesToContents;
889 }
890
891 /*!
892     \property QGraphicsWebView::tiledBackingStoreFrozen
893     \brief whether the tiled backing store updates its contents
894     \since 4.7 
895
896     If the tiled backing store is enabled using QWebSettings::TiledBackingStoreEnabled attribute, this property
897     can be used to disable backing store updates temporarily. This can be useful for example for running
898     a smooth animation that changes the scale of the QGraphicsWebView.
899  
900     When the backing store is unfrozen, its contents will be automatically updated to match the current
901     state of the document. If the QGraphicsWebView scale was changed, the backing store is also
902     re-rendered using the new scale.
903  
904     If the tiled backing store is not enabled, this property does nothing.
905
906     \sa QWebSettings::TiledBackingStoreEnabled
907     \sa QGraphicsObject::scale
908 */
909 bool QGraphicsWebView::isTiledBackingStoreFrozen() const
910 {
911 #if ENABLE(TILED_BACKING_STORE)
912     WebCore::TiledBackingStore* backingStore = QWebFramePrivate::core(page()->mainFrame())->tiledBackingStore();
913     if (!backingStore)
914         return false;
915     return backingStore->contentsFrozen();
916 #else
917     return false;
918 #endif
919 }
920
921 void QGraphicsWebView::setTiledBackingStoreFrozen(bool frozen)
922 {
923 #if ENABLE(TILED_BACKING_STORE)
924     WebCore::TiledBackingStore* backingStore = QWebFramePrivate::core(page()->mainFrame())->tiledBackingStore();
925     if (!backingStore)
926         return;
927     backingStore->setContentsFrozen(frozen);
928 #else
929     UNUSED_PARAM(frozen);
930 #endif
931 }
932
933 /*! \reimp
934 */
935 void QGraphicsWebView::hoverMoveEvent(QGraphicsSceneHoverEvent* ev)
936 {
937     if (d->page) {
938         const bool accepted = ev->isAccepted();
939         QMouseEvent me = QMouseEvent(QEvent::MouseMove,
940                 ev->pos().toPoint(), Qt::NoButton,
941                 Qt::NoButton, Qt::NoModifier);
942         d->page->event(&me);
943         ev->setAccepted(accepted);
944     }
945
946     if (!ev->isAccepted())
947         QGraphicsItem::hoverMoveEvent(ev);
948 }
949
950 /*! \reimp
951 */
952 void QGraphicsWebView::hoverLeaveEvent(QGraphicsSceneHoverEvent* ev)
953 {
954     Q_UNUSED(ev);
955 }
956
957 /*! \reimp
958 */
959 void QGraphicsWebView::mouseMoveEvent(QGraphicsSceneMouseEvent* ev)
960 {
961     if (d->page) {
962         const bool accepted = ev->isAccepted();
963         d->page->event(ev);
964         ev->setAccepted(accepted);
965     }
966
967     if (!ev->isAccepted())
968         QGraphicsItem::mouseMoveEvent(ev);
969 }
970
971 /*! \reimp
972 */
973 void QGraphicsWebView::mousePressEvent(QGraphicsSceneMouseEvent* ev)
974 {
975     if (d->page) {
976         const bool accepted = ev->isAccepted();
977         d->page->event(ev);
978         ev->setAccepted(accepted);
979     }
980
981     if (!ev->isAccepted())
982         QGraphicsItem::mousePressEvent(ev);
983 }
984
985 /*! \reimp
986 */
987 void QGraphicsWebView::mouseReleaseEvent(QGraphicsSceneMouseEvent* ev)
988 {
989     if (d->page) {
990         const bool accepted = ev->isAccepted();
991         d->page->event(ev);
992         ev->setAccepted(accepted);
993     }
994
995     if (!ev->isAccepted())
996         QGraphicsItem::mouseReleaseEvent(ev);
997 }
998
999 /*! \reimp
1000 */
1001 void QGraphicsWebView::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* ev)
1002 {
1003     if (d->page) {
1004         const bool accepted = ev->isAccepted();
1005         d->page->event(ev);
1006         ev->setAccepted(accepted);
1007     }
1008
1009     if (!ev->isAccepted())
1010         QGraphicsItem::mouseDoubleClickEvent(ev);
1011 }
1012
1013 /*! \reimp
1014 */
1015 void QGraphicsWebView::keyPressEvent(QKeyEvent* ev)
1016 {
1017     if (d->page)
1018         d->page->event(ev);
1019
1020     if (!ev->isAccepted())
1021         QGraphicsItem::keyPressEvent(ev);
1022 }
1023
1024 /*! \reimp
1025 */
1026 void QGraphicsWebView::keyReleaseEvent(QKeyEvent* ev)
1027 {
1028     if (d->page)
1029         d->page->event(ev);
1030
1031     if (!ev->isAccepted())
1032         QGraphicsItem::keyReleaseEvent(ev);
1033 }
1034
1035 /*! \reimp
1036 */
1037 void QGraphicsWebView::focusInEvent(QFocusEvent* ev)
1038 {
1039     if (d->page)
1040         d->page->event(ev);
1041     else
1042         QGraphicsItem::focusInEvent(ev);
1043 }
1044
1045 /*! \reimp
1046 */
1047 void QGraphicsWebView::focusOutEvent(QFocusEvent* ev)
1048 {
1049     if (d->page)
1050         d->page->event(ev);
1051     else
1052         QGraphicsItem::focusOutEvent(ev);
1053 }
1054
1055 /*! \reimp
1056 */
1057 bool QGraphicsWebView::focusNextPrevChild(bool next)
1058 {
1059     if (d->page)
1060         return d->page->focusNextPrevChild(next);
1061
1062     return QGraphicsWidget::focusNextPrevChild(next);
1063 }
1064
1065 /*! \reimp
1066 */
1067 void QGraphicsWebView::dragEnterEvent(QGraphicsSceneDragDropEvent* ev)
1068 {
1069 #ifndef QT_NO_DRAGANDDROP
1070     if (d->page)
1071         d->page->event(ev);
1072 #else
1073     Q_UNUSED(ev);
1074 #endif
1075 }
1076
1077 /*! \reimp
1078 */
1079 void QGraphicsWebView::dragLeaveEvent(QGraphicsSceneDragDropEvent* ev)
1080 {
1081 #ifndef QT_NO_DRAGANDDROP
1082     if (d->page) {
1083         const bool accepted = ev->isAccepted();
1084         d->page->event(ev);
1085         ev->setAccepted(accepted);
1086     }
1087
1088     if (!ev->isAccepted())
1089         QGraphicsWidget::dragLeaveEvent(ev);
1090 #else
1091     Q_UNUSED(ev);
1092 #endif
1093 }
1094
1095 /*! \reimp
1096 */
1097 void QGraphicsWebView::dragMoveEvent(QGraphicsSceneDragDropEvent* ev)
1098 {
1099 #ifndef QT_NO_DRAGANDDROP
1100     if (d->page) {
1101         const bool accepted = ev->isAccepted();
1102         d->page->event(ev);
1103         ev->setAccepted(accepted);
1104     }
1105
1106     if (!ev->isAccepted())
1107         QGraphicsWidget::dragMoveEvent(ev);
1108 #else
1109     Q_UNUSED(ev);
1110 #endif
1111 }
1112
1113 /*! \reimp
1114 */
1115 void QGraphicsWebView::dropEvent(QGraphicsSceneDragDropEvent* ev)
1116 {
1117 #ifndef QT_NO_DRAGANDDROP
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         QGraphicsWidget::dropEvent(ev);
1126 #else
1127     Q_UNUSED(ev);
1128 #endif
1129 }
1130
1131 #ifndef QT_NO_CONTEXTMENU
1132 /*! \reimp
1133 */
1134 void QGraphicsWebView::contextMenuEvent(QGraphicsSceneContextMenuEvent* ev)
1135 {
1136     if (d->page) {
1137         const bool accepted = ev->isAccepted();
1138         d->page->event(ev);
1139         ev->setAccepted(accepted);
1140     }
1141 }
1142 #endif // QT_NO_CONTEXTMENU
1143
1144 #ifndef QT_NO_WHEELEVENT
1145 /*! \reimp
1146 */
1147 void QGraphicsWebView::wheelEvent(QGraphicsSceneWheelEvent* ev)
1148 {
1149     if (d->page) {
1150         const bool accepted = ev->isAccepted();
1151         d->page->event(ev);
1152         ev->setAccepted(accepted);
1153     }
1154
1155     if (!ev->isAccepted())
1156         QGraphicsItem::wheelEvent(ev);
1157 }
1158 #endif // QT_NO_WHEELEVENT
1159
1160 /*! \reimp
1161 */
1162 void QGraphicsWebView::inputMethodEvent(QInputMethodEvent* ev)
1163 {
1164     if (d->page)
1165         d->page->event(ev);
1166
1167     if (!ev->isAccepted())
1168         QGraphicsItem::inputMethodEvent(ev);
1169 }
1170
1171 /*!
1172     \fn void QGraphicsWebView::statusBarMessage(const QString& text)
1173
1174     This signal is emitted when the statusbar \a text is changed by the page.
1175 */
1176
1177 /*!
1178     \fn void QGraphicsWebView::loadProgress(int progress)
1179
1180     This signal is emitted every time an element in the web page
1181     completes loading and the overall loading progress advances.
1182
1183     This signal tracks the progress of all child frames.
1184
1185     The current value is provided by \a progress and scales from 0 to 100,
1186     which is the default range of QProgressBar.
1187
1188     \sa loadStarted(), loadFinished()
1189 */
1190
1191 /*!
1192     \fn void QGraphicsWebView::linkClicked(const QUrl &url)
1193
1194     This signal is emitted whenever the user clicks on a link and the page's linkDelegationPolicy
1195     property is set to delegate the link handling for the specified \a url.
1196
1197     \sa QWebPage::linkDelegationPolicy()
1198 */
1199
1200 #endif // QT_NO_GRAPHICSVIEW
1201
1202 #include "moc_qgraphicswebview.cpp"