summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dist/changes-5.0.08
-rw-r--r--src/sql/models/qsqltablemodel.cpp36
-rw-r--r--tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp11
-rw-r--r--tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp79
4 files changed, 108 insertions, 26 deletions
diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0
index dd0a0693ed..33a8869397 100644
--- a/dist/changes-5.0.0
+++ b/dist/changes-5.0.0
@@ -406,6 +406,14 @@ ignore the rest of the range.
QSqlTableModel::indexInQuery() as example of how to implement in a
subclass.
+* QSqlTableModel edit strategies OnFieldChange/OnRowChange QTBUG-2875
+Previously, after changes were submitted in these edit strategies, select()
+was called which removed and inserted all rows. This ruined navigation
+in QTableView. Now, with these edit strategies, there is no implicit select()
+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.
+
****************************************************************************
* Database Drivers *
****************************************************************************
diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp
index 40230c3043..aa7dc3dcf8 100644
--- a/src/sql/models/qsqltablemodel.cpp
+++ b/src/sql/models/qsqltablemodel.cpp
@@ -663,8 +663,8 @@ bool QSqlTableModel::deleteRowFromTable(int row)
Returns false on error, detailed error information can be
obtained with lastError().
- On success the model will be repopulated. Any views
- presenting it will lose their selections.
+ In OnManualSubmit, on success the model will be repopulated.
+ Any views presenting it will lose their selections.
Note: In OnManualSubmit mode, already submitted changes won't
be cleared from the cache when submitAll() fails. This allows
@@ -677,6 +677,8 @@ bool QSqlTableModel::submitAll()
{
Q_D(QSqlTableModel);
+ bool success = true;
+
for (QSqlTableModelPrivate::CacheMap::Iterator it = d->cache.begin();
it != d->cache.constEnd(); ++it) {
if (it.value().submitted())
@@ -684,25 +686,35 @@ bool QSqlTableModel::submitAll()
switch (it.value().op()) {
case QSqlTableModelPrivate::Insert:
- if (!insertRowIntoTable(it.value().rec()))
- return false;
+ success = insertRowIntoTable(it.value().rec());
break;
case QSqlTableModelPrivate::Update:
- if (!updateRowInTable(it.key(), it.value().rec()))
- return false;
+ success = updateRowInTable(it.key(), it.value().rec());
break;
case QSqlTableModelPrivate::Delete:
- if (!deleteRowFromTable(it.key()))
- return false;
+ success = deleteRowFromTable(it.key());
break;
case QSqlTableModelPrivate::None:
Q_ASSERT_X(false, "QSqlTableModel::submitAll()", "Invalid cache operation");
break;
}
- it.value().setSubmitted();
+
+ if (success) {
+ it.value().setSubmitted();
+ if (d->strategy != OnManualSubmit)
+ success = selectRow(it.key());
+ }
+
+ if (!success)
+ break;
+ }
+
+ if (success) {
+ if (d->strategy == OnManualSubmit)
+ success = select();
}
- return select();
+ return success;
}
/*!
@@ -719,8 +731,8 @@ bool QSqlTableModel::submitAll()
Returns true on success; otherwise returns false. Use lastError()
to query detailed error information.
- On success the model will be repopulated. Any views
- presenting it will lose their selections.
+ Does not automatically repopulate the model. Submitted rows are
+ refreshed from the database on success.
\sa revert(), revertRow(), submitAll(), revertAll(), lastError()
*/
diff --git a/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp b/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp
index ddafeea427..ce0d8db1fd 100644
--- a/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp
+++ b/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp
@@ -542,6 +542,13 @@ void tst_QSqlRelationalTableModel::setRecord()
model.setSort(0, Qt::AscendingOrder);
QVERIFY_SQL(model, submit());
+ if (model.editStrategy() != QSqlTableModel::OnManualSubmit) {
+ QCOMPARE(model.data(model.index(1, 0)).toInt(), 7);
+ QCOMPARE(model.data(model.index(1, 1)).toString(), QString("tester"));
+ QCOMPARE(model.data(model.index(1, 2)).toString(), QString("herr"));
+ QVERIFY_SQL(model, select());
+ }
+
QCOMPARE(model.data(model.index(3, 0)).toInt(), 7);
QCOMPARE(model.data(model.index(3, 1)).toString(), QString("tester"));
QCOMPARE(model.data(model.index(3, 2)).toString(), QString("herr"));
@@ -599,6 +606,8 @@ void tst_QSqlRelationalTableModel::insertWithStrategies()
QVERIFY_SQL(model, submitAll());
model.setEditStrategy(QSqlTableModel::OnManualSubmit);
+ // The changes were submitted, but there was no automatic select to resort
+ QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0,0)).toInt(), 1);
QCOMPARE(model.data(model.index(0,1)).toString(), QString("harry"));
@@ -1401,6 +1410,8 @@ void tst_QSqlRelationalTableModel::whiteSpaceInIdentifiers()
QVERIFY_SQL(model, insertRecord(-1, rec));
model.submitAll();
+ if (model.editStrategy() != QSqlTableModel::OnManualSubmit)
+ QVERIFY_SQL(model, select());
QCOMPARE(model.data(model.index(0, 0)).toInt(), 3);
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("Washington"));
diff --git a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp
index 43829987d4..448111cd9f 100644
--- a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp
+++ b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp
@@ -411,8 +411,11 @@ void tst_QSqlTableModel::setRecord()
} else if ((QSqlTableModel::EditStrategy)submitpolicy == QSqlTableModel::OnRowChange && i == model.rowCount() -1)
model.submit();
else {
- // dataChanged() is not emitted when submitAll() is called
- QCOMPARE(spy.count(), 1);
+ // dataChanged() emitted by selectRow() as well as setRecord()
+ if ((QSqlTableModel::EditStrategy)submitpolicy == QSqlTableModel::OnFieldChange)
+ QCOMPARE(spy.count(), 2);
+ else
+ QCOMPARE(spy.count(), 1);
QCOMPARE(spy.at(0).count(), 2);
QCOMPARE(qvariant_cast<QModelIndex>(spy.at(0).at(0)), model.index(i, 0));
QCOMPARE(qvariant_cast<QModelIndex>(spy.at(0).at(1)), model.index(i, rec.count() - 1));
@@ -471,8 +474,7 @@ void tst_QSqlTableModel::insertRow()
rec.setValue(0, 42);
rec.setValue(1, QString("francis"));
- // FieldChange updates immediately and resorts
- // Row/Manual submit does not resort
+ // Setting record does not cause resort
QVERIFY(model.setRecord(2, rec));
QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
@@ -482,8 +484,23 @@ void tst_QSqlTableModel::insertRow()
QCOMPARE(model.data(model.index(1, 1)).toString(), QString("trond"));
QCOMPARE(model.data(model.index(1, 2)).toInt(), 2);
- // See comment above setRecord
- if (submitpolicy == QSqlTableModel::OnFieldChange) {
+ QCOMPARE(model.data(model.index(2, 0)).toInt(), 42);
+ QCOMPARE(model.data(model.index(2, 1)).toString(), QString("francis"));
+ QCOMPARE(model.data(model.index(2, 2)).toInt(), 2);
+ QCOMPARE(model.data(model.index(3, 0)).toInt(), 3);
+ QCOMPARE(model.data(model.index(3, 1)).toString(), QString("vohi"));
+ QCOMPARE(model.data(model.index(3, 2)).toInt(), 3);
+
+ QVERIFY(model.submitAll());
+
+ if (submitpolicy == QSqlTableModel::OnManualSubmit) {
+ // After the submit we should have the resorted view
+ QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
+ QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry"));
+ QCOMPARE(model.data(model.index(0, 2)).toInt(), 1);
+ QCOMPARE(model.data(model.index(1, 0)).toInt(), 2);
+ QCOMPARE(model.data(model.index(1, 1)).toString(), QString("trond"));
+ QCOMPARE(model.data(model.index(1, 2)).toInt(), 2);
QCOMPARE(model.data(model.index(2, 0)).toInt(), 3);
QCOMPARE(model.data(model.index(2, 1)).toString(), QString("vohi"));
QCOMPARE(model.data(model.index(2, 2)).toInt(), 3);
@@ -491,6 +508,13 @@ void tst_QSqlTableModel::insertRow()
QCOMPARE(model.data(model.index(3, 1)).toString(), QString("francis"));
QCOMPARE(model.data(model.index(3, 2)).toInt(), 2);
} else {
+ // Submit does not select, therefore not resorted
+ QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
+ QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry"));
+ QCOMPARE(model.data(model.index(0, 2)).toInt(), 1);
+ QCOMPARE(model.data(model.index(1, 0)).toInt(), 2);
+ QCOMPARE(model.data(model.index(1, 1)).toString(), QString("trond"));
+ QCOMPARE(model.data(model.index(1, 2)).toInt(), 2);
QCOMPARE(model.data(model.index(2, 0)).toInt(), 42);
QCOMPARE(model.data(model.index(2, 1)).toString(), QString("francis"));
QCOMPARE(model.data(model.index(2, 2)).toInt(), 2);
@@ -499,9 +523,8 @@ void tst_QSqlTableModel::insertRow()
QCOMPARE(model.data(model.index(3, 2)).toInt(), 3);
}
- QVERIFY(model.submitAll());
-
- // After the submit we should have the resorted view
+ QVERIFY(model.select());
+ // After the select we should have the resorted view in all strategies
QCOMPARE(model.data(model.index(0, 0)).toInt(), 1);
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry"));
QCOMPARE(model.data(model.index(0, 2)).toInt(), 1);
@@ -514,7 +537,6 @@ void tst_QSqlTableModel::insertRow()
QCOMPARE(model.data(model.index(3, 0)).toInt(), 42);
QCOMPARE(model.data(model.index(3, 1)).toString(), QString("francis"));
QCOMPARE(model.data(model.index(3, 2)).toInt(), 2);
-
}
void tst_QSqlTableModel::insertRecord()
@@ -647,8 +669,7 @@ void tst_QSqlTableModel::removeRow()
QVERIFY_SQL(model, select());
QCOMPARE(model.rowCount(), 3);
- // headerDataChanged must be emitted by the model when the edit strategy is OnManualSubmit,
- // when OnFieldChange or OnRowChange it's not needed because the model will re-select.
+ // headerDataChanged must be emitted by the model since the row won't vanish until select
qRegisterMetaType<Qt::Orientation>("Qt::Orientation");
QSignalSpy headerDataChangedSpy(&model, SIGNAL(headerDataChanged(Qt::Orientation, int, int)));
@@ -673,7 +694,10 @@ void tst_QSqlTableModel::removeRow()
headerDataChangedSpy.clear();
QVERIFY(model.removeRow(1));
- QCOMPARE(headerDataChangedSpy.count(), 0);
+ QCOMPARE(headerDataChangedSpy.count(), 1);
+ QCOMPARE(model.rowCount(), 3);
+
+ QVERIFY_SQL(model, select());
QCOMPARE(model.rowCount(), 2);
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry"));
@@ -706,6 +730,11 @@ void tst_QSqlTableModel::removeRows()
QCOMPARE(beforeDeleteSpy.count(), 2);
QVERIFY(beforeDeleteSpy.at(0).at(0).toInt() == 0);
QVERIFY(beforeDeleteSpy.at(1).at(0).toInt() == 1);
+ // deleted rows shown as empty until select
+ QCOMPARE(model.rowCount(), 3);
+ QCOMPARE(model.data(model.index(0, 1)).toString(), QString(""));
+ QVERIFY(model.select());
+ // deleted rows are gone
QCOMPARE(model.rowCount(), 1);
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("vohi"));
model.clear();
@@ -778,6 +807,14 @@ void tst_QSqlTableModel::removeInsertedRow()
model.submitAll();
+ if (model.editStrategy() != QSqlTableModel::OnManualSubmit) {
+ QCOMPARE(model.rowCount(), 4);
+ QCOMPARE(model.data(model.index(1, 0)).toInt(), 55);
+ QCOMPARE(model.data(model.index(1, 1)).toString(), QString("null columns"));
+ QCOMPARE(model.data(model.index(1, 2)).isNull(), true);
+ QVERIFY(model.select());
+ }
+
QCOMPARE(model.rowCount(), 4);
QCOMPARE(model.data(model.index(3, 0)).toInt(), 55);
QCOMPARE(model.data(model.index(3, 1)).toString(), QString("null columns"));
@@ -785,8 +822,17 @@ void tst_QSqlTableModel::removeInsertedRow()
QVERIFY(model.removeRow(3));
model.submitAll();
- QCOMPARE(model.rowCount(), 3);
+ if (model.editStrategy() != QSqlTableModel::OnManualSubmit) {
+ QCOMPARE(model.rowCount(), 4);
+ QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry"));
+ QCOMPARE(model.data(model.index(1, 1)).toString(), QString("trond"));
+ QCOMPARE(model.data(model.index(2, 1)).toString(), QString("vohi"));
+ QCOMPARE(model.data(model.index(3, 1)).toString(), QString(""));
+ QVERIFY(model.select());
+ }
+
+ QCOMPARE(model.rowCount(), 3);
QCOMPARE(model.data(model.index(0, 1)).toString(), QString("harry"));
QCOMPARE(model.data(model.index(1, 1)).toString(), QString("trond"));
QCOMPARE(model.data(model.index(2, 1)).toString(), QString("vohi"));
@@ -1129,6 +1175,11 @@ void tst_QSqlTableModel::insertRecordBeforeSelect()
buffer.setValue("title", 0);
QVERIFY_SQL(model, insertRecord(1, buffer));
+ if (model.editStrategy() != QSqlTableModel::OnManualSubmit) {
+ QCOMPARE(model.rowCount(), 2);
+ QVERIFY_SQL(model, select());
+ }
+
int rowCount = model.rowCount();
model.clear();
QCOMPARE(model.rowCount(), 0);