Skip to content

Commit fdee6ea

Browse files
authored
Merge pull request #5031 from boundlessgeo/gpkg-drag-n-drop
[feature][needs-docs] Geopackage handle drops in the browser
2 parents 11fb601 + e6814bc commit fdee6ea

File tree

2 files changed

+112
-1
lines changed

2 files changed

+112
-1
lines changed

src/providers/ogr/qgsgeopackagedataitems.cpp

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#include "qgsrasterlayer.h"
2323
#include "qgsogrprovider.h"
2424
#include "qgsnewgeopackagelayerdialog.h"
25+
#include "qgsmessageoutput.h"
26+
#include "qgsvectorlayerexporter.h"
2527

2628
#include <QAction>
2729
#include <QMessageBox>
@@ -271,6 +273,115 @@ QList<QAction *> QgsGeoPackageConnectionItem::actions()
271273
}
272274
#endif
273275

276+
277+
278+
bool QgsGeoPackageConnectionItem::handleDrop( const QMimeData *data, Qt::DropAction )
279+
{
280+
281+
if ( !QgsMimeDataUtils::isUriList( data ) )
282+
return false;
283+
284+
// TODO: probably should show a GUI with settings etc
285+
QString uri;
286+
287+
QStringList importResults;
288+
bool hasError = false;
289+
290+
QgsMimeDataUtils::UriList lst = QgsMimeDataUtils::decodeUriList( data );
291+
Q_FOREACH ( const QgsMimeDataUtils::Uri &u, lst )
292+
{
293+
if ( u.layerType == QStringLiteral( "vector" ) )
294+
{
295+
// open the source layer
296+
bool owner;
297+
QString error;
298+
QgsVectorLayer *srcLayer = u.vectorLayer( owner, error );
299+
if ( !srcLayer )
300+
{
301+
importResults.append( tr( "%1: %2" ).arg( u.name ).arg( error ) );
302+
hasError = true;
303+
continue;
304+
}
305+
306+
if ( srcLayer->isValid() )
307+
{
308+
uri = mPath;
309+
QgsDebugMsgLevel( "URI " + uri, 3 );
310+
311+
// check if the destination layer already exists
312+
bool exists = false;
313+
// Q_FOREACH won't detach ...
314+
for ( const auto child : children() )
315+
{
316+
if ( child->name() == u.name )
317+
{
318+
exists = true;
319+
}
320+
}
321+
if ( ! exists || QMessageBox::question( nullptr, tr( "Overwrite Layer" ),
322+
tr( "Destination layer <b>%1</b> already exists. Do you want to overwrite it?" ).arg( u.name ), QMessageBox::Yes | QMessageBox::No ) == QMessageBox::Yes )
323+
{
324+
325+
std::unique_ptr< QMap<QString, QVariant> > options( new QMap<QString, QVariant> );
326+
options->insert( QStringLiteral( "driverName" ), QStringLiteral( "GPKG" ) );
327+
options->insert( QStringLiteral( "update" ), true );
328+
options->insert( QStringLiteral( "overwrite" ), true );
329+
options->insert( QStringLiteral( "layerName" ), u.name );
330+
331+
std::unique_ptr< QgsVectorLayerExporterTask > exportTask( new QgsVectorLayerExporterTask( srcLayer, uri, QStringLiteral( "ogr" ), srcLayer->crs(), options.get(), owner ) );
332+
333+
// when export is successful:
334+
connect( exportTask.get(), &QgsVectorLayerExporterTask::exportComplete, this, [ = ]()
335+
{
336+
// this is gross - TODO - find a way to get access to messageBar from data items
337+
QMessageBox::information( nullptr, tr( "Import to GeoPackage database" ), tr( "Import was successful." ) );
338+
refreshConnections();
339+
} );
340+
341+
// when an error occurs:
342+
connect( exportTask.get(), &QgsVectorLayerExporterTask::errorOccurred, this, [ = ]( int error, const QString & errorMessage )
343+
{
344+
if ( error != QgsVectorLayerExporter::ErrUserCanceled )
345+
{
346+
QgsMessageOutput *output = QgsMessageOutput::createMessageOutput();
347+
output->setTitle( tr( "Import to GeoPackage database" ) );
348+
output->setMessage( tr( "Failed to import some layers!\n\n" ) + errorMessage, QgsMessageOutput::MessageText );
349+
output->showMessage();
350+
}
351+
} );
352+
353+
QgsApplication::taskManager()->addTask( exportTask.release() );
354+
}
355+
}
356+
else
357+
{
358+
importResults.append( tr( "%1: Not a valid layer!" ).arg( u.name ) );
359+
hasError = true;
360+
}
361+
}
362+
else
363+
{
364+
// TODO: implemnent raster import
365+
QgsMessageOutput *output = QgsMessageOutput::createMessageOutput();
366+
output->setTitle( tr( "Import to GeoPackage database faile" ) );
367+
output->setMessage( tr( "Failed to import some layers!\n\n" ) + QStringLiteral( "Raster import is not yet implemented!\n" ), QgsMessageOutput::MessageText );
368+
output->showMessage();
369+
}
370+
371+
}
372+
373+
if ( hasError )
374+
{
375+
QgsMessageOutput *output = QgsMessageOutput::createMessageOutput();
376+
output->setTitle( tr( "Import to GeoPackage database" ) );
377+
output->setMessage( tr( "Failed to import some layers!\n\n" ) + importResults.join( QStringLiteral( "\n" ) ), QgsMessageOutput::MessageText );
378+
output->showMessage();
379+
}
380+
381+
return true;
382+
}
383+
384+
274385
QgsLayerItem::LayerType QgsGeoPackageConnectionItem::layerTypeFromDb( const QString &geometryType )
275386
{
276387
if ( geometryType.contains( QStringLiteral( "Point" ), Qt::CaseInsensitive ) )

src/providers/ogr/qgsgeopackagedataitems.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class QgsGeoPackageConnectionItem : public QgsDataCollectionItem
7171
#endif
7272

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

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

0 commit comments

Comments
 (0)