Skip to content

Commit

Permalink
Allow data item providers to override default directory handling
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson authored and elpaso committed Sep 19, 2017
1 parent ac6eaa8 commit a6b6892
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 3 deletions.
16 changes: 16 additions & 0 deletions python/core/qgsdataitemprovider.sip
Expand Up @@ -10,6 +10,8 @@





class QgsDataItemProvider
{
%Docstring
Expand Down Expand Up @@ -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
};

/************************************************************************
Expand Down
17 changes: 16 additions & 1 deletion src/core/qgsdataitem.cpp
Expand Up @@ -703,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 )
{
Expand All @@ -719,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

Expand Down Expand Up @@ -755,7 +770,7 @@ QVector<QgsDataItem *> QgsDirectoryItem::createChildren()
}
}

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

Expand Down
5 changes: 5 additions & 0 deletions src/core/qgsdataitemprovider.cpp
Expand Up @@ -16,3 +16,8 @@
#include "qgsdataitemprovider.h"

// no implementation currently

bool QgsDataItemProvider::handlesDirectoryPath( const QString & )
{
return false;
}
17 changes: 17 additions & 0 deletions src/core/qgsdataitemprovider.h
Expand Up @@ -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.
*
Expand Down Expand Up @@ -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
16 changes: 14 additions & 2 deletions src/core/qgsdataitemproviderregistry.cpp
Expand Up @@ -36,10 +36,11 @@ typedef QList<QgsDataItemProvider *> *dataItemProviders_t();
class QgsDataItemProviderFromPlugin : public QgsDataItemProvider
{
public:
QgsDataItemProviderFromPlugin( const QString &name, dataCapabilities_t *capabilitiesFunc, dataItem_t *dataItemFunc )
QgsDataItemProviderFromPlugin( const QString &name, dataCapabilities_t *capabilitiesFunc, dataItem_t *dataItemFunc, handlesDirectoryPath_t *handlesDirectoryPathFunc )
: mName( name )
, mCapabilitiesFunc( capabilitiesFunc )
, mDataItemFunc( dataItemFunc )
, mHandlesDirectoryPathFunc( handlesDirectoryPathFunc )
{
}

Expand All @@ -49,10 +50,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;
};


Expand Down Expand Up @@ -93,7 +103,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 ) );
}
}

Expand Down
9 changes: 9 additions & 0 deletions src/providers/ogr/qgsogrdataitems.cpp
Expand Up @@ -668,3 +668,12 @@ QGISEXTERN QgsDataItem *dataItem( QString path, QgsDataItem *parentItem )
OGR_DS_Destroy( hDataSource );
return item;
}

QGISEXTERN bool handlesDirectoryPath( const QString &path )
{
QFileInfo info( path );
QString suffix = info.suffix().toLower();

QStringList dirExtensions = directoryExtensions();
return dirExtensions.contains( suffix );
}

0 comments on commit a6b6892

Please sign in to comment.