• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
37 class QWebViewPrivate {
38 public:
QWebViewPrivate(QWebView * view)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 
~QWebViewPrivate()58 QWebViewPrivate::~QWebViewPrivate()
59 {
60     detachCurrentPage();
61 }
62 
_q_pageDestroyed()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
qt_sendSpontaneousEvent(QObject * receiver,QEvent * ev)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:
QWebViewKineticScroller()81     QWebViewKineticScroller()
82         : QObject()
83         , QAbstractKineticScroller()
84         , m_view(0)
85         , m_ignoreEvents(false)
86     {
87     }
88 
setWidget(QWebView * widget)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:
eventFilter(QObject * o,QEvent * ev)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 
cancelLeftMouseButtonPress(const QPoint &)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 
currentFrame() const145     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.
scrollingFrameAt(const QPoint & pos) const157     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 
maximumScrollPosition() const172     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 
scrollPosition() const179     QPoint scrollPosition() const
180     {
181         QWebFrame* frame = currentFrame();
182         return frame ? frame->scrollPosition() : QPoint();
183     }
184 
viewportSize() const185     QSize viewportSize() const
186     {
187         return m_view ? m_view->page()->viewportSize() : QSize();
188     }
189 
setScrollPosition(const QPoint & point,const QPoint &)190     void setScrollPosition(const QPoint& point, const QPoint& /* overShootDelta */)
191     {
192         QWebFrame* frame = currentFrame();
193         if (frame)
194             frame->setScrollPosition(point);
195     }
196 
sendEvent(QWidget * w,QEvent * ev)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 */
QWebView(QWidget * parent)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 */
~QWebView()325 QWebView::~QWebView()
326 {
327     delete d;
328 }
329 
330 /*!
331     Returns a pointer to the underlying web page.
332 
333     \sa setPage()
334 */
page() const335 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 
detachCurrentPage()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 */
setPage(QWebPage * page)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 */
load(const QUrl & url)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 
load(const QNetworkRequest & request,QNetworkAccessManager::Operation operation,const QByteArray & body)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 */
setHtml(const QString & html,const QUrl & baseUrl)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 */
setContent(const QByteArray & data,const QString & mimeType,const QUrl & baseUrl)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 */
history() const502 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 */
settings() const516 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 */
title() const529 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 
setUrl(const QUrl & url)547 void QWebView::setUrl(const QUrl &url)
548 {
549     page()->mainFrame()->setUrl(url);
550 }
551 
url() const552 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 */
icon() const567 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 */
hasSelection() const582 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 */
selectedText() const597 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 */
selectedHtml() const613 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 */
pageAction(QWebPage::WebAction action) const624 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 */
triggerPageAction(QWebPage::WebAction action,bool checked)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 */
isModified() const655 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 */
sizeHint() const688 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 
setZoomFactor(qreal factor)699 void QWebView::setZoomFactor(qreal factor)
700 {
701     page()->mainFrame()->setZoomFactor(factor);
702 }
703 
zoomFactor() const704 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 */
setTextSizeMultiplier(qreal factor)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 */
textSizeMultiplier() const735 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 */
renderHints() const761 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 */
setRenderHints(QPainter::RenderHints hints)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 */
setRenderHint(QPainter::RenderHint hint,bool enabled)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 */
findText(const QString & subString,QWebPage::FindFlags options)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 */
event(QEvent * e)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 */
print(QPrinter * printer) const873 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 */
stop()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 */
back()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 */
forward()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 */
reload()932 void QWebView::reload()
933 {
934     if (d->page)
935         d->page->triggerAction(QWebPage::Reload);
936 }
937 
938 /*! \reimp
939 */
resizeEvent(QResizeEvent * e)940 void QWebView::resizeEvent(QResizeEvent *e)
941 {
942     if (d->page)
943         d->page->setViewportSize(e->size());
944 }
945 
946 /*! \reimp
947 */
paintEvent(QPaintEvent * ev)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 */
createWindow(QWebPage::WebWindowType type)983 QWebView *QWebView::createWindow(QWebPage::WebWindowType type)
984 {
985     Q_UNUSED(type)
986     return 0;
987 }
988 
989 /*! \reimp
990 */
mouseMoveEvent(QMouseEvent * ev)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 */
mousePressEvent(QMouseEvent * ev)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 */
mouseDoubleClickEvent(QMouseEvent * ev)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 */
mouseReleaseEvent(QMouseEvent * ev)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 */
contextMenuEvent(QContextMenuEvent * ev)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 */
wheelEvent(QWheelEvent * ev)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 */
keyPressEvent(QKeyEvent * ev)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 */
keyReleaseEvent(QKeyEvent * ev)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 */
focusInEvent(QFocusEvent * ev)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 */
focusOutEvent(QFocusEvent * ev)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 */
dragEnterEvent(QDragEnterEvent * ev)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 */
dragLeaveEvent(QDragLeaveEvent * ev)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 */
dragMoveEvent(QDragMoveEvent * ev)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 */
dropEvent(QDropEvent * ev)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 */
focusNextPrevChild(bool next)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 */
inputMethodQuery(Qt::InputMethodQuery property) const1150 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 */
inputMethodEvent(QInputMethodEvent * e)1159 void QWebView::inputMethodEvent(QInputMethodEvent *e)
1160 {
1161     if (d->page)
1162        d->page->event(e);
1163 }
1164 
1165 /*!\reimp
1166 */
changeEvent(QEvent * e)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