fix QSqlTableModel::headerData() for empty query with inserted row

QSqlQueryModel::headerData() relied on virtual indexInQuery() to
detect whether the requested column at row 0 mapped to an index in
the query. This failed when row 0 was a pending insert managed by
QSqlTableModel, and therefore not in the query.

The only thing that matters here is the column.

Task-number: QTBUG-29108
Change-Id: I3e0ae85ba223e444781ec8033386d394bb44f0e8
Reviewed-by: Andy Shaw <andy.shaw@digia.com>
Reviewed-by: Mark Brand <mabrand@mabrand.nl>
This commit is contained in:
Mark Brand 2013-01-26 23:09:24 +01:00 committed by The Qt Project
parent 04478614c1
commit a694b9f8d2
3 changed files with 20 additions and 10 deletions

View File

@ -95,6 +95,13 @@ void QSqlQueryModelPrivate::initColOffsets(int size)
memset(colOffsets.data(), 0, colOffsets.size() * sizeof(int)); memset(colOffsets.data(), 0, colOffsets.size() * sizeof(int));
} }
int QSqlQueryModelPrivate::columnInQuery(int modelColumn) const
{
if (modelColumn < 0 || modelColumn >= rec.count() || !rec.isGenerated(modelColumn) || modelColumn >= colOffsets.size())
return -1;
return modelColumn - colOffsets[modelColumn];
}
/*! /*!
\class QSqlQueryModel \class QSqlQueryModel
\brief The QSqlQueryModel class provides a read-only data model for SQL \brief The QSqlQueryModel class provides a read-only data model for SQL
@ -370,11 +377,7 @@ QVariant QSqlQueryModel::headerData(int section, Qt::Orientation orientation, in
val = d->headers.value(section).value(Qt::EditRole); val = d->headers.value(section).value(Qt::EditRole);
if (val.isValid()) if (val.isValid())
return val; return val;
if (role == Qt::DisplayRole && d->rec.count() > section && d->columnInQuery(section) != -1)
// See if it's an inserted column (iiq.column() != -1)
QModelIndex dItem = indexInQuery(createIndex(0, section));
if (role == Qt::DisplayRole && d->rec.count() > section && dItem.column() != -1)
return d->rec.fieldName(section); return d->rec.fieldName(section);
} }
return QAbstractItemModel::headerData(section, orientation, role); return QAbstractItemModel::headerData(section, orientation, role);
@ -668,12 +671,10 @@ bool QSqlQueryModel::removeColumns(int column, int count, const QModelIndex &par
QModelIndex QSqlQueryModel::indexInQuery(const QModelIndex &item) const QModelIndex QSqlQueryModel::indexInQuery(const QModelIndex &item) const
{ {
Q_D(const QSqlQueryModel); Q_D(const QSqlQueryModel);
if (item.column() < 0 || item.column() >= d->rec.count() int modelColumn = d->columnInQuery(item.column());
|| !d->rec.isGenerated(item.column()) if (modelColumn < 0)
|| item.column() >= d->colOffsets.size())
return QModelIndex(); return QModelIndex();
return createIndex(item.row(), item.column() - d->colOffsets[item.column()], return createIndex(item.row(), modelColumn, item.internalPointer());
item.internalPointer());
} }
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -72,6 +72,7 @@ public:
void prefetch(int); void prefetch(int);
void initColOffsets(int size); void initColOffsets(int size);
int columnInQuery(int modelColumn) const;
mutable QSqlQuery query; mutable QSqlQuery query;
mutable QSqlError error; mutable QSqlError error;

View File

@ -1433,6 +1433,14 @@ void tst_QSqlTableModel::emptyTable()
QVERIFY_SQL(model, select()); QVERIFY_SQL(model, select());
QCOMPARE(model.rowCount(), 0); QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.columnCount(), 1); QCOMPARE(model.columnCount(), 1);
// QTBUG-29108: check correct horizontal header for empty query with pending insert
QCOMPARE(model.headerData(0, Qt::Horizontal).toString(), QString("id"));
model.setEditStrategy(QSqlTableModel::OnManualSubmit);
model.insertRow(0);
QCOMPARE(model.rowCount(), 1);
QCOMPARE(model.headerData(0, Qt::Horizontal).toString(), QString("id"));
model.revertAll();
} }
void tst_QSqlTableModel::tablesAndSchemas() void tst_QSqlTableModel::tablesAndSchemas()