@@ -361,14 +361,6 @@ void QgsHandleBadLayers::apply()
361361{
362362 QgsProject::instance ()->layerTreeRegistryBridge ()->setEnabled ( true );
363363 buttonBox->button ( QDialogButtonBox::Ignore )->setEnabled ( false );
364- QList<QgsMapLayer *> toRemove;
365- for ( const auto &l : QgsProject::instance ()->mapLayers ( ) )
366- {
367- if ( ! l->isValid () )
368- toRemove << l;
369- }
370-
371- QgsProject::instance ()->removeMapLayers ( toRemove );
372364
373365 for ( int i = 0 ; i < mLayerList ->rowCount (); i++ )
374366 {
@@ -378,20 +370,60 @@ void QgsHandleBadLayers::apply()
378370 QTableWidgetItem *item = mLayerList ->item ( i, 4 );
379371 QString datasource = item->text ();
380372
381- node.namedItem ( QStringLiteral ( " datasource" ) ).toElement ().firstChild ().toText ().setData ( datasource );
382- if ( QgsProject::instance ()->readLayer ( node ) )
373+ bool dataSourceChanged { false };
374+ const QString layerId { node.namedItem ( QStringLiteral ( " id" ) ).toElement ().text () };
375+ const QString provider { node.namedItem ( QStringLiteral ( " provider" ) ).toElement ().text () };
376+ const QString name { mLayerList ->item ( i, 0 )->text () };
377+
378+ // Try first to change the datasource of the existing layers, this will
379+ // maintain the current status (checked/unchecked) and group
380+ if ( QgsProject::instance ()->mapLayer ( layerId ) )
381+ {
382+ QgsDataProvider::ProviderOptions options;
383+ QgsMapLayer *mapLayer = QgsProject::instance ()->mapLayer ( layerId );
384+ if ( mapLayer )
385+ {
386+ mapLayer->setDataSource ( datasource, name, provider, options );
387+ dataSourceChanged = mapLayer->isValid ();
388+ }
389+ }
390+
391+ // If the data source was changed successfully, remove the bad layer from the dialog
392+ // otherwise, try to set the new datasource in the XML node and reload the layer,
393+ // finally marks with red all remaining bad layers.
394+ if ( dataSourceChanged )
383395 {
384396 mLayerList ->removeRow ( i-- );
385397 }
386398 else
387399 {
388- item->setForeground ( QBrush ( Qt::red ) );
400+ node.namedItem ( QStringLiteral ( " datasource" ) ).toElement ().firstChild ().toText ().setData ( datasource );
401+ if ( QgsProject::instance ()->readLayer ( node ) )
402+ {
403+ mLayerList ->removeRow ( i-- );
404+ }
405+ else
406+ {
407+ item->setForeground ( QBrush ( Qt::red ) );
408+ }
389409 }
390410 }
391- QgsProject::instance ()->layerTreeRegistryBridge ()->setEnabled ( false );
392411
412+ // Final cleanup: remove any bad layer (it should not be any btw)
393413 if ( mLayerList ->rowCount () == 0 )
414+ {
415+ QList<QgsMapLayer *> toRemove;
416+ const auto mapLayers = QgsProject::instance ()->mapLayers ();
417+ for ( const auto &l : mapLayers )
418+ {
419+ if ( ! l->isValid () )
420+ toRemove << l;
421+ }
422+ QgsProject::instance ()->removeMapLayers ( toRemove );
394423 accept ();
424+ }
425+
426+ QgsProject::instance ()->layerTreeRegistryBridge ()->setEnabled ( false );
395427
396428}
397429
0 commit comments