Update to 5.0.0-beta1
[profile/ivi/qtdeclarative.git] / src / quick / items / qquickvisualitemmodel.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtQml module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qquickvisualitemmodel_p.h"
43 #include "qquickitem.h"
44
45 #include <QtCore/qcoreapplication.h>
46 #include <QtQml/qqmlcontext.h>
47 #include <QtQml/qqmlengine.h>
48
49 #include <private/qquickchangeset_p.h>
50 #include <private/qqmlglobal_p.h>
51 #include <private/qobject_p.h>
52
53 #include <QtCore/qhash.h>
54 #include <QtCore/qlist.h>
55
56 QT_BEGIN_NAMESPACE
57
58 QHash<QObject*, QQuickVisualItemModelAttached*> QQuickVisualItemModelAttached::attachedProperties;
59
60
61 class QQuickVisualItemModelPrivate : public QObjectPrivate
62 {
63     Q_DECLARE_PUBLIC(QQuickVisualItemModel)
64 public:
65     QQuickVisualItemModelPrivate() : QObjectPrivate() {}
66
67     static void children_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *item) {
68         static_cast<QQuickVisualItemModelPrivate *>(prop->data)->children.append(Item(item));
69         static_cast<QQuickVisualItemModelPrivate *>(prop->data)->itemAppended();
70         static_cast<QQuickVisualItemModelPrivate *>(prop->data)->emitChildrenChanged();
71     }
72
73     static int children_count(QQmlListProperty<QQuickItem> *prop) {
74         return static_cast<QQuickVisualItemModelPrivate *>(prop->data)->children.count();
75     }
76
77     static QQuickItem *children_at(QQmlListProperty<QQuickItem> *prop, int index) {
78         return static_cast<QQuickVisualItemModelPrivate *>(prop->data)->children.at(index).item;
79     }
80
81     void itemAppended() {
82         Q_Q(QQuickVisualItemModel);
83         QQuickVisualItemModelAttached *attached = QQuickVisualItemModelAttached::properties(children.last().item);
84         attached->setIndex(children.count()-1);
85         QQuickChangeSet changeSet;
86         changeSet.insert(children.count() - 1, 1);
87         emit q->modelUpdated(changeSet, false);
88         emit q->countChanged();
89     }
90
91     void emitChildrenChanged() {
92         Q_Q(QQuickVisualItemModel);
93         emit q->childrenChanged();
94     }
95
96     int indexOf(QQuickItem *item) const {
97         for (int i = 0; i < children.count(); ++i)
98             if (children.at(i).item == item)
99                 return i;
100         return -1;
101     }
102
103     class Item {
104     public:
105         Item(QQuickItem *i) : item(i), ref(0) {}
106
107         void addRef() { ++ref; }
108         bool deref() { return --ref == 0; }
109
110         QQuickItem *item;
111         int ref;
112     };
113
114     QList<Item> children;
115 };
116
117
118 /*!
119     \qmltype VisualItemModel
120     \instantiates QQuickVisualItemModel
121     \inqmlmodule QtQuick 2
122     \ingroup qtquick-models
123     \brief Defines items to be used added to a view
124
125     A VisualItemModel contains the visual items to be used in a view.
126     When a VisualItemModel is used in a view, the view does not require
127     a delegate since the VisualItemModel already contains the visual
128     delegate (items).
129
130     An item can determine its index within the
131     model via the \l{VisualItemModel::index}{index} attached property.
132
133     The example below places three colored rectangles in a ListView.
134     \code
135     import QtQuick 2.0
136
137     Rectangle {
138         VisualItemModel {
139             id: itemModel
140             Rectangle { height: 30; width: 80; color: "red" }
141             Rectangle { height: 30; width: 80; color: "green" }
142             Rectangle { height: 30; width: 80; color: "blue" }
143         }
144
145         ListView {
146             anchors.fill: parent
147             model: itemModel
148         }
149     }
150     \endcode
151
152     \image visualitemmodel.png
153
154     \sa {quick/modelviews/visualitemmodel}{VisualItemModel example}
155 */
156 QQuickVisualItemModel::QQuickVisualItemModel(QObject *parent)
157     : QQuickVisualModel(*(new QQuickVisualItemModelPrivate), parent)
158 {
159 }
160
161 /*!
162     \qmlattachedproperty int QtQuick2::VisualItemModel::index
163     This attached property holds the index of this delegate's item within the model.
164
165     It is attached to each instance of the delegate.
166 */
167
168 QQmlListProperty<QQuickItem> QQuickVisualItemModel::children()
169 {
170     Q_D(QQuickVisualItemModel);
171     return QQmlListProperty<QQuickItem>(this, d, d->children_append,
172                                                       d->children_count, d->children_at);
173 }
174
175 /*!
176     \qmlproperty int QtQuick2::VisualItemModel::count
177
178     The number of items in the model.  This property is readonly.
179 */
180 int QQuickVisualItemModel::count() const
181 {
182     Q_D(const QQuickVisualItemModel);
183     return d->children.count();
184 }
185
186 bool QQuickVisualItemModel::isValid() const
187 {
188     return true;
189 }
190
191 QQuickItem *QQuickVisualItemModel::item(int index, bool)
192 {
193     Q_D(QQuickVisualItemModel);
194     QQuickVisualItemModelPrivate::Item &item = d->children[index];
195     item.addRef();
196     if (item.ref == 1) {
197         emit initItem(index, item.item);
198         emit createdItem(index, item.item);
199     }
200     return item.item;
201 }
202
203 QQuickVisualModel::ReleaseFlags QQuickVisualItemModel::release(QQuickItem *item)
204 {
205     Q_D(QQuickVisualItemModel);
206     int idx = d->indexOf(item);
207     if (idx >= 0) {
208         if (d->children[idx].deref()) {
209             // XXX todo - the original did item->scene()->removeItem().  Why?
210             item->setParentItem(0);
211         } else {
212             return QQuickVisualModel::Referenced;
213         }
214     }
215     return 0;
216 }
217
218 QString QQuickVisualItemModel::stringValue(int index, const QString &name)
219 {
220     Q_D(QQuickVisualItemModel);
221     if (index < 0 || index >= d->children.count())
222         return QString();
223     return QQmlEngine::contextForObject(d->children.at(index).item)->contextProperty(name).toString();
224 }
225
226 int QQuickVisualItemModel::indexOf(QQuickItem *item, QObject *) const
227 {
228     Q_D(const QQuickVisualItemModel);
229     return d->indexOf(item);
230 }
231
232 QQuickVisualItemModelAttached *QQuickVisualItemModel::qmlAttachedProperties(QObject *obj)
233 {
234     return QQuickVisualItemModelAttached::properties(obj);
235 }
236
237 QT_END_NAMESPACE
238