Skip to content

Commit

Permalink
Fix crashes in geometry checker (fixes #18736) (#7292)
Browse files Browse the repository at this point in the history
This fixes two different crashes:
- when trying to close the checker dialog while checks are running in background
- when trying to run checks again after previously aborting a run
  • Loading branch information
wonder-sk committed Jun 21, 2018
1 parent 314eca9 commit 73fd83f
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 2 deletions.
10 changes: 10 additions & 0 deletions src/plugins/geometry_checker/qgsgeometrycheckerdialog.cpp
Expand Up @@ -89,6 +89,16 @@ void QgsGeometryCheckerDialog::done( int r )

void QgsGeometryCheckerDialog::closeEvent( QCloseEvent *ev )
{
if ( QgsGeometryCheckerSetupTab *setupTab = qobject_cast<QgsGeometryCheckerSetupTab *>( mTabWidget->widget( 0 ) ) )
{
// do not allow closing the dialog - this would delete the geometry checker and crash
if ( setupTab->isRunningInBackground() )
{
ev->ignore();
return;
}
}

if ( qobject_cast<QgsGeometryCheckerResultTab *>( mTabWidget->widget( 1 ) ) &&
!static_cast<QgsGeometryCheckerResultTab *>( mTabWidget->widget( 1 ) )->isCloseable() )
{
Expand Down
5 changes: 3 additions & 2 deletions src/plugins/geometry_checker/qgsgeometrycheckerresulttab.cpp
Expand Up @@ -616,10 +616,11 @@ void QgsGeometryCheckerResultTab::checkRemovedLayer( const QStringList &ids )
bool requiredLayersRemoved = false;
for ( const QString &layerId : mChecker->getContext()->featurePools.keys() )
{
if ( ids.contains( layerId ) && isEnabled() )
if ( ids.contains( layerId ) )
{
mChecker->getContext()->featurePools[layerId]->clearLayer();
requiredLayersRemoved = true;
if ( isEnabled() )
requiredLayersRemoved = true;
}
}
if ( requiredLayersRemoved )
Expand Down
4 changes: 4 additions & 0 deletions src/plugins/geometry_checker/qgsgeometrycheckersetuptab.cpp
Expand Up @@ -467,11 +467,15 @@ void QgsGeometryCheckerSetupTab::runChecks()
connect( mAbortButton, &QAbstractButton::clicked, &futureWatcher, &QFutureWatcherBase::cancel );
connect( mAbortButton, &QAbstractButton::clicked, this, &QgsGeometryCheckerSetupTab::showCancelFeedback );

mIsRunningInBackground = true;

int maxSteps = 0;
futureWatcher.setFuture( checker->execute( &maxSteps ) );
ui.progressBar->setRange( 0, maxSteps );
evLoop.exec();

mIsRunningInBackground = false;

// Restore window
unsetCursor();
mAbortButton->setEnabled( true );
Expand Down
7 changes: 7 additions & 0 deletions src/plugins/geometry_checker/qgsgeometrycheckersetuptab.h
Expand Up @@ -34,6 +34,12 @@ class QgsGeometryCheckerSetupTab : public QWidget
QgsGeometryCheckerSetupTab( QgisInterface *iface, QDialog *checkerDialog, QWidget *parent = nullptr );
~QgsGeometryCheckerSetupTab() override;

/**
* Indicates whether the geometry checker is currently running its checks in the background.
* Useful to figure out whether it is safe to close the dialog and thus destroy the checker.
*/
bool isRunningInBackground() const { return mIsRunningInBackground; }

signals:
void checkerStarted( QgsGeometryChecker *checker );
void checkerFinished( bool );
Expand All @@ -45,6 +51,7 @@ class QgsGeometryCheckerSetupTab : public QWidget
QPushButton *mRunButton = nullptr;
QPushButton *mAbortButton = nullptr;
QMutex m_errorListMutex;
bool mIsRunningInBackground = false;

QList<QgsVectorLayer *> getSelectedLayers();

Expand Down

0 comments on commit 73fd83f

Please sign in to comment.