Skip to content

Commit da6049e

Browse files
committed
Adds delete layer context action to ogr and geopackage items
TODO: decide what to do if the layer to be deleted was added to the canvas: block the deletion? Current implementation just ignores the fact with no apparent serious consequences beside that obviously the layer is not drawn anymore.
1 parent 755980f commit da6049e

File tree

5 files changed

+159
-2
lines changed

5 files changed

+159
-2
lines changed

src/providers/ogr/qgsgeopackagedataitems.cpp

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,16 @@
2020
#include "qgsproject.h"
2121
#include "qgsvectorlayer.h"
2222
#include "qgsrasterlayer.h"
23+
#include "qgsogrprovider.h"
2324
#include "qgsnewgeopackagelayerdialog.h"
2425

2526
#include <QAction>
2627
#include <QMessageBox>
2728
#include <QFileDialog>
2829
#include <QInputDialog>
2930

31+
QGISEXTERN bool deleteLayer( const QString &uri, const QString &errCause );
32+
3033
QgsDataItem *QgsGeoPackageDataItemProvider::createDataItem( const QString &path, QgsDataItem *parentItem )
3134
{
3235
QgsDebugMsg( "path = " + path );
@@ -327,7 +330,6 @@ void QgsGeoPackageConnectionItem::addTable()
327330
QList<QAction *> QgsGeoPackageAbstractLayerItem::actions()
328331
{
329332
QList<QAction *> lst;
330-
331333
// TODO: delete layer when the provider supports it (not currently implemented)
332334
return lst;
333335
}
@@ -352,3 +354,39 @@ QgsGeoPackageRasterLayerItem::QgsGeoPackageRasterLayerItem( QgsDataItem *parent,
352354
{
353355

354356
}
357+
358+
359+
360+
#ifdef HAVE_GUI
361+
QList<QAction *> QgsGeoPackageVectorLayerItem::actions()
362+
{
363+
QList<QAction *> lst = QgsGeoPackageAbstractLayerItem::actions();
364+
QAction *actionDeleteLayer = new QAction( tr( "Delete %1" ).arg( mName ), this );
365+
connect( actionDeleteLayer, &QAction::triggered, this, &QgsGeoPackageVectorLayerItem::deleteLayer );
366+
lst.append( actionDeleteLayer );
367+
return lst;
368+
}
369+
370+
371+
void QgsGeoPackageVectorLayerItem::deleteLayer()
372+
{
373+
if ( QMessageBox::question( nullptr, QObject::tr( "Delete Layer" ),
374+
QObject::tr( "Are you sure you want to delete %1?" ).arg( mName ),
375+
QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) != QMessageBox::Yes )
376+
return;
377+
378+
QString errCause;
379+
bool res = ::deleteLayer( mUri, errCause );
380+
if ( !res )
381+
{
382+
QMessageBox::warning( nullptr, tr( "Delete Layer" ), errCause );
383+
}
384+
else
385+
{
386+
QMessageBox::information( nullptr, tr( "Delete Layer" ), tr( "Layer deleted successfully." ) );
387+
if ( mParent )
388+
mParent->refresh();
389+
}
390+
}
391+
#endif
392+

src/providers/ogr/qgsgeopackagedataitems.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,11 @@ class QgsGeoPackageVectorLayerItem : public QgsGeoPackageAbstractLayerItem
4949
Q_OBJECT
5050
public:
5151
QgsGeoPackageVectorLayerItem( QgsDataItem *parent, QString name, QString path, QString uri, LayerType layerType );
52-
52+
#ifdef HAVE_GUI
53+
QList<QAction *> actions() override;
54+
public slots:
55+
void deleteLayer();
56+
#endif
5357
};
5458

5559

src/providers/ogr/qgsogrdataitems.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <QFileInfo>
2323
#include <QTextStream>
2424
#include <QAction>
25+
#include <QMessageBox>
2526

2627
#include <ogr_srs_api.h>
2728
#include <cpl_error.h>
@@ -31,6 +32,8 @@
3132
QGISEXTERN QStringList fileExtensions();
3233
QGISEXTERN QStringList wildcards();
3334

35+
QGISEXTERN bool deleteLayer( const QString &uri, const QString &errCause );
36+
3437

3538
QgsOgrLayerItem::QgsOgrLayerItem( QgsDataItem *parent,
3639
QString name, QString path, QString uri, LayerType layerType )
@@ -56,6 +59,7 @@ QgsOgrLayerItem::QgsOgrLayerItem( QgsDataItem *parent,
5659
}
5760
}
5861

62+
5963
bool QgsOgrLayerItem::setCrs( const QgsCoordinateReferenceSystem &crs )
6064
{
6165
if ( !( mCapabilities & SetCrs ) )
@@ -110,6 +114,38 @@ QString QgsOgrLayerItem::layerName() const
110114
return info.completeBaseName();
111115
}
112116

117+
#ifdef HAVE_GUI
118+
QList<QAction *> QgsOgrLayerItem::actions()
119+
{
120+
QList<QAction *> lst;
121+
QAction *actionDeleteLayer = new QAction( tr( "Delete %1" ).arg( mName ), this );
122+
connect( actionDeleteLayer, &QAction::triggered, this, &QgsOgrLayerItem::deleteLayer );
123+
lst.append( actionDeleteLayer );
124+
return lst;
125+
}
126+
127+
void QgsOgrLayerItem::deleteLayer()
128+
{
129+
if ( QMessageBox::question( nullptr, QObject::tr( "Delete Layer" ),
130+
QObject::tr( "Are you sure you want to delete %1?" ).arg( mName ),
131+
QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) != QMessageBox::Yes )
132+
return;
133+
134+
QString errCause;
135+
bool res = ::deleteLayer( mUri, errCause );
136+
if ( !res )
137+
{
138+
QMessageBox::warning( nullptr, tr( "Delete Layer" ), errCause );
139+
}
140+
else
141+
{
142+
QMessageBox::information( nullptr, tr( "Delete Layer" ), tr( "Layer deleted successfully." ) );
143+
if ( mParent )
144+
mParent->refresh();
145+
}
146+
}
147+
#endif
148+
113149
// -------
114150

115151
static QgsOgrLayerItem *dataItemForLayer( QgsDataItem *parentItem, QString name, QString path, OGRDataSourceH hDataSource, int layerId )

src/providers/ogr/qgsogrdataitems.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ class QgsOgrLayerItem : public QgsLayerItem
2929
bool setCrs( const QgsCoordinateReferenceSystem &crs ) override;
3030

3131
QString layerName() const override;
32+
33+
#ifdef HAVE_GUI
34+
QList<QAction *> actions() override;
35+
public slots:
36+
void deleteLayer();
37+
#endif
3238
};
3339

3440

src/providers/ogr/qgsogrprovider.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4297,3 +4297,76 @@ QGISEXTERN void cleanupProvider()
42974297
// NOTE: QgsApplication takes care of
42984298
// calling OGRCleanupAll();
42994299
}
4300+
4301+
4302+
4303+
QGISEXTERN bool deleteLayer( const QString &uri, QString &errCause )
4304+
{
4305+
bool isSubLayer;
4306+
int layerIndex;
4307+
QString layerName;
4308+
QString subsetString;
4309+
OGRwkbGeometryType ogrGeometryType;
4310+
QString filePath = AnalyzeURI( uri,
4311+
isSubLayer,
4312+
layerIndex,
4313+
layerName,
4314+
subsetString,
4315+
ogrGeometryType );
4316+
4317+
OGRDataSourceH hDS = GDALOpenEx( filePath.toLocal8Bit().data(), GDAL_OF_RASTER | GDAL_OF_VECTOR | GDAL_OF_UPDATE, NULL, NULL, NULL );
4318+
if ( hDS && ( ! layerName.isEmpty() || layerIndex != -1 ) )
4319+
{
4320+
if ( layerIndex == -1 )
4321+
{
4322+
for ( int i = 0; i < GDALDatasetGetLayerCount( hDS ); i++ )
4323+
{
4324+
OGRLayerH hL = GDALDatasetGetLayer( hDS, i );
4325+
if ( layerName == QString( OGR_L_GetName( hL ) ) )
4326+
{
4327+
layerIndex = i;
4328+
}
4329+
}
4330+
}
4331+
OGRErr error = GDALDatasetDeleteLayer( hDS, layerIndex );
4332+
switch ( error )
4333+
{
4334+
case OGRERR_NOT_ENOUGH_DATA:
4335+
errCause = QStringLiteral( "Not enough data to deserialize" );
4336+
break;
4337+
case OGRERR_NOT_ENOUGH_MEMORY:
4338+
errCause = QStringLiteral( "Not enough memory" );
4339+
break;
4340+
case OGRERR_UNSUPPORTED_GEOMETRY_TYPE:
4341+
errCause = QStringLiteral( "Unsupported geometry type" );
4342+
break;
4343+
case OGRERR_UNSUPPORTED_OPERATION:
4344+
errCause = QStringLiteral( "Unsupported operation" );
4345+
break;
4346+
case OGRERR_CORRUPT_DATA:
4347+
errCause = QStringLiteral( "Corrupt data" );
4348+
break;
4349+
case OGRERR_FAILURE:
4350+
errCause = QStringLiteral( "Failure" );
4351+
break;
4352+
case OGRERR_UNSUPPORTED_SRS:
4353+
errCause = QStringLiteral( "Unsupported SRS" );
4354+
break;
4355+
case OGRERR_INVALID_HANDLE:
4356+
errCause = QStringLiteral( "Invalid handle" );
4357+
break;
4358+
case OGRERR_NON_EXISTING_FEATURE:
4359+
errCause = QStringLiteral( "Non existing feature" );
4360+
break;
4361+
default:
4362+
case OGRERR_NONE:
4363+
errCause = QStringLiteral( "Success" );
4364+
break;
4365+
}
4366+
errCause = QStringLiteral( "OGR result code: %s" ).arg( errCause );
4367+
return error == OGRERR_NONE;
4368+
}
4369+
// This should never happen:
4370+
errCause = QStringLiteral( "Layer not found: %s" ).arg( uri );
4371+
return false;
4372+
}

0 commit comments

Comments
 (0)