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 | 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 
     58 QWebViewPrivate::~QWebViewPrivate()
     59 {
     60     detachCurrentPage();
     61 }
     62 
     63 void 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
     74 bool qt_sendSpontaneousEvent(QObject* receiver, QEvent* ev)
     75 {
     76     return QCoreApplication::sendSpontaneousEvent(receiver, ev);
     77 }
     78 
     79 class QWebViewKineticScroller : public QObject, public QAbstractKineticScroller {
     80 public:
     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 
    110 protected:
    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 */
    301 QWebView::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 */
    325 QWebView::~QWebView()
    326 {
    327     delete d;
    328 }
    329 
    330 /*!
    331     Returns a pointer to the underlying web page.
    332 
    333     \sa setPage()
    334 */
    335 QWebPage *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 
    344 void 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 */
    380 void 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 */
    429 void 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 
    446 void 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 */
    474 void 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 */
    490 void 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 */
    502 QWebHistory *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 */
    516 QWebSettings *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 */
    529 QString 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 
    547 void QWebView::setUrl(const QUrl &url)
    548 {
    549     page()->mainFrame()->setUrl(url);
    550 }
    551 
    552 QUrl 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 */
    567 QIcon 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 */
    582 bool 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 */
    597 QString 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 */
    613 QString 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 */
    624 QAction *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 */
    641 void 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 */
    655 bool QWebView::isModified() const
    656 {
    657     if (d->page)
    658         return d->page->isModified();
    659     return false;
    660 }
    661 
    662 /*
    663 Qt::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 /*
    678 void QWebView::setTextInteractionFlags(Qt::TextInteractionFlags flags)
    679 {
    680     Q_UNUSED(flags)
    681     // ### FIXME (add to page)
    682 }
    683 */
    684 
    685 /*!
    686     \reimp
    687 */
    688 QSize 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 
    699 void QWebView::setZoomFactor(qreal factor)
    700 {
    701     page()->mainFrame()->setZoomFactor(factor);
    702 }
    703 
    704 qreal 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 */
    727 void 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 */
    735 qreal 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 */
    761 QPainter::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 */
    772 void 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 */
    787 void 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 */
    815 bool 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 */
    824 bool 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 */
    873 void 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 */
    889 void 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 */
    905 void 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 */
    921 void 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 */
    932 void QWebView::reload()
    933 {
    934     if (d->page)
    935         d->page->triggerAction(QWebPage::Reload);
    936 }
    937 
    938 /*! \reimp
    939 */
    940 void QWebView::resizeEvent(QResizeEvent *e)
    941 {
    942     if (d->page)
    943         d->page->setViewportSize(e->size());
    944 }
    945 
    946 /*! \reimp
    947 */
    948 void 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 */
    983 QWebView *QWebView::createWindow(QWebPage::WebWindowType type)
    984 {
    985     Q_UNUSED(type)
    986     return 0;
    987 }
    988 
    989 /*! \reimp
    990 */
    991 void 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 */
   1002 void 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 */
   1013 void 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 */
   1024 void 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 */
   1036 void 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 */
   1049 void 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 */
   1061 void 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 */
   1071 void 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 */
   1081 void 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 */
   1091 void 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 */
   1101 void 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 */
   1111 void 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 */
   1121 void 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 */
   1131 void 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 */
   1141 bool 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 */
   1150 QVariant 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 */
   1159 void QWebView::inputMethodEvent(QInputMethodEvent *e)
   1160 {
   1161     if (d->page)
   1162        d->page->event(e);
   1163 }
   1164 
   1165 /*!\reimp
   1166 */
   1167 void 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