Skip to content
Permalink
Browse files

File browser: use GeoPackage items for gpkg files

  • Loading branch information
elpaso committed Sep 15, 2017
1 parent 9f1f3ea commit ab74ecc3ad6fe8dc20a942d14d01f185b2fe1797
@@ -120,7 +120,7 @@ void QgsGeoPackageRootItem::createDatabase()
#endif


QgsGeoPackageConnectionItem::QgsGeoPackageConnectionItem( QgsDataItem *parent, const QString &name, const QString &path )
QgsGeoPackageCollectionItem::QgsGeoPackageCollectionItem( QgsDataItem *parent, const QString &name, const QString &path )
: QgsDataCollectionItem( parent, name, path )
, mPath( path )
{
@@ -129,7 +129,7 @@ QgsGeoPackageConnectionItem::QgsGeoPackageConnectionItem( QgsDataItem *parent, c



QVector<QgsDataItem *> QgsGeoPackageConnectionItem::createChildren()
QVector<QgsDataItem *> QgsGeoPackageCollectionItem::createChildren()
{
QVector<QgsDataItem *> children;
const auto layers = QgsOgrLayerItem::subLayers( mPath, QStringLiteral( "GPKG" ) );
@@ -148,30 +148,31 @@ QVector<QgsDataItem *> QgsGeoPackageConnectionItem::createChildren()
return children;
}

bool QgsGeoPackageConnectionItem::equal( const QgsDataItem *other )
bool QgsGeoPackageCollectionItem::equal( const QgsDataItem *other )
{
if ( type() != other->type() )
{
return false;
}
const QgsGeoPackageConnectionItem *o = dynamic_cast<const QgsGeoPackageConnectionItem *>( other );
const QgsGeoPackageCollectionItem *o = dynamic_cast<const QgsGeoPackageCollectionItem *>( other );
return o && mPath == o->mPath && mName == o->mName;

}

#ifdef HAVE_GUI

QList<QAction *> QgsGeoPackageConnectionItem::actions()
QList<QAction *> QgsGeoPackageCollectionItem::actions()
{
QList<QAction *> lst;

QAction *actionDeleteConnection = new QAction( tr( "Remove connection" ), this );
connect( actionDeleteConnection, &QAction::triggered, this, &QgsGeoPackageConnectionItem::deleteConnection );
lst.append( actionDeleteConnection );
// Add to stored connections
QAction *actionAddConnection = new QAction( tr( "Add connection" ), this );
connect( actionAddConnection, &QAction::triggered, this, &QgsGeoPackageCollectionItem::addConnection );
lst.append( actionAddConnection );

// Add table to existing DB
QAction *actionAddTable = new QAction( tr( "Create a new layer or table..." ), this );
connect( actionAddTable, &QAction::triggered, this, &QgsGeoPackageConnectionItem::addTable );
connect( actionAddTable, &QAction::triggered, this, &QgsGeoPackageCollectionItem::addTable );
lst.append( actionAddTable );

return lst;
@@ -180,7 +181,7 @@ QList<QAction *> QgsGeoPackageConnectionItem::actions()



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

if ( !QgsMimeDataUtils::isUriList( data ) )
@@ -327,7 +328,7 @@ bool QgsGeoPackageConnectionItem::handleDrop( const QMimeData *data, Qt::DropAct
}


bool QgsGeoPackageConnectionItem::deleteGeoPackageRasterLayer( const QString &uri, QString &errCause )
bool QgsGeoPackageCollectionItem::deleteGeoPackageRasterLayer( const QString &uri, QString &errCause )
{
bool result = false;
// Better safe than sorry
@@ -444,15 +445,49 @@ bool QgsGeoPackageConnectionItem::deleteGeoPackageRasterLayer( const QString &ur
return result;
}

QgsGeoPackageConnectionItem::QgsGeoPackageConnectionItem( QgsDataItem *parent, const QString &name, const QString &path )
: QgsGeoPackageCollectionItem( parent, name, path )
{

}

bool QgsGeoPackageConnectionItem::equal( const QgsDataItem *other )
{
if ( type() != other->type() )
{
return false;
}
const QgsGeoPackageConnectionItem *o = dynamic_cast<const QgsGeoPackageConnectionItem *>( other );
return o && mPath == o->mPath && mName == o->mName;

}

#ifdef HAVE_GUI
QList<QAction *> QgsGeoPackageConnectionItem::actions()
{
QList<QAction *> lst;

QAction *actionDeleteConnection = new QAction( tr( "Remove connection" ), this );
connect( actionDeleteConnection, &QAction::triggered, this, &QgsGeoPackageConnectionItem::deleteConnection );
lst.append( actionDeleteConnection );

// Add table to existing DB
QAction *actionAddTable = new QAction( tr( "Create a new layer or table..." ), this );
connect( actionAddTable, &QAction::triggered, this, &QgsGeoPackageConnectionItem::addTable );
lst.append( actionAddTable );


return lst;
}

void QgsGeoPackageConnectionItem::deleteConnection()
{
QgsOgrDbConnection::deleteConnection( name(), QStringLiteral( "GPKG" ) );
mParent->refreshConnections();
}

#ifdef HAVE_GUI
void QgsGeoPackageConnectionItem::addTable()

void QgsGeoPackageCollectionItem::addTable()
{
QgsNewGeoPackageLayerDialog dialog( nullptr );
QFileInfo fileInfo( mPath );
@@ -472,6 +507,14 @@ void QgsGeoPackageConnectionItem::addTable()
QgsDebugMsg( QStringLiteral( "Cannot add Table: connection %1 does not exists or the path is empy!" ).arg( connName ) );
}
}

void QgsGeoPackageCollectionItem::addConnection()
{
QgsOgrDbConnection connection( mName, QStringLiteral( "GeoPackage" ) );
connection.save();
emit connectionsChanged();
}

#endif

#ifdef HAVE_GUI
@@ -554,7 +597,7 @@ QgsGeoPackageRasterLayerItem::QgsGeoPackageRasterLayerItem( QgsDataItem *parent,

bool QgsGeoPackageRasterLayerItem::executeDeleteLayer( QString &errCause )
{
return QgsGeoPackageConnectionItem::deleteGeoPackageRasterLayer( mUri, errCause );
return QgsGeoPackageCollectionItem::deleteGeoPackageRasterLayer( mUri, errCause );
}


@@ -64,12 +64,16 @@ class QgsGeoPackageVectorLayerItem : public QgsGeoPackageAbstractLayerItem
};


class QgsGeoPackageConnectionItem : public QgsDataCollectionItem
/**
* \brief The QgsGeoPackageCollectionItem class is the base class for
* GeoPackage container
*/
class QgsGeoPackageCollectionItem : public QgsDataCollectionItem
{
Q_OBJECT

public:
QgsGeoPackageConnectionItem( QgsDataItem *parent, const QString &name, const QString &path );
QgsGeoPackageCollectionItem( QgsDataItem *parent, const QString &name, const QString &path );
QVector<QgsDataItem *> createChildren() override;
virtual bool equal( const QgsDataItem *other ) override;

@@ -87,16 +91,40 @@ class QgsGeoPackageConnectionItem : public QgsDataCollectionItem

public slots:
#ifdef HAVE_GUI
void editConnection();
void deleteConnection();
void addTable();
void addConnection();
#endif

protected:
QString mPath;
};


/**
* \brief The QgsGeoPackageConnectionItem class adds the stored
* connection management to QgsGeoPackageCollectionItem
*/
class QgsGeoPackageConnectionItem : public QgsGeoPackageCollectionItem
{
Q_OBJECT

public:
QgsGeoPackageConnectionItem( QgsDataItem *parent, const QString &name, const QString &path );
virtual bool equal( const QgsDataItem *other ) override;

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

public slots:
#ifdef HAVE_GUI
void editConnection();
void deleteConnection();
#endif

};


class QgsGeoPackageRootItem : public QgsDataCollectionItem
{
Q_OBJECT
@@ -22,6 +22,7 @@
#include "qgsproject.h"
#include "qgsvectorlayer.h"
#include "qgsrasterlayer.h"
#include "qgsgeopackagedataitems.h"

#include <QFileInfo>
#include <QTextStream>
@@ -567,9 +568,19 @@ QGISEXTERN QgsDataItem *dataItem( QString path, QgsDataItem *parentItem )
#endif
}

// return item without testing if:
// scanExtSetting
// or zipfile and scan zip == "Basic scan"
// Filters out the OGR/GDAL supported formats that can contain multiple layers
// and should be treated like a DB: GeoPackage and SQLite
// NOTE: this formats are scanned for rasters too and they must
// be skipped by "gdal" provider or the rasters will be listed
// twice. ogrSupportedDbLayersExtensions must be kept in sync
// with the companion variable (same name) in the gdal provider
// class
// TODO: add more OGR supported multiple layers formats here!
QStringList ogrSupportedDbLayersExtensions;
ogrSupportedDbLayersExtensions << QLatin1String( "gpkg" ) << QLatin1String( "sqlite" ) << QLatin1String( "db" );

// Fast track: return item without testing if:
// scanExtSetting or zipfile and scan zip == "Basic scan"
if ( scanExtSetting ||
( ( is_vsizip || is_vsitar ) && scanZipSetting == QLatin1String( "basic" ) ) )
{
@@ -596,13 +607,18 @@ QGISEXTERN QgsDataItem *dataItem( QString path, QgsDataItem *parentItem )
// Handle collections
// Check if the layer has sublayers by comparing the extension
QgsDataItem *item;
QStringList multipleLayersExtensions;
// TODO: add more OGR supported multiple layers formats here!
multipleLayersExtensions << QLatin1String( "gpkg" ) << QLatin1String( "sqlite" ) << QLatin1String( "db" );
if ( ! multipleLayersExtensions.contains( suffix ) )
if ( ! ogrSupportedDbLayersExtensions.contains( suffix ) )
{
item = new QgsOgrLayerItem( parentItem, name, path, path, QgsLayerItem::Vector );
}
else if ( suffix.compare( QLatin1String( "gpkg" ), Qt::CaseInsensitive ) == 0 )
{
item = new QgsGeoPackageCollectionItem( parentItem, name, path );
}
else
{
item = new QgsOgrDataCollectionItem( parentItem, name, path );
}

if ( item )
return item;
@@ -625,10 +641,9 @@ QGISEXTERN QgsDataItem *dataItem( QString path, QgsDataItem *parentItem )

QgsDebugMsgLevel( QString( "GDAL Driver : %1" ).arg( GDALGetDriverShortName( hDriver ) ), 2 );

int numLayers = GDALDatasetGetLayerCount( hDataSource );

QgsDataItem *item = nullptr;

int numLayers = OGR_DS_GetLayerCount( hDataSource );
if ( numLayers == 1 )
{
QgsDebugMsgLevel( QString( "using name = %1" ).arg( name ), 2 );
@@ -639,6 +654,10 @@ QGISEXTERN QgsDataItem *dataItem( QString path, QgsDataItem *parentItem )
QgsDebugMsgLevel( QString( "using name = %1" ).arg( name ), 2 );
item = new QgsOgrDataCollectionItem( parentItem, name, path );
}
else if ( suffix.compare( QLatin1String( "gpkg" ), Qt::CaseInsensitive ) == 0 )
{
item = new QgsGeoPackageCollectionItem( parentItem, name, path );
}

GDALClose( hDataSource );
return item;

0 comments on commit ab74ecc

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