Skip to content

Commit a6b6892

Browse files
nyalldawsonelpaso
authored andcommitted
Allow data item providers to override default directory handling
1 parent ac6eaa8 commit a6b6892

File tree

6 files changed

+77
-3
lines changed

6 files changed

+77
-3
lines changed

python/core/qgsdataitemprovider.sip

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111

1212

13+
14+
1315
class QgsDataItemProvider
1416
{
1517
%Docstring
@@ -54,6 +56,20 @@ Caller takes responsibility of deleting created items.
5456
Caller takes responsibility of deleting created items.
5557
:rtype: list of QgsDataItem
5658
%End
59+
60+
virtual bool handlesDirectoryPath( const QString &path );
61+
%Docstring
62+
Returns true if the provider will handle the directory at the specified ``path``.
63+
64+
If the provider indicates that it will handle the directory, the default creation and
65+
population of directory items for the path will be avoided and it is left to the
66+
provider to correctly populate relevant entries for the path.
67+
68+
The default implementation returns false for all paths.
69+
70+
.. versionadded:: 3.0
71+
:rtype: bool
72+
%End
5773
};
5874

5975
/************************************************************************

src/core/qgsdataitem.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,8 @@ QVector<QgsDataItem *> QgsDirectoryItem::createChildren()
703703
QVector<QgsDataItem *> children;
704704
QDir dir( mDirPath );
705705

706+
const QList<QgsDataItemProvider *> providers = QgsApplication::dataItemProviderRegistry()->providers();
707+
706708
QStringList entries = dir.entryList( QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name | QDir::IgnoreCase );
707709
Q_FOREACH ( const QString &subdir, entries )
708710
{
@@ -719,6 +721,19 @@ QVector<QgsDataItem *> QgsDirectoryItem::createChildren()
719721
QString path = mPath + '/' + subdir; // may differ from subdirPath
720722
if ( QgsDirectoryItem::hiddenPath( path ) )
721723
continue;
724+
725+
bool handledByProvider = false;
726+
for ( QgsDataItemProvider *provider : providers )
727+
{
728+
if ( provider->handlesDirectoryPath( path ) )
729+
{
730+
handledByProvider = true;
731+
break;
732+
}
733+
}
734+
if ( handledByProvider )
735+
continue;
736+
722737
QgsDirectoryItem *item = new QgsDirectoryItem( this, subdir, subdirPath, path );
723738
// propagate signals up to top
724739

@@ -755,7 +770,7 @@ QVector<QgsDataItem *> QgsDirectoryItem::createChildren()
755770
}
756771
}
757772

758-
Q_FOREACH ( QgsDataItemProvider *provider, QgsApplication::dataItemProviderRegistry()->providers() )
773+
for ( QgsDataItemProvider *provider : providers )
759774
{
760775
int capabilities = provider->capabilities();
761776

src/core/qgsdataitemprovider.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,8 @@
1616
#include "qgsdataitemprovider.h"
1717

1818
// no implementation currently
19+
20+
bool QgsDataItemProvider::handlesDirectoryPath( const QString & )
21+
{
22+
return false;
23+
}

src/core/qgsdataitemprovider.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ class QgsDataItem;
2424

2525
class QString;
2626

27+
//! handlesDirectoryPath function
28+
typedef bool handlesDirectoryPath_t( const QString &path ) SIP_SKIP;
29+
30+
2731
/** \ingroup core
2832
* This is the interface for those who want to add custom data items to the browser tree.
2933
*
@@ -54,6 +58,19 @@ class CORE_EXPORT QgsDataItemProvider
5458
//! Create a vector of instances of QgsDataItem (or null) for given path and parent item.
5559
//! Caller takes responsibility of deleting created items.
5660
virtual QVector<QgsDataItem *> createDataItems( const QString &path, QgsDataItem *parentItem ) { Q_UNUSED( path ); Q_UNUSED( parentItem ); return QVector<QgsDataItem *>(); }
61+
62+
/**
63+
* Returns true if the provider will handle the directory at the specified \a path.
64+
*
65+
* If the provider indicates that it will handle the directory, the default creation and
66+
* population of directory items for the path will be avoided and it is left to the
67+
* provider to correctly populate relevant entries for the path.
68+
*
69+
* The default implementation returns false for all paths.
70+
*
71+
* \since QGIS 3.0
72+
*/
73+
virtual bool handlesDirectoryPath( const QString &path );
5774
};
5875

5976
#endif // QGSDATAITEMPROVIDER_H

src/core/qgsdataitemproviderregistry.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,11 @@ typedef QList<QgsDataItemProvider *> *dataItemProviders_t();
3636
class QgsDataItemProviderFromPlugin : public QgsDataItemProvider
3737
{
3838
public:
39-
QgsDataItemProviderFromPlugin( const QString &name, dataCapabilities_t *capabilitiesFunc, dataItem_t *dataItemFunc )
39+
QgsDataItemProviderFromPlugin( const QString &name, dataCapabilities_t *capabilitiesFunc, dataItem_t *dataItemFunc, handlesDirectoryPath_t *handlesDirectoryPathFunc )
4040
: mName( name )
4141
, mCapabilitiesFunc( capabilitiesFunc )
4242
, mDataItemFunc( dataItemFunc )
43+
, mHandlesDirectoryPathFunc( handlesDirectoryPathFunc )
4344
{
4445
}
4546

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

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

53+
bool handlesDirectoryPath( const QString &path ) override
54+
{
55+
if ( mHandlesDirectoryPathFunc )
56+
return mHandlesDirectoryPathFunc( path );
57+
else
58+
return false;
59+
}
60+
5261
protected:
5362
QString mName;
5463
dataCapabilities_t *mCapabilitiesFunc = nullptr;
5564
dataItem_t *mDataItemFunc = nullptr;
65+
handlesDirectoryPath_t *mHandlesDirectoryPathFunc = nullptr;
5666
};
5767

5868

@@ -93,7 +103,9 @@ QgsDataItemProviderRegistry::QgsDataItemProviderRegistry()
93103
continue;
94104
}
95105

96-
mProviders.append( new QgsDataItemProviderFromPlugin( library->fileName(), dataCapabilities, dataItem ) );
106+
handlesDirectoryPath_t *handlesDirectoryPath = reinterpret_cast< handlesDirectoryPath_t * >( cast_to_fptr( library->resolve( "handlesDirectoryPath" ) ) );
107+
108+
mProviders.append( new QgsDataItemProviderFromPlugin( library->fileName(), dataCapabilities, dataItem, handlesDirectoryPath ) );
97109
}
98110
}
99111

src/providers/ogr/qgsogrdataitems.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,3 +668,12 @@ QGISEXTERN QgsDataItem *dataItem( QString path, QgsDataItem *parentItem )
668668
OGR_DS_Destroy( hDataSource );
669669
return item;
670670
}
671+
672+
QGISEXTERN bool handlesDirectoryPath( const QString &path )
673+
{
674+
QFileInfo info( path );
675+
QString suffix = info.suffix().toLower();
676+
677+
QStringList dirExtensions = directoryExtensions();
678+
return dirExtensions.contains( suffix );
679+
}

0 commit comments

Comments
 (0)