support copy vector layer to browser postgres/spatialite by drag and drop

This commit is contained in:
Radim Blazek 2017-06-21 15:11:11 +02:00
parent c1d4862840
commit fb6f181fa8
8 changed files with 81 additions and 18 deletions

View File

@ -40,6 +40,14 @@ Returns encoded representation of the object
:rtype: str
%End
QgsVectorLayer *vectorLayer( bool &owner, QString &error ) const;
%Docstring
Get vector layer from uri if possible, otherwise returns 0 and error is set
\param owner set to true if caller becomes owner
\param error set to error message if cannot get vector
:rtype: QgsVectorLayer
%End
QString layerType;
%Docstring
Type of URI. Recognized types: "vector" / "raster" / "plugin" / "custom"

View File

@ -149,11 +149,13 @@ class QgsVectorLayerExporterTask : QgsTask
const QString &uri,
const QString &providerKey,
const QgsCoordinateReferenceSystem &destinationCrs,
QMap<QString, QVariant> *options = 0 );
QMap<QString, QVariant> *options = 0,
bool ownsLayer = false );
%Docstring
Constructor for QgsVectorLayerExporterTask. Takes a source ``layer``, destination ``uri``
and ``providerKey``, and various export related parameters such as destination CRS
and export ``options``.
\param ownsLayer take ownership of layer and deletes it after export
%End
static QgsVectorLayerExporterTask *withLayerOwnership( QgsVectorLayer *layer /Transfer/,

View File

@ -27,7 +27,6 @@
static const char *QGIS_URILIST_MIMETYPE = "application/x-vnd.qgis.qgis.uri";
QgsMimeDataUtils::Uri::Uri()
{
}
@ -66,6 +65,41 @@ QString QgsMimeDataUtils::Uri::data() const
return encode( QStringList() << layerType << providerKey << name << uri << encode( supportedCrs ) << encode( supportedFormats ) );
}
QgsVectorLayer *QgsMimeDataUtils::Uri::vectorLayer( bool &owner, QString &error ) const
{
owner = false;
if ( layerType != QLatin1String( "vector" ) )
{
error = QObject::tr( "%1: Not a vector layer." ).arg( name );
return nullptr;
}
if ( providerKey == QLatin1String( "memory" ) )
{
QUrl url = QUrl::fromEncoded( uri.toUtf8() );
if ( !url.hasQueryItem( QStringLiteral( "pid" ) ) || !url.hasQueryItem( QStringLiteral( "layerid" ) ) )
{
error = QObject::tr( "Memory layer uri does not contain process or layer id." );
return nullptr;
}
qint64 pid = url.queryItemValue( QStringLiteral( "pid" ) ).toLongLong();
if ( pid != QCoreApplication::applicationPid() )
{
error = QObject::tr( "Memory layer from another QGIS instance." );
return nullptr;
}
QString layerId = url.queryItemValue( QStringLiteral( "layerid" ) );
QgsVectorLayer *vectorLayer = qobject_cast< QgsVectorLayer *>( QgsProject::instance()->mapLayer( layerId ) );
if ( !vectorLayer )
{
error = QObject::tr( "Cannot get memory layer." );
return nullptr;
}
return vectorLayer;
}
owner = true;
return new QgsVectorLayer( uri, name, providerKey );
}
// -----
bool QgsMimeDataUtils::isUriList( const QMimeData *data )
@ -119,6 +153,13 @@ static void _addLayerTreeNodeToUriList( QgsLayerTreeNode *node, QgsMimeDataUtils
if ( layer->type() == QgsMapLayer::VectorLayer )
{
uri.layerType = QStringLiteral( "vector" );
if ( uri.providerKey == QStringLiteral( "memory" ) )
{
QUrl url = QUrl::fromEncoded( uri.uri.toUtf8() );
url.addQueryItem( QStringLiteral( "pid" ), QString::number( QCoreApplication::applicationPid() ) );
url.addQueryItem( QStringLiteral( "layerid" ), layer->id() );
uri.uri = QString( url.toEncoded() );
}
}
else if ( layer->type() == QgsMapLayer::RasterLayer )
{

View File

@ -22,6 +22,7 @@
class QgsLayerItem;
class QgsLayerTreeNode;
class QgsVectorLayer;
/** \ingroup core
* \class QgsMimeDataUtils
@ -44,6 +45,12 @@ class CORE_EXPORT QgsMimeDataUtils
//! Returns encoded representation of the object
QString data() const;
/** Get vector layer from uri if possible, otherwise returns 0 and error is set
* \param owner set to true if caller becomes owner
* \param error set to error message if cannot get vector
*/
QgsVectorLayer *vectorLayer( bool &owner, QString &error ) const;
//! Type of URI. Recognized types: "vector" / "raster" / "plugin" / "custom"
QString layerType;
//! For "vector" / "raster" type: provider id.

View File

@ -456,9 +456,10 @@ QgsVectorLayerExporter::exportLayer( QgsVectorLayer *layer,
// QgsVectorLayerExporterTask
//
QgsVectorLayerExporterTask::QgsVectorLayerExporterTask( QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destinationCrs, QMap<QString, QVariant> *options )
QgsVectorLayerExporterTask::QgsVectorLayerExporterTask( QgsVectorLayer *layer, const QString &uri, const QString &providerKey, const QgsCoordinateReferenceSystem &destinationCrs, QMap<QString, QVariant> *options, bool ownsLayer )
: QgsTask( tr( "Exporting %1" ).arg( layer->name() ), QgsTask::CanCancel )
, mLayer( layer )
, mOwnsLayer( ownsLayer )
, mDestUri( uri )
, mDestProviderKey( providerKey )
, mDestCrs( destinationCrs )

View File

@ -189,12 +189,14 @@ class CORE_EXPORT QgsVectorLayerExporterTask : public QgsTask
* Constructor for QgsVectorLayerExporterTask. Takes a source \a layer, destination \a uri
* and \a providerKey, and various export related parameters such as destination CRS
* and export \a options.
* \param ownsLayer take ownership of layer and deletes it after export
*/
QgsVectorLayerExporterTask( QgsVectorLayer *layer,
const QString &uri,
const QString &providerKey,
const QgsCoordinateReferenceSystem &destinationCrs,
QMap<QString, QVariant> *options = nullptr );
QMap<QString, QVariant> *options = nullptr,
bool ownsLayer = false );
/**
* Creates a new QgsVectorLayerExporterTask which has ownership over a source \a layer.

View File

@ -201,16 +201,17 @@ bool QgsPGConnectionItem::handleDrop( const QMimeData *data, const QString &toSc
QgsMimeDataUtils::UriList lst = QgsMimeDataUtils::decodeUriList( data );
Q_FOREACH ( const QgsMimeDataUtils::Uri &u, lst )
{
if ( u.layerType != QLatin1String( "vector" ) )
// open the source layer
bool owner;
QString error;
QgsVectorLayer *srcLayer = u.vectorLayer( owner, error );
if ( !srcLayer )
{
importResults.append( tr( "%1: Not a vector layer!" ).arg( u.name ) );
hasError = true; // only vectors can be imported
importResults.append( tr( "%1: %2" ).arg( u.name ).arg( error ) );
hasError = true;
continue;
}
// open the source layer
QgsVectorLayer *srcLayer = new QgsVectorLayer( u.uri, u.name, u.providerKey );
if ( srcLayer->isValid() )
{
uri.setDataSource( QString(), u.name, srcLayer->geometryType() != QgsWkbTypes::NullGeometry ? QStringLiteral( "geom" ) : QString() );
@ -221,7 +222,7 @@ bool QgsPGConnectionItem::handleDrop( const QMimeData *data, const QString &toSc
uri.setSchema( toSchema );
}
std::unique_ptr< QgsVectorLayerExporterTask > exportTask( QgsVectorLayerExporterTask::withLayerOwnership( srcLayer, uri.uri( false ), QStringLiteral( "postgres" ), srcLayer->crs() ) );
std::unique_ptr< QgsVectorLayerExporterTask > exportTask( new QgsVectorLayerExporterTask( srcLayer, uri.uri( false ), QStringLiteral( "postgres" ), srcLayer->crs(), nullptr, owner ) );
// when export is successful:
connect( exportTask.get(), &QgsVectorLayerExporterTask::exportComplete, this, [ = ]()

View File

@ -205,22 +205,23 @@ bool QgsSLConnectionItem::handleDrop( const QMimeData *data, Qt::DropAction )
QgsMimeDataUtils::UriList lst = QgsMimeDataUtils::decodeUriList( data );
Q_FOREACH ( const QgsMimeDataUtils::Uri &u, lst )
{
if ( u.layerType != QLatin1String( "vector" ) )
// open the source layer
bool owner;
QString error;
QgsVectorLayer *srcLayer = u.vectorLayer( owner, error );
if ( !srcLayer )
{
importResults.append( tr( "%1: Not a vector layer!" ).arg( u.name ) );
hasError = true; // only vectors can be imported
importResults.append( tr( "%1: %2" ).arg( u.name ).arg( error ) );
hasError = true;
continue;
}
// open the source layer
QgsVectorLayer *srcLayer = new QgsVectorLayer( u.uri, u.name, u.providerKey );
if ( srcLayer->isValid() )
{
destUri.setDataSource( QString(), u.name, srcLayer->geometryType() != QgsWkbTypes::NullGeometry ? QStringLiteral( "geom" ) : QString() );
QgsDebugMsg( "URI " + destUri.uri() );
std::unique_ptr< QgsVectorLayerExporterTask > exportTask( QgsVectorLayerExporterTask::withLayerOwnership( srcLayer, destUri.uri(), QStringLiteral( "spatialite" ), srcLayer->crs() ) );
std::unique_ptr< QgsVectorLayerExporterTask > exportTask( new QgsVectorLayerExporterTask( srcLayer, destUri.uri(), QStringLiteral( "spatialite" ), srcLayer->crs(), nullptr, owner ) );
// when export is successful:
connect( exportTask.get(), &QgsVectorLayerExporterTask::exportComplete, this, [ = ]()