fix QSqlTableModel:revert() for OnFieldChange

revert() should operate in OnFieldChange edit strategy just as
submit() does. The reason in Qt 4 for excluding OnFieldChange
was that there was no opportunity to revert. The model was
refreshed, causing all changes to be lost. In Qt 5 a failed
edit remains in the cache until user action, which could be
to revert.

Change-Id: Ide021c4f83a53834b7ed81f2abfa3aa49317704d
Reviewed-by: Mark Brand <mabrand@mabrand.nl>
This commit is contained in:
Mark Brand 2013-02-04 02:01:28 +01:00 committed by The Qt Project
parent 6b8d0b3092
commit 93ed02e3b1
2 changed files with 82 additions and 2 deletions

View File

@ -839,7 +839,8 @@ bool QSqlTableModel::submit()
user canceled editing the current row.
Reverts the changes if the model's strategy is set to
OnRowChange. Does nothing for the other edit strategies.
OnRowChange or OnFieldChange. Does nothing for the OnManualSubmit
strategy.
Use revertAll() to revert all pending changes for the
OnManualSubmit strategy or revertRow() to revert a specific row.
@ -849,7 +850,7 @@ bool QSqlTableModel::submit()
void QSqlTableModel::revert()
{
Q_D(QSqlTableModel);
if (d->strategy == OnRowChange)
if (d->strategy == OnRowChange || d->strategy == OnFieldChange)
revertAll();
}

View File

@ -109,6 +109,8 @@ private slots:
void removeInsertedRow();
void removeInsertedRows_data() { generic_data(); }
void removeInsertedRows();
void revert_data() { generic_data_with_strategies("QSQLITE"); }
void revert();
void isDirty_data() { generic_data_with_strategies(); }
void isDirty();
void setFilter_data() { generic_data(); }
@ -1368,6 +1370,83 @@ void tst_QSqlTableModel::removeInsertedRows()
QCOMPARE(model.data(model.index(1, 1)).toString(), QString("vohi"));
}
void tst_QSqlTableModel::revert()
{
QFETCH(QString, dbName);
QFETCH(int, submitpolicy_i);
QSqlTableModel::EditStrategy submitpolicy = (QSqlTableModel::EditStrategy) submitpolicy_i;
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
QString tblA = qTableName("revertATest", __FILE__);
QString tblB = qTableName("revertBTest", __FILE__);
QSqlQuery q(db);
q.exec("PRAGMA foreign_keys = ON;");
q.exec("DROP TABLE " + tblB);
q.exec("DROP TABLE " + tblA);
QVERIFY_SQL(q, exec("CREATE TABLE " + tblA + "(a INT PRIMARY KEY)"));
QVERIFY_SQL(q, exec("CREATE TABLE " + tblB + "(b INT PRIMARY KEY, FOREIGN KEY (b) REFERENCES " + tblA + " (a))"));
QVERIFY_SQL(q, exec("INSERT INTO " + tblA + "(a) VALUES (1)"));
QVERIFY_SQL(q, exec("INSERT INTO " + tblB + "(b) VALUES (1)"));
if (q.exec("UPDATE " + tblA + " SET a = -1"))
QSKIP("database does not enforce foreign key constraints, skipping test");
QSqlTableModel model(0, db);
model.setTable(tblA);
model.setSort(0, Qt::AscendingOrder);
model.setEditStrategy(submitpolicy);
QVERIFY_SQL(model, select());
QCOMPARE(model.rowCount(), 1);
QFAIL_SQL(model, isDirty());
// don't crash if there is no change
model.revert();
// UPDATE
// invalid value makes submit fail leaving pending update in cache
const QModelIndex idx = model.index(0, 0);
if (submitpolicy == QSqlTableModel::OnFieldChange)
QFAIL_SQL(model, setData(idx, int(-1)));
else
QVERIFY_SQL(model, setData(idx, int(-1)));
QVERIFY_SQL(model, isDirty(idx));
model.revert();
if (submitpolicy != QSqlTableModel::OnManualSubmit)
QFAIL_SQL(model, isDirty(idx));
else
QVERIFY_SQL(model, isDirty(idx));
// INSERT
QVERIFY_SQL(model, select());
// insertRow() does not submit leaving pending insert in cache
QVERIFY_SQL(model, insertRow(0));
QCOMPARE(model.rowCount(), 2);
QVERIFY_SQL(model, isDirty());
model.revert();
if (submitpolicy != QSqlTableModel::OnManualSubmit)
QFAIL_SQL(model, isDirty());
else
QVERIFY_SQL(model, isDirty());
// DELETE
QVERIFY_SQL(model, select());
// foreign key makes submit fail leaving pending delete in cache
if (submitpolicy == QSqlTableModel::OnManualSubmit)
QVERIFY_SQL(model, removeRow(0));
else
QFAIL_SQL(model, removeRow(0));
QVERIFY_SQL(model, isDirty());
model.revert();
if (submitpolicy != QSqlTableModel::OnManualSubmit)
QFAIL_SQL(model, isDirty());
else
QVERIFY_SQL(model, isDirty());
q.exec("DROP TABLE " + tblB);
q.exec("DROP TABLE " + tblA);
}
void tst_QSqlTableModel::isDirty()
{
QFETCH(QString, dbName);