aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/types/qqmlobjectmodel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/types/qqmlobjectmodel.cpp')
-rw-r--r--src/qml/types/qqmlobjectmodel.cpp204
1 files changed, 189 insertions, 15 deletions
diff --git a/src/qml/types/qqmlobjectmodel.cpp b/src/qml/types/qqmlobjectmodel.cpp
index 7081e96070..4b64f24806 100644
--- a/src/qml/types/qqmlobjectmodel.cpp
+++ b/src/qml/types/qqmlobjectmodel.cpp
@@ -36,10 +36,12 @@
#include <QtCore/qcoreapplication.h>
#include <QtQml/qqmlcontext.h>
#include <QtQml/qqmlengine.h>
+#include <QtQml/qqmlinfo.h>
#include <private/qqmlchangeset_p.h>
#include <private/qqmlglobal_p.h>
#include <private/qobject_p.h>
+#include <private/qpodvector_p.h>
#include <QtCore/qhash.h>
#include <QtCore/qlist.h>
@@ -67,9 +69,8 @@ public:
QQmlObjectModelPrivate() : QObjectPrivate() {}
static void children_append(QQmlListProperty<QObject> *prop, QObject *item) {
- static_cast<QQmlObjectModelPrivate *>(prop->data)->children.append(Item(item));
- static_cast<QQmlObjectModelPrivate *>(prop->data)->itemAppended();
- static_cast<QQmlObjectModelPrivate *>(prop->data)->emitChildrenChanged();
+ int index = static_cast<QQmlObjectModelPrivate *>(prop->data)->children.count();
+ static_cast<QQmlObjectModelPrivate *>(prop->data)->insert(index, item);
}
static int children_count(QQmlListProperty<QObject> *prop) {
@@ -81,33 +82,77 @@ public:
}
static void children_clear(QQmlListProperty<QObject> *prop) {
- static_cast<QQmlObjectModelPrivate *>(prop->data)->itemCleared(static_cast<QQmlObjectModelPrivate *>(prop->data)->children);
- static_cast<QQmlObjectModelPrivate *>(prop->data)->children.clear();
- static_cast<QQmlObjectModelPrivate *>(prop->data)->emitChildrenChanged();
+ static_cast<QQmlObjectModelPrivate *>(prop->data)->clear();
}
- void itemAppended() {
+ void insert(int index, QObject *item) {
Q_Q(QQmlObjectModel);
- QQmlObjectModelAttached *attached = QQmlObjectModelAttached::properties(children.last().item);
- attached->setIndex(children.count()-1);
+ children.insert(index, Item(item));
+ for (int i = index; i < children.count(); ++i) {
+ QQmlObjectModelAttached *attached = QQmlObjectModelAttached::properties(children.at(i).item);
+ attached->setIndex(i);
+ }
QQmlChangeSet changeSet;
- changeSet.insert(children.count() - 1, 1);
+ changeSet.insert(index, 1);
emit q->modelUpdated(changeSet, false);
emit q->countChanged();
+ emit q->childrenChanged();
}
- void itemCleared(const QList<Item> &children) {
+ void move(int from, int to, int n) {
Q_Q(QQmlObjectModel);
- foreach (const Item &child, children)
- emit q->destroyingItem(child.item);
- emit q->countChanged();
+ if (from > to) {
+ // Only move forwards - flip if backwards moving
+ int tfrom = from;
+ int tto = to;
+ from = tto;
+ to = tto+n;
+ n = tfrom-tto;
+ }
+
+ QPODVector<QQmlObjectModelPrivate::Item, 4> store;
+ for (int i = 0; i < to - from; ++i)
+ store.append(children[from + n + i]);
+ for (int i = 0; i < n; ++i)
+ store.append(children[from + i]);
+
+ for (int i = 0; i < store.count(); ++i) {
+ children[from + i] = store[i];
+ QQmlObjectModelAttached *attached = QQmlObjectModelAttached::properties(children.at(from + i).item);
+ attached->setIndex(from + i);
+ }
+
+ QQmlChangeSet changeSet;
+ changeSet.move(from, to, n, -1);
+ emit q->modelUpdated(changeSet, false);
+ emit q->childrenChanged();
}
- void emitChildrenChanged() {
+ void remove(int index, int n) {
Q_Q(QQmlObjectModel);
+ for (int i = index; i < index + n; ++i) {
+ QQmlObjectModelAttached *attached = QQmlObjectModelAttached::properties(children.at(i).item);
+ attached->setIndex(-1);
+ }
+ children.erase(children.begin() + index, children.begin() + index + n);
+ for (int i = index; i < children.count(); ++i) {
+ QQmlObjectModelAttached *attached = QQmlObjectModelAttached::properties(children.at(i).item);
+ attached->setIndex(i);
+ }
+ QQmlChangeSet changeSet;
+ changeSet.remove(index, n);
+ emit q->modelUpdated(changeSet, false);
+ emit q->countChanged();
emit q->childrenChanged();
}
+ void clear() {
+ Q_Q(QQmlObjectModel);
+ foreach (const Item &child, children)
+ emit q->destroyingItem(child.item);
+ remove(0, children.count());
+ }
+
int indexOf(QObject *item) const {
for (int i = 0; i < children.count(); ++i)
if (children.at(i).item == item)
@@ -258,4 +303,133 @@ QQmlObjectModelAttached *QQmlObjectModel::qmlAttachedProperties(QObject *obj)
return QQmlObjectModelAttached::properties(obj);
}
+/*!
+ \qmlmethod object QtQml.Models::ObjectModel::get(int index)
+ \since 5.6
+
+ Returns the item at \a index in the model. This allows the item
+ to be accessed or modified from JavaScript:
+
+ \code
+ Component.onCompleted: {
+ objectModel.append(objectComponent.createObject())
+ console.log(objectModel.get(0).objectName);
+ objectModel.get(0).objectName = "first";
+ }
+ \endcode
+
+ The \a index must be an element in the list.
+
+ \sa append()
+*/
+QObject *QQmlObjectModel::get(int index) const
+{
+ Q_D(const QQmlObjectModel);
+ if (index < 0 || index >= d->children.count())
+ return 0;
+ return d->children.at(index).item;
+}
+
+/*!
+ \qmlmethod QtQml.Models::ObjectModel::append(object item)
+ \since 5.6
+
+ Appends a new item to the end of the model.
+
+ \code
+ objectModel.append(objectComponent.createObject())
+ \endcode
+
+ \sa insert(), remove()
+*/
+void QQmlObjectModel::append(QObject *object)
+{
+ Q_D(QQmlObjectModel);
+ d->insert(count(), object);
+}
+
+/*!
+ \qmlmethod QtQml.Models::ObjectModel::insert(int index, object item)
+ \since 5.6
+
+ Inserts a new item to the model at position \a index.
+
+ \code
+ objectModel.insert(2, objectComponent.createObject())
+ \endcode
+
+ The \a index must be to an existing item in the list, or one past
+ the end of the list (equivalent to append).
+
+ \sa append(), remove()
+*/
+void QQmlObjectModel::insert(int index, QObject *object)
+{
+ Q_D(QQmlObjectModel);
+ if (index < 0 || index > count()) {
+ qmlInfo(this) << tr("insert: index %1 out of range").arg(index);
+ return;
+ }
+ d->insert(index, object);
+}
+
+/*!
+ \qmlmethod QtQml.Models::ObjectModel::move(int from, int to, int n = 1)
+ \since 5.6
+
+ Moves \a n items \a from one position \a to another.
+
+ The from and to ranges must exist; for example, to move the first 3 items
+ to the end of the model:
+
+ \code
+ objectModel.move(0, objectModel.count - 3, 3)
+ \endcode
+
+ \sa append()
+*/
+void QQmlObjectModel::move(int from, int to, int n)
+{
+ Q_D(QQmlObjectModel);
+ if (n <= 0 || from == to)
+ return;
+ if (from < 0 || to < 0 || from + n > count() || to + n > count()) {
+ qmlInfo(this) << tr("move: out of range");
+ return;
+ }
+ d->move(from, to, n);
+}
+
+/*!
+ \qmlmethod QtQml.Models::ObjectModel::remove(int index, int n = 1)
+ \since 5.6
+
+ Removes the items at \a index from the model.
+
+ \sa clear()
+*/
+void QQmlObjectModel::remove(int index, int n)
+{
+ Q_D(QQmlObjectModel);
+ if (index < 0 || n <= 0 || index + n > count()) {
+ qmlInfo(this) << tr("remove: indices [%1 - %2] out of range [0 - %3]").arg(index).arg(index+n).arg(count());
+ return;
+ }
+ d->remove(index, n);
+}
+
+/*!
+ \qmlmethod QtQml.Models::ObjectModel::clear()
+ \since 5.6
+
+ Clears all items from the model.
+
+ \sa append(), remove()
+*/
+void QQmlObjectModel::clear()
+{
+ Q_D(QQmlObjectModel);
+ d->clear();
+}
+
QT_END_NAMESPACE