File indexing completed on 2024-11-24 04:53:25
0001 /* 0002 Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) 0003 0004 This library is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Library General Public 0006 License as published by the Free Software Foundation; either 0007 version 2 of the License, or (at your option) any later version. 0008 0009 This library is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 Library General Public License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this library; see the file COPYING.LIB. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 Boston, MA 02110-1301, USA. 0018 */ 0019 0020 0021 #include "qdeclarativewebview_p.h" 0022 0023 #include <QtCore/QDebug> 0024 #include <QtCore/QEvent> 0025 #include <QtCore/QFile> 0026 #include <QtDeclarative/QDeclarativeContext> 0027 #include <QtDeclarative/QDeclarativeEngine> 0028 #include <QtDeclarative/qdeclarative.h> 0029 #include <QtGui/QApplication> 0030 #include <QtGui/QGraphicsSceneMouseEvent> 0031 #include <QtGui/QKeyEvent> 0032 #include <QtGui/QMouseEvent> 0033 #include <QtGui/QPen> 0034 #include "qwebelement.h" 0035 #include "qwebframe.h" 0036 #include "qwebpage.h" 0037 #include "qwebsettings.h" 0038 0039 QT_BEGIN_NAMESPACE 0040 0041 class TrojitaQNAMDeclarativeWebViewPrivate { 0042 public: 0043 TrojitaQNAMDeclarativeWebViewPrivate(TrojitaQNAMDeclarativeWebView* qq) 0044 : q(qq) 0045 , preferredwidth(0) 0046 , preferredheight(0) 0047 , progress(1.0) 0048 , status(TrojitaQNAMDeclarativeWebView::Null) 0049 , pending(PendingNone) 0050 , newWindowComponent(0) 0051 , newWindowParent(0) 0052 , networkAccessManager(0) 0053 , rendering(true) 0054 { 0055 } 0056 0057 TrojitaQNAMDeclarativeWebView* q; 0058 0059 QUrl url; // page url might be different if it has not loaded yet 0060 TrojitaQNAMGraphicsWebView* view; 0061 0062 int preferredwidth, preferredheight; 0063 qreal progress; 0064 TrojitaQNAMDeclarativeWebView::Status status; 0065 QString statusText; 0066 enum { PendingNone, PendingUrl, PendingHtml, PendingContent } pending; 0067 QUrl pendingUrl; 0068 QString pendingString; 0069 QByteArray pendingData; 0070 mutable TrojitaDeclarativeWebSettings settings; 0071 QDeclarativeComponent* newWindowComponent; 0072 QDeclarativeItem* newWindowParent; 0073 QNetworkAccessManager* networkAccessManager; 0074 0075 static void windowObjectsAppend(QDeclarativeListProperty<QObject>* prop, QObject* o) 0076 { 0077 static_cast<TrojitaQNAMDeclarativeWebViewPrivate*>(prop->data)->windowObjects.append(o); 0078 static_cast<TrojitaQNAMDeclarativeWebViewPrivate*>(prop->data)->updateWindowObjects(); 0079 } 0080 0081 void updateWindowObjects(); 0082 QObjectList windowObjects; 0083 0084 bool rendering; 0085 }; 0086 0087 TrojitaQNAMGraphicsWebView::TrojitaQNAMGraphicsWebView(TrojitaQNAMDeclarativeWebView* parent) 0088 : QGraphicsWebView(parent) 0089 , parent(parent) 0090 , pressTime(400) 0091 { 0092 } 0093 0094 void TrojitaQNAMGraphicsWebView::mousePressEvent(QGraphicsSceneMouseEvent* event) 0095 { 0096 pressPoint = event->pos(); 0097 if (pressTime) { 0098 pressTimer.start(pressTime, this); 0099 parent->setKeepMouseGrab(false); 0100 } else { 0101 grabMouse(); 0102 parent->setKeepMouseGrab(true); 0103 } 0104 QGraphicsWebView::mousePressEvent(event); 0105 0106 QWebHitTestResult hit = page()->mainFrame()->hitTestContent(pressPoint.toPoint()); 0107 if (hit.isContentEditable()) 0108 parent->forceActiveFocus(); 0109 setFocus(); 0110 } 0111 0112 void TrojitaQNAMGraphicsWebView::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) 0113 { 0114 QGraphicsWebView::mouseReleaseEvent(event); 0115 pressTimer.stop(); 0116 parent->setKeepMouseGrab(false); 0117 ungrabMouse(); 0118 } 0119 0120 void TrojitaQNAMGraphicsWebView::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event) 0121 { 0122 QMouseEvent* me = new QMouseEvent(QEvent::MouseButtonDblClick, (event->pos() / parent->contentsScale()).toPoint(), event->button(), event->buttons(), 0); 0123 emit doubleClick(event->pos().x(), event->pos().y()); 0124 delete me; 0125 } 0126 0127 void TrojitaQNAMGraphicsWebView::timerEvent(QTimerEvent* event) 0128 { 0129 if (event->timerId() == pressTimer.timerId()) { 0130 pressTimer.stop(); 0131 grabMouse(); 0132 parent->setKeepMouseGrab(true); 0133 } 0134 } 0135 0136 void TrojitaQNAMGraphicsWebView::mouseMoveEvent(QGraphicsSceneMouseEvent* event) 0137 { 0138 if (pressTimer.isActive()) { 0139 if ((event->pos() - pressPoint).manhattanLength() > QApplication::startDragDistance()) 0140 pressTimer.stop(); 0141 } 0142 if (parent->keepMouseGrab()) 0143 QGraphicsWebView::mouseMoveEvent(event); 0144 } 0145 0146 bool TrojitaQNAMGraphicsWebView::sceneEvent(QEvent *event) 0147 { 0148 bool rv = QGraphicsWebView::sceneEvent(event); 0149 if (event->type() == QEvent::UngrabMouse) { 0150 pressTimer.stop(); 0151 parent->setKeepMouseGrab(false); 0152 } 0153 return rv; 0154 } 0155 0156 /*! 0157 \qmlclass WebView QDeclarativeWebView 0158 \ingroup qml-view-elements 0159 \since 4.7 0160 \brief The WebView item allows you to add Web content to a canvas. 0161 \inherits Item 0162 0163 A WebView renders Web content based on a URL. 0164 0165 This type is made available by importing the \c QtWebKit module: 0166 0167 \bold{import QtWebKit 1.0} 0168 0169 The WebView item includes no scrolling, scaling, toolbars, or other common browser 0170 components. These must be implemented around WebView. See the \l{QML Web Browser} 0171 example for a demonstration of this. 0172 0173 The page to be displayed by the item is specified using the \l url property, 0174 and this can be changed to fetch and display a new page. While the page loads, 0175 the \l progress property is updated to indicate how much of the page has been 0176 loaded. 0177 0178 \section1 Appearance 0179 0180 If the width and height of the item is not set, they will dynamically adjust 0181 to a size appropriate for the content. This width may be large for typical 0182 online web pages, typically greater than 800 by 600 pixels. 0183 0184 If the \l{Item::}{width} or \l{Item::}{height} is explictly set, the rendered Web site will be 0185 clipped, not scaled, to fit into the set dimensions. 0186 0187 If the preferredWidth property is set, the width will be this amount or larger, 0188 usually laying out the Web content to fit the preferredWidth. 0189 0190 The appearance of the content can be controlled to a certain extent by changing 0191 the settings.standardFontFamily property and other settings related to fonts. 0192 0193 The page can be zoomed by calling the heuristicZoom() method, which performs a 0194 series of tests to determine whether zoomed content will be displayed in an 0195 appropriate way in the space allocated to the item. 0196 0197 \section1 User Interaction and Navigation 0198 0199 By default, certain mouse and touch events are delivered to other items in 0200 preference to the Web content. For example, when a scrolling view is created 0201 by placing a WebView in a Flickable, move events are delivered to the Flickable 0202 so that the user can scroll the page. This prevents the user from accidentally 0203 selecting text in a Web page instead of scrolling. 0204 0205 The pressGrabTime property defines the time the user must touch or press a 0206 mouse button over the WebView before the Web content will receive the move 0207 events it needs to select text and images. 0208 0209 When this item has keyboard focus, all keyboard input will be sent directly to 0210 the Web page within. 0211 0212 When the navigates by clicking on links, the item records the pages visited 0213 in its internal history 0214 0215 Because this item is designed to be used as a component in a browser, it 0216 exposes \l{Action}{actions} for \l back, \l forward, \l reload and \l stop. 0217 These can be triggered to change the current page displayed by the item. 0218 0219 \section1 Example Usage 0220 0221 \beginfloatright 0222 \inlineimage webview.png 0223 \endfloat 0224 0225 The following example displays a scaled down Web page at a fixed size. 0226 0227 \snippet doc/src/snippets/declarative/webview/webview.qml document 0228 0229 \clearfloat 0230 0231 \sa {declarative/modelviews/webview}{WebView example}, {demos/declarative/webbrowser}{Web Browser demo} 0232 */ 0233 0234 /*! 0235 \internal 0236 \class QDeclarativeWebView 0237 \brief The QDeclarativeWebView class allows you to add web content to a QDeclarativeView. 0238 0239 A WebView renders web content base on a URL. 0240 0241 \image webview.png 0242 0243 The item includes no scrolling, scaling, 0244 toolbars, etc., those must be implemented around WebView. See the WebBrowser example 0245 for a demonstration of this. 0246 0247 A QDeclarativeWebView object can be instantiated in Qml using the tag \l WebView. 0248 */ 0249 0250 TrojitaQNAMDeclarativeWebView::TrojitaQNAMDeclarativeWebView(QDeclarativeItem *parent) : QDeclarativeItem(parent) 0251 { 0252 init(); 0253 } 0254 0255 TrojitaQNAMDeclarativeWebView::~TrojitaQNAMDeclarativeWebView() 0256 { 0257 delete d; 0258 } 0259 0260 void TrojitaQNAMDeclarativeWebView::init() 0261 { 0262 d = new TrojitaQNAMDeclarativeWebViewPrivate(this); 0263 0264 if (QWebSettings::iconDatabasePath().isNull() && 0265 QWebSettings::globalSettings()->localStoragePath().isNull() && 0266 QWebSettings::offlineStoragePath().isNull() && 0267 QWebSettings::offlineWebApplicationCachePath().isNull()) 0268 QWebSettings::enablePersistentStorage(); 0269 0270 setAcceptedMouseButtons(Qt::LeftButton); 0271 setFlag(QGraphicsItem::ItemHasNoContents, true); 0272 setClip(true); 0273 0274 d->view = new TrojitaQNAMGraphicsWebView(this); 0275 d->view->setResizesToContents(true); 0276 QWebPage* wp = new TrojitaQNAMDeclarativeWebPage(this); 0277 setPage(wp); 0278 connect(d->view, SIGNAL(geometryChanged()), this, SLOT(updateDeclarativeWebViewSize())); 0279 connect(d->view, SIGNAL(doubleClick(int, int)), this, SIGNAL(doubleClick(int, int))); 0280 connect(d->view, SIGNAL(scaleChanged()), this, SIGNAL(contentsScaleChanged())); 0281 } 0282 0283 void TrojitaQNAMDeclarativeWebView::componentComplete() 0284 { 0285 QDeclarativeItem::componentComplete(); 0286 0287 if (networkAccessManager()) 0288 page()->setNetworkAccessManager(networkAccessManager()); 0289 else 0290 page()->setNetworkAccessManager(qmlEngine(this)->networkAccessManager()); 0291 0292 switch (d->pending) { 0293 case TrojitaQNAMDeclarativeWebViewPrivate::PendingUrl: 0294 setUrl(d->pendingUrl); 0295 break; 0296 case TrojitaQNAMDeclarativeWebViewPrivate::PendingHtml: 0297 setHtml(d->pendingString, d->pendingUrl); 0298 break; 0299 case TrojitaQNAMDeclarativeWebViewPrivate::PendingContent: 0300 setContent(d->pendingData, d->pendingString, d->pendingUrl); 0301 break; 0302 default: 0303 break; 0304 } 0305 d->pending = TrojitaQNAMDeclarativeWebViewPrivate::PendingNone; 0306 d->updateWindowObjects(); 0307 } 0308 0309 TrojitaQNAMDeclarativeWebView::Status TrojitaQNAMDeclarativeWebView::status() const 0310 { 0311 return d->status; 0312 } 0313 0314 0315 /*! 0316 \qmlproperty real WebView::progress 0317 This property holds the progress of loading the current URL, from 0 to 1. 0318 0319 If you just want to know when progress gets to 1, use 0320 WebView::onLoadFinished() or WebView::onLoadFailed() instead. 0321 */ 0322 qreal TrojitaQNAMDeclarativeWebView::progress() const 0323 { 0324 return d->progress; 0325 } 0326 0327 void TrojitaQNAMDeclarativeWebView::doLoadStarted() 0328 { 0329 if (!d->url.isEmpty()) { 0330 d->status = Loading; 0331 emit statusChanged(d->status); 0332 } 0333 emit loadStarted(); 0334 } 0335 0336 void TrojitaQNAMDeclarativeWebView::doLoadProgress(int p) 0337 { 0338 if (d->progress == p / 100.0) 0339 return; 0340 d->progress = p / 100.0; 0341 emit progressChanged(); 0342 } 0343 0344 void TrojitaQNAMDeclarativeWebView::pageUrlChanged() 0345 { 0346 updateContentsSize(); 0347 0348 if ((d->url.isEmpty() && page()->mainFrame()->url() != QUrl(QLatin1String("about:blank"))) 0349 || (d->url != page()->mainFrame()->url() && !page()->mainFrame()->url().isEmpty())) 0350 { 0351 d->url = page()->mainFrame()->url(); 0352 if (d->url == QUrl(QLatin1String("about:blank"))) 0353 d->url = QUrl(); 0354 emit urlChanged(); 0355 } 0356 } 0357 0358 void TrojitaQNAMDeclarativeWebView::doLoadFinished(bool ok) 0359 { 0360 if (ok) { 0361 d->status = d->url.isEmpty() ? Null : Ready; 0362 emit loadFinished(); 0363 } else { 0364 d->status = Error; 0365 emit loadFailed(); 0366 } 0367 emit statusChanged(d->status); 0368 } 0369 0370 /*! 0371 \qmlproperty url WebView::url 0372 This property holds the URL to the page displayed in this item. It can be set, 0373 but also can change spontaneously (eg. because of network redirection). 0374 0375 If the url is empty, the page is blank. 0376 0377 The url is always absolute (QML will resolve relative URL strings in the context 0378 of the containing QML document). 0379 */ 0380 QUrl TrojitaQNAMDeclarativeWebView::url() const 0381 { 0382 return d->url; 0383 } 0384 0385 void TrojitaQNAMDeclarativeWebView::setUrl(const QUrl& url) 0386 { 0387 if (url == d->url) 0388 return; 0389 0390 if (isComponentComplete()) { 0391 d->url = url; 0392 updateContentsSize(); 0393 QUrl seturl = url; 0394 if (seturl.isEmpty()) 0395 seturl = QUrl(QLatin1String("about:blank")); 0396 0397 Q_ASSERT(!seturl.isRelative()); 0398 0399 page()->mainFrame()->load(seturl); 0400 0401 emit urlChanged(); 0402 0403 } else { 0404 d->pending = d->PendingUrl; 0405 d->pendingUrl = url; 0406 } 0407 } 0408 0409 /*! 0410 \qmlproperty int WebView::preferredWidth 0411 This property holds the ideal width for displaying the current URL. 0412 */ 0413 int TrojitaQNAMDeclarativeWebView::preferredWidth() const 0414 { 0415 return d->preferredwidth; 0416 } 0417 0418 void TrojitaQNAMDeclarativeWebView::setPreferredWidth(int width) 0419 { 0420 if (d->preferredwidth == width) 0421 return; 0422 d->preferredwidth = width; 0423 updateContentsSize(); 0424 emit preferredWidthChanged(); 0425 } 0426 0427 /*! 0428 \qmlproperty int WebView::preferredHeight 0429 This property holds the ideal height for displaying the current URL. 0430 This only affects the area zoomed by heuristicZoom(). 0431 */ 0432 int TrojitaQNAMDeclarativeWebView::preferredHeight() const 0433 { 0434 return d->preferredheight; 0435 } 0436 0437 void TrojitaQNAMDeclarativeWebView::setPreferredHeight(int height) 0438 { 0439 if (d->preferredheight == height) 0440 return; 0441 d->preferredheight = height; 0442 updateContentsSize(); 0443 emit preferredHeightChanged(); 0444 } 0445 0446 /*! 0447 \qmlmethod bool WebView::evaluateJavaScript(string scriptSource) 0448 0449 Evaluates the \a scriptSource JavaScript inside the context of the 0450 main web frame, and returns the result of the last executed statement. 0451 0452 Note that this JavaScript does \e not have any access to QML objects 0453 except as made available as windowObjects. 0454 */ 0455 QVariant TrojitaQNAMDeclarativeWebView::evaluateJavaScript(const QString& scriptSource) 0456 { 0457 return this->page()->mainFrame()->evaluateJavaScript(scriptSource); 0458 } 0459 0460 void TrojitaQNAMDeclarativeWebView::updateDeclarativeWebViewSize() 0461 { 0462 QSizeF size = d->view->geometry().size() * contentsScale(); 0463 setImplicitWidth(size.width()); 0464 setImplicitHeight(size.height()); 0465 } 0466 0467 void TrojitaQNAMDeclarativeWebView::initialLayout() 0468 { 0469 // nothing useful to do at this point 0470 } 0471 0472 void TrojitaQNAMDeclarativeWebView::updateContentsSize() 0473 { 0474 if (page()) { 0475 page()->setPreferredContentsSize(QSize( 0476 d->preferredwidth>0 ? d->preferredwidth : width(), 0477 d->preferredheight>0 ? d->preferredheight : height())); 0478 } 0479 } 0480 0481 void TrojitaQNAMDeclarativeWebView::geometryChanged(const QRectF& newGeometry, const QRectF& oldGeometry) 0482 { 0483 QWebPage* webPage = page(); 0484 if (newGeometry.size() != oldGeometry.size() && webPage) { 0485 QSize contentSize = webPage->preferredContentsSize(); 0486 if (widthValid()) 0487 contentSize.setWidth(width()); 0488 if (heightValid()) 0489 contentSize.setHeight(height()); 0490 if (contentSize != webPage->preferredContentsSize()) 0491 webPage->setPreferredContentsSize(contentSize); 0492 } 0493 QDeclarativeItem::geometryChanged(newGeometry, oldGeometry); 0494 } 0495 0496 /*! 0497 \qmlproperty list<object> WebView::javaScriptWindowObjects 0498 0499 A list of QML objects to expose to the web page. 0500 0501 Each object will be added as a property of the web frame's window object. The 0502 property name is controlled by the value of \c WebView.windowObjectName 0503 attached property. 0504 0505 Exposing QML objects to a web page allows JavaScript executing in the web 0506 page itself to communicate with QML, by reading and writing properties and 0507 by calling methods of the exposed QML objects. 0508 0509 This example shows how to call into a QML method using a window object. 0510 0511 \qml 0512 WebView { 0513 javaScriptWindowObjects: QtObject { 0514 WebView.windowObjectName: "qml" 0515 0516 function qmlCall() { 0517 console.log("This call is in QML!"); 0518 } 0519 } 0520 0521 html: "<script>console.log(\"This is in WebKit!\"); window.qml.qmlCall();</script>" 0522 } 0523 \endqml 0524 0525 The output of the example will be: 0526 \code 0527 This is in WebKit! 0528 This call is in QML! 0529 \endcode 0530 0531 If Javascript is not enabled for the page, then this property does nothing. 0532 */ 0533 QDeclarativeListProperty<QObject> TrojitaQNAMDeclarativeWebView::javaScriptWindowObjects() 0534 { 0535 return QDeclarativeListProperty<QObject>(this, d, &TrojitaQNAMDeclarativeWebViewPrivate::windowObjectsAppend); 0536 } 0537 0538 TrojitaQNAMDeclarativeWebViewAttached* TrojitaQNAMDeclarativeWebView::qmlAttachedProperties(QObject* o) 0539 { 0540 return new TrojitaQNAMDeclarativeWebViewAttached(o); 0541 } 0542 0543 void TrojitaQNAMDeclarativeWebViewPrivate::updateWindowObjects() 0544 { 0545 if (!q->isComponentCompletePublic() || !q->page()) 0546 return; 0547 0548 for (int i = 0; i < windowObjects.count(); ++i) { 0549 QObject* object = windowObjects.at(i); 0550 TrojitaQNAMDeclarativeWebViewAttached* attached = static_cast<TrojitaQNAMDeclarativeWebViewAttached *>(qmlAttachedPropertiesObject<TrojitaQNAMDeclarativeWebView>(object)); 0551 if (attached && !attached->windowObjectName().isEmpty()) 0552 q->page()->mainFrame()->addToJavaScriptWindowObject(attached->windowObjectName(), object); 0553 } 0554 } 0555 0556 bool TrojitaQNAMDeclarativeWebView::renderingEnabled() const 0557 { 0558 return d->rendering; 0559 } 0560 0561 void TrojitaQNAMDeclarativeWebView::setRenderingEnabled(bool enabled) 0562 { 0563 if (d->rendering == enabled) 0564 return; 0565 d->rendering = enabled; 0566 emit renderingEnabledChanged(); 0567 d->view->setTiledBackingStoreFrozen(!enabled); 0568 } 0569 0570 /*! 0571 \qmlsignal WebView::onDoubleClick(int clickx, int clicky) 0572 0573 The WebView does not pass double-click events to the web engine, but rather 0574 emits this signals. 0575 */ 0576 0577 /*! 0578 \qmlmethod bool WebView::heuristicZoom(int clickX, int clickY, real maxzoom) 0579 0580 Finds a zoom that: 0581 \list 0582 \i shows a whole item 0583 \i includes (\a clickX, \a clickY) 0584 \i fits into the preferredWidth and preferredHeight 0585 \i zooms by no more than \a maxZoom 0586 \i is more than 10% above the current zoom 0587 \endlist 0588 0589 If such a zoom exists, emits zoomTo(zoom,centerX,centerY) and returns true; otherwise, 0590 no signal is emitted and returns false. 0591 */ 0592 bool TrojitaQNAMDeclarativeWebView::heuristicZoom(int clickX, int clickY, qreal maxZoom) 0593 { 0594 if (contentsScale() >= maxZoom / scale()) 0595 return false; 0596 qreal ozf = contentsScale(); 0597 QRect showArea = elementAreaAt(clickX, clickY, d->preferredwidth / maxZoom, d->preferredheight / maxZoom); 0598 qreal z = qMin(qreal(d->preferredwidth) / showArea.width(), qreal(d->preferredheight) / showArea.height()); 0599 if (z > maxZoom / scale()) 0600 z = maxZoom / scale(); 0601 if (z / ozf > 1.2) { 0602 QRectF r(showArea.left() * z, showArea.top() * z, showArea.width() * z, showArea.height() * z); 0603 emit zoomTo(z, r.x() + r.width() / 2, r.y() + r.height() / 2); 0604 return true; 0605 } 0606 return false; 0607 } 0608 0609 /*! 0610 \qmlproperty int WebView::pressGrabTime 0611 0612 The number of milliseconds the user must press before the WebView 0613 starts passing move events through to the Web engine (rather than 0614 letting other QML elements such as a Flickable take them). 0615 0616 Defaults to 400ms. Set to 0 to always grab and pass move events to 0617 the Web engine. 0618 */ 0619 int TrojitaQNAMDeclarativeWebView::pressGrabTime() const 0620 { 0621 return d->view->pressTime; 0622 } 0623 0624 void TrojitaQNAMDeclarativeWebView::setPressGrabTime(int millis) 0625 { 0626 if (d->view->pressTime == millis) 0627 return; 0628 d->view->pressTime = millis; 0629 emit pressGrabTimeChanged(); 0630 } 0631 0632 #ifndef QT_NO_ACTION 0633 /*! 0634 \qmlproperty action WebView::back 0635 This property holds the action for causing the previous URL in the history to be displayed. 0636 */ 0637 QAction* TrojitaQNAMDeclarativeWebView::backAction() const 0638 { 0639 return page()->action(QWebPage::Back); 0640 } 0641 0642 /*! 0643 \qmlproperty action WebView::forward 0644 This property holds the action for causing the next URL in the history to be displayed. 0645 */ 0646 QAction* TrojitaQNAMDeclarativeWebView::forwardAction() const 0647 { 0648 return page()->action(QWebPage::Forward); 0649 } 0650 0651 /*! 0652 \qmlproperty action WebView::reload 0653 This property holds the action for reloading with the current URL 0654 */ 0655 QAction* TrojitaQNAMDeclarativeWebView::reloadAction() const 0656 { 0657 return page()->action(QWebPage::Reload); 0658 } 0659 0660 /*! 0661 \qmlproperty action WebView::stop 0662 This property holds the action for stopping loading with the current URL 0663 */ 0664 QAction* TrojitaQNAMDeclarativeWebView::stopAction() const 0665 { 0666 return page()->action(QWebPage::Stop); 0667 } 0668 #endif // QT_NO_ACTION 0669 0670 /*! 0671 \qmlproperty string WebView::title 0672 This property holds the title of the web page currently viewed 0673 0674 By default, this property contains an empty string. 0675 */ 0676 QString TrojitaQNAMDeclarativeWebView::title() const 0677 { 0678 return page()->mainFrame()->title(); 0679 } 0680 0681 /*! 0682 \qmlproperty pixmap WebView::icon 0683 This property holds the icon associated with the web page currently viewed 0684 */ 0685 QPixmap TrojitaQNAMDeclarativeWebView::icon() const 0686 { 0687 return page()->mainFrame()->icon().pixmap(QSize(256, 256)); 0688 } 0689 0690 /*! 0691 \qmlproperty string WebView::statusText 0692 0693 This property is the current status suggested by the current web page. In a web browser, 0694 such status is often shown in some kind of status bar. 0695 */ 0696 void TrojitaQNAMDeclarativeWebView::setStatusText(const QString& text) 0697 { 0698 d->statusText = text; 0699 emit statusTextChanged(); 0700 } 0701 0702 void TrojitaQNAMDeclarativeWebView::windowObjectCleared() 0703 { 0704 d->updateWindowObjects(); 0705 } 0706 0707 QString TrojitaQNAMDeclarativeWebView::statusText() const 0708 { 0709 return d->statusText; 0710 } 0711 0712 QWebPage* TrojitaQNAMDeclarativeWebView::page() const 0713 { 0714 return d->view->page(); 0715 } 0716 0717 // The QObject interface to settings(). 0718 /*! 0719 \qmlproperty string WebView::settings.standardFontFamily 0720 \qmlproperty string WebView::settings.fixedFontFamily 0721 \qmlproperty string WebView::settings.serifFontFamily 0722 \qmlproperty string WebView::settings.sansSerifFontFamily 0723 \qmlproperty string WebView::settings.cursiveFontFamily 0724 \qmlproperty string WebView::settings.fantasyFontFamily 0725 0726 \qmlproperty int WebView::settings.minimumFontSize 0727 \qmlproperty int WebView::settings.minimumLogicalFontSize 0728 \qmlproperty int WebView::settings.defaultFontSize 0729 \qmlproperty int WebView::settings.defaultFixedFontSize 0730 0731 \qmlproperty bool WebView::settings.autoLoadImages 0732 \qmlproperty bool WebView::settings.javascriptEnabled 0733 \qmlproperty bool WebView::settings.javaEnabled 0734 \qmlproperty bool WebView::settings.pluginsEnabled 0735 \qmlproperty bool WebView::settings.privateBrowsingEnabled 0736 \qmlproperty bool WebView::settings.javascriptCanOpenWindows 0737 \qmlproperty bool WebView::settings.javascriptCanAccessClipboard 0738 \qmlproperty bool WebView::settings.developerExtrasEnabled 0739 \qmlproperty bool WebView::settings.linksIncludedInFocusChain 0740 \qmlproperty bool WebView::settings.zoomTextOnly 0741 \qmlproperty bool WebView::settings.printElementBackgrounds 0742 \qmlproperty bool WebView::settings.offlineStorageDatabaseEnabled 0743 \qmlproperty bool WebView::settings.offlineWebApplicationCacheEnabled 0744 \qmlproperty bool WebView::settings.localStorageDatabaseEnabled 0745 \qmlproperty bool WebView::settings.localContentCanAccessRemoteUrls 0746 0747 These properties give access to the settings controlling the web view. 0748 0749 See QWebSettings for details of these properties. 0750 0751 \qml 0752 WebView { 0753 settings.pluginsEnabled: true 0754 settings.standardFontFamily: "Arial" 0755 // ... 0756 } 0757 \endqml 0758 */ 0759 TrojitaDeclarativeWebSettings* TrojitaQNAMDeclarativeWebView::settingsObject() const 0760 { 0761 d->settings.s = page()->settings(); 0762 return &d->settings; 0763 } 0764 0765 void TrojitaQNAMDeclarativeWebView::setPage(QWebPage* page) 0766 { 0767 if (d->view->page() == page) 0768 return; 0769 0770 d->view->setPage(page); 0771 updateContentsSize(); 0772 page->mainFrame()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff); 0773 page->mainFrame()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff); 0774 connect(page->mainFrame(), SIGNAL(urlChanged(QUrl)), this, SLOT(pageUrlChanged())); 0775 connect(page->mainFrame(), SIGNAL(titleChanged(QString)), this, SIGNAL(titleChanged(QString))); 0776 connect(page->mainFrame(), SIGNAL(titleChanged(QString)), this, SIGNAL(iconChanged())); 0777 connect(page->mainFrame(), SIGNAL(iconChanged()), this, SIGNAL(iconChanged())); 0778 connect(page->mainFrame(), SIGNAL(initialLayoutCompleted()), this, SLOT(initialLayout())); 0779 connect(page->mainFrame(), SIGNAL(contentsSizeChanged(QSize)), this, SIGNAL(contentsSizeChanged(QSize))); 0780 0781 connect(page, SIGNAL(loadStarted()), this, SLOT(doLoadStarted())); 0782 connect(page, SIGNAL(loadProgress(int)), this, SLOT(doLoadProgress(int))); 0783 connect(page, SIGNAL(loadFinished(bool)), this, SLOT(doLoadFinished(bool))); 0784 connect(page, SIGNAL(statusBarMessage(QString)), this, SLOT(setStatusText(QString))); 0785 0786 connect(page->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(windowObjectCleared())); 0787 0788 page->settings()->setAttribute(QWebSettings::TiledBackingStoreEnabled, true); 0789 } 0790 0791 /*! 0792 \qmlsignal WebView::onLoadStarted() 0793 0794 This handler is called when the web engine begins loading 0795 a page. Later, WebView::onLoadFinished() or WebView::onLoadFailed() 0796 will be emitted. 0797 */ 0798 0799 /*! 0800 \qmlsignal WebView::onLoadFinished() 0801 0802 This handler is called when the web engine \e successfully 0803 finishes loading a page, including any component content 0804 (WebView::onLoadFailed() will be emitted otherwise). 0805 0806 \sa progress 0807 */ 0808 0809 /*! 0810 \qmlsignal WebView::onLoadFailed() 0811 0812 This handler is called when the web engine fails loading 0813 a page or any component content 0814 (WebView::onLoadFinished() will be emitted on success). 0815 */ 0816 0817 void TrojitaQNAMDeclarativeWebView::load(const QNetworkRequest& request, QNetworkAccessManager::Operation operation, const QByteArray& body) 0818 { 0819 page()->mainFrame()->load(request, operation, body); 0820 } 0821 0822 QString TrojitaQNAMDeclarativeWebView::html() const 0823 { 0824 return page()->mainFrame()->toHtml(); 0825 } 0826 0827 /*! 0828 \qmlproperty string WebView::html 0829 This property holds HTML text set directly 0830 0831 The html property can be set as a string. 0832 0833 \qml 0834 WebView { 0835 html: "<p>This is <b>HTML</b>." 0836 } 0837 \endqml 0838 */ 0839 void TrojitaQNAMDeclarativeWebView::setHtml(const QString& html, const QUrl& baseUrl) 0840 { 0841 updateContentsSize(); 0842 if (isComponentComplete()) 0843 page()->mainFrame()->setHtml(html, baseUrl); 0844 else { 0845 d->pending = d->PendingHtml; 0846 d->pendingUrl = baseUrl; 0847 d->pendingString = html; 0848 } 0849 emit htmlChanged(); 0850 } 0851 0852 void TrojitaQNAMDeclarativeWebView::setContent(const QByteArray& data, const QString& mimeType, const QUrl& baseUrl) 0853 { 0854 updateContentsSize(); 0855 0856 if (isComponentComplete()) 0857 page()->mainFrame()->setContent(data, mimeType, qmlContext(this)->resolvedUrl(baseUrl)); 0858 else { 0859 d->pending = d->PendingContent; 0860 d->pendingUrl = baseUrl; 0861 d->pendingString = mimeType; 0862 d->pendingData = data; 0863 } 0864 } 0865 0866 QWebHistory* TrojitaQNAMDeclarativeWebView::history() const 0867 { 0868 return page()->history(); 0869 } 0870 0871 QWebSettings* TrojitaQNAMDeclarativeWebView::settings() const 0872 { 0873 return page()->settings(); 0874 } 0875 0876 TrojitaQNAMDeclarativeWebView* TrojitaQNAMDeclarativeWebView::createWindow(QWebPage::WebWindowType type) 0877 { 0878 switch (type) { 0879 case QWebPage::WebBrowserWindow: { 0880 if (!d->newWindowComponent && d->newWindowParent) 0881 qWarning("WebView::newWindowComponent not set - WebView::newWindowParent ignored"); 0882 else if (d->newWindowComponent && !d->newWindowParent) 0883 qWarning("WebView::newWindowParent not set - WebView::newWindowComponent ignored"); 0884 else if (d->newWindowComponent && d->newWindowParent) { 0885 TrojitaQNAMDeclarativeWebView* webview = 0; 0886 QDeclarativeContext* windowContext = new QDeclarativeContext(qmlContext(this)); 0887 0888 QObject* newObject = d->newWindowComponent->create(windowContext); 0889 if (newObject) { 0890 windowContext->setParent(newObject); 0891 QDeclarativeItem* item = qobject_cast<QDeclarativeItem *>(newObject); 0892 if (!item) 0893 delete newObject; 0894 else { 0895 webview = item->findChild<TrojitaQNAMDeclarativeWebView*>(); 0896 if (!webview) 0897 delete item; 0898 else { 0899 newObject->setParent(d->newWindowParent); 0900 static_cast<QGraphicsObject*>(item)->setParentItem(d->newWindowParent); 0901 } 0902 } 0903 } else 0904 delete windowContext; 0905 0906 return webview; 0907 } 0908 } 0909 break; 0910 case QWebPage::WebModalDialog: { 0911 // Not supported 0912 } 0913 } 0914 return 0; 0915 } 0916 0917 /*! 0918 \qmlproperty component WebView::newWindowComponent 0919 0920 This property holds the component to use for new windows. 0921 The component must have a WebView somewhere in its structure. 0922 0923 When the web engine requests a new window, it will be an instance of 0924 this component. 0925 0926 The parent of the new window is set by newWindowParent. It must be set. 0927 */ 0928 QDeclarativeComponent* TrojitaQNAMDeclarativeWebView::newWindowComponent() const 0929 { 0930 return d->newWindowComponent; 0931 } 0932 0933 void TrojitaQNAMDeclarativeWebView::setNewWindowComponent(QDeclarativeComponent* newWindow) 0934 { 0935 if (newWindow == d->newWindowComponent) 0936 return; 0937 d->newWindowComponent = newWindow; 0938 emit newWindowComponentChanged(); 0939 } 0940 0941 0942 /*! 0943 \qmlproperty item WebView::newWindowParent 0944 0945 The parent item for new windows. 0946 0947 \sa newWindowComponent 0948 */ 0949 QDeclarativeItem* TrojitaQNAMDeclarativeWebView::newWindowParent() const 0950 { 0951 return d->newWindowParent; 0952 } 0953 0954 void TrojitaQNAMDeclarativeWebView::setNewWindowParent(QDeclarativeItem* parent) 0955 { 0956 if (parent == d->newWindowParent) 0957 return; 0958 if (d->newWindowParent && parent) { 0959 QList<QGraphicsItem *> children = d->newWindowParent->childItems(); 0960 for (int i = 0; i < children.count(); ++i) 0961 children.at(i)->setParentItem(parent); 0962 } 0963 d->newWindowParent = parent; 0964 emit newWindowParentChanged(); 0965 } 0966 0967 QSize TrojitaQNAMDeclarativeWebView::contentsSize() const 0968 { 0969 return page()->mainFrame()->contentsSize() * contentsScale(); 0970 } 0971 0972 qreal TrojitaQNAMDeclarativeWebView::contentsScale() const 0973 { 0974 return d->view->scale(); 0975 } 0976 0977 void TrojitaQNAMDeclarativeWebView::setContentsScale(qreal scale) 0978 { 0979 if (scale == d->view->scale()) 0980 return; 0981 d->view->setScale(scale); 0982 updateDeclarativeWebViewSize(); 0983 emit contentsScaleChanged(); 0984 } 0985 0986 /*! 0987 Returns the area of the largest element at position (\a x,\a y) that is no larger 0988 than \a maxWidth by \a maxHeight pixels. 0989 0990 May return an area larger in the case when no smaller element is at the position. 0991 */ 0992 QRect TrojitaQNAMDeclarativeWebView::elementAreaAt(int x, int y, int maxWidth, int maxHeight) const 0993 { 0994 QWebHitTestResult hit = page()->mainFrame()->hitTestContent(QPoint(x, y)); 0995 QRect hitRect = hit.boundingRect(); 0996 QWebElement element = hit.enclosingBlockElement(); 0997 if (maxWidth <= 0) 0998 maxWidth = INT_MAX; 0999 if (maxHeight <= 0) 1000 maxHeight = INT_MAX; 1001 while (!element.parent().isNull() && element.geometry().width() <= maxWidth && element.geometry().height() <= maxHeight) { 1002 hitRect = element.geometry(); 1003 element = element.parent(); 1004 } 1005 return hitRect; 1006 } 1007 1008 QNetworkAccessManager *TrojitaQNAMDeclarativeWebView::networkAccessManager() const 1009 { 1010 return d->networkAccessManager; 1011 } 1012 1013 void TrojitaQNAMDeclarativeWebView::setNetworkAccessManager(QNetworkAccessManager *manager) 1014 { 1015 if (manager) { 1016 d->networkAccessManager = manager; 1017 page()->setNetworkAccessManager(manager); 1018 } 1019 } 1020 1021 /*! 1022 \internal 1023 \class TrojitaQNAMDeclarativeWebPage 1024 \brief The TrojitaQNAMDeclarativeWebPage class is a QWebPage that can create QML plugins. 1025 1026 \sa QDeclarativeWebView 1027 */ 1028 TrojitaQNAMDeclarativeWebPage::TrojitaQNAMDeclarativeWebPage(TrojitaQNAMDeclarativeWebView* parent) : 1029 QWebPage(parent) 1030 { 1031 } 1032 1033 TrojitaQNAMDeclarativeWebPage::~TrojitaQNAMDeclarativeWebPage() 1034 { 1035 } 1036 1037 QString TrojitaQNAMDeclarativeWebPage::chooseFile(QWebFrame* originatingFrame, const QString& oldFile) 1038 { 1039 // Not supported (it's modal) 1040 Q_UNUSED(originatingFrame) 1041 Q_UNUSED(oldFile) 1042 return oldFile; 1043 } 1044 1045 /*! 1046 \qmlsignal WebView::onAlert(string message) 1047 1048 The handler is called when the web engine sends a JavaScript alert. The \a message is the text 1049 to be displayed in the alert to the user. 1050 */ 1051 1052 1053 void TrojitaQNAMDeclarativeWebPage::javaScriptAlert(QWebFrame* originatingFrame, const QString& msg) 1054 { 1055 Q_UNUSED(originatingFrame) 1056 emit viewItem()->alert(msg); 1057 } 1058 1059 bool TrojitaQNAMDeclarativeWebPage::javaScriptConfirm(QWebFrame* originatingFrame, const QString& msg) 1060 { 1061 // Not supported (it's modal) 1062 Q_UNUSED(originatingFrame) 1063 Q_UNUSED(msg) 1064 return false; 1065 } 1066 1067 bool TrojitaQNAMDeclarativeWebPage::javaScriptPrompt(QWebFrame* originatingFrame, const QString& msg, const QString& defaultValue, QString* result) 1068 { 1069 // Not supported (it's modal) 1070 Q_UNUSED(originatingFrame) 1071 Q_UNUSED(msg) 1072 Q_UNUSED(defaultValue) 1073 Q_UNUSED(result) 1074 return false; 1075 } 1076 1077 1078 TrojitaQNAMDeclarativeWebView* TrojitaQNAMDeclarativeWebPage::viewItem() 1079 { 1080 return static_cast<TrojitaQNAMDeclarativeWebView*>(parent()); 1081 } 1082 1083 QWebPage* TrojitaQNAMDeclarativeWebPage::createWindow(WebWindowType type) 1084 { 1085 TrojitaQNAMDeclarativeWebView* newView = viewItem()->createWindow(type); 1086 if (newView) 1087 return newView->page(); 1088 return 0; 1089 } 1090 1091 QT_END_NAMESPACE 1092