1/* 2 Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) 3 Copyright (C) 2008 Holger Hans Peter Freyther 4 Copyright (C) 2009 Girish Ramakrishnan <girish@forwardbias.in> 5 6 This library is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Library General Public 8 License as published by the Free Software Foundation; either 9 version 2 of the License, or (at your option) any later version. 10 11 This library is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Library General Public License for more details. 15 16 You should have received a copy of the GNU Library General Public License 17 along with this library; see the file COPYING.LIB. If not, write to 18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 Boston, MA 02110-1301, USA. 20*/ 21 22#include "config.h" 23#include "qwebview.h" 24 25#include "Page.h" 26#include "QWebPageClient.h" 27#include "Settings.h" 28#include "qwebframe.h" 29#include "qwebpage_p.h" 30#include "qbitmap.h" 31#include "qevent.h" 32#include "qpainter.h" 33#include "qprinter.h" 34#include "qdir.h" 35#include "qfile.h" 36 37class QWebViewPrivate { 38public: 39 QWebViewPrivate(QWebView *view) 40 : view(view) 41 , page(0) 42 , renderHints(QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform) 43 { 44 Q_ASSERT(view); 45 } 46 47 virtual ~QWebViewPrivate(); 48 49 void _q_pageDestroyed(); 50 void detachCurrentPage(); 51 52 QWebView *view; 53 QWebPage *page; 54 55 QPainter::RenderHints renderHints; 56}; 57 58QWebViewPrivate::~QWebViewPrivate() 59{ 60 detachCurrentPage(); 61} 62 63void QWebViewPrivate::_q_pageDestroyed() 64{ 65 page = 0; 66 view->setPage(0); 67} 68 69#ifdef Q_WS_MAEMO_5 70#include "qabstractkineticscroller.h" 71#include "qapplication.h" 72 73// QCoreApplication::sendSpontaneousEvent() is private, hence this friend wrapper 74bool qt_sendSpontaneousEvent(QObject* receiver, QEvent* ev) 75{ 76 return QCoreApplication::sendSpontaneousEvent(receiver, ev); 77} 78 79class QWebViewKineticScroller : public QObject, public QAbstractKineticScroller { 80public: 81 QWebViewKineticScroller() 82 : QObject() 83 , QAbstractKineticScroller() 84 , m_view(0) 85 , m_ignoreEvents(false) 86 { 87 } 88 89 void setWidget(QWebView* widget) 90 { 91 if (m_view) { 92 m_view->removeEventFilter(this); 93 QWebFrame* frame = m_view->page()->mainFrame(); 94 frame->setScrollBarPolicy(Qt::Vertical, m_oldVerticalScrollBarPolicy); 95 frame->setScrollBarPolicy(Qt::Horizontal, m_oldHorizontalScrollBarPolicy); 96 } 97 98 m_view = widget; 99 setParent(m_view); 100 if (m_view) { 101 QWebFrame* frame = m_view->page()->mainFrame(); 102 m_oldHorizontalScrollBarPolicy = frame->scrollBarPolicy(Qt::Horizontal); 103 m_oldVerticalScrollBarPolicy = frame->scrollBarPolicy(Qt::Vertical); 104 frame->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff); 105 frame->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff); 106 m_view->installEventFilter(this); 107 } 108 } 109 110protected: 111 bool eventFilter(QObject* o, QEvent* ev) 112 { 113 if (!o || m_view != o || m_ignoreEvents || !m_view->isEnabled()) 114 return QObject::eventFilter(o, ev); 115 116 bool res = false; 117 118 switch (ev->type()) { 119 case QEvent::MouseButtonPress: { 120 // remember the frame where the button was pressed 121 QWebFrame* hitFrame = scrollingFrameAt(static_cast<QMouseEvent*>(ev)->pos()); 122 if (hitFrame) 123 m_frame = hitFrame; 124 // fall through 125 } 126 case QEvent::MouseMove: 127 case QEvent::MouseButtonRelease: 128 case QEvent::MouseButtonDblClick: 129 res = handleMouseEvent(static_cast<QMouseEvent*>(ev)); 130 break; 131 default: 132 break; 133 } 134 return res ? true : QObject::eventFilter(o, ev); 135 } 136 137 void cancelLeftMouseButtonPress(const QPoint& /* globalPressPos */) 138 { 139 QMouseEvent cmem(QEvent::MouseMove, QPoint(-INT_MAX, -INT_MAX), Qt::LeftButton, QApplication::mouseButtons() | Qt::LeftButton, QApplication::keyboardModifiers()); 140 sendEvent(m_view, &cmem); 141 QMouseEvent cmer(QEvent::MouseButtonRelease, QPoint(-INT_MAX, -INT_MAX), Qt::LeftButton, QApplication::mouseButtons() & ~Qt::LeftButton, QApplication::keyboardModifiers()); 142 sendEvent(m_view, &cmer); 143 } 144 145 QWebFrame* currentFrame() const 146 { 147 if (m_frame) 148 return m_frame; 149 150 if (m_view) 151 return m_view->page()->mainFrame(); 152 153 return 0; 154 } 155 156 // Returns the innermost frame at the given position that can scroll. 157 QWebFrame* scrollingFrameAt(const QPoint& pos) const 158 { 159 QWebFrame* hitFrame = 0; 160 if (m_view) { 161 QWebFrame* frame = m_view->page()->mainFrame(); 162 hitFrame = frame->hitTestContent(pos).frame(); 163 QSize range = hitFrame->contentsSize() - hitFrame->geometry().size(); 164 165 while (hitFrame && range.width() <= 1 && range.height() <= 1) 166 hitFrame = hitFrame->parentFrame(); 167 168 return hitFrame; 169 } 170 } 171 172 QPoint maximumScrollPosition() const 173 { 174 QWebFrame* frame = currentFrame(); 175 QSize s = frame ? frame->contentsSize() - frame->geometry().size() : QSize(0, 0); 176 return QPoint(qMax(0, s.width()), qMax(0, s.height())); 177 } 178 179 QPoint scrollPosition() const 180 { 181 QWebFrame* frame = currentFrame(); 182 return frame ? frame->scrollPosition() : QPoint(); 183 } 184 185 QSize viewportSize() const 186 { 187 return m_view ? m_view->page()->viewportSize() : QSize(); 188 } 189 190 void setScrollPosition(const QPoint& point, const QPoint& /* overShootDelta */) 191 { 192 QWebFrame* frame = currentFrame(); 193 if (frame) 194 frame->setScrollPosition(point); 195 } 196 197 void sendEvent(QWidget* w, QEvent* ev) 198 { 199 m_ignoreEvents = true; 200 qt_sendSpontaneousEvent(w, ev); 201 m_ignoreEvents = false; 202 } 203 204 QWebView* m_view; 205 bool m_ignoreEvents; 206 QPointer<QWebFrame> m_frame; 207 Qt::ScrollBarPolicy m_oldVerticalScrollBarPolicy; 208 Qt::ScrollBarPolicy m_oldHorizontalScrollBarPolicy; 209}; 210 211#endif // Q_WS_MAEMO_5 212 213 214/*! 215 \class QWebView 216 \since 4.4 217 \brief The QWebView class provides a widget that is used to view and edit 218 web documents. 219 \ingroup advanced 220 221 \inmodule QtWebKit 222 223 QWebView is the main widget component of the QtWebKit web browsing module. 224 It can be used in various applications to display web content live from the 225 Internet. 226 227 The image below shows QWebView previewed in \QD with a Nokia website. 228 229 \image qwebview-url.png 230 231 A web site can be loaded onto QWebView with the load() function. Like all 232 Qt widgets, the show() function must be invoked in order to display 233 QWebView. The snippet below illustrates this: 234 235 \snippet webkitsnippets/simple/main.cpp Using QWebView 236 237 Alternatively, setUrl() can also be used to load a web site. If you have 238 the HTML content readily available, you can use setHtml() instead. 239 240 The loadStarted() signal is emitted when the view begins loading. The 241 loadProgress() signal, on the other hand, is emitted whenever an element of 242 the web view completes loading, such as an embedded image, a script, etc. 243 Finally, the loadFinished() signal is emitted when the view has loaded 244 completely. It's argument - either \c true or \c false - indicates 245 load success or failure. 246 247 The page() function returns a pointer to the web page object. See 248 \l{Elements of QWebView} for an explanation of how the web page 249 is related to the view. To modify your web view's settings, you can access 250 the QWebSettings object with the settings() function. With QWebSettings, 251 you can change the default fonts, enable or disable features such as 252 JavaScript and plugins. 253 254 The title of an HTML document can be accessed with the title() property. 255 Additionally, a web site may also specify an icon, which can be accessed 256 using the icon() property. If the title or the icon changes, the corresponding 257 titleChanged() and iconChanged() signals will be emitted. The 258 textSizeMultiplier() property can be used to change the overall size of 259 the text displayed in the web view. 260 261 If you require a custom context menu, you can implement it by reimplementing 262 \l{QWidget::}{contextMenuEvent()} and populating your QMenu with the actions 263 obtained from pageAction(). More functionality such as reloading the view, 264 copying selected text to the clipboard, or pasting into the view, is also 265 encapsulated within the QAction objects returned by pageAction(). These 266 actions can be programmatically triggered using triggerPageAction(). 267 Alternatively, the actions can be added to a toolbar or a menu directly. 268 QWebView maintains the state of the returned actions but allows 269 modification of action properties such as \l{QAction::}{text} or 270 \l{QAction::}{icon}. 271 272 A QWebView can be printed onto a QPrinter using the print() function. 273 This function is marked as a slot and can be conveniently connected to 274 \l{QPrintPreviewDialog}'s \l{QPrintPreviewDialog::}{paintRequested()} 275 signal. 276 277 If you want to provide support for web sites that allow the user to open 278 new windows, such as pop-up windows, you can subclass QWebView and 279 reimplement the createWindow() function. 280 281 \section1 Elements of QWebView 282 283 QWebView consists of other objects such as QWebFrame and QWebPage. The 284 flowchart below shows these elements are related. 285 286 \image qwebview-diagram.png 287 288 \note It is possible to use QWebPage and QWebFrame, without using QWebView, 289 if you do not require QWidget attributes. Nevertheless, QtWebKit depends 290 on QtGui, so you should use a QApplication instead of QCoreApplication. 291 292 \sa {Previewer Example}, {Web Browser}, {Form Extractor Example}, 293 {Google Chat Example}, {Fancy Browser Example} 294*/ 295 296/*! 297 Constructs an empty QWebView with parent \a parent. 298 299 \sa load() 300*/ 301QWebView::QWebView(QWidget *parent) 302 : QWidget(parent) 303{ 304 d = new QWebViewPrivate(this); 305 306#if !defined(Q_WS_QWS) && !defined(Q_OS_SYMBIAN) 307 setAttribute(Qt::WA_InputMethodEnabled); 308#endif 309 310 setAttribute(Qt::WA_AcceptTouchEvents); 311#if defined(Q_WS_MAEMO_5) 312 QAbstractKineticScroller* scroller = new QWebViewKineticScroller(); 313 static_cast<QWebViewKineticScroller*>(scroller)->setWidget(this); 314 setProperty("kineticScroller", QVariant::fromValue(scroller)); 315#endif 316 setAcceptDrops(true); 317 318 setMouseTracking(true); 319 setFocusPolicy(Qt::WheelFocus); 320} 321 322/*! 323 Destroys the web view. 324*/ 325QWebView::~QWebView() 326{ 327 delete d; 328} 329 330/*! 331 Returns a pointer to the underlying web page. 332 333 \sa setPage() 334*/ 335QWebPage *QWebView::page() const 336{ 337 if (!d->page) { 338 QWebView *that = const_cast<QWebView *>(this); 339 that->setPage(new QWebPage(that)); 340 } 341 return d->page; 342} 343 344void QWebViewPrivate::detachCurrentPage() 345{ 346 if (!page) 347 return; 348 349 page->d->view.clear(); 350 351 // if the page client is the special client constructed for 352 // delegating the responsibilities to a QWidget, we need 353 // to destroy it. 354 355 if (page->d->client && page->d->client->isQWidgetClient()) 356 page->d->client.clear(); 357 358 page->d->client.release(); 359 360 // if the page was created by us, we own it and need to 361 // destroy it as well. 362 363 if (page->parent() == view) 364 delete page; 365 else 366 page->disconnect(view); 367 368 page = 0; 369} 370 371/*! 372 Makes \a page the new web page of the web view. 373 374 The parent QObject of the provided page remains the owner 375 of the object. If the current document is a child of the web 376 view, it will be deleted. 377 378 \sa page() 379*/ 380void QWebView::setPage(QWebPage* page) 381{ 382 if (d->page == page) 383 return; 384 385 d->detachCurrentPage(); 386 d->page = page; 387 388 if (d->page) { 389 d->page->setView(this); 390 d->page->setPalette(palette()); 391 // #### connect signals 392 QWebFrame *mainFrame = d->page->mainFrame(); 393 connect(mainFrame, SIGNAL(titleChanged(QString)), 394 this, SIGNAL(titleChanged(QString))); 395 connect(mainFrame, SIGNAL(iconChanged()), 396 this, SIGNAL(iconChanged())); 397 connect(mainFrame, SIGNAL(urlChanged(QUrl)), 398 this, SIGNAL(urlChanged(QUrl))); 399 400 connect(d->page, SIGNAL(loadStarted()), 401 this, SIGNAL(loadStarted())); 402 connect(d->page, SIGNAL(loadProgress(int)), 403 this, SIGNAL(loadProgress(int))); 404 connect(d->page, SIGNAL(loadFinished(bool)), 405 this, SIGNAL(loadFinished(bool))); 406 connect(d->page, SIGNAL(statusBarMessage(QString)), 407 this, SIGNAL(statusBarMessage(QString))); 408 connect(d->page, SIGNAL(linkClicked(QUrl)), 409 this, SIGNAL(linkClicked(QUrl))); 410 connect(d->page, SIGNAL(selectionChanged()), 411 this, SIGNAL(selectionChanged())); 412 413 connect(d->page, SIGNAL(microFocusChanged()), 414 this, SLOT(updateMicroFocus())); 415 connect(d->page, SIGNAL(destroyed()), 416 this, SLOT(_q_pageDestroyed())); 417 } 418 setAttribute(Qt::WA_OpaquePaintEvent, d->page); 419 update(); 420} 421 422/*! 423 Loads the specified \a url and displays it. 424 425 \note The view remains the same until enough data has arrived to display the new \a url. 426 427 \sa setUrl(), url(), urlChanged(), QUrl::fromUserInput() 428*/ 429void QWebView::load(const QUrl &url) 430{ 431 page()->mainFrame()->load(url); 432} 433 434/*! 435 \fn void QWebView::load(const QNetworkRequest &request, QNetworkAccessManager::Operation operation, const QByteArray &body) 436 437 Loads a network request, \a request, using the method specified in \a operation. 438 439 \a body is optional and is only used for POST operations. 440 441 \note The view remains the same until enough data has arrived to display the new url. 442 443 \sa url(), urlChanged() 444*/ 445 446void QWebView::load(const QNetworkRequest &request, 447 QNetworkAccessManager::Operation operation, 448 const QByteArray &body) 449{ 450 page()->mainFrame()->load(request, operation, body); 451} 452 453/*! 454 Sets the content of the web view to the specified \a html. 455 456 External objects such as stylesheets or images referenced in the HTML 457 document are located relative to \a baseUrl. 458 459 The \a html is loaded immediately; external objects are loaded asynchronously. 460 461 When using this method, WebKit assumes that external resources such as 462 JavaScript programs or style sheets are encoded in UTF-8 unless otherwise 463 specified. For example, the encoding of an external script can be specified 464 through the charset attribute of the HTML script tag. Alternatively, the 465 encoding can also be specified by the web server. 466 467 This is a convenience function equivalent to setContent(html, "text/html", baseUrl). 468 469 \warning This function works only for HTML, for other mime types (i.e. XHTML, SVG) 470 setContent() should be used instead. 471 472 \sa load(), setContent(), QWebFrame::toHtml(), QWebFrame::setContent() 473*/ 474void QWebView::setHtml(const QString &html, const QUrl &baseUrl) 475{ 476 page()->mainFrame()->setHtml(html, baseUrl); 477} 478 479/*! 480 Sets the content of the web view to the specified content \a data. If the \a mimeType argument 481 is empty it is currently assumed that the content is HTML but in future versions we may introduce 482 auto-detection. 483 484 External objects referenced in the content are located relative to \a baseUrl. 485 486 The \a data is loaded immediately; external objects are loaded asynchronously. 487 488 \sa load(), setHtml(), QWebFrame::toHtml() 489*/ 490void QWebView::setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl) 491{ 492 page()->mainFrame()->setContent(data, mimeType, baseUrl); 493} 494 495/*! 496 Returns a pointer to the view's history of navigated web pages. 497 498 It is equivalent to 499 500 \snippet webkitsnippets/qtwebkit_qwebview_snippet.cpp 0 501*/ 502QWebHistory *QWebView::history() const 503{ 504 return page()->history(); 505} 506 507/*! 508 Returns a pointer to the view/page specific settings object. 509 510 It is equivalent to 511 512 \snippet webkitsnippets/qtwebkit_qwebview_snippet.cpp 1 513 514 \sa QWebSettings::globalSettings() 515*/ 516QWebSettings *QWebView::settings() const 517{ 518 return page()->settings(); 519} 520 521/*! 522 \property QWebView::title 523 \brief the title of the web page currently viewed 524 525 By default, this property contains an empty string. 526 527 \sa titleChanged() 528*/ 529QString QWebView::title() const 530{ 531 if (d->page) 532 return d->page->mainFrame()->title(); 533 return QString(); 534} 535 536/*! 537 \property QWebView::url 538 \brief the url of the web page currently viewed 539 540 Setting this property clears the view and loads the URL. 541 542 By default, this property contains an empty, invalid URL. 543 544 \sa load(), urlChanged() 545*/ 546 547void QWebView::setUrl(const QUrl &url) 548{ 549 page()->mainFrame()->setUrl(url); 550} 551 552QUrl QWebView::url() const 553{ 554 if (d->page) 555 return d->page->mainFrame()->url(); 556 return QUrl(); 557} 558 559/*! 560 \property QWebView::icon 561 \brief the icon associated with the web page currently viewed 562 563 By default, this property contains a null icon. 564 565 \sa iconChanged(), QWebSettings::iconForUrl() 566*/ 567QIcon QWebView::icon() const 568{ 569 if (d->page) 570 return d->page->mainFrame()->icon(); 571 return QIcon(); 572} 573 574/*! 575 \property QWebView::hasSelection 576 \brief whether this page contains selected content or not. 577 578 By default, this property is false. 579 580 \sa selectionChanged() 581*/ 582bool QWebView::hasSelection() const 583{ 584 if (d->page) 585 return d->page->hasSelection(); 586 return false; 587} 588 589/*! 590 \property QWebView::selectedText 591 \brief the text currently selected 592 593 By default, this property contains an empty string. 594 595 \sa findText(), selectionChanged(), selectedHtml() 596*/ 597QString QWebView::selectedText() const 598{ 599 if (d->page) 600 return d->page->selectedText(); 601 return QString(); 602} 603 604/*! 605 \since 4.8 606 \property QWebView::selectedHtml 607 \brief the HTML currently selected 608 609 By default, this property contains an empty string. 610 611 \sa findText(), selectionChanged(), selectedText() 612*/ 613QString QWebView::selectedHtml() const 614{ 615 if (d->page) 616 return d->page->selectedHtml(); 617 return QString(); 618} 619 620#ifndef QT_NO_ACTION 621/*! 622 Returns a pointer to a QAction that encapsulates the specified web action \a action. 623*/ 624QAction *QWebView::pageAction(QWebPage::WebAction action) const 625{ 626 return page()->action(action); 627} 628#endif 629 630/*! 631 Triggers the specified \a action. If it is a checkable action the specified 632 \a checked state is assumed. 633 634 The following example triggers the copy action and therefore copies any 635 selected text to the clipboard. 636 637 \snippet webkitsnippets/qtwebkit_qwebview_snippet.cpp 2 638 639 \sa pageAction() 640*/ 641void QWebView::triggerPageAction(QWebPage::WebAction action, bool checked) 642{ 643 page()->triggerAction(action, checked); 644} 645 646/*! 647 \property QWebView::modified 648 \brief whether the document was modified by the user 649 650 Parts of HTML documents can be editable for example through the 651 \c{contenteditable} attribute on HTML elements. 652 653 By default, this property is false. 654*/ 655bool QWebView::isModified() const 656{ 657 if (d->page) 658 return d->page->isModified(); 659 return false; 660} 661 662/* 663Qt::TextInteractionFlags QWebView::textInteractionFlags() const 664{ 665 // ### FIXME (add to page) 666 return Qt::TextInteractionFlags(); 667} 668*/ 669 670/* 671 \property QWebView::textInteractionFlags 672 \brief how the view should handle user input 673 674 Specifies how the user can interact with the text on the page. 675*/ 676 677/* 678void QWebView::setTextInteractionFlags(Qt::TextInteractionFlags flags) 679{ 680 Q_UNUSED(flags) 681 // ### FIXME (add to page) 682} 683*/ 684 685/*! 686 \reimp 687*/ 688QSize QWebView::sizeHint() const 689{ 690 return QSize(800, 600); // ####... 691} 692 693/*! 694 \property QWebView::zoomFactor 695 \since 4.5 696 \brief the zoom factor for the view 697*/ 698 699void QWebView::setZoomFactor(qreal factor) 700{ 701 page()->mainFrame()->setZoomFactor(factor); 702} 703 704qreal QWebView::zoomFactor() const 705{ 706 return page()->mainFrame()->zoomFactor(); 707} 708 709/*! 710 \property QWebView::textSizeMultiplier 711 \brief the scaling factor for all text in the frame 712 \obsolete 713 714 Use setZoomFactor instead, in combination with the 715 ZoomTextOnly attribute in QWebSettings. 716 717 \note Setting this property also enables the 718 ZoomTextOnly attribute in QWebSettings. 719 720 By default, this property contains a value of 1.0. 721*/ 722 723/*! 724 Sets the value of the multiplier used to scale the text in a Web page to 725 the \a factor specified. 726*/ 727void QWebView::setTextSizeMultiplier(qreal factor) 728{ 729 page()->mainFrame()->setTextSizeMultiplier(factor); 730} 731 732/*! 733 Returns the value of the multiplier used to scale the text in a Web page. 734*/ 735qreal QWebView::textSizeMultiplier() const 736{ 737 return page()->mainFrame()->textSizeMultiplier(); 738} 739 740/*! 741 \property QWebView::renderHints 742 \since 4.6 743 \brief the default render hints for the view 744 745 These hints are used to initialize QPainter before painting the Web page. 746 747 QPainter::TextAntialiasing and QPainter::SmoothPixmapTransform are enabled by default. 748 749 \note This property is not available on Symbian. However, the getter and 750 setter functions can still be used directly. 751 752 \sa QPainter::renderHints() 753*/ 754 755/*! 756 \since 4.6 757 Returns the render hints used by the view to render content. 758 759 \sa QPainter::renderHints() 760*/ 761QPainter::RenderHints QWebView::renderHints() const 762{ 763 return d->renderHints; 764} 765 766/*! 767 \since 4.6 768 Sets the render hints used by the view to the specified \a hints. 769 770 \sa QPainter::setRenderHints() 771*/ 772void QWebView::setRenderHints(QPainter::RenderHints hints) 773{ 774 if (hints == d->renderHints) 775 return; 776 d->renderHints = hints; 777 update(); 778} 779 780/*! 781 \since 4.6 782 If \a enabled is true, enables the specified render \a hint; otherwise 783 disables it. 784 785 \sa renderHints, QPainter::renderHints() 786*/ 787void QWebView::setRenderHint(QPainter::RenderHint hint, bool enabled) 788{ 789 QPainter::RenderHints oldHints = d->renderHints; 790 if (enabled) 791 d->renderHints |= hint; 792 else 793 d->renderHints &= ~hint; 794 if (oldHints != d->renderHints) 795 update(); 796} 797 798 799/*! 800 Finds the specified string, \a subString, in the page, using the given \a options. 801 802 If the HighlightAllOccurrences flag is passed, the function will highlight all occurrences 803 that exist in the page. All subsequent calls will extend the highlight, rather than 804 replace it, with occurrences of the new string. 805 806 If the HighlightAllOccurrences flag is not passed, the function will select an occurrence 807 and all subsequent calls will replace the current occurrence with the next one. 808 809 To clear the selection, just pass an empty string. 810 811 Returns true if \a subString was found; otherwise returns false. 812 813 \sa selectedText(), selectionChanged() 814*/ 815bool QWebView::findText(const QString &subString, QWebPage::FindFlags options) 816{ 817 if (d->page) 818 return d->page->findText(subString, options); 819 return false; 820} 821 822/*! \reimp 823*/ 824bool QWebView::event(QEvent *e) 825{ 826 if (d->page) { 827#ifndef QT_NO_CONTEXTMENU 828 if (e->type() == QEvent::ContextMenu) { 829 if (!isEnabled()) 830 return false; 831 QContextMenuEvent *event = static_cast<QContextMenuEvent *>(e); 832 if (d->page->swallowContextMenuEvent(event)) { 833 e->accept(); 834 return true; 835 } 836 d->page->updatePositionDependentActions(event->pos()); 837 } else 838#endif // QT_NO_CONTEXTMENU 839 if (e->type() == QEvent::ShortcutOverride) { 840 d->page->event(e); 841#ifndef QT_NO_CURSOR 842 } else if (e->type() == QEvent::CursorChange) { 843 // An unsetCursor will set the cursor to Qt::ArrowCursor. 844 // Thus this cursor change might be a QWidget::unsetCursor() 845 // If this is not the case and it came from WebCore, the 846 // QWebPageClient already has set its cursor internally 847 // to Qt::ArrowCursor, so updating the cursor is always 848 // right, as it falls back to the last cursor set by 849 // WebCore. 850 // FIXME: Add a QEvent::CursorUnset or similar to Qt. 851 if (cursor().shape() == Qt::ArrowCursor) 852 d->page->d->client->resetCursor(); 853#endif 854 } else if (e->type() == QEvent::TouchBegin 855 || e->type() == QEvent::TouchEnd 856 || e->type() == QEvent::TouchUpdate) { 857 d->page->event(e); 858 859 // Always return true so that we'll receive also TouchUpdate and TouchEnd events 860 return true; 861 } else if (e->type() == QEvent::Leave) 862 d->page->event(e); 863 } 864 865 return QWidget::event(e); 866} 867 868/*! 869 Prints the main frame to the given \a printer. 870 871 \sa QWebFrame::print(), QPrintPreviewDialog 872*/ 873void QWebView::print(QPrinter *printer) const 874{ 875#ifndef QT_NO_PRINTER 876 page()->mainFrame()->print(printer); 877#endif 878} 879 880/*! 881 Convenience slot that stops loading the document. 882 883 It is equivalent to 884 885 \snippet webkitsnippets/qtwebkit_qwebview_snippet.cpp 3 886 887 \sa reload(), pageAction(), loadFinished() 888*/ 889void QWebView::stop() 890{ 891 if (d->page) 892 d->page->triggerAction(QWebPage::Stop); 893} 894 895/*! 896 Convenience slot that loads the previous document in the list of documents 897 built by navigating links. Does nothing if there is no previous document. 898 899 It is equivalent to 900 901 \snippet webkitsnippets/qtwebkit_qwebview_snippet.cpp 4 902 903 \sa forward(), pageAction() 904*/ 905void QWebView::back() 906{ 907 if (d->page) 908 d->page->triggerAction(QWebPage::Back); 909} 910 911/*! 912 Convenience slot that loads the next document in the list of documents 913 built by navigating links. Does nothing if there is no next document. 914 915 It is equivalent to 916 917 \snippet webkitsnippets/qtwebkit_qwebview_snippet.cpp 5 918 919 \sa back(), pageAction() 920*/ 921void QWebView::forward() 922{ 923 if (d->page) 924 d->page->triggerAction(QWebPage::Forward); 925} 926 927/*! 928 Reloads the current document. 929 930 \sa stop(), pageAction(), loadStarted() 931*/ 932void QWebView::reload() 933{ 934 if (d->page) 935 d->page->triggerAction(QWebPage::Reload); 936} 937 938/*! \reimp 939*/ 940void QWebView::resizeEvent(QResizeEvent *e) 941{ 942 if (d->page) 943 d->page->setViewportSize(e->size()); 944} 945 946/*! \reimp 947*/ 948void QWebView::paintEvent(QPaintEvent *ev) 949{ 950 if (!d->page) 951 return; 952#ifdef QWEBKIT_TIME_RENDERING 953 QTime time; 954 time.start(); 955#endif 956 957 QWebFrame *frame = d->page->mainFrame(); 958 QPainter p(this); 959 p.setRenderHints(d->renderHints); 960 961 frame->render(&p, ev->region()); 962 963#ifdef QWEBKIT_TIME_RENDERING 964 int elapsed = time.elapsed(); 965 qDebug() << "paint event on " << ev->region() << ", took to render = " << elapsed; 966#endif 967} 968 969/*! 970 This function is called from the createWindow() method of the associated QWebPage, 971 each time the page wants to create a new window of the given \a type. This might 972 be the result, for example, of a JavaScript request to open a document in a new window. 973 974 \note If the createWindow() method of the associated page is reimplemented, this 975 method is not called, unless explicitly done so in the reimplementation. 976 977 \note In the cases when the window creation is being triggered by JavaScript, apart from 978 reimplementing this method application must also set the JavaScriptCanOpenWindows attribute 979 of QWebSettings to true in order for it to get called. 980 981 \sa QWebPage::createWindow(), QWebPage::acceptNavigationRequest() 982*/ 983QWebView *QWebView::createWindow(QWebPage::WebWindowType type) 984{ 985 Q_UNUSED(type) 986 return 0; 987} 988 989/*! \reimp 990*/ 991void QWebView::mouseMoveEvent(QMouseEvent* ev) 992{ 993 if (d->page) { 994 const bool accepted = ev->isAccepted(); 995 d->page->event(ev); 996 ev->setAccepted(accepted); 997 } 998} 999 1000/*! \reimp 1001*/ 1002void QWebView::mousePressEvent(QMouseEvent* ev) 1003{ 1004 if (d->page) { 1005 const bool accepted = ev->isAccepted(); 1006 d->page->event(ev); 1007 ev->setAccepted(accepted); 1008 } 1009} 1010 1011/*! \reimp 1012*/ 1013void QWebView::mouseDoubleClickEvent(QMouseEvent* ev) 1014{ 1015 if (d->page) { 1016 const bool accepted = ev->isAccepted(); 1017 d->page->event(ev); 1018 ev->setAccepted(accepted); 1019 } 1020} 1021 1022/*! \reimp 1023*/ 1024void QWebView::mouseReleaseEvent(QMouseEvent* ev) 1025{ 1026 if (d->page) { 1027 const bool accepted = ev->isAccepted(); 1028 d->page->event(ev); 1029 ev->setAccepted(accepted); 1030 } 1031} 1032 1033#ifndef QT_NO_CONTEXTMENU 1034/*! \reimp 1035*/ 1036void QWebView::contextMenuEvent(QContextMenuEvent* ev) 1037{ 1038 if (d->page) { 1039 const bool accepted = ev->isAccepted(); 1040 d->page->event(ev); 1041 ev->setAccepted(accepted); 1042 } 1043} 1044#endif // QT_NO_CONTEXTMENU 1045 1046#ifndef QT_NO_WHEELEVENT 1047/*! \reimp 1048*/ 1049void QWebView::wheelEvent(QWheelEvent* ev) 1050{ 1051 if (d->page) { 1052 const bool accepted = ev->isAccepted(); 1053 d->page->event(ev); 1054 ev->setAccepted(accepted); 1055 } 1056} 1057#endif // QT_NO_WHEELEVENT 1058 1059/*! \reimp 1060*/ 1061void QWebView::keyPressEvent(QKeyEvent* ev) 1062{ 1063 if (d->page) 1064 d->page->event(ev); 1065 if (!ev->isAccepted()) 1066 QWidget::keyPressEvent(ev); 1067} 1068 1069/*! \reimp 1070*/ 1071void QWebView::keyReleaseEvent(QKeyEvent* ev) 1072{ 1073 if (d->page) 1074 d->page->event(ev); 1075 if (!ev->isAccepted()) 1076 QWidget::keyReleaseEvent(ev); 1077} 1078 1079/*! \reimp 1080*/ 1081void QWebView::focusInEvent(QFocusEvent* ev) 1082{ 1083 if (d->page) 1084 d->page->event(ev); 1085 else 1086 QWidget::focusInEvent(ev); 1087} 1088 1089/*! \reimp 1090*/ 1091void QWebView::focusOutEvent(QFocusEvent* ev) 1092{ 1093 if (d->page) 1094 d->page->event(ev); 1095 else 1096 QWidget::focusOutEvent(ev); 1097} 1098 1099/*! \reimp 1100*/ 1101void QWebView::dragEnterEvent(QDragEnterEvent* ev) 1102{ 1103#ifndef QT_NO_DRAGANDDROP 1104 if (d->page) 1105 d->page->event(ev); 1106#endif 1107} 1108 1109/*! \reimp 1110*/ 1111void QWebView::dragLeaveEvent(QDragLeaveEvent* ev) 1112{ 1113#ifndef QT_NO_DRAGANDDROP 1114 if (d->page) 1115 d->page->event(ev); 1116#endif 1117} 1118 1119/*! \reimp 1120*/ 1121void QWebView::dragMoveEvent(QDragMoveEvent* ev) 1122{ 1123#ifndef QT_NO_DRAGANDDROP 1124 if (d->page) 1125 d->page->event(ev); 1126#endif 1127} 1128 1129/*! \reimp 1130*/ 1131void QWebView::dropEvent(QDropEvent* ev) 1132{ 1133#ifndef QT_NO_DRAGANDDROP 1134 if (d->page) 1135 d->page->event(ev); 1136#endif 1137} 1138 1139/*! \reimp 1140*/ 1141bool QWebView::focusNextPrevChild(bool next) 1142{ 1143 if (d->page && d->page->focusNextPrevChild(next)) 1144 return true; 1145 return QWidget::focusNextPrevChild(next); 1146} 1147 1148/*!\reimp 1149*/ 1150QVariant QWebView::inputMethodQuery(Qt::InputMethodQuery property) const 1151{ 1152 if (d->page) 1153 return d->page->inputMethodQuery(property); 1154 return QVariant(); 1155} 1156 1157/*!\reimp 1158*/ 1159void QWebView::inputMethodEvent(QInputMethodEvent *e) 1160{ 1161 if (d->page) 1162 d->page->event(e); 1163} 1164 1165/*!\reimp 1166*/ 1167void QWebView::changeEvent(QEvent *e) 1168{ 1169 if (d->page && e->type() == QEvent::PaletteChange) 1170 d->page->setPalette(palette()); 1171 QWidget::changeEvent(e); 1172} 1173 1174/*! 1175 \fn void QWebView::titleChanged(const QString &title) 1176 1177 This signal is emitted whenever the \a title of the main frame changes. 1178 1179 \sa title() 1180*/ 1181 1182/*! 1183 \fn void QWebView::urlChanged(const QUrl &url) 1184 1185 This signal is emitted when the \a url of the view changes. 1186 1187 \sa url(), load() 1188*/ 1189 1190/*! 1191 \fn void QWebView::statusBarMessage(const QString& text) 1192 1193 This signal is emitted when the status bar \a text is changed by the page. 1194*/ 1195 1196/*! 1197 \fn void QWebView::iconChanged() 1198 1199 This signal is emitted whenever the icon of the page is loaded or changes. 1200 1201 In order for icons to be loaded, you will need to set an icon database path 1202 using QWebSettings::setIconDatabasePath(). 1203 1204 \sa icon(), QWebSettings::setIconDatabasePath() 1205*/ 1206 1207/*! 1208 \fn void QWebView::loadStarted() 1209 1210 This signal is emitted when a new load of the page is started. 1211 1212 \sa loadProgress(), loadFinished() 1213*/ 1214 1215/*! 1216 \fn void QWebView::loadFinished(bool ok) 1217 1218 This signal is emitted when a load of the page is finished. 1219 \a ok will indicate whether the load was successful or any error occurred. 1220 1221 \sa loadStarted() 1222*/ 1223 1224/*! 1225 \fn void QWebView::selectionChanged() 1226 1227 This signal is emitted whenever the selection changes. 1228 1229 \sa selectedText() 1230*/ 1231 1232/*! 1233 \fn void QWebView::loadProgress(int progress) 1234 1235 This signal is emitted every time an element in the web page 1236 completes loading and the overall loading progress advances. 1237 1238 This signal tracks the progress of all child frames. 1239 1240 The current value is provided by \a progress and scales from 0 to 100, 1241 which is the default range of QProgressBar. 1242 1243 \sa loadStarted(), loadFinished() 1244*/ 1245 1246/*! 1247 \fn void QWebView::linkClicked(const QUrl &url) 1248 1249 This signal is emitted whenever the user clicks on a link and the page's linkDelegationPolicy 1250 property is set to delegate the link handling for the specified \a url. 1251 1252 \sa QWebPage::linkDelegationPolicy() 1253*/ 1254 1255#include "moc_qwebview.cpp" 1256 1257