diff options
Diffstat (limited to 'src/sql')
-rw-r--r-- | src/sql/models/qsqltablemodel.cpp | 52 | ||||
-rw-r--r-- | src/sql/models/qsqltablemodel_p.h | 47 |
2 files changed, 71 insertions, 28 deletions
diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp index 24668dd946..9ade5f14d5 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -87,7 +87,7 @@ int QSqlTableModelPrivate::insertCount(int maxRow) const for (; i != e && (maxRow < 0 || i.key() <= maxRow); ++i) { - if (i.value().op() == Insert) + if (i.value().insert()) ++cnt; } @@ -122,19 +122,17 @@ void QSqlTableModelPrivate::revertCachedRow(int row) Q_Q(QSqlTableModel); ModifiedRow r = cache.value(row); - // cannot revert a committed change - if (r.submitted()) - return; - switch (r.op()) { case QSqlTableModelPrivate::None: Q_ASSERT_X(false, "QSqlTableModelPrivate::revertCachedRow()", "Invalid entry in cache map"); return; case QSqlTableModelPrivate::Update: case QSqlTableModelPrivate::Delete: - cache.remove(row); - emit q->dataChanged(q->createIndex(row, 0), - q->createIndex(row, q->columnCount() - 1)); + if (!r.submitted()) { + cache[row].revert(); + emit q->dataChanged(q->createIndex(row, 0), + q->createIndex(row, q->columnCount() - 1)); + } break; case QSqlTableModelPrivate::Insert: { QMap<int, QSqlTableModelPrivate::ModifiedRow>::Iterator it = cache.find(row); @@ -373,7 +371,7 @@ bool QSqlTableModel::select() while (it != d->cache.constBegin()) { --it; // rows must be accounted for - if (it.value().op() == QSqlTableModelPrivate::Insert) { + if (it.value().insert()) { beginRemoveRows(QModelIndex(), it.key(), it.key()); it = d->cache.erase(it); endRemoveRows(); @@ -470,11 +468,14 @@ bool QSqlTableModel::setData(const QModelIndex &index, const QVariant &value, in if (!index.isValid() || index.column() >= d->rec.count() || index.row() >= rowCount()) return false; + if (d->cache.value(index.row()).op() == QSqlTableModelPrivate::Delete) + return false; + if (d->strategy == OnFieldChange && d->cache.value(index.row()).op() != QSqlTableModelPrivate::Insert) { - d->cache.clear(); + revertAll(); } else if (d->strategy == OnRowChange && !d->cache.isEmpty() && !d->cache.contains(index.row())) { submit(); - d->cache.clear(); + revertAll(); } QSqlTableModelPrivate::ModifiedRow &row = d->cache[index.row()]; @@ -759,8 +760,10 @@ void QSqlTableModel::revertAll() { Q_D(QSqlTableModel); - while (!d->cache.isEmpty()) - revertRow(d->cache.constBegin().key()); + const QList<int> rows(d->cache.keys()); + for (int i = rows.size() - 1; i >= 0; --i) { + revertRow(rows.value(i)); + } } /*! @@ -967,15 +970,17 @@ bool QSqlTableModel::removeRows(int row, int count, const QModelIndex &parent) else if (!count) return true; - for (int i = 0; i < count; ++i) { - int idx = row + i; - if (d->cache.value(idx).op() == QSqlTableModelPrivate::Insert) { + // Iterate backwards so we don't have to worry about removed rows causing + // higher cache entries to shift downwards. + for (int idx = row + count - 1; idx >= row; --idx) { + QSqlTableModelPrivate::ModifiedRow& mrow = d->cache[idx]; + if (mrow.op() == QSqlTableModelPrivate::Insert) { revertRow(idx); - // Reverting a row means all the other cache entries have been adjusted downwards - // so fake this by adjusting row - --row; } else { - d->cache[idx] = QSqlTableModelPrivate::ModifiedRow(QSqlTableModelPrivate::Delete, record(idx)); + if (mrow.op() == QSqlTableModelPrivate::None) + mrow = QSqlTableModelPrivate::ModifiedRow(QSqlTableModelPrivate::Delete, record(idx)); + else + mrow.setOp(QSqlTableModelPrivate::Delete); if (d->strategy == OnManualSubmit) emit headerDataChanged(Qt::Vertical, idx, idx); } @@ -1158,6 +1163,8 @@ Qt::ItemFlags QSqlTableModel::flags(const QModelIndex &index) const return 0; if (d->rec.field(index.column()).isReadOnly()) return Qt::ItemIsSelectable | Qt::ItemIsEnabled; + if (d->cache.value(index.row()).op() == QSqlTableModelPrivate::Delete) + return Qt::ItemIsSelectable | Qt::ItemIsEnabled; return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable; } @@ -1186,8 +1193,11 @@ bool QSqlTableModel::setRecord(int row, const QSqlRecord &values) if (row >= rowCount()) return false; + if (d->cache.value(row).op() == QSqlTableModelPrivate::Delete) + return false; + if (d->strategy == OnFieldChange && d->cache.value(row).op() != QSqlTableModelPrivate::Insert) - d->cache.clear(); + revertAll(); else if (d->strategy == OnRowChange && !d->cache.isEmpty() && !d->cache.contains(row)) submit(); diff --git a/src/sql/models/qsqltablemodel_p.h b/src/sql/models/qsqltablemodel_p.h index 57051a0e9c..ba2fdf5df3 100644 --- a/src/sql/models/qsqltablemodel_p.h +++ b/src/sql/models/qsqltablemodel_p.h @@ -101,18 +101,51 @@ public: { public: inline ModifiedRow(Op o = None, const QSqlRecord &r = QSqlRecord()) - : m_op(o), m_rec(r), m_submitted(false) - { init_rec(); } + : m_op(None), m_db_values(r), m_insert(o == Insert) + { setOp(o); } inline Op op() const { return m_op; } + inline void setOp(Op o) + { + if (o == m_op) + return; + m_submitted = (o != Insert && o != Delete); + m_op = o; + m_rec = m_db_values; + setGenerated(m_rec, m_op == Delete); + } inline QSqlRecord rec() const { return m_rec; } inline QSqlRecord& recRef() { return m_rec; } inline void setValue(int c, const QVariant &v) { + m_submitted = false; m_rec.setValue(c, v); m_rec.setGenerated(c, true); } inline bool submitted() const { return m_submitted; } - inline void setSubmitted() { m_submitted = true; } + inline void setSubmitted() + { + m_submitted = true; + setGenerated(m_rec, false); + if (m_op == Delete) { + m_rec.clearValues(); + } + else { + m_op = Update; + m_db_values = m_rec; + setGenerated(m_db_values, true); + } + } + inline bool insert() const { return m_insert; } + inline void revert() + { + if (m_submitted) + return; + if (m_op == Delete) + m_op = Update; + m_rec = m_db_values; + setGenerated(m_rec, false); + m_submitted = true; + } inline QSqlRecord primaryValues(const QSqlRecord& pi) const { if (m_op == None || m_op == Insert) @@ -126,16 +159,16 @@ public: return values; } private: - void init_rec() + inline static void setGenerated(QSqlRecord& r, bool g) { - for (int i = m_rec.count() - 1; i >= 0; --i) - m_rec.setGenerated(i, false); - m_db_values = m_rec; + for (int i = r.count() - 1; i >= 0; --i) + r.setGenerated(i, g); } Op m_op; QSqlRecord m_rec; QSqlRecord m_db_values; bool m_submitted; + bool m_insert; }; typedef QMap<int, ModifiedRow> CacheMap; |