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