Qt 4.8
qdeclarativeloader.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "private/qdeclarativeloader_p_p.h"
43 
44 #include <qdeclarativeinfo.h>
45 #include <qdeclarativeengine_p.h>
46 #include <qdeclarativeglobal_p.h>
47 
49 
51  : item(0), component(0), ownComponent(false), updatingSize(false),
52  itemWidthValid(false), itemHeightValid(false)
53 {
54 }
55 
57 {
58 }
59 
60 void QDeclarativeLoaderPrivate::itemGeometryChanged(QDeclarativeItem *resizeItem, const QRectF &newGeometry, const QRectF &oldGeometry)
61 {
62  if (resizeItem == item) {
63  if (!updatingSize && newGeometry.width() != oldGeometry.width())
64  itemWidthValid = true;
65  if (!updatingSize && newGeometry.height() != oldGeometry.height())
66  itemHeightValid = true;
67  _q_updateSize(false);
68  }
69  QDeclarativeItemChangeListener::itemGeometryChanged(resizeItem, newGeometry, oldGeometry);
70 }
71 
73 {
74  if (ownComponent) {
76  component = 0;
77  ownComponent = false;
78  }
79  source = QUrl();
80 
81  if (item) {
82  if (QDeclarativeItem *qmlItem = qobject_cast<QDeclarativeItem*>(item)) {
84  static_cast<QDeclarativeItemPrivate *>(QGraphicsItemPrivate::get(qmlItem));
86  }
87 
88  // We can't delete immediately because our item may have triggered
89  // the Loader to load a different item.
90  if (item->scene()) {
92  } else {
93  item->setParentItem(0);
94  item->setVisible(false);
95  }
96  item->deleteLater();
97  item = 0;
98  }
99 }
100 
102 {
104  if (QDeclarativeItem *qmlItem = qobject_cast<QDeclarativeItem*>(item)) {
106  static_cast<QDeclarativeItemPrivate *>(QGraphicsItemPrivate::get(qmlItem));
108  // We may override the item's size, so we need to remember
109  // whether the item provided its own valid size.
112  } else if (item && item->isWidget()) {
113  QGraphicsWidget *widget = static_cast<QGraphicsWidget*>(item);
114  widget->installEventFilter(q);
115  }
116  _q_updateSize();
117 }
118 
233 {
236 }
237 
239 {
241  if (d->item) {
242  if (QDeclarativeItem *qmlItem = qobject_cast<QDeclarativeItem*>(d->item)) {
244  static_cast<QDeclarativeItemPrivate *>(QGraphicsItemPrivate::get(qmlItem));
246  }
247  }
248 }
249 
267 {
268  Q_D(const QDeclarativeLoader);
269  return d->source;
270 }
271 
273 {
275  if (d->source == url)
276  return;
277 
278  d->clear();
279 
280  d->source = url;
281 
282  if (d->source.isEmpty()) {
286  emit itemChanged();
287  return;
288  }
289 
290  d->component = new QDeclarativeComponent(qmlEngine(this), d->source, this);
291  d->ownComponent = true;
292 
293  if (isComponentComplete())
294  d->load();
295 }
296 
323 {
324  Q_D(const QDeclarativeLoader);
325  return d->component;
326 }
327 
329 {
331  if (comp == d->component)
332  return;
333 
334  d->clear();
335 
336  d->component = comp;
337  d->ownComponent = false;
338 
339  if (!d->component) {
343  emit itemChanged();
344  return;
345  }
346 
347  if (isComponentComplete())
348  d->load();
349 }
350 
352 {
354 }
355 
357 {
359 
360  if (!q->isComponentComplete() || !component)
361  return;
362 
363  if (!component->isLoading()) {
364  _q_sourceLoaded();
365  } else {
367  q, SLOT(_q_sourceLoaded()));
369  q, SIGNAL(progressChanged()));
370  emit q->statusChanged();
371  emit q->progressChanged();
372  emit q->sourceChanged();
373  emit q->itemChanged();
374  }
375 }
376 
378 {
380 
381  if (component) {
382  if (!component->errors().isEmpty()) {
384  emit q->sourceChanged();
385  emit q->statusChanged();
386  emit q->progressChanged();
387  return;
388  }
389 
390  QDeclarativeContext *creationContext = component->creationContext();
391  if (!creationContext) creationContext = qmlContext(q);
392  QDeclarativeContext *ctxt = new QDeclarativeContext(creationContext);
393  ctxt->setContextObject(q);
394 
396  QObject *obj = component->beginCreate(ctxt);
397  if (component != c) {
398  // component->create could trigger a change in source that causes
399  // component to be set to something else. In that case we just
400  // need to cleanup.
401  if (c)
402  c->completeCreate();
403  delete obj;
404  delete ctxt;
405  return;
406  }
407  if (obj) {
409  if (item) {
412  item->setParentItem(q);
413 // item->setFocus(true);
414  initResize();
415  } else {
416  qmlInfo(q) << QDeclarativeLoader::tr("Loader does not support loading non-visual elements.");
417  delete obj;
418  delete ctxt;
419  }
420  } else {
421  if (!component->errors().isEmpty())
423  delete obj;
424  delete ctxt;
425  source = QUrl();
426  }
427  component->completeCreate();
428  emit q->sourceChanged();
429  emit q->statusChanged();
430  emit q->progressChanged();
431  emit q->itemChanged();
432  emit q->loaded();
433  }
434 }
435 
480 {
481  Q_D(const QDeclarativeLoader);
482 
483  if (d->component)
484  return static_cast<QDeclarativeLoader::Status>(d->component->status());
485 
486  if (d->item)
487  return Ready;
488 
489  return d->source.isEmpty() ? Null : Error;
490 }
491 
493 {
495 
497  d->load();
498 }
499 
500 
522 {
523  Q_D(const QDeclarativeLoader);
524 
525  if (d->item)
526  return 1.0;
527 
528  if (d->component)
529  return d->component->progress();
530 
531  return 0.0;
532 }
533 
534 void QDeclarativeLoaderPrivate::_q_updateSize(bool loaderGeometryChanged)
535 {
537  if (!item || updatingSize)
538  return;
539 
540  updatingSize = true;
541  if (QDeclarativeItem *qmlItem = qobject_cast<QDeclarativeItem*>(item)) {
542  if (!itemWidthValid)
543  q->setImplicitWidth(qmlItem->implicitWidth());
544  else
545  q->setImplicitWidth(qmlItem->width());
546  if (loaderGeometryChanged && q->widthValid())
547  qmlItem->setWidth(q->width());
548  if (!itemHeightValid)
549  q->setImplicitHeight(qmlItem->implicitHeight());
550  else
551  q->setImplicitHeight(qmlItem->height());
552  if (loaderGeometryChanged && q->heightValid())
553  qmlItem->setHeight(q->height());
554  } else if (item && item->isWidget()) {
555  QGraphicsWidget *widget = static_cast<QGraphicsWidget*>(item);
556  QSizeF widgetSize = widget->size();
557  q->setImplicitWidth(widgetSize.width());
558  if (loaderGeometryChanged && q->widthValid())
559  widgetSize.setWidth(q->width());
560  q->setImplicitHeight(widgetSize.height());
561  if (loaderGeometryChanged && q->heightValid())
562  widgetSize.setHeight(q->height());
563  if (widget->size() != widgetSize)
564  widget->resize(widgetSize);
565  }
566  updatingSize = false;
567 }
568 
577 {
578  Q_D(const QDeclarativeLoader);
579  return d->item;
580 }
581 
582 void QDeclarativeLoader::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
583 {
585  if (newGeometry != oldGeometry) {
586  d->_q_updateSize();
587  }
588  QDeclarativeItem::geometryChanged(newGeometry, oldGeometry);
589 }
590 
592 {
594  if (change == ItemSceneHasChanged) {
595  if (d->item && d->item->isWidget()) {
596  d->item->removeEventFilter(this);
597  d->item->installEventFilter(this);
598  }
599  }
600  return QDeclarativeItem::itemChange(change, value);
601 }
602 
604 {
606  if (watched == d->item && e->type() == QEvent::GraphicsSceneResize) {
607  if (d->item && d->item->isWidget())
608  d->_q_updateSize(false);
609  }
610  return QDeclarativeItem::eventFilter(watched, e);
611 }
612 
613 #include <moc_qdeclarativeloader_p.cpp>
614 
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
Status
Emitted after component "startup" has completed.
QGraphicsItem * parent
double qreal
Definition: qglobal.h:1193
unsigned char c[8]
Definition: qnumeric_p.h:62
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QPointer< QWidget > widget
QDeclarativeParserStatus ** d
QVariant itemChange(GraphicsItemChange change, const QVariant &value)
Note that unlike QGraphicsItems, QDeclarativeItem::itemChange() is not called during initial widget p...
void setSource(const QUrl &)
bool isComponentComplete() const
Returns true if construction of the QML component is complete; otherwise returns false.
qreal width() const
Returns the width.
Definition: qsize.h:284
void setParentItem(QGraphicsItem *parent)
Sets this item&#39;s parent item to newParent.
#define SLOT(a)
Definition: qobjectdefs.h:226
qreal height() const
Returns the height.
Definition: qsize.h:287
qreal progress() const
static QString tr(const char *sourceText, const char *comment=0, int n=-1)
GraphicsItemChange
This enum describes the state changes that are notified by QGraphicsItem::itemChange().
The QUrl class provides a convenient interface for working with URLs.
Definition: qurl.h:61
T * qobject_cast(QObject *object)
Definition: qobject.h:375
void setWidth(qreal w)
Sets the width to the given width.
Definition: qsize.h:290
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
Q_DECLARATIVE_EXPORT QDeclarativeContext * qmlContext(const QObject *)
#define Q_D(Class)
Definition: qglobal.h:2482
The QSizeF class defines the size of a two-dimensional object using floating point precision...
Definition: qsize.h:202
void setVisible(bool visible)
If visible is true, the item is made visible.
QUrl source() const
#define Q_Q(Class)
Definition: qglobal.h:2483
void setContextObject(QObject *)
Set the context object.
#define SIGNAL(a)
Definition: qobjectdefs.h:227
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
The QRectF class defines a rectangle in the plane using floating point precision. ...
Definition: qrect.h:511
The QDeclarativeComponent class encapsulates a QML component definition.
The QDeclarativeItem class provides the most basic of all visual items in QML.
static bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Creates a connection of the given type from the signal in the sender object to the method in the rece...
Definition: qobject.cpp:2580
void addItemChangeListener(QDeclarativeItemChangeListener *listener, ChangeTypes types)
void removeItem(QGraphicsItem *item)
Removes the item item and all its children from the scene.
qreal height() const
Returns the height of the rectangle.
Definition: qrect.h:710
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
This function is called to handle this item&#39;s changes in geometry from oldGeometry to newGeometry...
QDeclarativeComponent * component
#define emit
Definition: qobjectdefs.h:76
qreal width() const
Returns the width of the rectangle.
Definition: qrect.h:707
Status status() const
static qreal component(const QPointF &point, unsigned int i)
virtual void itemGeometryChanged(QDeclarativeItem *, const QRectF &, const QRectF &)
QDeclarativeLoader(QDeclarativeItem *parent=0)
virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
This function is called to handle this item&#39;s changes in geometry from oldGeometry to newGeometry...
virtual bool eventFilter(QObject *, QEvent *)
Filters events if this object has been installed as an event filter for the watched object...
Definition: qobject.cpp:1375
QGraphicsObject * item() const
void removeItemChangeListener(QDeclarativeItemChangeListener *, ChangeTypes types)
Q_DECLARATIVE_EXPORT QDeclarativeEngine * qmlEngine(const QObject *)
virtual QVariant itemChange(GraphicsItemChange, const QVariant &)
Note that unlike QGraphicsItems, QDeclarativeItem::itemChange() is not called during initial widget p...
void QDeclarative_setParent_noEvent(QObject *object, QObject *parent)
Makes the object a child of parent.
void _q_updateSize(bool loaderGeometryChanged=true)
virtual void componentComplete()
void installEventFilter(QObject *)
Installs an event filter filterObj on this object.
Definition: qobject.cpp:2070
bool isWidget() const
Returns true if this item is a widget (i.
void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry)
The QDeclarativeContext class defines a context within a QML engine.
static const QGraphicsItemPrivate * get(const QGraphicsItem *item)
void setHeight(qreal h)
Sets the height to the given height.
Definition: qsize.h:293
QGraphicsScene * scene() const
Returns the current scene for the item, or 0 if the item is not stored in a scene.
QDeclarativeInfo qmlInfo(const QObject *me)
The QGraphicsObject class provides a base class for all graphics items that require signals...
QSizeF size
the size of the widget
void warning(const QDeclarativeError &)
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
Type type() const
Returns the event type.
Definition: qcoreevent.h:303
void setSourceComponent(QDeclarativeComponent *)
QDeclarativeComponent * sourceComponent() const
void deleteLater()
Schedules this object for deletion.
Definition: qobject.cpp:2145
bool eventFilter(QObject *watched, QEvent *e)
Filters events if this object has been installed as an event filter for the watched object...
void resize(const QSizeF &size)
virtual void completeCreate()
This method provides more advanced control over component instance creation.
The QGraphicsWidget class is the base class for all widget items in a QGraphicsScene.