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