Skip to content

Commit

Permalink
Modernize paste to memory layer code
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Feb 5, 2018
1 parent 5ba69ea commit dbe45b8
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 27 deletions.
44 changes: 20 additions & 24 deletions src/app/qgisapp.cpp
Expand Up @@ -8220,18 +8220,15 @@ void QgisApp::pasteFromClipboard( QgsMapLayer *destinationLayer )
void QgisApp::pasteAsNewVector()
{

QgsVectorLayer *layer = pasteToNewMemoryVector();
std::unique_ptr< QgsVectorLayer > layer = pasteToNewMemoryVector();
if ( !layer )
return;

saveAsVectorFileGeneral( layer, false );

delete layer;
saveAsVectorFileGeneral( layer.get(), false );
}

QgsVectorLayer *QgisApp::pasteAsNewMemoryVector( const QString &layerName )
{

QString layerNameCopy = layerName;

if ( layerNameCopy.isEmpty() )
Expand All @@ -8250,36 +8247,36 @@ QgsVectorLayer *QgisApp::pasteAsNewMemoryVector( const QString &layerName )
}
}

QgsVectorLayer *layer = pasteToNewMemoryVector();
std::unique_ptr< QgsVectorLayer > layer = pasteToNewMemoryVector();
if ( !layer )
return nullptr;

layer->setName( layerNameCopy );

freezeCanvases();

QgsProject::instance()->addMapLayer( layer );
QgsVectorLayer *result = layer.get();
QgsProject::instance()->addMapLayer( layer.release() );

freezeCanvases( false );
refreshMapCanvas();

return layer;
return result;
}

QgsVectorLayer *QgisApp::pasteToNewMemoryVector()
std::unique_ptr<QgsVectorLayer> QgisApp::pasteToNewMemoryVector()
{
QgsFields fields = clipboard()->fields();
const QgsFields fields = clipboard()->fields();

// Decide geometry type from features, switch to multi type if at least one multi is found
QMap<QgsWkbTypes::Type, int> typeCounts;
QgsFeatureList features = clipboard()->copyOf( fields );
for ( int i = 0; i < features.size(); i++ )
const QgsFeatureList features = clipboard()->copyOf( fields );
for ( const QgsFeature &feature : features )
{
QgsFeature &feature = features[i];
if ( !feature.hasGeometry() )
continue;

QgsWkbTypes::Type type = feature.geometry().wkbType();
const QgsWkbTypes::Type type = feature.geometry().wkbType();

if ( type == QgsWkbTypes::Unknown || type == QgsWkbTypes::NoGeometry )
continue;
Expand Down Expand Up @@ -8307,7 +8304,7 @@ QgsVectorLayer *QgisApp::pasteToNewMemoryVector()
}
}

QgsWkbTypes::Type wkbType = !typeCounts.isEmpty() ? typeCounts.keys().value( 0 ) : QgsWkbTypes::NoGeometry;
const QgsWkbTypes::Type wkbType = !typeCounts.isEmpty() ? typeCounts.keys().value( 0 ) : QgsWkbTypes::NoGeometry;

if ( features.isEmpty() )
{
Expand All @@ -8325,39 +8322,38 @@ QgsVectorLayer *QgisApp::pasteToNewMemoryVector()
QgsMessageBar::INFO, messageTimeout() );
}

QgsVectorLayer *layer = QgsMemoryProviderUtils::createMemoryLayer( QStringLiteral( "pasted_features" ), QgsFields(), wkbType, clipboard()->crs() );
std::unique_ptr< QgsVectorLayer > layer( QgsMemoryProviderUtils::createMemoryLayer( QStringLiteral( "pasted_features" ), QgsFields(), wkbType, clipboard()->crs() ) );

if ( !layer->isValid() || !layer->dataProvider() )
{
delete layer;
messageBar()->pushMessage( tr( "Paste features" ),
tr( "Cannot create new layer." ),
QgsMessageBar::WARNING, messageTimeout() );
return nullptr;
}

layer->startEditing();
Q_FOREACH ( QgsField f, clipboard()->fields().toList() )
for ( const QgsField &f : clipboard()->fields() )
{
QgsDebugMsg( QString( "field %1 (%2)" ).arg( f.name(), QVariant::typeToName( f.type() ) ) );
if ( !layer->addAttribute( f ) )
{
messageBar()->pushMessage( tr( "Paste features" ),
tr( "Cannot create field %1 (%2,%3)" ).arg( f.name(), f.typeName(), QVariant::typeToName( f.type() ) ),
QgsMessageBar::WARNING, messageTimeout() );
delete layer;
return nullptr;
}
}

// Convert to multi if necessary
for ( int i = 0; i < features.size(); i++ )
QgsFeatureList convertedFeatures;
convertedFeatures.reserve( features.length() );
for ( QgsFeature feature : features )
{
QgsFeature &feature = features[i];
if ( !feature.hasGeometry() )
continue;

QgsWkbTypes::Type type = feature.geometry().wkbType();
const QgsWkbTypes::Type type = feature.geometry().wkbType();
if ( type == QgsWkbTypes::Unknown || type == QgsWkbTypes::NoGeometry )
continue;

Expand All @@ -8372,11 +8368,11 @@ QgsVectorLayer *QgisApp::pasteToNewMemoryVector()
g.convertToMultiType();
feature.setGeometry( g );
}
convertedFeatures.append( feature );
}
if ( ! layer->addFeatures( features ) || !layer->commitChanges() )
if ( ! layer->addFeatures( convertedFeatures ) || !layer->commitChanges() )
{
QgsDebugMsg( "Cannot add features or commit changes" );
delete layer;
return nullptr;
}

Expand Down
6 changes: 3 additions & 3 deletions src/app/qgisapp.h
Expand Up @@ -1751,10 +1751,10 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow

/**
* Paste features from clipboard into a new memory layer.
* If no features are in clipboard an empty layer is returned.
* \returns pointer to a new layer or 0 if failed
* If no features are in clipboard an empty layer is returned.
* Returns a new memory layer or a nullptr if the operation failed.
*/
QgsVectorLayer *pasteToNewMemoryVector();
std::unique_ptr< QgsVectorLayer > pasteToNewMemoryVector();

//! Returns all annotation items in the canvas
QList<QgsMapCanvasAnnotationItem *> annotationItems();
Expand Down

0 comments on commit dbe45b8

Please sign in to comment.