1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qquickview.h"
43 #include "qquickview_p.h"
45 #include "qquickcanvas_p.h"
46 #include "qquickitem_p.h"
47 #include "qquickitemchangelistener_p.h"
49 #include <private/qdeclarativedebugtrace_p.h>
50 #include <private/qdeclarativeinspectorservice_p.h>
52 #include <QtDeclarative/qdeclarativeengine.h>
53 #include <private/qdeclarativeengine_p.h>
54 #include <QtCore/qbasictimer.h>
59 void QQuickViewPrivate::init()
63 engine.setIncubationController(q->incubationController());
65 if (QDeclarativeDebugService::isDebuggingEnabled())
66 QDeclarativeInspectorService::instance()->addView(q);
69 QQuickViewPrivate::QQuickViewPrivate()
70 : root(0), component(0), resizeMode(QQuickView::SizeViewToRootObject), initialSize(0,0)
74 QQuickViewPrivate::~QQuickViewPrivate()
76 if (QDeclarativeDebugService::isDebuggingEnabled())
77 QDeclarativeInspectorService::instance()->removeView(q_func());
82 void QQuickViewPrivate::execute()
93 if (!source.isEmpty()) {
94 component = new QDeclarativeComponent(&engine, source, q);
95 if (!component->isLoading()) {
98 QObject::connect(component, SIGNAL(statusChanged(QDeclarativeComponent::Status)),
99 q, SLOT(continueExecute()));
104 void QQuickViewPrivate::itemGeometryChanged(QQuickItem *resizeItem, const QRectF &newGeometry, const QRectF &oldGeometry)
107 if (resizeItem == root && resizeMode == QQuickView::SizeViewToRootObject) {
108 // wait for both width and height to be changed
109 resizetimer.start(0,q);
111 QQuickItemChangeListener::itemGeometryChanged(resizeItem, newGeometry, oldGeometry);
117 \brief The QQuickView class provides a window for displaying a Qt Quick user interface.
121 This is a convenience subclass of QQuickCanvas which
122 will automatically load and display a QML scene when given the URL of the main source file. Alternatively,
123 you can instantiate your own objects using QDeclarativeComponent and place them in a manually setup QQuickCanvas.
128 QQuickView *view = new QQuickView;
129 view->setSource(QUrl::fromLocalFile("myqmlfile.qml"));
133 To receive errors related to loading and executing QML with QQuickView,
134 you can connect to the statusChanged() signal and monitor for QQuickView::Error.
135 The errors are available via QQuickView::errors().
137 \sa {Using QML Bindings in C++ Applications}
141 /*! \fn void QQuickView::sceneResized(QSize size)
142 This signal is emitted when the view is resized to \a size.
145 /*! \fn void QQuickView::statusChanged(QQuickView::Status status)
146 This signal is emitted when the component's current \a status changes.
149 /*! \fn void QQuickView::initialSizeChanged(QSize size)
154 \fn QQuickView::QQuickView(QWindow *parent)
156 Constructs a QQuickView with the given \a parent.
158 QQuickView::QQuickView(QWindow *parent, Qt::WindowFlags f)
159 : QQuickCanvas(*(new QQuickViewPrivate), parent)
166 \fn QQuickView::QQuickView(const QUrl &source, QWidget *parent)
168 Constructs a QQuickView with the given QML \a source and \a parent.
170 QQuickView::QQuickView(const QUrl &source, QWindow *parent, Qt::WindowFlags f)
171 : QQuickCanvas(*(new QQuickViewPrivate), parent)
178 QQuickView::~QQuickView()
182 /*! \property QQuickView::source
183 \brief The URL of the source of the QML component.
185 Changing this property causes the QML component to be reloaded.
187 Ensure that the URL provided is full and correct, in particular, use
188 \l QUrl::fromLocalFile() when loading a file from the local filesystem.
192 Sets the source to the \a url, loads the QML component and instantiates it.
194 Ensure that the URL provided is full and correct, in particular, use
195 \l QUrl::fromLocalFile() when loading a file from the local filesystem.
197 Calling this methods multiple times with the same url will result
198 in the QML being reloaded.
200 void QQuickView::setSource(const QUrl& url)
208 Returns the source URL, if set.
212 QUrl QQuickView::source() const
214 Q_D(const QQuickView);
219 Returns a pointer to the QDeclarativeEngine used for instantiating
222 QDeclarativeEngine* QQuickView::engine() const
224 Q_D(const QQuickView);
225 return const_cast<QDeclarativeEngine *>(&d->engine);
229 This function returns the root of the context hierarchy. Each QML
230 component is instantiated in a QDeclarativeContext. QDeclarativeContext's are
231 essential for passing data to QML components. In QML, contexts are
232 arranged hierarchically and this hierarchy is managed by the
235 QDeclarativeContext* QQuickView::rootContext() const
237 Q_D(const QQuickView);
238 return d->engine.rootContext();
242 \enum QQuickView::Status
243 Specifies the loading status of the QQuickView.
245 \value Null This QQuickView has no source set.
246 \value Ready This QQuickView has loaded and created the QML component.
247 \value Loading This QQuickView is loading network data.
248 \value Error One or more errors has occurred. Call errors() to retrieve a list
252 /*! \enum QQuickView::ResizeMode
254 This enum specifies how to resize the view.
256 \value SizeViewToRootObject The view resizes with the root item in the QML.
257 \value SizeRootObjectToView The view will automatically resize the root item to the size of the view.
261 \property QQuickView::status
262 The component's current \l{QQuickView::Status} {status}.
265 QQuickView::Status QQuickView::status() const
267 Q_D(const QQuickView);
269 return QQuickView::Null;
271 return QQuickView::Status(d->component->status());
275 Return the list of errors that occurred during the last compile or create
276 operation. When the status is not Error, an empty list is returned.
278 QList<QDeclarativeError> QQuickView::errors() const
280 Q_D(const QQuickView);
282 return d->component->errors();
283 return QList<QDeclarativeError>();
287 \property QQuickView::resizeMode
288 \brief whether the view should resize the canvas contents
290 If this property is set to SizeViewToRootObject (the default), the view
291 resizes with the root item in the QML.
293 If this property is set to SizeRootObjectToView, the view will
294 automatically resize the root item.
296 Regardless of this property, the sizeHint of the view
297 is the initial size of the root item. Note though that
298 since QML may load dynamically, that size may change.
301 void QQuickView::setResizeMode(ResizeMode mode)
304 if (d->resizeMode == mode)
308 if (d->resizeMode == SizeViewToRootObject) {
309 QQuickItemPrivate *p = QQuickItemPrivate::get(d->root);
310 p->removeItemChangeListener(d, QQuickItemPrivate::Geometry);
314 d->resizeMode = mode;
320 void QQuickViewPrivate::initResize()
323 if (resizeMode == QQuickView::SizeViewToRootObject) {
324 QQuickItemPrivate *p = QQuickItemPrivate::get(root);
325 p->addItemChangeListener(this, QQuickItemPrivate::Geometry);
331 void QQuickViewPrivate::updateSize()
337 if (resizeMode == QQuickView::SizeViewToRootObject) {
338 QSize newSize = QSize(root->width(), root->height());
339 if (newSize.isValid() && newSize != q->size()) {
342 } else if (resizeMode == QQuickView::SizeRootObjectToView) {
343 if (!qFuzzyCompare(q->width(), root->width()))
344 root->setWidth(q->width());
345 if (!qFuzzyCompare(q->height(), root->height()))
346 root->setHeight(q->height());
350 QSize QQuickViewPrivate::rootObjectSize() const
352 QSize rootObjectSize(0,0);
353 int widthCandidate = -1;
354 int heightCandidate = -1;
356 widthCandidate = root->width();
357 heightCandidate = root->height();
359 if (widthCandidate > 0) {
360 rootObjectSize.setWidth(widthCandidate);
362 if (heightCandidate > 0) {
363 rootObjectSize.setHeight(heightCandidate);
365 return rootObjectSize;
368 QQuickView::ResizeMode QQuickView::resizeMode() const
370 Q_D(const QQuickView);
371 return d->resizeMode;
377 void QQuickView::continueExecute()
380 disconnect(d->component, SIGNAL(statusChanged(QDeclarativeComponent::Status)), this, SLOT(continueExecute()));
382 if (d->component->isError()) {
383 QList<QDeclarativeError> errorList = d->component->errors();
384 foreach (const QDeclarativeError &error, errorList) {
387 emit statusChanged(status());
391 QObject *obj = d->component->create();
393 if (d->component->isError()) {
394 QList<QDeclarativeError> errorList = d->component->errors();
395 foreach (const QDeclarativeError &error, errorList) {
398 emit statusChanged(status());
402 d->setRootObject(obj);
403 emit statusChanged(status());
410 void QQuickViewPrivate::setRootObject(QObject *obj)
415 if (QQuickItem *sgItem = qobject_cast<QQuickItem *>(obj)) {
417 sgItem->setParentItem(q->QQuickCanvas::rootItem());
419 qWarning() << "QQuickView only supports loading of root objects that derive from QQuickItem." << endl
421 << "If your example is using QML 2, (such as qmlscene) and the .qml file you" << endl
422 << "loaded has 'import QtQuick 1.0' or 'import Qt 4.7', this error will occur." << endl
424 << "To load files with 'import QtQuick 1.0' with QML 2, specify:" << endl
425 << " QMLSCENE_IMPORT_NAME=quick1" << endl
426 << "on as an environment variable prior to launching the application." << endl
428 << "To load files with 'import Qt 4.7' with QML 2, specify:" << endl
429 << " QMLSCENE_IMPORT_NAME=qt" << endl
430 << "on as an environment variable prior to launching the application." << endl;
435 initialSize = rootObjectSize();
436 if ((resizeMode == QQuickView::SizeViewToRootObject || !q->width() || !q->height())
437 && initialSize != q->size()) {
438 q->resize(initialSize);
446 If the \l {QTimerEvent} {timer event} \a e is this
447 view's resize timer, sceneResized() is emitted.
449 void QQuickView::timerEvent(QTimerEvent* e)
452 if (!e || e->timerId() == d->resizetimer.timerId()) {
454 d->resizetimer.stop();
460 Preferred size follows the root object geometry.
462 QSize QQuickView::sizeHint() const
464 Q_D(const QQuickView);
465 QSize rootObjectSize = d->rootObjectSize();
466 if (rootObjectSize.isEmpty()) {
469 return rootObjectSize;
474 Returns the initial size of the root object
476 QSize QQuickView::initialSize() const
478 Q_D(const QQuickView);
479 return d->initialSize;
483 Returns the view's root \l {QQuickItem} {item}.
485 QQuickItem *QQuickView::rootObject() const
487 Q_D(const QQuickView);
493 This function handles the \l {QResizeEvent} {resize event}
496 void QQuickView::resizeEvent(QResizeEvent *e)
499 if (d->resizeMode == SizeRootObjectToView)
502 QQuickCanvas::resizeEvent(e);
505 void QQuickView::keyPressEvent(QKeyEvent *e)
507 QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Key);
509 QQuickCanvas::keyPressEvent(e);
512 void QQuickView::keyReleaseEvent(QKeyEvent *e)
514 QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Key);
516 QQuickCanvas::keyReleaseEvent(e);
519 void QQuickView::mouseMoveEvent(QMouseEvent *e)
521 QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Mouse);
523 QQuickCanvas::mouseMoveEvent(e);
526 void QQuickView::mousePressEvent(QMouseEvent *e)
528 QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Mouse);
530 QQuickCanvas::mousePressEvent(e);
533 void QQuickView::mouseReleaseEvent(QMouseEvent *e)
535 QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Mouse);
537 QQuickCanvas::mouseReleaseEvent(e);