source: trunk/src/declarative/util/qdeclarativepropertymap.cpp@ 1023

Last change on this file since 1023 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 8.2 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtDeclarative module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
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.
23**
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.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qdeclarativepropertymap.h"
43
44#include <private/qmetaobjectbuilder_p.h>
45#include "private/qdeclarativeopenmetaobject_p.h"
46
47#include <QDebug>
48
49QT_BEGIN_NAMESPACE
50
51//QDeclarativePropertyMapMetaObject lets us listen for changes coming from QML
52//so we can emit the changed signal.
53class QDeclarativePropertyMapMetaObject : public QDeclarativeOpenMetaObject
54{
55public:
56 QDeclarativePropertyMapMetaObject(QDeclarativePropertyMap *obj, QDeclarativePropertyMapPrivate *objPriv);
57
58protected:
59 virtual void propertyWritten(int index);
60 virtual void propertyCreated(int, QMetaPropertyBuilder &);
61
62private:
63 QDeclarativePropertyMap *map;
64 QDeclarativePropertyMapPrivate *priv;
65};
66
67class QDeclarativePropertyMapPrivate : public QObjectPrivate
68{
69 Q_DECLARE_PUBLIC(QDeclarativePropertyMap)
70public:
71 QDeclarativePropertyMapMetaObject *mo;
72 QStringList keys;
73 void emitChanged(const QString &key, const QVariant &value);
74};
75
76void QDeclarativePropertyMapPrivate::emitChanged(const QString &key, const QVariant &value)
77{
78 Q_Q(QDeclarativePropertyMap);
79 emit q->valueChanged(key, value);
80}
81
82QDeclarativePropertyMapMetaObject::QDeclarativePropertyMapMetaObject(QDeclarativePropertyMap *obj, QDeclarativePropertyMapPrivate *objPriv) : QDeclarativeOpenMetaObject(obj)
83{
84 map = obj;
85 priv = objPriv;
86}
87
88void QDeclarativePropertyMapMetaObject::propertyWritten(int index)
89{
90 priv->emitChanged(QString::fromUtf8(name(index)), operator[](index));
91}
92
93void QDeclarativePropertyMapMetaObject::propertyCreated(int, QMetaPropertyBuilder &b)
94{
95 priv->keys.append(QString::fromUtf8(b.name()));
96}
97
98/*!
99 \class QDeclarativePropertyMap
100 \since 4.7
101 \brief The QDeclarativePropertyMap class allows you to set key-value pairs that can be used in QML bindings.
102
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
105 access it in QML.
106
107 In the C++ file:
108 \code
109 // create our data
110 QDeclarativePropertyMap ownerData;
111 ownerData.insert("name", QVariant(QString("John Smith")));
112 ownerData.insert("phone", QVariant(QString("555-5555")));
113
114 // expose it to the UI layer
115 QDeclarativeView view;
116 QDeclarativeContext *ctxt = view.rootContext();
117 ctxt->setContextProperty("owner", &ownerData);
118
119 view.setSource(QUrl::fromLocalFile("main.qml"));
120 view.show();
121 \endcode
122
123 Then, in \c main.qml:
124 \code
125 Text { text: owner.name + " " + owner.phone }
126 \endcode
127
128 The binding is dynamic - whenever a key's value is updated, anything bound to that
129 key will be updated as well.
130
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.
134
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.
137*/
138
139/*!
140 Constructs a bindable map with parent object \a parent.
141*/
142QDeclarativePropertyMap::QDeclarativePropertyMap(QObject *parent)
143: QObject(*(new QDeclarativePropertyMapPrivate), parent)
144{
145 Q_D(QDeclarativePropertyMap);
146 d->mo = new QDeclarativePropertyMapMetaObject(this, d);
147}
148
149/*!
150 Destroys the bindable map.
151*/
152QDeclarativePropertyMap::~QDeclarativePropertyMap()
153{
154}
155
156/*!
157 Clears the value (if any) associated with \a key.
158*/
159void QDeclarativePropertyMap::clear(const QString &key)
160{
161 Q_D(QDeclarativePropertyMap);
162 d->mo->setValue(key.toUtf8(), QVariant());
163}
164
165/*!
166 Returns the value associated with \a key.
167
168 If no value has been set for this key (or if the value has been cleared),
169 an invalid QVariant is returned.
170*/
171QVariant QDeclarativePropertyMap::value(const QString &key) const
172{
173 Q_D(const QDeclarativePropertyMap);
174 return d->mo->value(key.toUtf8());
175}
176
177/*!
178 Sets the value associated with \a key to \a value.
179
180 If the key doesn't exist, it is automatically created.
181*/
182void QDeclarativePropertyMap::insert(const QString &key, const QVariant &value)
183{
184 Q_D(QDeclarativePropertyMap);
185 d->mo->setValue(key.toUtf8(), value);
186}
187
188/*!
189 Returns the list of keys.
190
191 Keys that have been cleared will still appear in this list, even though their
192 associated values are invalid QVariants.
193*/
194QStringList QDeclarativePropertyMap::keys() const
195{
196 Q_D(const QDeclarativePropertyMap);
197 return d->keys;
198}
199
200/*!
201 \overload
202
203 Same as size().
204*/
205int QDeclarativePropertyMap::count() const
206{
207 Q_D(const QDeclarativePropertyMap);
208 return d->keys.count();
209}
210
211/*!
212 Returns the number of keys in the map.
213
214 \sa isEmpty(), count()
215*/
216int QDeclarativePropertyMap::size() const
217{
218 Q_D(const QDeclarativePropertyMap);
219 return d->keys.size();
220}
221
222/*!
223 Returns true if the map contains no keys; otherwise returns
224 false.
225
226 \sa size()
227*/
228bool QDeclarativePropertyMap::isEmpty() const
229{
230 Q_D(const QDeclarativePropertyMap);
231 return d->keys.isEmpty();
232}
233
234/*!
235 Returns true if the map contains \a key.
236
237 \sa size()
238*/
239bool QDeclarativePropertyMap::contains(const QString &key) const
240{
241 Q_D(const QDeclarativePropertyMap);
242 return d->keys.contains(key);
243}
244
245/*!
246 Returns the value associated with the key \a key as a modifiable
247 reference.
248
249 If the map contains no item with key \a key, the function inserts
250 an invalid QVariant into the map with key \a key, and
251 returns a reference to it.
252
253 \sa insert(), value()
254*/
255QVariant &QDeclarativePropertyMap::operator[](const QString &key)
256{
257 //### optimize
258 Q_D(QDeclarativePropertyMap);
259 QByteArray utf8key = key.toUtf8();
260 if (!d->keys.contains(key))
261 d->mo->setValue(utf8key, QVariant()); //force creation -- needed below
262
263 return (*(d->mo))[utf8key];
264}
265
266/*!
267 \overload
268
269 Same as value().
270*/
271QVariant QDeclarativePropertyMap::operator[](const QString &key) const
272{
273 return value(key);
274}
275
276/*!
277 \fn void QDeclarativePropertyMap::valueChanged(const QString &key, const QVariant &value)
278 This signal is emitted whenever one of the values in the map is changed. \a key
279 is the key corresponding to the \a value that was changed.
280
281 \note valueChanged() is \bold NOT emitted when changes are made by calling insert()
282 or clear() - it is only emitted when a value is updated from QML.
283*/
284
285QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.