diff options
-rw-r--r-- | src/qml/types/qqmltablemodel.cpp | 62 | ||||
-rw-r--r-- | src/qml/types/qqmltablemodel_p.h | 8 | ||||
-rw-r--r-- | tests/auto/qml/qqmltablemodel/data/dataAndSetData.qml | 66 | ||||
-rw-r--r-- | tests/auto/qml/qqmltablemodel/tst_qqmltablemodel.cpp | 22 |
4 files changed, 155 insertions, 3 deletions
diff --git a/src/qml/types/qqmltablemodel.cpp b/src/qml/types/qqmltablemodel.cpp index c4bddfaa62..0b1273a54b 100644 --- a/src/qml/types/qqmltablemodel.cpp +++ b/src/qml/types/qqmltablemodel.cpp @@ -581,6 +581,36 @@ void QQmlTableModel::setRoleDataProvider(QJSValue roleDataProvider) emit roleDataProviderChanged(); } +/*! + \qmlmethod QModelIndex TableModel::index(int row, int column) + + Returns a \l QModelIndex object referencing the given \a row and \a column, + which can be passed to the data() function to get the data from that cell, + or to setData() to edit the contents of that cell. + + \code + import QtQml 2.14 + import Qt.labs.qmlmodels 1.0 + + TableModel { + id: model + rows: [ + [{ fruitType: "Apple" }, { fruitPrice: 1.50 }], + [{ fruitType: "Orange" }, { fruitPrice: 2.50 }] + ] + Component.onCompleted: { + for (var r = 0; r < model.rowCount; ++r) { + console.log("An " + model.data(model.index(r, 0)).fruitType + + " costs " + model.data(model.index(r, 1)).fruitPrice.toFixed(2)) + } + } + } + \endcode + + \sa {QModelIndex and related Classes in QML}, data() +*/ +// Note: we don't document the parent argument, because you never need it, because +// cells in a TableModel don't have parents. But it is there because this function is an override. QModelIndex QQmlTableModel::index(int row, int column, const QModelIndex &parent) const { return row >= 0 && row < rowCount() && column >= 0 && column < columnCount() && !parent.isValid() @@ -622,6 +652,22 @@ int QQmlTableModel::columnCount(const QModelIndex &parent) const return mColumnCount; } +/*! + \qmlmethod variant TableModel::data(QModelIndex index, string role) + + Returns the data from the table cell at the given \a index belonging to the + given \a role. + + \sa index() +*/ +QVariant QQmlTableModel::data(const QModelIndex &index, const QString &role) const +{ + const int iRole = mRoleNames.key(role.toUtf8(), -1); + if (iRole >= 0) + return data(index, iRole); + return QVariant(); +} + QVariant QQmlTableModel::data(const QModelIndex &index, int role) const { const int row = index.row(); @@ -662,6 +708,22 @@ QVariant QQmlTableModel::data(const QModelIndex &index, int role) const return value; } +/*! + \qmlmethod bool TableModel::setData(QModelIndex index, string role, variant value) + + Inserts or updates the data field named by \a role in the table cell at the + given \a index with \a value. Returns true if sucessful, false if not. + + \sa index() +*/ +bool QQmlTableModel::setData(const QModelIndex &index, const QString &role, const QVariant &value) +{ + const int iRole = mRoleNames.key(role.toUtf8(), -1); + if (iRole >= 0) + return setData(index, value, iRole); + return false; +} + bool QQmlTableModel::setData(const QModelIndex &index, const QVariant &value, int role) { const int row = index.row(); diff --git a/src/qml/types/qqmltablemodel_p.h b/src/qml/types/qqmltablemodel_p.h index 863c592678..5cb42b2cc8 100644 --- a/src/qml/types/qqmltablemodel_p.h +++ b/src/qml/types/qqmltablemodel_p.h @@ -85,11 +85,13 @@ public: QJSValue roleDataProvider() const; void setRoleDataProvider(QJSValue roleDataProvider); - QModelIndex index(int row, int column, const QModelIndex &parent) const override; + Q_INVOKABLE QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; - QVariant data(const QModelIndex &index, int role) const override; - bool setData(const QModelIndex &index, const QVariant &value, int role) override; + Q_INVOKABLE QVariant data(const QModelIndex &index, const QString &role) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + Q_INVOKABLE bool setData(const QModelIndex &index, const QString &role, const QVariant &value); + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::DisplayRole) override; QHash<int, QByteArray> roleNames() const override; Q_SIGNALS: diff --git a/tests/auto/qml/qqmltablemodel/data/dataAndSetData.qml b/tests/auto/qml/qqmltablemodel/data/dataAndSetData.qml new file mode 100644 index 0000000000..d61c50ba2c --- /dev/null +++ b/tests/auto/qml/qqmltablemodel/data/dataAndSetData.qml @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.12 +import Qt.labs.qmlmodels 1.0 + +TableView { + width: 200; height: 200 + model: TableModel { + id: testModel + objectName: "testModel" + rows: [ + [ + { name: "John", someOtherRole1: "foo" }, // column 0 + { age: 22, someOtherRole2: "foo" } // column 1 + ], + [ + { name: "Oliver", someOtherRole1: "foo" }, // column 0 + { age: 33, someOtherRole2: "foo" } // column 1 + ] + ] + + // This is silly: in real life, store the birthdate instead of the age, + // and let the delegate calculate the age, so it won't need updating + function happyBirthday(dude) { + var row = -1; + for (var r = 0; row < 0 && r < testModel.rowCount; ++r) + if (testModel.data(testModel.index(r, 0), "name") === dude) + row = r; + var index = testModel.index(row, 1) + testModel.setData(index, "age", testModel.data(index, "age") + 1) + } + } + delegate: Text { + id: textItem + text: model.display + TapHandler { + onTapped: testModel.happyBirthday(testModel.data(testModel.index(row, 0), "name")) + } + } +} diff --git a/tests/auto/qml/qqmltablemodel/tst_qqmltablemodel.cpp b/tests/auto/qml/qqmltablemodel/tst_qqmltablemodel.cpp index 276f4e2b9f..eb1fbda45a 100644 --- a/tests/auto/qml/qqmltablemodel/tst_qqmltablemodel.cpp +++ b/tests/auto/qml/qqmltablemodel/tst_qqmltablemodel.cpp @@ -57,6 +57,7 @@ private slots: void setRowsMultipleTimes(); void defaultDisplayRoles(); void roleDataProvider(); + void dataAndEditing(); }; void tst_QQmlTableModel::appendRemoveRow() @@ -878,6 +879,27 @@ void tst_QQmlTableModel::roleDataProvider() QCOMPARE(model->data(model->index(1, 1, QModelIndex()), roleNames.key("display")).toInt(), 5 * 7); } +void tst_QQmlTableModel::dataAndEditing() +{ + QQuickView view(testFileUrl("dataAndSetData.qml")); + QCOMPARE(view.status(), QQuickView::Ready); + view.show(); + QVERIFY(QTest::qWaitForWindowActive(&view)); + + QQmlTableModel *model = view.rootObject()->property("model").value<QQmlTableModel*>(); + QVERIFY(model); + + const QHash<int, QByteArray> roleNames = model->roleNames(); + QVERIFY(roleNames.values().contains("display")); + QCOMPARE(model->data(model->index(0, 1, QModelIndex()), roleNames.key("display")).toInt(), 22); + QCOMPARE(model->data(model->index(1, 1, QModelIndex()), roleNames.key("display")).toInt(), 33); + QVERIFY(QMetaObject::invokeMethod(model, "happyBirthday", Q_ARG(QVariant, QLatin1String("Oliver")))); + QCOMPARE(model->data(model->index(0, 0, QModelIndex()), roleNames.key("display")).toString(), QLatin1String("John")); + QCOMPARE(model->data(model->index(0, 1, QModelIndex()), roleNames.key("display")).toInt(), 22); + QCOMPARE(model->data(model->index(1, 0, QModelIndex()), roleNames.key("display")).toString(), QLatin1String("Oliver")); + QCOMPARE(model->data(model->index(1, 1, QModelIndex()), roleNames.key("display")).toInt(), 34); +} + QTEST_MAIN(tst_QQmlTableModel) #include "tst_qqmltablemodel.moc" |