diff options
Diffstat (limited to 'src/declarative/util/qdeclarativepropertymap.cpp')
-rw-r--r-- | src/declarative/util/qdeclarativepropertymap.cpp | 279 |
1 files changed, 279 insertions, 0 deletions
diff --git a/src/declarative/util/qdeclarativepropertymap.cpp b/src/declarative/util/qdeclarativepropertymap.cpp new file mode 100644 index 0000000..fcea515 --- /dev/null +++ b/src/declarative/util/qdeclarativepropertymap.cpp @@ -0,0 +1,279 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdeclarativepropertymap.h" + +#include "qdeclarativeopenmetaobject_p.h" + +#include <QDebug> + +QT_BEGIN_NAMESPACE + +//QDeclarativePropertyMapMetaObject lets us listen for changes coming from QML +//so we can emit the changed signal. +class QDeclarativePropertyMapMetaObject : public QDeclarativeOpenMetaObject +{ +public: + QDeclarativePropertyMapMetaObject(QDeclarativePropertyMap *obj, QDeclarativePropertyMapPrivate *objPriv); + +protected: + virtual void propertyWrite(int index); + +private: + QDeclarativePropertyMap *map; + QDeclarativePropertyMapPrivate *priv; +}; + +class QDeclarativePropertyMapPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QDeclarativePropertyMap) +public: + QDeclarativePropertyMapMetaObject *mo; + QStringList keys; + void emitChanged(const QString &key); +}; + +void QDeclarativePropertyMapPrivate::emitChanged(const QString &key) +{ + Q_Q(QDeclarativePropertyMap); + emit q->valueChanged(key); +} + +QDeclarativePropertyMapMetaObject::QDeclarativePropertyMapMetaObject(QDeclarativePropertyMap *obj, QDeclarativePropertyMapPrivate *objPriv) : QDeclarativeOpenMetaObject(obj) +{ + map = obj; + priv = objPriv; +} + +void QDeclarativePropertyMapMetaObject::propertyWrite(int index) +{ + priv->emitChanged(QString::fromUtf8(name(index))); +} + +/*! + \class QDeclarativePropertyMap + \since 4.7 + \brief The QDeclarativePropertyMap class allows you to set key-value pairs that can be used in bindings. + + QDeclarativePropertyMap provides a convenient way to expose domain data to the UI layer. + The following example shows how you might declare data in C++ and then + access it in QML. + + Setup in C++: + \code + //create our data + QDeclarativePropertyMap ownerData; + ownerData.insert("name", QVariant(QString("John Smith"))); + ownerData.insert("phone", QVariant(QString("555-5555"))); + + //expose it to the UI layer + QDeclarativeContext *ctxt = view->bindContext(); + ctxt->setProperty("owner", &data); + \endcode + + Then, in QML: + \code + Text { text: owner.name } + Text { text: owner.phone } + \endcode + + The binding is dynamic - whenever a key's value is updated, anything bound to that + key will be updated as well. + + To detect value changes made in the UI layer you can connect to the valueChanged() signal. + However, note that valueChanged() is \bold NOT emitted when changes are made by calling insert() + or clear() - it is only emitted when a value is updated from QML. + + \note It is not possible to remove keys from the map; once a key has been added, you can only + modify or clear its associated value. +*/ + +/*! + Constructs a bindable map with parent object \a parent. +*/ +QDeclarativePropertyMap::QDeclarativePropertyMap(QObject *parent) +: QObject(*(new QDeclarativePropertyMapPrivate), parent) +{ + Q_D(QDeclarativePropertyMap); + d->mo = new QDeclarativePropertyMapMetaObject(this, d); +} + +/*! + Destroys the bindable map. +*/ +QDeclarativePropertyMap::~QDeclarativePropertyMap() +{ +} + +/*! + Clears the value (if any) associated with \a key. +*/ +void QDeclarativePropertyMap::clear(const QString &key) +{ + Q_D(QDeclarativePropertyMap); + d->mo->setValue(key.toUtf8(), QVariant()); +} + +/*! + Returns the value associated with \a key. + + If no value has been set for this key (or if the value has been cleared), + an invalid QVariant is returned. +*/ +QVariant QDeclarativePropertyMap::value(const QString &key) const +{ + Q_D(const QDeclarativePropertyMap); + return d->mo->value(key.toUtf8()); +} + +/*! + Sets the value associated with \a key to \a value. + + If the key doesn't exist, it is automatically created. +*/ +void QDeclarativePropertyMap::insert(const QString &key, const QVariant &value) +{ + Q_D(QDeclarativePropertyMap); + if (!d->keys.contains(key)) + d->keys.append(key); + d->mo->setValue(key.toUtf8(), value); +} + +/*! + Returns the list of keys. + + Keys that have been cleared will still appear in this list, even though their + associated values are invalid QVariants. +*/ +QStringList QDeclarativePropertyMap::keys() const +{ + Q_D(const QDeclarativePropertyMap); + return d->keys; +} + +/*! + \overload + + Same as size(). +*/ +int QDeclarativePropertyMap::count() const +{ + Q_D(const QDeclarativePropertyMap); + return d->keys.count(); +} + +/*! + Returns the number of keys in the map. + + \sa isEmpty(), count() +*/ +int QDeclarativePropertyMap::size() const +{ + Q_D(const QDeclarativePropertyMap); + return d->keys.size(); +} + +/*! + Returns true if the map contains no keys; otherwise returns + false. + + \sa size() +*/ +bool QDeclarativePropertyMap::isEmpty() const +{ + Q_D(const QDeclarativePropertyMap); + return d->keys.isEmpty(); +} + +/*! + Returns true if the map contains \a key. + + \sa size() +*/ +bool QDeclarativePropertyMap::contains(const QString &key) const +{ + Q_D(const QDeclarativePropertyMap); + return d->keys.contains(key); +} + +/*! + Returns the value associated with the key \a key as a modifiable + reference. + + If the map contains no item with key \a key, the function inserts + an invalid QVariant into the map with key \a key, and + returns a reference to it. + + \sa insert(), value() +*/ +QVariant &QDeclarativePropertyMap::operator[](const QString &key) +{ + //### optimize + Q_D(QDeclarativePropertyMap); + QByteArray utf8key = key.toUtf8(); + if (!d->keys.contains(key)) { + d->keys.append(key); + d->mo->setValue(utf8key, QVariant()); //force creation -- needed below + } + + return (*(d->mo))[utf8key]; +} + +/*! + \overload + + Same as value(). +*/ +const QVariant QDeclarativePropertyMap::operator[](const QString &key) const +{ + return value(key); +} + +/*! + \fn void QDeclarativePropertyMap::valueChanged(const QString &key) + This signal is emitted whenever one of the values in the map is changed. \a key + is the key corresponding to the value that was changed. + + \note valueChanged() is \bold NOT emitted when changes are made by calling insert() + or clear() - it is only emitted when a value is updated from QML. +*/ + +QT_END_NAMESPACE |