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