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