diff options
Diffstat (limited to 'src/sql/models/qsqlquerymodel.cpp')
-rw-r--r-- | src/sql/models/qsqlquerymodel.cpp | 99 |
1 files changed, 55 insertions, 44 deletions
diff --git a/src/sql/models/qsqlquerymodel.cpp b/src/sql/models/qsqlquerymodel.cpp index fefb87dcf5..723767344c 100644 --- a/src/sql/models/qsqlquerymodel.cpp +++ b/src/sql/models/qsqlquerymodel.cpp @@ -78,9 +78,11 @@ void QSqlQueryModelPrivate::prefetch(int limit) atEnd = true; // this is the end. } if (newBottom.row() >= 0 && newBottom.row() > bottom.row()) { - q->beginInsertRows(QModelIndex(), bottom.row() + 1, newBottom.row()); + if (!resetting) + q->beginInsertRows(QModelIndex(), bottom.row() + 1, newBottom.row()); bottom = newBottom; - q->endInsertRows(); + if (!resetting) + q->endInsertRows(); } else { bottom = newBottom; } @@ -109,7 +111,7 @@ void QSqlQueryModelPrivate::initColOffsets(int size) the lower-level QSqlQuery and can be used to provide data to view classes such as QTableView. For example: - \snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 16 + \snippet sqldatabase/sqldatabase.cpp 16 We set the model's query, then we set up the labels displayed in the view header. @@ -117,13 +119,13 @@ void QSqlQueryModelPrivate::initColOffsets(int size) QSqlQueryModel can also be used to access a database programmatically, without binding it to a view: - \snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 21 + \snippet sqldatabase/sqldatabase.cpp 21 The code snippet above extracts the \c salary field from record 4 in the result set of the query \c{SELECT * from employee}. Assuming that \c salary is column 2, we can rewrite the last line as follows: - \snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 22 + \snippet sqldatabase/sqldatabase.cpp 22 The model is read-only by default. To make it read-write, you must subclass it and reimplement setData() and flags(). Another @@ -175,9 +177,9 @@ QSqlQueryModel::~QSqlQueryModel() This only affects databases that don't report back the size of a query (see QSqlDriver::hasFeature()). - To force fetching of the entire database, you can use the following: + To force fetching of the entire result set, you can use the following: - \snippet doc/src/snippets/code/src_sql_models_qsqlquerymodel.cpp 0 + \snippet code/src_sql_models_qsqlquerymodel.cpp 0 \a parent should always be an invalid QModelIndex. @@ -208,6 +210,28 @@ bool QSqlQueryModel::canFetchMore(const QModelIndex &parent) const return (!parent.isValid() && !d->atEnd); } +/*! \reimp + */ +void QSqlQueryModel::beginResetModel() +{ + Q_D(QSqlQueryModel); + if (!d->resetting) { + QAbstractTableModel::beginResetModel(); + d->resetting = true; + } +} + +/*! \reimp + */ +void QSqlQueryModel::endResetModel() +{ + Q_D(QSqlQueryModel); + if (d->resetting) { + d->resetting = false; + QAbstractTableModel::endResetModel(); + } +} + /*! \fn int QSqlQueryModel::rowCount(const QModelIndex &parent) const \since 4.1 @@ -317,60 +341,47 @@ void QSqlQueryModel::queryChange() void QSqlQueryModel::setQuery(const QSqlQuery &query) { Q_D(QSqlQueryModel); + beginResetModel(); + QSqlRecord newRec = query.record(); bool columnsChanged = (newRec != d->rec); - bool hasQuerySize = query.driver()->hasFeature(QSqlDriver::QuerySize); - bool hasNewData = (newRec != QSqlRecord()) || !query.lastError().isValid(); if (d->colOffsets.size() != newRec.count() || columnsChanged) d->initColOffsets(newRec.count()); - bool mustClearModel = d->bottom.isValid(); - if (mustClearModel) { - d->atEnd = true; - beginRemoveRows(QModelIndex(), 0, qMax(d->bottom.row(), 0)); - d->bottom = QModelIndex(); - } - + d->bottom = QModelIndex(); d->error = QSqlError(); d->query = query; d->rec = newRec; + d->atEnd = true; - if (mustClearModel) - endRemoveRows(); - - d->atEnd = false; - - if (columnsChanged && hasNewData) - reset(); + if (query.isForwardOnly()) { + d->error = QSqlError(QLatin1String("Forward-only queries " + "cannot be used in a data model"), + QString(), QSqlError::ConnectionError); + endResetModel(); + return; + } - if (!query.isActive() || query.isForwardOnly()) { - d->atEnd = true; - d->bottom = QModelIndex(); - if (query.isForwardOnly()) - d->error = QSqlError(QLatin1String("Forward-only queries " - "cannot be used in a data model"), - QString(), QSqlError::ConnectionError); - else - d->error = query.lastError(); + if (!query.isActive()) { + d->error = query.lastError(); + endResetModel(); return; } - QModelIndex newBottom; - if (hasQuerySize && d->query.size() > 0) { - newBottom = createIndex(d->query.size() - 1, d->rec.count() - 1); - beginInsertRows(QModelIndex(), 0, qMax(0, newBottom.row())); - d->bottom = createIndex(d->query.size() - 1, columnsChanged ? 0 : d->rec.count() - 1); - d->atEnd = true; - endInsertRows(); + + if (query.driver()->hasFeature(QSqlDriver::QuerySize) && d->query.size() > 0) { + d->bottom = createIndex(d->query.size() - 1, d->rec.count() - 1); } else { - newBottom = createIndex(-1, d->rec.count() - 1); + d->bottom = createIndex(-1, d->rec.count() - 1); + d->atEnd = false; } - d->bottom = newBottom; - queryChange(); // fetchMore does the rowsInserted stuff for incremental models fetchMore(); + + endResetModel(); + queryChange(); } /*! \overload @@ -383,7 +394,7 @@ void QSqlQueryModel::setQuery(const QSqlQuery &query) was an error setting the query. Example: - \snippet doc/src/snippets/code/src_sql_models_qsqlquerymodel.cpp 1 + \snippet code/src_sql_models_qsqlquerymodel.cpp 1 \sa query(), queryChange(), lastError() */ @@ -518,7 +529,7 @@ QSqlRecord QSqlQueryModel::record() const By default, inserted columns are empty. To fill them with data, reimplement data() and handle any inserted column separately: - \snippet doc/src/snippets/sqldatabase/sqldatabase.cpp 23 + \snippet sqldatabase/sqldatabase.cpp 23 \sa removeColumns() */ |