Skip to content

Commit

Permalink
[feature] Geopackage handle drops in the browser
Browse files Browse the repository at this point in the history
It is now possible to drag and drop from any vector
layer onto a gpkg node layer and import a layer.

Overwrites are protected by a confirmation dialog.
  • Loading branch information
elpaso committed Aug 16, 2017
1 parent 0be0a4e commit e6814bc
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 1 deletion.
111 changes: 111 additions & 0 deletions src/providers/ogr/qgsgeopackagedataitems.cpp
Expand Up @@ -21,6 +21,8 @@
#include "qgsvectorlayer.h"
#include "qgsrasterlayer.h"
#include "qgsnewgeopackagelayerdialog.h"
#include "qgsmessageoutput.h"
#include "qgsvectorlayerexporter.h"

#include <QAction>
#include <QMessageBox>
Expand Down Expand Up @@ -268,6 +270,115 @@ QList<QAction *> QgsGeoPackageConnectionItem::actions()
}
#endif



bool QgsGeoPackageConnectionItem::handleDrop( const QMimeData *data, Qt::DropAction )
{

if ( !QgsMimeDataUtils::isUriList( data ) )
return false;

// TODO: probably should show a GUI with settings etc
QString uri;

QStringList importResults;
bool hasError = false;

QgsMimeDataUtils::UriList lst = QgsMimeDataUtils::decodeUriList( data );
Q_FOREACH ( const QgsMimeDataUtils::Uri &u, lst )
{
if ( u.layerType == QStringLiteral( "vector" ) )
{
// open the source layer
bool owner;
QString error;
QgsVectorLayer *srcLayer = u.vectorLayer( owner, error );
if ( !srcLayer )
{
importResults.append( tr( "%1: %2" ).arg( u.name ).arg( error ) );
hasError = true;
continue;
}

if ( srcLayer->isValid() )
{
uri = mPath;
QgsDebugMsgLevel( "URI " + uri, 3 );

// check if the destination layer already exists
bool exists = false;
// Q_FOREACH won't detach ...
for ( const auto child : children() )
{
if ( child->name() == u.name )
{
exists = true;
}
}
if ( ! exists || QMessageBox::question( nullptr, tr( "Overwrite Layer" ),
tr( "Destination layer <b>%1</b> already exists. Do you want to overwrite it?" ).arg( u.name ), QMessageBox::Yes | QMessageBox::No ) == QMessageBox::Yes )
{

std::unique_ptr< QMap<QString, QVariant> > options( new QMap<QString, QVariant> );
options->insert( QStringLiteral( "driverName" ), QStringLiteral( "GPKG" ) );
options->insert( QStringLiteral( "update" ), true );
options->insert( QStringLiteral( "overwrite" ), true );
options->insert( QStringLiteral( "layerName" ), u.name );

std::unique_ptr< QgsVectorLayerExporterTask > exportTask( new QgsVectorLayerExporterTask( srcLayer, uri, QStringLiteral( "ogr" ), srcLayer->crs(), options.get(), owner ) );

// when export is successful:
connect( exportTask.get(), &QgsVectorLayerExporterTask::exportComplete, this, [ = ]()
{
// this is gross - TODO - find a way to get access to messageBar from data items
QMessageBox::information( nullptr, tr( "Import to GeoPackage database" ), tr( "Import was successful." ) );
refreshConnections();
} );

// when an error occurs:
connect( exportTask.get(), &QgsVectorLayerExporterTask::errorOccurred, this, [ = ]( int error, const QString & errorMessage )
{
if ( error != QgsVectorLayerExporter::ErrUserCanceled )
{
QgsMessageOutput *output = QgsMessageOutput::createMessageOutput();
output->setTitle( tr( "Import to GeoPackage database" ) );
output->setMessage( tr( "Failed to import some layers!\n\n" ) + errorMessage, QgsMessageOutput::MessageText );
output->showMessage();
}
} );

QgsApplication::taskManager()->addTask( exportTask.release() );
}
}
else
{
importResults.append( tr( "%1: Not a valid layer!" ).arg( u.name ) );
hasError = true;
}
}
else
{
// TODO: implemnent raster import
QgsMessageOutput *output = QgsMessageOutput::createMessageOutput();
output->setTitle( tr( "Import to GeoPackage database faile" ) );
output->setMessage( tr( "Failed to import some layers!\n\n" ) + QStringLiteral( "Raster import is not yet implemented!\n" ), QgsMessageOutput::MessageText );
output->showMessage();
}

}

if ( hasError )
{
QgsMessageOutput *output = QgsMessageOutput::createMessageOutput();
output->setTitle( tr( "Import to GeoPackage database" ) );
output->setMessage( tr( "Failed to import some layers!\n\n" ) + importResults.join( QStringLiteral( "\n" ) ), QgsMessageOutput::MessageText );
output->showMessage();
}

return true;
}


QgsLayerItem::LayerType QgsGeoPackageConnectionItem::layerTypeFromDb( const QString &geometryType )
{
if ( geometryType.contains( QStringLiteral( "Point" ), Qt::CaseInsensitive ) )
Expand Down
2 changes: 1 addition & 1 deletion src/providers/ogr/qgsgeopackagedataitems.h
Expand Up @@ -67,7 +67,7 @@ class QgsGeoPackageConnectionItem : public QgsDataCollectionItem
#endif

virtual bool acceptDrop() override { return true; }
//virtual bool handleDrop( const QMimeData *data, Qt::DropAction action ) override;
virtual bool handleDrop( const QMimeData *data, Qt::DropAction action ) override;

//! Return the layer type from \a geometryType
static QgsLayerItem::LayerType layerTypeFromDb( const QString &geometryType );
Expand Down

0 comments on commit e6814bc

Please sign in to comment.