From 13c57d0f68cffb139311e8e22a074099eb28a88f Mon Sep 17 00:00:00 2001 From: Mark Brand Date: Tue, 28 Feb 2012 22:42:02 +0100 Subject: [PATCH] QSqlTableModel::isDirty(): new overloaded method Checks if model has any changes to submit. Includes new test covering isDirty(index) as well the new overloaded function. Task-number: QTBUG-3108 Change-Id: I0ccbda45d5d9f06434cf1e1c037a9efb76d0cc37 Reviewed-by: Honglei Zhang --- dist/changes-5.0.0 | 3 + src/sql/models/qsqltablemodel.cpp | 18 ++ src/sql/models/qsqltablemodel.h | 2 + .../qsqltablemodel/tst_qsqltablemodel.cpp | 162 ++++++++++++++++++ 4 files changed, 185 insertions(+) diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0 index ba1adde6c0..80ea702b76 100644 --- a/dist/changes-5.0.0 +++ b/dist/changes-5.0.0 @@ -420,6 +420,9 @@ done after committing. This includes deleted rows which remain in the model as blank rows until the application calls select(). Instead, selectRow() is called to refresh only the affected row. +* QSqlTableModel::isDirty(): New overloaded method to check whether model +has any changes to submit. QTBUG-3108 + **************************************************************************** * Database Drivers * **************************************************************************** diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp index 5fed167070..30e01b06e7 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -468,6 +468,24 @@ QVariant QSqlTableModel::headerData(int section, Qt::Orientation orientation, in return QSqlQueryModel::headerData(section, orientation, role); } +/*! + \overload + \since 5.0 + + Returns true if the model contains modified values that have not been + committed to the datase, otherwise false. +*/ +bool QSqlTableModel::isDirty() const +{ + Q_D(const QSqlTableModel); + QSqlTableModelPrivate::CacheMap::ConstIterator i = d->cache.constBegin(); + const QSqlTableModelPrivate::CacheMap::ConstIterator e = d->cache.constEnd(); + for (; i != e; i++) + if (!i.value().submitted()) + return true; + return false; +} + /*! Returns true if the value at the index \a index is dirty, otherwise false. Dirty values are values that were modified in the model diff --git a/src/sql/models/qsqltablemodel.h b/src/sql/models/qsqltablemodel.h index 13316bc4ed..62e09869c9 100644 --- a/src/sql/models/qsqltablemodel.h +++ b/src/sql/models/qsqltablemodel.h @@ -79,7 +79,9 @@ public: QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + bool isDirty() const; bool isDirty(const QModelIndex &index) const; + void clear(); virtual void setEditStrategy(EditStrategy strategy); diff --git a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp index 448111cd9f..7dcc109cdc 100644 --- a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp +++ b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp @@ -95,6 +95,8 @@ private slots: void removeInsertedRow(); void removeInsertedRows_data() { generic_data(); } void removeInsertedRows(); + void isDirty_data() { generic_data_with_strategies(); } + void isDirty(); void setFilter_data() { generic_data(); } void setFilter(); void setInvalidFilter_data() { generic_data(); } @@ -956,6 +958,166 @@ void tst_QSqlTableModel::removeInsertedRows() QCOMPARE(model.data(model.index(1, 1)).toString(), QString("vohi")); } +void tst_QSqlTableModel::isDirty() +{ + QFETCH(QString, dbName); + QFETCH(int, submitpolicy_i); + QSqlTableModel::EditStrategy submitpolicy = (QSqlTableModel::EditStrategy) submitpolicy_i; + QSqlDatabase db = QSqlDatabase::database(dbName); + CHECK_DATABASE(db); + + QSqlTableModel model(0, db); + model.setEditStrategy(submitpolicy); + model.setTable(test); + QFAIL_SQL(model, isDirty()); + + model.setSort(0, Qt::AscendingOrder); + QVERIFY_SQL(model, select()); + QFAIL_SQL(model, isDirty()); + + if (submitpolicy != QSqlTableModel::OnFieldChange) { + // setData() followed by revertAll() + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QVERIFY_SQL(model, setData(model.index(0, 1), QString("sam i am"))); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("sam i am")); + QVERIFY_SQL(model, isDirty()); + QVERIFY_SQL(model, isDirty(model.index(0, 1))); + model.revertAll(); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QFAIL_SQL(model, isDirty()); + QFAIL_SQL(model, isDirty(model.index(0, 1))); + + // setData() followed by select(), which clears changes + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QVERIFY_SQL(model, setData(model.index(0, 1), QString("sam i am"))); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("sam i am")); + QVERIFY_SQL(model, isDirty()); + QVERIFY_SQL(model, isDirty(model.index(0, 1))); + QVERIFY_SQL(model, select()); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QFAIL_SQL(model, isDirty()); + QFAIL_SQL(model, isDirty(model.index(0, 1))); + } + + // setData() followed by submitAll() + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QVERIFY_SQL(model, setData(model.index(0, 1), QString("sam i am"))); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("sam i am")); + if (submitpolicy != QSqlTableModel::OnFieldChange) { + QVERIFY_SQL(model, isDirty()); + QVERIFY_SQL(model, isDirty(model.index(0, 1))); + } + QVERIFY_SQL(model, submitAll()); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("sam i am")); + QFAIL_SQL(model, isDirty()); + QFAIL_SQL(model, isDirty(model.index(0, 1))); + // check status after refreshing underlying query + QVERIFY_SQL(model, select()); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("sam i am")); + QFAIL_SQL(model, isDirty()); + QFAIL_SQL(model, isDirty(model.index(0, 1))); + //restore original state + QVERIFY_SQL(model, setData(model.index(0, 1), QString("harry"))); + QVERIFY_SQL(model, submitAll()); + QVERIFY_SQL(model, select()); + QFAIL_SQL(model, isDirty()); + QFAIL_SQL(model, isDirty(model.index(0, 1))); + + QSqlRecord newvals = model.record(0); + newvals.setValue(1, QString("sam i am")); + newvals.setGenerated(1, true); + if (submitpolicy != QSqlTableModel::OnFieldChange) { + // setRecord() followed by revertAll() + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QVERIFY_SQL(model, setRecord(0, newvals)); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("sam i am")); + QVERIFY_SQL(model, isDirty()); + QVERIFY_SQL(model, isDirty(model.index(0, 1))); + model.revertAll(); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QFAIL_SQL(model, isDirty()); + QFAIL_SQL(model, isDirty(model.index(0, 1))); + + // setRecord() followed by select(), which clears changes + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QVERIFY_SQL(model, setRecord(0, newvals)); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("sam i am")); + QVERIFY_SQL(model, isDirty()); + QVERIFY_SQL(model, isDirty(model.index(0, 1))); + QVERIFY_SQL(model, select()); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QFAIL_SQL(model, isDirty()); + QFAIL_SQL(model, isDirty(model.index(0, 1))); + } + + // setRecord() followed by submitAll() + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QVERIFY_SQL(model, setRecord(0, newvals)); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("sam i am")); + if (submitpolicy != QSqlTableModel::OnFieldChange) { + QVERIFY_SQL(model, isDirty()); + QVERIFY_SQL(model, isDirty(model.index(0, 1))); + } + QVERIFY_SQL(model, submitAll()); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("sam i am")); + QFAIL_SQL(model, isDirty()); + QFAIL_SQL(model, isDirty(model.index(0, 1))); + // check status after refreshing underlying query + QVERIFY_SQL(model, select()); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("sam i am")); + QFAIL_SQL(model, isDirty()); + QFAIL_SQL(model, isDirty(model.index(0, 1))); + //restore original state + QVERIFY_SQL(model, setData(model.index(0, 1), QString("harry"))); + QVERIFY_SQL(model, submitAll()); + QVERIFY_SQL(model, select()); + QFAIL_SQL(model, isDirty()); + QFAIL_SQL(model, isDirty(model.index(0, 1))); + + // insertRow() + QVERIFY_SQL(model, insertRow(0)); + QVERIFY_SQL(model, isDirty()); + QVERIFY_SQL(model, isDirty(model.index(0, 1))); + model.revertAll(); + QFAIL_SQL(model, isDirty()); + QFAIL_SQL(model, isDirty(model.index(0, 1))); + QVERIFY_SQL(model, select()); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); + QFAIL_SQL(model, isDirty()); + QFAIL_SQL(model, isDirty(model.index(0, 1))); + + // removeRow() + QSqlRecord saved_rec = model.record(0); + QVERIFY_SQL(model, removeRow(0)); + if (submitpolicy == QSqlTableModel::OnManualSubmit) { + QVERIFY_SQL(model, isDirty()); + QVERIFY_SQL(model, isDirty(model.index(0, 1))); + } + QVERIFY_SQL(model, submitAll()); + QFAIL_SQL(model, isDirty()); + QFAIL_SQL(model, isDirty(model.index(0, 1))); + QVERIFY_SQL(model, select()); + QFAIL_SQL(model, isDirty()); + QFAIL_SQL(model, isDirty(model.index(0, 1))); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("trond")); + + // insertRecord(), put back the removed row + for (int i = saved_rec.count() - 1; i >= 0; --i) + saved_rec.setGenerated(i, true); + QVERIFY_SQL(model, insertRecord(0, saved_rec)); + if (submitpolicy == QSqlTableModel::OnManualSubmit) { + QVERIFY_SQL(model, isDirty()); + QVERIFY_SQL(model, isDirty(model.index(0, 1))); + } + QVERIFY_SQL(model, submitAll()); + QFAIL_SQL(model, isDirty()); + QFAIL_SQL(model, isDirty(model.index(0, 1))); + QVERIFY_SQL(model, select()); + QFAIL_SQL(model, isDirty()); + QFAIL_SQL(model, isDirty(model.index(0, 1))); + QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry")); +} + void tst_QSqlTableModel::emptyTable() { QFETCH(QString, dbName);