@@ -361,14 +361,6 @@ void QgsHandleBadLayers::apply()
361
361
{
362
362
QgsProject::instance ()->layerTreeRegistryBridge ()->setEnabled ( true );
363
363
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 );
372
364
373
365
for ( int i = 0 ; i < mLayerList ->rowCount (); i++ )
374
366
{
@@ -378,20 +370,60 @@ void QgsHandleBadLayers::apply()
378
370
QTableWidgetItem *item = mLayerList ->item ( i, 4 );
379
371
QString datasource = item->text ();
380
372
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 )
383
395
{
384
396
mLayerList ->removeRow ( i-- );
385
397
}
386
398
else
387
399
{
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
+ }
389
409
}
390
410
}
391
- QgsProject::instance ()->layerTreeRegistryBridge ()->setEnabled ( false );
392
411
412
+ // Final cleanup: remove any bad layer (it should not be any btw)
393
413
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 );
394
423
accept ();
424
+ }
425
+
426
+ QgsProject::instance ()->layerTreeRegistryBridge ()->setEnabled ( false );
395
427
396
428
}
397
429
0 commit comments