1 /* 2 Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) 3 Copyright (C) 2009 Girish Ramakrishnan <girish (at) 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: 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 80 QGraphicsItemOverlay* overlay() const 81 { 82 if (!page || !page->d->client) 83 return 0; 84 return pageClient()->overlay; 85 } 86 87 PageClientQGraphicsWidget* pageClient() const 88 { 89 return static_cast<WebCore::PageClientQGraphicsWidget*> (page->d->client.get()); 90 } 91 }; 92 93 QGraphicsWebViewPrivate::~QGraphicsWebViewPrivate() 94 { 95 detachCurrentPage(); 96 } 97 98 void QGraphicsWebViewPrivate::syncLayers() 99 { 100 #if USE(ACCELERATED_COMPOSITING) 101 pageClient()->syncLayers(); 102 #endif 103 } 104 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 114 void QGraphicsWebViewPrivate::_q_pageDestroyed() 115 { 116 page = 0; 117 q->setPage(0); 118 } 119 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 139 void QGraphicsWebViewPrivate::_q_contentsSizeChanged(const QSize& size) 140 { 141 if (!resizesToContents) 142 return; 143 q->setGeometry(QRectF(q->geometry().topLeft(), size)); 144 } 145 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 */ 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 */ 252 QGraphicsWebView::~QGraphicsWebView() 253 { 254 delete d; 255 } 256 257 /*! 258 Returns a pointer to the underlying web page. 259 260 \sa setPage() 261 */ 262 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 */ 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 */ 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 */ 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 */ 350 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 */ 359 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 */ 388 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 */ 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 */ 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 */ 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 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 */ 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 555 void QGraphicsWebView::setUrl(const QUrl &url) 556 { 557 page()->mainFrame()->setUrl(url); 558 } 559 560 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 */ 576 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 */ 592 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 605 void QGraphicsWebView::setZoomFactor(qreal factor) 606 { 607 if (factor == page()->mainFrame()->zoomFactor()) 608 return; 609 610 page()->mainFrame()->setZoomFactor(factor); 611 } 612 613 qreal QGraphicsWebView::zoomFactor() const 614 { 615 return page()->mainFrame()->zoomFactor(); 616 } 617 618 /*! \reimp 619 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 */ 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 */ 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 */ 778 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 */ 792 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 */ 808 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 */ 816 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 */ 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 */ 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 */ 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 884 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 */ 907 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 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 */ 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 */ 950 void QGraphicsWebView::hoverLeaveEvent(QGraphicsSceneHoverEvent* ev) 951 { 952 Q_UNUSED(ev); 953 } 954 955 /*! \reimp 956 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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