Doc: Grouped Qt Quick types into several groups
[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     \qmlclass VisualItemModel QQuickVisualItemModel
120     \inqmlmodule QtQuick 2
121     \ingroup qtquick-models
122     \brief Defines items to be used added to a view
123
124     A VisualItemModel contains the visual items to be used in a view.
125     When a VisualItemModel is used in a view, the view does not require
126     a delegate since the VisualItemModel already contains the visual
127     delegate (items).
128
129     An item can determine its index within the
130     model via the \l{VisualItemModel::index}{index} attached property.
131
132     The example below places three colored rectangles in a ListView.
133     \code
134     import QtQuick 2.0
135
136     Rectangle {
137         VisualItemModel {
138             id: itemModel
139             Rectangle { height: 30; width: 80; color: "red" }
140             Rectangle { height: 30; width: 80; color: "green" }
141             Rectangle { height: 30; width: 80; color: "blue" }
142         }
143
144         ListView {
145             anchors.fill: parent
146             model: itemModel
147         }
148     }
149     \endcode
150
151     \image visualitemmodel.png
152
153     \sa {declarative/modelviews/visualitemmodel}{VisualItemModel example}
154 */
155 QQuickVisualItemModel::QQuickVisualItemModel(QObject *parent)
156     : QQuickVisualModel(*(new QQuickVisualItemModelPrivate), parent)
157 {
158 }
159
160 /*!
161     \qmlattachedproperty int QtQuick2::VisualItemModel::index
162     This attached property holds the index of this delegate's item within the model.
163
164     It is attached to each instance of the delegate.
165 */
166
167 QQmlListProperty<QQuickItem> QQuickVisualItemModel::children()
168 {
169     Q_D(QQuickVisualItemModel);
170     return QQmlListProperty<QQuickItem>(this, d, d->children_append,
171                                                       d->children_count, d->children_at);
172 }
173
174 /*!
175     \qmlproperty int QtQuick2::VisualItemModel::count
176
177     The number of items in the model.  This property is readonly.
178 */
179 int QQuickVisualItemModel::count() const
180 {
181     Q_D(const QQuickVisualItemModel);
182     return d->children.count();
183 }
184
185 bool QQuickVisualItemModel::isValid() const
186 {
187     return true;
188 }
189
190 QQuickItem *QQuickVisualItemModel::item(int index, bool)
191 {
192     Q_D(QQuickVisualItemModel);
193     QQuickVisualItemModelPrivate::Item &item = d->children[index];
194     item.addRef();
195     if (item.ref == 1) {
196         emit initItem(index, item.item);
197         emit createdItem(index, item.item);
198     }
199     return item.item;
200 }
201
202 QQuickVisualModel::ReleaseFlags QQuickVisualItemModel::release(QQuickItem *item)
203 {
204     Q_D(QQuickVisualItemModel);
205     int idx = d->indexOf(item);
206     if (idx >= 0) {
207         if (d->children[idx].deref()) {
208             // XXX todo - the original did item->scene()->removeItem().  Why?
209             item->setParentItem(0);
210         } else {
211             return QQuickVisualModel::Referenced;
212         }
213     }
214     return 0;
215 }
216
217 QString QQuickVisualItemModel::stringValue(int index, const QString &name)
218 {
219     Q_D(QQuickVisualItemModel);
220     if (index < 0 || index >= d->children.count())
221         return QString();
222     return QQmlEngine::contextForObject(d->children.at(index).item)->contextProperty(name).toString();
223 }
224
225 int QQuickVisualItemModel::indexOf(QQuickItem *item, QObject *) const
226 {
227     Q_D(const QQuickVisualItemModel);
228     return d->indexOf(item);
229 }
230
231 QQuickVisualItemModelAttached *QQuickVisualItemModel::qmlAttachedProperties(QObject *obj)
232 {
233     return QQuickVisualItemModelAttached::properties(obj);
234 }
235
236 QT_END_NAMESPACE
237