diff options
Diffstat (limited to 'src/qml/types')
-rw-r--r-- | src/qml/types/qqmltablemodel.cpp | 40 | ||||
-rw-r--r-- | src/qml/types/qqmltablemodel_p.h | 6 |
2 files changed, 46 insertions, 0 deletions
diff --git a/src/qml/types/qqmltablemodel.cpp b/src/qml/types/qqmltablemodel.cpp index cf3fc0298a..9bf8c7f562 100644 --- a/src/qml/types/qqmltablemodel.cpp +++ b/src/qml/types/qqmltablemodel.cpp @@ -548,6 +548,38 @@ void QQmlTableModel::setRow(int rowIndex, const QVariant &row) } } +/*! + \qmlproperty var TableModel::roleDataProvider + + This property can hold a function that will map roles to values. + + When assigned, it will be called each time data() is called, to enable + extracting arbitrary values, converting the data in arbitrary ways, or even + doing calculations. It takes 4 arguments: \c row, \c column, \c role (as a + string), and \c cellData, which is the complete data that is stored in the + given cell. (If the cell contains a JS object with multiple named values, + the entire object will be given in cellData.) The function that you define + must return the value to be used; for example a typical delegate will + display the value returned for the \c display role, so you can check + whether that is the role and return data in a form that is suitable for the + delegate to show: + + \snippet qml/tablemodel/roleDataProvider.qml 0 +*/ +QJSValue QQmlTableModel::roleDataProvider() const +{ + return mRoleDataProvider; +} + +void QQmlTableModel::setRoleDataProvider(QJSValue roleDataProvider) +{ + if (roleDataProvider.strictlyEquals(mRoleDataProvider)) + return; + + mRoleDataProvider = roleDataProvider; + emit roleDataProviderChanged(); +} + QModelIndex QQmlTableModel::index(int row, int column, const QModelIndex &parent) const { return row >= 0 && row < rowCount() && column >= 0 && column < columnCount() && !parent.isValid() @@ -603,6 +635,14 @@ QVariant QQmlTableModel::data(const QModelIndex &index, int role) const return QVariant(); const QVariantList rowData = mRows.at(row).toList(); + + if (mRoleDataProvider.isCallable()) { + const auto args = QJSValueList() << row << column << + QString::fromUtf8(mRoleNames.value(role)) << + qmlEngine(this)->toScriptValue(rowData.at(column)); + return const_cast<QQmlTableModel*>(this)->mRoleDataProvider.call(args).toVariant(); + } + const QVariantMap columnData = rowData.at(column).toMap(); int effectiveRole = role; diff --git a/src/qml/types/qqmltablemodel_p.h b/src/qml/types/qqmltablemodel_p.h index 8da930872d..863c592678 100644 --- a/src/qml/types/qqmltablemodel_p.h +++ b/src/qml/types/qqmltablemodel_p.h @@ -65,6 +65,7 @@ class Q_QML_PRIVATE_EXPORT QQmlTableModel : public QAbstractTableModel Q_PROPERTY(int columnCount READ columnCount NOTIFY columnCountChanged FINAL) Q_PROPERTY(int rowCount READ rowCount NOTIFY rowCountChanged FINAL) Q_PROPERTY(QVariant rows READ rows WRITE setRows NOTIFY rowsChanged FINAL) + Q_PROPERTY(QJSValue roleDataProvider READ roleDataProvider WRITE setRoleDataProvider NOTIFY roleDataProviderChanged) public: QQmlTableModel(QObject *parent = nullptr); @@ -81,6 +82,9 @@ public: Q_INVOKABLE void removeRow(int rowIndex, int rows = 1); Q_INVOKABLE void setRow(int rowIndex, const QVariant &row); + QJSValue roleDataProvider() const; + void setRoleDataProvider(QJSValue roleDataProvider); + QModelIndex index(int row, int column, const QModelIndex &parent) const override; int rowCount(const QModelIndex &parent = QModelIndex()) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; @@ -92,6 +96,7 @@ Q_SIGNALS: void columnCountChanged(); void rowCountChanged(); void rowsChanged(); + void roleDataProviderChanged(); private: class ColumnPropertyInfo @@ -136,6 +141,7 @@ private: // key = column index // value = index (key) into mRoleNames QHash<int, int> mDefaultDisplayRoles; + QJSValue mRoleDataProvider; }; QT_END_NAMESPACE |