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 + .../models/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 ba1adde..80ea702 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 5fed167..30e01b0 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -469,6 +469,24 @@ QVariant QSqlTableModel::headerData(int section, Qt::Orientation orientation, in } /*! + \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 but not yet written into the database. diff --git a/src/sql/models/qsqltablemodel.h b/src/sql/models/qsqltablemodel.h index 13316bc..62e0986 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 448111c..7dcc109 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); -- 2.7.4