Skip to content
Permalink
Browse files

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.
  • Loading branch information
elpaso committed Aug 15, 2017
1 parent 755980f commit da6049ea38344451ab774f648ecd0d7a4e745ed6
@@ -20,13 +20,16 @@
#include "qgsproject.h"
#include "qgsvectorlayer.h"
#include "qgsrasterlayer.h"
#include "qgsogrprovider.h"
#include "qgsnewgeopackagelayerdialog.h"

#include <QAction>
#include <QMessageBox>
#include <QFileDialog>
#include <QInputDialog>

QGISEXTERN bool deleteLayer( const QString &uri, const QString &errCause );

QgsDataItem *QgsGeoPackageDataItemProvider::createDataItem( const QString &path, QgsDataItem *parentItem )
{
QgsDebugMsg( "path = " + path );
@@ -327,7 +330,6 @@ void QgsGeoPackageConnectionItem::addTable()
QList<QAction *> QgsGeoPackageAbstractLayerItem::actions()
{
QList<QAction *> lst;

// TODO: delete layer when the provider supports it (not currently implemented)
return lst;
}
@@ -352,3 +354,39 @@ QgsGeoPackageRasterLayerItem::QgsGeoPackageRasterLayerItem( QgsDataItem *parent,
{

}



#ifdef HAVE_GUI
QList<QAction *> QgsGeoPackageVectorLayerItem::actions()
{
QList<QAction *> lst = QgsGeoPackageAbstractLayerItem::actions();
QAction *actionDeleteLayer = new QAction( tr( "Delete %1" ).arg( mName ), this );
connect( actionDeleteLayer, &QAction::triggered, this, &QgsGeoPackageVectorLayerItem::deleteLayer );
lst.append( actionDeleteLayer );
return lst;
}


void QgsGeoPackageVectorLayerItem::deleteLayer()
{
if ( QMessageBox::question( nullptr, QObject::tr( "Delete Layer" ),
QObject::tr( "Are you sure you want to delete %1?" ).arg( mName ),
QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) != QMessageBox::Yes )
return;

QString errCause;
bool res = ::deleteLayer( mUri, errCause );
if ( !res )
{
QMessageBox::warning( nullptr, tr( "Delete Layer" ), errCause );
}
else
{
QMessageBox::information( nullptr, tr( "Delete Layer" ), tr( "Layer deleted successfully." ) );
if ( mParent )
mParent->refresh();
}
}
#endif

@@ -49,7 +49,11 @@ class QgsGeoPackageVectorLayerItem : public QgsGeoPackageAbstractLayerItem
Q_OBJECT
public:
QgsGeoPackageVectorLayerItem( QgsDataItem *parent, QString name, QString path, QString uri, LayerType layerType );

#ifdef HAVE_GUI
QList<QAction *> actions() override;
public slots:
void deleteLayer();
#endif
};


@@ -22,6 +22,7 @@
#include <QFileInfo>
#include <QTextStream>
#include <QAction>
#include <QMessageBox>

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

QGISEXTERN bool deleteLayer( const QString &uri, const QString &errCause );


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


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

#ifdef HAVE_GUI
QList<QAction *> QgsOgrLayerItem::actions()
{
QList<QAction *> lst;
QAction *actionDeleteLayer = new QAction( tr( "Delete %1" ).arg( mName ), this );
connect( actionDeleteLayer, &QAction::triggered, this, &QgsOgrLayerItem::deleteLayer );
lst.append( actionDeleteLayer );
return lst;
}

void QgsOgrLayerItem::deleteLayer()
{
if ( QMessageBox::question( nullptr, QObject::tr( "Delete Layer" ),
QObject::tr( "Are you sure you want to delete %1?" ).arg( mName ),
QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) != QMessageBox::Yes )
return;

QString errCause;
bool res = ::deleteLayer( mUri, errCause );
if ( !res )
{
QMessageBox::warning( nullptr, tr( "Delete Layer" ), errCause );
}
else
{
QMessageBox::information( nullptr, tr( "Delete Layer" ), tr( "Layer deleted successfully." ) );
if ( mParent )
mParent->refresh();
}
}
#endif

// -------

static QgsOgrLayerItem *dataItemForLayer( QgsDataItem *parentItem, QString name, QString path, OGRDataSourceH hDataSource, int layerId )
@@ -29,6 +29,12 @@ class QgsOgrLayerItem : public QgsLayerItem
bool setCrs( const QgsCoordinateReferenceSystem &crs ) override;

QString layerName() const override;

#ifdef HAVE_GUI
QList<QAction *> actions() override;
public slots:
void deleteLayer();
#endif
};


@@ -4297,3 +4297,76 @@ QGISEXTERN void cleanupProvider()
// NOTE: QgsApplication takes care of
// calling OGRCleanupAll();
}



QGISEXTERN bool deleteLayer( const QString &uri, QString &errCause )
{
bool isSubLayer;
int layerIndex;
QString layerName;
QString subsetString;
OGRwkbGeometryType ogrGeometryType;
QString filePath = AnalyzeURI( uri,
isSubLayer,
layerIndex,
layerName,
subsetString,
ogrGeometryType );

OGRDataSourceH hDS = GDALOpenEx( filePath.toLocal8Bit().data(), GDAL_OF_RASTER | GDAL_OF_VECTOR | GDAL_OF_UPDATE, NULL, NULL, NULL );
if ( hDS && ( ! layerName.isEmpty() || layerIndex != -1 ) )
{
if ( layerIndex == -1 )
{
for ( int i = 0; i < GDALDatasetGetLayerCount( hDS ); i++ )
{
OGRLayerH hL = GDALDatasetGetLayer( hDS, i );
if ( layerName == QString( OGR_L_GetName( hL ) ) )
{
layerIndex = i;
}
}
}
OGRErr error = GDALDatasetDeleteLayer( hDS, layerIndex );
switch ( error )
{
case OGRERR_NOT_ENOUGH_DATA:
errCause = QStringLiteral( "Not enough data to deserialize" );
break;
case OGRERR_NOT_ENOUGH_MEMORY:
errCause = QStringLiteral( "Not enough memory" );
break;
case OGRERR_UNSUPPORTED_GEOMETRY_TYPE:
errCause = QStringLiteral( "Unsupported geometry type" );
break;
case OGRERR_UNSUPPORTED_OPERATION:
errCause = QStringLiteral( "Unsupported operation" );
break;
case OGRERR_CORRUPT_DATA:
errCause = QStringLiteral( "Corrupt data" );
break;
case OGRERR_FAILURE:
errCause = QStringLiteral( "Failure" );
break;
case OGRERR_UNSUPPORTED_SRS:
errCause = QStringLiteral( "Unsupported SRS" );
break;
case OGRERR_INVALID_HANDLE:
errCause = QStringLiteral( "Invalid handle" );
break;
case OGRERR_NON_EXISTING_FEATURE:
errCause = QStringLiteral( "Non existing feature" );
break;
default:
case OGRERR_NONE:
errCause = QStringLiteral( "Success" );
break;
}
errCause = QStringLiteral( "OGR result code: %s" ).arg( errCause );
return error == OGRERR_NONE;
}
// This should never happen:
errCause = QStringLiteral( "Layer not found: %s" ).arg( uri );
return false;
}

0 comments on commit da6049e

Please sign in to comment.
You can’t perform that action at this time.