Skip to content

Commit

Permalink
Geopackage moved delete to abstract item and implement raster deletion
Browse files Browse the repository at this point in the history
  • Loading branch information
elpaso committed Aug 17, 2017
1 parent 26a911c commit f999897
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 58 deletions.
148 changes: 105 additions & 43 deletions src/providers/ogr/qgsgeopackagedataitems.cpp
Expand Up @@ -13,6 +13,8 @@
* *
***************************************************************************/

#include "sqlite3.h"

#include "qgsgeopackagedataitems.h"
#include "qgsgeopackageconnection.h"
#include "qgslogger.h"
Expand Down Expand Up @@ -69,6 +71,7 @@ QVector<QgsDataItem *> QgsGeoPackageRootItem::createChildren()
return connections;
}

#ifdef HAVE_GUI
QList<QAction *> QgsGeoPackageRootItem::actions()
{
QList<QAction *> lst;
Expand All @@ -88,7 +91,7 @@ QWidget *QgsGeoPackageRootItem::paramWidget()
{
return nullptr;
}

#endif

void QgsGeoPackageRootItem::connectionsChanged()
{
Expand Down Expand Up @@ -214,16 +217,15 @@ QVector<QgsDataItem *> QgsGeoPackageConnectionItem::createChildren()
uri = QStringLiteral( "%1|layerid=%2" ).arg( mPath, layerId );
}
QgsGeoPackageVectorLayerItem *item = new QgsGeoPackageVectorLayerItem( this, name, mPath, uri, layerType );
QgsDebugMsgLevel( QStringLiteral( "Adding GPKG Vector item %1 %2 %3" ).arg( name, uri, geometryType ), 3 );
QgsDebugMsgLevel( QStringLiteral( "Adding GeoPackage Vector item %1 %2 %3" ).arg( name, uri, geometryType ), 3 );
children.append( item );
}
}
else
{
QgsDebugMsgLevel( QStringLiteral( "Layer type is not a supported GeoPackage Vector layer %1" ).arg( mPath ), 3 );
}
QgsDebugMsgLevel( QStringLiteral( "Adding GPKG Vector item %1 %2 %3" ).arg( name, uri, geometryType ), 3 );
qDebug() << QStringLiteral( "Adding GPKG Vector item %1 %2 %3" ).arg( name, uri, geometryType );
QgsDebugMsgLevel( QStringLiteral( "Adding GeoPackage Vector item %1 %2 %3" ).arg( name, uri, geometryType ), 3 );
}
}
}
Expand All @@ -233,7 +235,7 @@ QVector<QgsDataItem *> QgsGeoPackageConnectionItem::createChildren()
{
QStringList pieces = uri.split( ':' );
QString name = pieces.value( pieces.length() - 1 );
QgsDebugMsg( QStringLiteral( "Adding GPKG Raster item %1 %2 %3" ).arg( name, uri ) );
QgsDebugMsgLevel( QStringLiteral( "Adding GeoPackage Raster item %1 %2 %3" ).arg( name, uri ), 3 );
QgsGeoPackageRasterLayerItem *item = new QgsGeoPackageRasterLayerItem( this, name, mPath, uri );
children.append( item );

Expand Down Expand Up @@ -361,7 +363,7 @@ bool QgsGeoPackageConnectionItem::handleDrop( const QMimeData *data, Qt::DropAct
}
else
{
// TODO: implemnent raster import
// TODO: implement 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 );
Expand Down Expand Up @@ -441,44 +443,14 @@ void QgsGeoPackageConnectionItem::addTable()
QList<QAction *> QgsGeoPackageAbstractLayerItem::actions()
{
QList<QAction *> lst;
// TODO: delete layer when the provider supports it (not currently implemented)
return lst;
}
#endif

QgsGeoPackageAbstractLayerItem::QgsGeoPackageAbstractLayerItem( QgsDataItem *parent, QString name, QString path, QString uri, QgsLayerItem::LayerType layerType, QString providerKey )
: QgsLayerItem( parent, name, path, uri, layerType, providerKey )
{
setState( Populated ); // no children are expected
}


QgsGeoPackageVectorLayerItem::QgsGeoPackageVectorLayerItem( QgsDataItem *parent, QString name, QString path, QString uri, LayerType layerType )
: QgsGeoPackageAbstractLayerItem( parent, name, path, uri, layerType, QStringLiteral( "ogr" ) )
{

}


QgsGeoPackageRasterLayerItem::QgsGeoPackageRasterLayerItem( QgsDataItem *parent, QString name, QString path, QString uri )
: QgsGeoPackageAbstractLayerItem( parent, name, path, uri, QgsLayerItem::LayerType::Raster, QStringLiteral( "gdal" ) )
{

}


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


void QgsGeoPackageVectorLayerItem::deleteLayer()
void QgsGeoPackageAbstractLayerItem::deleteLayer()
{
// Check if the layer is in the registry
const QgsMapLayer *projectLayer = nullptr;
Expand All @@ -492,12 +464,12 @@ void QgsGeoPackageVectorLayerItem::deleteLayer()
if ( ! projectLayer )
{
if ( QMessageBox::question( nullptr, QObject::tr( "Delete Layer" ),
QObject::tr( "Are you sure you want to delete layer '%1' from GeoPackage?" ).arg( mName ),
QObject::tr( "Are you sure you want to delete layer <b>%1</b> from GeoPackage?" ).arg( mName ),
QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) != QMessageBox::Yes )
return;

QString errCause;
bool res = ::deleteLayer( mUri, errCause );
bool res = executeDeleteLayer( errCause );
if ( !res )
{
QMessageBox::warning( nullptr, tr( "Delete Layer" ), errCause );
Expand All @@ -511,9 +483,99 @@ void QgsGeoPackageVectorLayerItem::deleteLayer()
}
else
{
QMessageBox::warning( nullptr, QObject::tr( "Delete Layer" ), QObject::tr( "The layer '%1' cannot be deleted because it is in the current project as '%2',"
QMessageBox::warning( nullptr, QObject::tr( "Delete Layer" ), QObject::tr( "The layer <b>%1</b> cannot be deleted because it is in the current project as <b>%2</b>,"
" remove it from the project and retry." ).arg( mName, projectLayer->name() ) );
}

}

QgsGeoPackageAbstractLayerItem::QgsGeoPackageAbstractLayerItem( QgsDataItem *parent, QString name, QString path, QString uri, QgsLayerItem::LayerType layerType, QString providerKey )
: QgsLayerItem( parent, name, path, uri, layerType, providerKey )
{
setState( Populated ); // no children are expected
}

bool QgsGeoPackageAbstractLayerItem::executeDeleteLayer( QString &errCause )
{
errCause = QObject::tr( "The layer <b>%1</b> cannot be deleted because the this feature is not yet implemented for this kind of layers." ).arg( mName );
return false;
}


QgsGeoPackageVectorLayerItem::QgsGeoPackageVectorLayerItem( QgsDataItem *parent, QString name, QString path, QString uri, LayerType layerType )
: QgsGeoPackageAbstractLayerItem( parent, name, path, uri, layerType, QStringLiteral( "ogr" ) )
{

}


QgsGeoPackageRasterLayerItem::QgsGeoPackageRasterLayerItem( QgsDataItem *parent, QString name, QString path, QString uri )
: QgsGeoPackageAbstractLayerItem( parent, name, path, uri, QgsLayerItem::LayerType::Raster, QStringLiteral( "gdal" ) )
{

}

bool QgsGeoPackageRasterLayerItem::executeDeleteLayer( QString &errCause )
{
bool result = false;
// Better safe than sorry
if ( ! mUri.isEmpty( ) )
{
QStringList pieces( mUri.split( ':' ) );
if ( pieces.size() != 3 )
{
errCause = QStringLiteral( "Layer URI is malformed: layer <b>%1</b> cannot be deleted!" ).arg( mName );
}
else
{
QString baseUri = pieces.at( 1 );
QString layerName = pieces.at( 2 );
sqlite3 *handle;
int status = sqlite3_open_v2( baseUri.toLocal8Bit().data(), &handle, SQLITE_OPEN_READWRITE, NULL );
if ( status != SQLITE_OK )
{
errCause = sqlite3_errmsg( handle );
}
else
{
// Remove table
QString sql;
char *errmsg = NULL;
sql = QStringLiteral( "DROP table %1;"
"DELETE FROM gpkg_contents WHERE table_name = '%1';"
"DELETE FROM gpkg_tile_matrix WHERE table_name = '%1';"
"DELETE FROM gpkg_tile_matrix_set WHERE table_name = '%1';" ).arg( layerName );
status = sqlite3_exec(
handle, /* An open database */
sql.toLocal8Bit().data(), /* SQL to be evaluated */
NULL, /* Callback function */
NULL, /* 1st argument to callback */
&errmsg /* Error msg written here */
);
if ( status == SQLITE_OK )
{
result = true;
}
else
{
errCause = tr( "There was an error deleting the layer: %1" ).arg( errmsg );
sqlite3_free( errmsg );
}
}
sqlite3_close_v2( handle );
}
}
else
{
// This should never happen!
errCause = QStringLiteral( "Layer URI is empty: layer <b>%1</b> cannot be deleted!" ).arg( mName );
}
return result;
}


bool QgsGeoPackageVectorLayerItem::executeDeleteLayer( QString &errCause )
{
return ::deleteLayer( mUri, errCause );
}
#endif

33 changes: 18 additions & 15 deletions src/providers/ogr/qgsgeopackagedataitems.h
Expand Up @@ -29,49 +29,55 @@ class QgsGeoPackageAbstractLayerItem : public QgsLayerItem
protected:
QgsGeoPackageAbstractLayerItem( QgsDataItem *parent, QString name, QString path, QString uri, LayerType layerType, QString providerKey );

/** Subclasses need to implement this function with
* the real deletion implementation
*/
virtual bool executeDeleteLayer( QString &errCause );
#ifdef HAVE_GUI
QList<QAction *> actions() override;
QList<QAction *> actions();
public slots:
virtual void deleteLayer();
#endif
};


class QgsGeoPackageRasterLayerItem : public QgsGeoPackageAbstractLayerItem
{
Q_OBJECT

public:
QgsGeoPackageRasterLayerItem( QgsDataItem *parent, QString name, QString path, QString uri );

protected:
virtual bool executeDeleteLayer( QString &errCause ) override;
};


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
protected:
virtual bool executeDeleteLayer( QString &errCause ) override;
};


class QgsGeoPackageConnectionItem : public QgsDataCollectionItem
{
Q_OBJECT

public:
QgsGeoPackageConnectionItem( QgsDataItem *parent, QString name, QString path );

QVector<QgsDataItem *> createChildren() override;
virtual bool equal( const QgsDataItem *other ) override;

#ifdef HAVE_GUI
virtual QList<QAction *> actions() override;
#endif

virtual bool acceptDrop() override { return true; }
virtual bool handleDrop( const QMimeData *data, Qt::DropAction action ) override;
QList<QAction *> actions();
#endif

//! Return the layer type from \a geometryType
static QgsLayerItem::LayerType layerTypeFromDb( const QString &geometryType );
Expand All @@ -91,19 +97,18 @@ class QgsGeoPackageConnectionItem : public QgsDataCollectionItem
class QgsGeoPackageRootItem : public QgsDataCollectionItem
{
Q_OBJECT

public:
QgsGeoPackageRootItem( QgsDataItem *parent, QString name, QString path );
~QgsGeoPackageRootItem();

QVector<QgsDataItem *> createChildren() override;

#ifdef HAVE_GUI
virtual QList<QAction *> actions() override;
virtual QWidget *paramWidget() override;
#endif
QList<QAction *> actions();

public slots:
#ifdef HAVE_GUI
void newConnection();
void connectionsChanged();
void createDatabase();
Expand All @@ -120,9 +125,7 @@ class QgsGeoPackageDataItemProvider : public QgsDataItemProvider
{
public:
virtual QString name() override { return QStringLiteral( "GPKG" ); }

virtual int capabilities() override { return QgsDataProvider::Database; }

virtual QgsDataItem *createDataItem( const QString &path, QgsDataItem *parentItem ) override;
};

Expand Down

0 comments on commit f999897

Please sign in to comment.