From 9f905a8bbda30abb563c27ee847f47e1866e448c Mon Sep 17 00:00:00 2001 From: Julien Cabieces Date: Thu, 6 Jun 2024 16:24:42 +0200 Subject: [PATCH] fix(TopoChecker): Reset correctly the model Fixes #53425 Reset view model correctly to avoid QAbstractItemModel accessing some missing rows/errors --- src/plugins/topology/checkDock.cpp | 17 +++++++++------ src/plugins/topology/checkDock.h | 7 +++++++ src/plugins/topology/dockModel.cpp | 33 +++++++++++++++--------------- src/plugins/topology/dockModel.h | 29 +++++++++++++------------- 4 files changed, 49 insertions(+), 37 deletions(-) diff --git a/src/plugins/topology/checkDock.cpp b/src/plugins/topology/checkDock.cpp index 2a0dfa6134e6..3584888a08ac 100644 --- a/src/plugins/topology/checkDock.cpp +++ b/src/plugins/topology/checkDock.cpp @@ -52,7 +52,7 @@ checkDock::checkDock( QgisInterface *qIface, QWidget *parent ) mFixButton->hide(); mFixBox->hide(); - mErrorListModel = new DockFilterModel( mErrorList, parent ); + mErrorListModel = new DockFilterModel( parent ); mErrorListModel->setFilterCaseSensitivity( Qt::CaseInsensitive ); mErrorTableView->setModel( mErrorListModel ); mErrorTableView->setSelectionBehavior( QAbstractItemView::SelectRows ); @@ -156,12 +156,17 @@ void checkDock::deleteErrors() updateFilterComboBox(); mErrorList.clear(); - mErrorListModel->resetModel(); + updateModel(); qDeleteAll( mRbErrorMarkers ); mRbErrorMarkers.clear(); } +void checkDock::updateModel() +{ + mErrorListModel->setErrors( mErrorList ); +} + void checkDock::parseErrorListByLayer( const QString &layerId ) { QgsVectorLayer *layer = QgsProject::instance()->mapLayer( layerId ); @@ -179,7 +184,7 @@ void checkDock::parseErrorListByLayer( const QString &layerId ) ++it; } - mErrorListModel->resetModel(); + updateModel(); mComment->setText( tr( "No errors were found" ) ); } @@ -200,7 +205,7 @@ void checkDock::parseErrorListByFeature( int featureId ) } mComment->setText( tr( "No errors were found" ) ); - mErrorListModel->resetModel(); + updateModel(); } void checkDock::configure() @@ -323,7 +328,7 @@ void checkDock::fix() if ( mErrorList.at( row )->fix( fixName ) ) { mErrorList.removeAt( row ); - mErrorListModel->resetModel(); + updateModel(); //parseErrorListByFeature(); mComment->setText( tr( "%n error(s) were found", nullptr, mErrorList.count() ) ); qgsInterface->mapCanvas()->refresh(); @@ -402,7 +407,7 @@ void checkDock::runTests( ValidateType type ) updateFilterComboBox(); mToggleRubberband->setChecked( true ); - mErrorListModel->resetModel(); + updateModel(); } void checkDock::updateFilterComboBox() diff --git a/src/plugins/topology/checkDock.h b/src/plugins/topology/checkDock.h index f390eb6f5a60..8f88ea6f8a29 100644 --- a/src/plugins/topology/checkDock.h +++ b/src/plugins/topology/checkDock.h @@ -118,6 +118,13 @@ class checkDock : public QgsDockWidget, private Ui::checkDock void filterErrors(); private: + + /** + * Update check table model according to current errors + * \since QGIS 3.38 + */ + void updateModel(); + rulesDialog *mConfigureDialog = nullptr; QObjectUniquePtr mRBConflict; diff --git a/src/plugins/topology/dockModel.cpp b/src/plugins/topology/dockModel.cpp index 21717941b6a0..f1495a086075 100644 --- a/src/plugins/topology/dockModel.cpp +++ b/src/plugins/topology/dockModel.cpp @@ -20,14 +20,20 @@ #include "qgsvectorlayer.h" #include -DockModel::DockModel( ErrorList &errorList, QObject *parent = nullptr ) - : mErrorlist( errorList ) +DockModel::DockModel( QObject *parent ) { Q_UNUSED( parent ) mHeader << QObject::tr( "Error" ) << QObject::tr( "Layer" ) << QObject::tr( "Feature ID" ); } +void DockModel::setErrors( const ErrorList &errorList ) +{ + beginResetModel(); + mErrorlist = errorList; + endResetModel(); +} + int DockModel::rowCount( const QModelIndex &parent ) const { Q_UNUSED( parent ) @@ -48,12 +54,13 @@ QVariant DockModel::headerData( int section, Qt::Orientation orientation, int ro { return QVariant( section ); } - else + else if ( section >= 0 && section < mHeader.count() ) { return mHeader[section]; } } - else return QVariant(); + + return QAbstractItemModel::headerData( section, orientation, role ); } QVariant DockModel::data( const QModelIndex &index, int role ) const @@ -122,32 +129,26 @@ Qt::ItemFlags DockModel::flags( const QModelIndex &index ) const return flags; } -void DockModel::resetModel() -{ - beginResetModel(); - endResetModel(); -} - void DockModel::reload( const QModelIndex &index1, const QModelIndex &index2 ) { emit dataChanged( index1, index2 ); } -DockFilterModel::DockFilterModel( ErrorList &errorList, QObject *parent = nullptr ) +DockFilterModel::DockFilterModel( QObject *parent ) : QSortFilterProxyModel( parent ) - , mDockModel( new DockModel( errorList, parent ) ) + , mDockModel( new DockModel( parent ) ) { setSourceModel( mDockModel ); setFilterKeyColumn( 0 ); } -void DockFilterModel::reload( const QModelIndex &index1, const QModelIndex &index2 ) +void DockFilterModel::setErrors( const ErrorList &errorList ) { - mDockModel->reload( index1, index2 ); + mDockModel->setErrors( errorList ); } -void DockFilterModel::resetModel() +void DockFilterModel::reload( const QModelIndex &index1, const QModelIndex &index2 ) { - mDockModel->resetModel(); + mDockModel->reload( index1, index2 ); } diff --git a/src/plugins/topology/dockModel.h b/src/plugins/topology/dockModel.h index 30f4209d40f0..29261e69f328 100644 --- a/src/plugins/topology/dockModel.h +++ b/src/plugins/topology/dockModel.h @@ -33,10 +33,15 @@ class DockModel : public QAbstractTableModel /** * Constructor - * \param errorList reference to the ErrorList where errors will be stored * \param parent parent object */ - DockModel( ErrorList &errorList, QObject *parent ); + DockModel( QObject *parent = nullptr ); + + /** + * \param errorList reference to the ErrorList where errors will be stored + * \since 3.38 + */ + void setErrors( const ErrorList &errorList ); /** * Returns header data @@ -86,13 +91,8 @@ class DockModel : public QAbstractTableModel */ void reload( const QModelIndex &index1, const QModelIndex &index2 ); - /** - * Resets the model - */ - void resetModel(); - private: - ErrorList &mErrorlist; + ErrorList mErrorlist; QList mHeader; }; @@ -104,13 +104,17 @@ class DockFilterModel : public QSortFilterProxyModel /** * Constructor - * \param errorList reference to the ErrorList where errors will be stored * \param parent parent object */ - DockFilterModel( ErrorList &errorList, QObject *parent ); + DockFilterModel( QObject *parent = nullptr ); ~DockFilterModel() = default; + /** + * \param errorList reference to the ErrorList where errors will be stored + */ + void setErrors( const ErrorList &errorList ); + /** * Reloads the model data between indices * \param index1 start index @@ -118,11 +122,6 @@ class DockFilterModel : public QSortFilterProxyModel */ void reload( const QModelIndex &index1, const QModelIndex &index2 ); - /** - * Resets the model - */ - void resetModel(); - private: DockModel *mDockModel = nullptr;