Skip to content
Permalink
Browse files

After fixing a broken layer path, also auto-fix any other broken layers

which are pointing to a file in the same folder as the layer we just fixed,
(where a matching filename exists in the newly selected folder)

Previously this logic only applied to layers where the file path was
identical to the layer just fixed (i.e. multi-layer sources such as
gpkg/gdb), now it also works nicely with multi-file directories
such as directories full of shapefiles.
  • Loading branch information
nyalldawson committed Mar 17, 2020
1 parent 342f1e3 commit 29db15a439e61765ba77fd71748ee644fded4f2a
Showing with 36 additions and 11 deletions.
  1. +36 −11 src/app/qgisapp.cpp
@@ -7846,20 +7846,45 @@ void QgisApp::changeDataSource( QgsMapLayer *layer )
const QVariantMap fixedUriParts = QgsProviderRegistry::instance()->decodeUri( layer->providerType(), layer->source() );

// next, we loop through to see if we can auto-fix any other layers with the same source
const QMap< QString, QgsMapLayer * > layers = QgsProject::instance()->mapLayers( false );
for ( auto it = layers.begin(); it != layers.end(); ++it )
if ( originalSourceParts.contains( QStringLiteral( "path" ) ) )
{
if ( it.value()->isValid() )
continue;
const QString originalPath = originalSourceParts.value( QStringLiteral( "path" ) ).toString();
const QFileInfo originalPathFi( originalPath );

QVariantMap thisParts = QgsProviderRegistry::instance()->decodeUri( it.value()->providerType(), it.value()->source() );
if ( thisParts.contains( QStringLiteral( "path" ) ) && thisParts.value( QStringLiteral( "path" ) ) == originalSourceParts.value( QStringLiteral( "path" ) ) )
const QMap< QString, QgsMapLayer * > layers = QgsProject::instance()->mapLayers( false );
for ( auto it = layers.begin(); it != layers.end(); ++it )
{
// found a broken layer with the same original path, fix this one too
uri.uri = it.value()->source().replace( thisParts.value( QStringLiteral( "path" ) ).toString(),
fixedUriParts.value( QStringLiteral( "path" ) ).toString() );
uri.providerKey = it.value()->providerType();
fixLayer( it.value(), uri );
if ( it.value()->isValid() )
continue;

QVariantMap thisParts = QgsProviderRegistry::instance()->decodeUri( it.value()->providerType(), it.value()->source() );
if ( thisParts.contains( QStringLiteral( "path" ) ) )
{
const QString thisBrokenPath = thisParts.value( QStringLiteral( "path" ) ).toString();
QString fixedPath;

const QFileInfo thisBrokenPathFi( thisBrokenPath );
if ( thisBrokenPath == originalPath )
{
// found a broken layer with the same original path, fix this one too
fixedPath = fixedUriParts.value( QStringLiteral( "path" ) ).toString();
}
else if ( thisBrokenPathFi.path() == originalPathFi.path() )
{
// file from same original directory
QDir fixedDir = QFileInfo( fixedUriParts.value( QStringLiteral( "path" ) ).toString() ).dir();
const QString newCandidatePath = fixedDir.filePath( thisBrokenPathFi.fileName() );
if ( QFileInfo::exists( newCandidatePath ) )
fixedPath = newCandidatePath;
}

if ( !fixedPath.isEmpty() )
{
uri.uri = it.value()->source().replace( thisBrokenPath, fixedPath );
uri.providerKey = it.value()->providerType();
fixLayer( it.value(), uri );
}
}
}
}
}

0 comments on commit 29db15a

Please sign in to comment.
You can’t perform that action at this time.