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