/* Eliminate the need to instantiate the layer based on provider type. The caller is responsible for cobbling together the needed information to open the layer */ QgsDebugMsg( "Creating new vector layer using " + vectorLayerPath + " with baseName of " + baseName + " and providerKey of " + providerKey );
// if the layer needs authentication, ensure the master password is set bool authok = true; QRegExp rx( "authcfg=([a-z]|[A-Z]|[0-9]){7}" ); if ( rx.indexIn( vectorLayerPath ) != -1 ) { authok = false; if ( !QgsAuthGuiUtils::isDisabled( messageBar(), messageTimeout() ) ) { authok = QgsApplication::authManager()->setMasterPassword( true ); } }
// create the layer QgsVectorLayer::LayerOptions options { QgsProject::instance()->transformContext() }; // Default style is loaded later in this method options.loadDefaultStyle = false; QgsVectorLayer *layer = new QgsVectorLayer( vectorLayerPath, baseName, providerKey, options );
// If the newly created layer has more than 1 layer of data available, we show the // sublayers selection dialog so the user can select the sublayers to actually load. if ( sublayers.count() > 1 && ! vectorLayerPath.contains( QStringLiteral( "layerid=" ) ) && ! vectorLayerPath.contains( QStringLiteral( "layername=" ) ) ) { QList< QgsMapLayer * > addedLayers = askUserForOGRSublayers( layer );
// The first layer loaded is not useful in that case. The user can select it in // the list if he wants to load it. delete layer; layer = addedLayers.isEmpty() ? nullptr : qobject_cast< QgsVectorLayer * >( addedLayers.at( 0 ) ); for ( QgsMapLayer *l : addedLayers ) askUserForDatumTransform( l->crs(), QgsProject::instance()->crs(), l ); } else { // Register this layer with the layers registry QList<QgsMapLayer *> myList;
//set friendly name for datasources with only one layer QStringList sublayers = layer->dataProvider()->subLayers(); if ( !sublayers.isEmpty() ) { setupVectorLayer( vectorLayerPath, sublayers, layer, providerKey, options ); }
bool ok; layer->loadDefaultStyle( ok ); layer->loadDefaultMetadata( ok ); } } else { if ( guiWarning ) { QString message = layer->dataProvider() ? layer->dataProvider()->error().message( QgsErrorMessage::Text ) : tr( "Invalid provider" ); QString msg = tr( "The layer %1 is not a valid layer and can not be added to the map. Reason: %2" ).arg( vectorLayerPath, message ); visibleMessageBar()->pushMessage( tr( "Layer is not valid" ), msg, Qgis::Critical, messageTimeout() ); }
delete layer; returnnullptr; }
// Let render() do its own cursor management // QApplication::restoreOverrideCursor();
QgsSublayersDialog::LayerDefinitionList list; QMap< QString, int > mapLayerNameToCount; bool uniqueNames = true; int lastLayerId = -1; constauto constSublayers = sublayers; for ( const QString &sublayer : constSublayers ) { // OGR provider returns items in this format: // <layer_index>:<name>:<feature_count>:<geom_type>
QStringList elements = splitSubLayerDef( sublayer ); if ( elements.count() >= 4 ) { QgsSublayersDialog::LayerDefinition def; def.layerId = elements[0].toInt(); def.layerName = elements[1]; def.count = elements[2].toInt(); def.type = elements[3]; // ignore geometry column name at elements[4] if ( elements.count() >= 6 ) def.description = elements[5]; if ( lastLayerId != def.layerId ) { int count = ++mapLayerNameToCount[def.layerName]; if ( count > 1 || def.layerName.isEmpty() ) uniqueNames = false; lastLayerId = def.layerId; } list << def; } else { QgsDebugMsg( "Unexpected output from OGR provider's subLayers()! " + sublayer ); } }
// Check if the current layer uri contains the
// We initialize a selection dialog and display it. QgsSublayersDialog chooseSublayersDialog( QgsSublayersDialog::Ogr, QStringLiteral( "ogr" ), this ); chooseSublayersDialog.setShowAddToGroupCheckbox( true ); chooseSublayersDialog.populateLayerTable( list );
if ( !chooseSublayersDialog.exec() ) return result;
// The uri must contain the actual uri of the vectorLayer from which we are // going to load the sublayers. QString fileName = QFileInfo( uri ).baseName(); constauto constSelection = chooseSublayersDialog.selection(); for ( const QgsSublayersDialog::LayerDefinition &def : constSelection ) { QString layerGeometryType = def.type; QString composedURI = uri; if ( uniqueNames ) { composedURI += "|layername=" + def.layerName; } else { // Only use layerId if there are ambiguities with names composedURI += "|layerid=" + QString::number( def.layerId ); }
QgsDebugMsg( "Creating new vector layer using " + composedURI ); QString name = fileName + " " + def.layerName; QgsVectorLayer::LayerOptions options { QgsProject::instance()->transformContext() }; options.loadDefaultStyle = false; QgsVectorLayer *layer = new QgsVectorLayer( composedURI, name, QStringLiteral( "ogr" ), options ); if ( layer && layer->isValid() ) { result << layer; } else { QString msg = tr( "%1 is not a valid or recognized data source" ).arg( composedURI ); visibleMessageBar()->pushMessage( tr( "Invalid Data Source" ), msg, Qgis::Critical, messageTimeout() ); delete layer; } }
if ( !result.isEmpty() ) { QgsSettings settings; bool addToGroup = settings.value( QStringLiteral( "/qgis/openSublayersInGroup" ), true ).toBool(); bool newLayersVisible = settings.value( QStringLiteral( "/qgis/new_layers_visible" ), true ).toBool(); QgsLayerTreeGroup *group = nullptr; if ( addToGroup ) group = QgsProject::instance()->layerTreeRoot()->insertGroup( 0, name );
QgsProject::instance()->addMapLayers( result, ! addToGroup ); for ( QgsMapLayer *l : qgis::as_const( result ) ) { bool ok; l->loadDefaultStyle( ok ); l->loadDefaultMetadata( ok ); if ( addToGroup ) group->addLayer( l ); }
// Respect if user don't want the new group of layers visible. if ( addToGroup && ! newLayersVisible ) group->setItemVisibilityCheckedRecursive( newLayersVisible ); } return result; }