1 /****************************************************************************
3 ** Copyright (C) 2011 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 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #include "qdeclarativepropertymap.h"
44 #include <private/qmetaobjectbuilder_p.h>
45 #include "private/qdeclarativeopenmetaobject_p.h"
51 //QDeclarativePropertyMapMetaObject lets us listen for changes coming from QML
52 //so we can emit the changed signal.
53 class QDeclarativePropertyMapMetaObject : public QDeclarativeOpenMetaObject
56 QDeclarativePropertyMapMetaObject(QDeclarativePropertyMap *obj, QDeclarativePropertyMapPrivate *objPriv);
59 virtual void propertyWritten(int index);
60 virtual void propertyCreated(int, QMetaPropertyBuilder &);
63 QDeclarativePropertyMap *map;
64 QDeclarativePropertyMapPrivate *priv;
67 class QDeclarativePropertyMapPrivate : public QObjectPrivate
69 Q_DECLARE_PUBLIC(QDeclarativePropertyMap)
71 QDeclarativePropertyMapMetaObject *mo;
73 void emitChanged(const QString &key, const QVariant &value);
76 void QDeclarativePropertyMapPrivate::emitChanged(const QString &key, const QVariant &value)
78 Q_Q(QDeclarativePropertyMap);
79 emit q->valueChanged(key, value);
82 QDeclarativePropertyMapMetaObject::QDeclarativePropertyMapMetaObject(QDeclarativePropertyMap *obj, QDeclarativePropertyMapPrivate *objPriv) : QDeclarativeOpenMetaObject(obj)
88 void QDeclarativePropertyMapMetaObject::propertyWritten(int index)
90 priv->emitChanged(QString::fromUtf8(name(index)), operator[](index));
93 void QDeclarativePropertyMapMetaObject::propertyCreated(int, QMetaPropertyBuilder &b)
95 priv->keys.append(QString::fromUtf8(b.name()));
99 \class QDeclarativePropertyMap
101 \brief The QDeclarativePropertyMap class allows you to set key-value pairs that can be used in QML bindings.
103 QDeclarativePropertyMap provides a convenient way to expose domain data to the UI layer.
104 The following example shows how you might declare data in C++ and then
110 QDeclarativePropertyMap ownerData;
111 ownerData.insert("name", QVariant(QString("John Smith")));
112 ownerData.insert("phone", QVariant(QString("555-5555")));
114 // expose it to the UI layer
115 QDeclarativeView view;
116 QDeclarativeContext *ctxt = view.rootContext();
117 ctxt->setContextProperty("owner", &ownerData);
119 view.setSource(QUrl::fromLocalFile("main.qml"));
123 Then, in \c main.qml:
125 Text { text: owner.name + " " + owner.phone }
128 The binding is dynamic - whenever a key's value is updated, anything bound to that
129 key will be updated as well.
131 To detect value changes made in the UI layer you can connect to the valueChanged() signal.
132 However, note that valueChanged() is \bold NOT emitted when changes are made by calling insert()
133 or clear() - it is only emitted when a value is updated from QML.
135 \note It is not possible to remove keys from the map; once a key has been added, you can only
136 modify or clear its associated value.
140 Constructs a bindable map with parent object \a parent.
142 QDeclarativePropertyMap::QDeclarativePropertyMap(QObject *parent)
143 : QObject(*(new QDeclarativePropertyMapPrivate), parent)
145 Q_D(QDeclarativePropertyMap);
146 d->mo = new QDeclarativePropertyMapMetaObject(this, d);
150 Destroys the bindable map.
152 QDeclarativePropertyMap::~QDeclarativePropertyMap()
157 Clears the value (if any) associated with \a key.
159 void QDeclarativePropertyMap::clear(const QString &key)
161 Q_D(QDeclarativePropertyMap);
162 d->mo->setValue(key.toUtf8(), QVariant());
166 Returns the value associated with \a key.
168 If no value has been set for this key (or if the value has been cleared),
169 an invalid QVariant is returned.
171 QVariant QDeclarativePropertyMap::value(const QString &key) const
173 Q_D(const QDeclarativePropertyMap);
174 return d->mo->value(key.toUtf8());
178 Sets the value associated with \a key to \a value.
180 If the key doesn't exist, it is automatically created.
182 void QDeclarativePropertyMap::insert(const QString &key, const QVariant &value)
184 Q_D(QDeclarativePropertyMap);
185 //The following strings shouldn't be used as property names
186 if (key != QLatin1String("keys")
187 && key != QLatin1String("valueChanged")
188 && key != QLatin1String("QObject")
189 && key != QLatin1String("destroyed")
190 && key != QLatin1String("deleteLater")) {
191 d->mo->setValue(key.toUtf8(), value);
193 qWarning() << "Creating property with name"
195 << "is not permitted, conflicts with internal symbols.";
200 Returns the list of keys.
202 Keys that have been cleared will still appear in this list, even though their
203 associated values are invalid QVariants.
205 QStringList QDeclarativePropertyMap::keys() const
207 Q_D(const QDeclarativePropertyMap);
216 int QDeclarativePropertyMap::count() const
218 Q_D(const QDeclarativePropertyMap);
219 return d->keys.count();
223 Returns the number of keys in the map.
225 \sa isEmpty(), count()
227 int QDeclarativePropertyMap::size() const
229 Q_D(const QDeclarativePropertyMap);
230 return d->keys.size();
234 Returns true if the map contains no keys; otherwise returns
239 bool QDeclarativePropertyMap::isEmpty() const
241 Q_D(const QDeclarativePropertyMap);
242 return d->keys.isEmpty();
246 Returns true if the map contains \a key.
250 bool QDeclarativePropertyMap::contains(const QString &key) const
252 Q_D(const QDeclarativePropertyMap);
253 return d->keys.contains(key);
257 Returns the value associated with the key \a key as a modifiable
260 If the map contains no item with key \a key, the function inserts
261 an invalid QVariant into the map with key \a key, and
262 returns a reference to it.
264 \sa insert(), value()
266 QVariant &QDeclarativePropertyMap::operator[](const QString &key)
269 Q_D(QDeclarativePropertyMap);
270 QByteArray utf8key = key.toUtf8();
271 if (!d->keys.contains(key))
272 insert(key, QVariant());//force creation -- needed below
274 return (*(d->mo))[utf8key];
282 QVariant QDeclarativePropertyMap::operator[](const QString &key) const
288 \fn void QDeclarativePropertyMap::valueChanged(const QString &key, const QVariant &value)
289 This signal is emitted whenever one of the values in the map is changed. \a key
290 is the key corresponding to the \a value that was changed.
292 \note valueChanged() is \bold NOT emitted when changes are made by calling insert()
293 or clear() - it is only emitted when a value is updated from QML.