Skip to content
Permalink
Browse files

Merge pull request #5212 from boundlessgeo/browser_homogenize

Geopackage: browser homogenize
  • Loading branch information
elpaso committed Sep 19, 2017
2 parents e05f266 + a5647c7 commit b0892488be7ee4544a81b40338d75fc76f6139d5
@@ -10,6 +10,8 @@





class QgsDataItemProvider
{
%Docstring
@@ -54,6 +56,20 @@ Caller takes responsibility of deleting created items.
Caller takes responsibility of deleting created items.
:rtype: list of QgsDataItem
%End

virtual bool handlesDirectoryPath( const QString &path );
%Docstring
Returns true if the provider will handle the directory at the specified ``path``.

If the provider indicates that it will handle the directory, the default creation and
population of directory items for the path will be avoided and it is left to the
provider to correctly populate relevant entries for the path.

The default implementation returns false for all paths.

.. versionadded:: 3.0
:rtype: bool
%End
};

/************************************************************************
@@ -9690,7 +9690,7 @@ bool QgisApp::setActiveLayer( QgsMapLayer *layer )

void QgisApp::reloadConnections()
{
emit( connectionsChanged( ) );
emit connectionsChanged( );
}


@@ -345,8 +345,16 @@ void QgsDataItem::refresh()

void QgsDataItem::refreshConnections()
{
refresh();
emit connectionsChanged();
// Walk up until the root node is reached
if ( mParent )
{
mParent->refreshConnections();
}
else
{
refresh();
emit connectionsChanged();
}
}

void QgsDataItem::refresh( const QVector<QgsDataItem *> &children )
@@ -695,6 +703,8 @@ QVector<QgsDataItem *> QgsDirectoryItem::createChildren()
QVector<QgsDataItem *> children;
QDir dir( mDirPath );

const QList<QgsDataItemProvider *> providers = QgsApplication::dataItemProviderRegistry()->providers();

QStringList entries = dir.entryList( QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name | QDir::IgnoreCase );
Q_FOREACH ( const QString &subdir, entries )
{
@@ -711,6 +721,19 @@ QVector<QgsDataItem *> QgsDirectoryItem::createChildren()
QString path = mPath + '/' + subdir; // may differ from subdirPath
if ( QgsDirectoryItem::hiddenPath( path ) )
continue;

bool handledByProvider = false;
for ( QgsDataItemProvider *provider : providers )
{
if ( provider->handlesDirectoryPath( path ) )
{
handledByProvider = true;
break;
}
}
if ( handledByProvider )
continue;

QgsDirectoryItem *item = new QgsDirectoryItem( this, subdir, subdirPath, path );
// propagate signals up to top

@@ -747,7 +770,7 @@ QVector<QgsDataItem *> QgsDirectoryItem::createChildren()
}
}

Q_FOREACH ( QgsDataItemProvider *provider, QgsApplication::dataItemProviderRegistry()->providers() )
for ( QgsDataItemProvider *provider : providers )
{
int capabilities = provider->capabilities();

@@ -1312,7 +1335,6 @@ QVector<QgsDataItem *> QgsZipItem::createChildren()
// the item comes with zipped file name, set the name to relative path within zip file
item->setName( fileName );
children.append( item );
break;
}
else
{
@@ -16,3 +16,8 @@
#include "qgsdataitemprovider.h"

// no implementation currently

bool QgsDataItemProvider::handlesDirectoryPath( const QString & )
{
return false;
}
@@ -24,6 +24,10 @@ class QgsDataItem;

class QString;

//! handlesDirectoryPath function
typedef bool handlesDirectoryPath_t( const QString &path ) SIP_SKIP;


/** \ingroup core
* This is the interface for those who want to add custom data items to the browser tree.
*
@@ -54,6 +58,19 @@ class CORE_EXPORT QgsDataItemProvider
//! Create a vector of instances of QgsDataItem (or null) for given path and parent item.
//! Caller takes responsibility of deleting created items.
virtual QVector<QgsDataItem *> createDataItems( const QString &path, QgsDataItem *parentItem ) { Q_UNUSED( path ); Q_UNUSED( parentItem ); return QVector<QgsDataItem *>(); }

/**
* Returns true if the provider will handle the directory at the specified \a path.
*
* If the provider indicates that it will handle the directory, the default creation and
* population of directory items for the path will be avoided and it is left to the
* provider to correctly populate relevant entries for the path.
*
* The default implementation returns false for all paths.
*
* \since QGIS 3.0
*/
virtual bool handlesDirectoryPath( const QString &path );
};

#endif // QGSDATAITEMPROVIDER_H
@@ -36,10 +36,19 @@ typedef QList<QgsDataItemProvider *> *dataItemProviders_t();
class QgsDataItemProviderFromPlugin : public QgsDataItemProvider
{
public:
QgsDataItemProviderFromPlugin( const QString &name, dataCapabilities_t *capabilitiesFunc, dataItem_t *dataItemFunc )

/**
* QgsDataItemProviderFromPlugin constructor
* \param name plugin name
* \param capabilitiesFunc function pointer to the data capabilities
* \param dataItemFunc function pointer to the data items
* \param handlesDirectoryPathFunc function pointer to handlesDirectoryPath
*/
QgsDataItemProviderFromPlugin( const QString &name, dataCapabilities_t *capabilitiesFunc, dataItem_t *dataItemFunc, handlesDirectoryPath_t *handlesDirectoryPathFunc )
: mName( name )
, mCapabilitiesFunc( capabilitiesFunc )
, mDataItemFunc( dataItemFunc )
, mHandlesDirectoryPathFunc( handlesDirectoryPathFunc )
{
}

@@ -49,10 +58,19 @@ class QgsDataItemProviderFromPlugin : public QgsDataItemProvider

QgsDataItem *createDataItem( const QString &path, QgsDataItem *parentItem ) override { return mDataItemFunc( path, parentItem ); }

bool handlesDirectoryPath( const QString &path ) override
{
if ( mHandlesDirectoryPathFunc )
return mHandlesDirectoryPathFunc( path );
else
return false;
}

protected:
QString mName;
dataCapabilities_t *mCapabilitiesFunc = nullptr;
dataItem_t *mDataItemFunc = nullptr;
handlesDirectoryPath_t *mHandlesDirectoryPathFunc = nullptr;
};


@@ -93,7 +111,9 @@ QgsDataItemProviderRegistry::QgsDataItemProviderRegistry()
continue;
}

mProviders.append( new QgsDataItemProviderFromPlugin( library->fileName(), dataCapabilities, dataItem ) );
handlesDirectoryPath_t *handlesDirectoryPath = reinterpret_cast< handlesDirectoryPath_t * >( cast_to_fptr( library->resolve( "handlesDirectoryPath" ) ) );

mProviders.append( new QgsDataItemProviderFromPlugin( library->fileName(), dataCapabilities, dataItem, handlesDirectoryPath ) );
}
}

@@ -241,12 +241,32 @@ QGISEXTERN QgsDataItem *dataItem( QString path, QgsDataItem *parentItem )
#endif
}

// 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 are handled
// by the "ogr" provider. For this reason 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 ogr provider
// class
// TODO: add more OGR supported multiple layers formats here!
QStringList ogrSupportedDbLayersExtensions;
ogrSupportedDbLayersExtensions << QLatin1String( "gpkg" ) << QLatin1String( "sqlite" ) << QLatin1String( "db" ) << QLatin1String( "gdb" );
QStringList ogrSupportedDbDriverNames;
ogrSupportedDbDriverNames << QLatin1String( "GPKG" ) << QLatin1String( "db" ) << QLatin1String( "gdb" );

// return item without testing if:
// scanExtSetting
// or zipfile and scan zip == "Basic scan"
if ( scanExtSetting ||
( ( is_vsizip || is_vsitar ) && scanZipSetting == QLatin1String( "basic" ) ) )
{
// Skip this layer if it's handled by ogr:
if ( ogrSupportedDbLayersExtensions.contains( suffix ) )
{
return nullptr;
}

// if this is a VRT file make sure it is raster VRT to avoid duplicates
if ( suffix == QLatin1String( "vrt" ) )
{
@@ -283,6 +303,15 @@ QGISEXTERN QgsDataItem *dataItem( QString path, QgsDataItem *parentItem )
return nullptr;
}

GDALDriverH hDriver = GDALGetDatasetDriver( hDS );
QString ogrDriverName = GDALGetDriverShortName( hDriver );

// Skip this layer if it's handled by ogr:
if ( ogrSupportedDbDriverNames.contains( ogrDriverName ) )
{
return nullptr;
}

QStringList sublayers = QgsGdalProvider::subLayers( hDS );

GDALClose( hDS );

0 comments on commit b089248

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