diff options
-rw-r--r-- | dist/changes-5.0.0 | 14 | ||||
-rw-r--r-- | src/sql/models/qsqltablemodel.cpp | 30 | ||||
-rw-r--r-- | src/sql/models/qsqltablemodel_p.h | 4 |
3 files changed, 30 insertions, 18 deletions
diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0 index 5317137059..c62d8b1163 100644 --- a/dist/changes-5.0.0 +++ b/dist/changes-5.0.0 @@ -328,6 +328,20 @@ QTestLib * [QTBUG-20615] Autotests can now log test output to multiple destinations and log formats simultaneously. +QtSql +----- +QSqlTableModel/QSqlRelationalTableModel + +* The dataChanged() signal is now emitted for changes made to an inserted +record that has not yet been committed. Previously, dataChanged() was +suppressed in this case for OnRowChange and OnFieldChange. This was probably +an attempt to avoid trouble if setData() was called while handling +primeInsert(). By emitting dataChanged(), we ensure that all views are aware +of the change. + +* While handling primeInsert() signal, the record must be manipulated using +the provided reference. Do not attempt to manipulate the records using the +model methods setData() or setRecord(). * removeRows() no longer emits extra beforeDelete signal for out of range row. diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp index e83115b66e..d943b5d1dc 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -256,7 +256,9 @@ QSqlRecord QSqlTableModelPrivate::primaryValues(int row) initiated in the given \a row of the currently active database table. The \a record parameter can be written to (since it is a reference), for example to populate some fields with default - values. + values and set the generated flags of the fields. Do not try to + edit the record via other means such as setData() or setRecord() + while handling this signal. */ /*! @@ -479,6 +481,9 @@ bool QSqlTableModel::isDirty(const QModelIndex &index) const bool QSqlTableModel::setData(const QModelIndex &index, const QVariant &value, int role) { Q_D(QSqlTableModel); + if (d->busyInsertingRows) + return false; + if (role != Qt::EditRole) return QSqlQueryModel::setData(index, value, role); @@ -512,19 +517,7 @@ bool QSqlTableModel::setData(const QModelIndex &index, const QVariant &value, in select(); } - // historical bug: dataChanged() is suppressed for OnFieldChange and OnRowChange - // when operating on an "insert" record. This is to accomodate - // applications that call setData() while handling primeInsert(). - // Otherwise dataChanged() would be emitted between beginInsert() - // and endInsert(). - // The price of this workaround is that, although the view making - // the change will already display the new value, other views connected - // to the model probably will not. - // It's not clear why OnManualSubmit is excluded from this workaround. - // Calling setData() while handling primeInsert() is arguably very wrong anyway. - // primeInsert() provides a ref to the record for settings values. - if (d->strategy == OnManualSubmit || row.op() != QSqlTableModelPrivate::Insert) - emit dataChanged(index, index); + emit dataChanged(index, index); return isOk; } @@ -1049,6 +1042,7 @@ bool QSqlTableModel::insertRows(int row, int count, const QModelIndex &parent) if (d->strategy != OnManualSubmit && count != 1) return false; + d->busyInsertingRows = true; beginInsertRows(parent, row, row + count - 1); if (d->strategy != OnManualSubmit) @@ -1071,6 +1065,7 @@ bool QSqlTableModel::insertRows(int row, int count, const QModelIndex &parent) } endInsertRows(); + d->busyInsertingRows = false; return true; } @@ -1205,6 +1200,9 @@ bool QSqlTableModel::setRecord(int row, const QSqlRecord &record) { Q_D(QSqlTableModel); Q_ASSERT_X(row >= 0, "QSqlTableModel::setRecord()", "Cannot set a record to a row less than 0"); + if (d->busyInsertingRows) + return false; + if (row >= rowCount()) return false; @@ -1233,10 +1231,8 @@ bool QSqlTableModel::setRecord(int row, const QSqlRecord &record) // historical bug: it's a bad idea to check for change here // historical bug: should test oldValue.isNull() != value.isNull() if (oldValue.isNull() || oldValue != value) { - // historical bug: dataChanged() is suppressed for Insert. See also setData(). mrow.setValue(idx, record.value(i)); - if (mrow.op() != QSqlTableModelPrivate::Insert) - emit dataChanged(cIndex, cIndex); + emit dataChanged(cIndex, cIndex); } } else { mrow.setValue(idx, record.value(i)); diff --git a/src/sql/models/qsqltablemodel_p.h b/src/sql/models/qsqltablemodel_p.h index e6e70d23bc..dbf2e275b8 100644 --- a/src/sql/models/qsqltablemodel_p.h +++ b/src/sql/models/qsqltablemodel_p.h @@ -66,7 +66,8 @@ public: QSqlTableModelPrivate() : sortColumn(-1), sortOrder(Qt::AscendingOrder), - strategy(QSqlTableModel::OnRowChange) + strategy(QSqlTableModel::OnRowChange), + busyInsertingRows(false) {} void clear(); QSqlRecord primaryValues(int index); @@ -86,6 +87,7 @@ public: Qt::SortOrder sortOrder; QSqlTableModel::EditStrategy strategy; + bool busyInsertingRows; QSqlQuery editQuery; QSqlIndex primaryIndex; |