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