22#include "qgsgeopackagedataitems.h"
24#include "qgsogrproviderutils.h"
35#include "moc_qgsfilebaseddataitemprovider.cpp"
59 if ( mDetails.driverName() == QLatin1String(
"SQLite" ) )
62 path() + QStringLiteral(
"/columns/ " ),
63 QStringLiteral( R
"(dbname="%1")" ).arg( parent()->path().replace( '"', QLatin1String( R
"(\")" ) ) ),
64 QStringLiteral( "spatialite" ), QString(),
name() ) );
66 else if ( mDetails.providerKey() == QLatin1String(
"ogr" ) )
71 path() + QStringLiteral(
"/columns/ " ),
73 QStringLiteral(
"ogr" ), QString(),
name() ) );
78 QString relationError;
79 QList< QgsWeakRelation > relations;
82 relations = conn->relationships( QString(), mDetails.name() );
86 relationError = ex.
what();
89 if ( !relations.empty() || !relationError.isEmpty() )
91 auto relationsItem = std::make_unique< QgsRelationshipsItem >(
this,
mPath +
"/relations", conn->uri(), QStringLiteral(
"ogr" ), QString(), mDetails.name() );
93 relationsItem->setSortKey( QString( QChar( 0x11FFFF ) ) );
94 children.append( relationsItem.release() );
115 if ( mDetails.providerKey() == QLatin1String(
"ogr" ) )
120 parts.insert( QStringLiteral(
"path" ),
path() );
130 switch ( sublayer.
type() )
181 return mDetails.name();
191 mIconName = QStringLiteral(
"mIconDbSchema.svg" );
196 mSublayers.append( sublayer );
207 res.reserve( mSublayers.size() );
223 , mExtraUriParts( extraUriParts )
232 mIconName = QStringLiteral(
"/mIconZip.svg" );
238 QList< QgsProviderSublayerDetails>
sublayers;
241 QSet< QString > providers;
244 providers.insert( details.providerKey() );
247 for (
const QString &provider : std::as_const( providers ) )
251 if ( !mExtraUriParts.empty() )
253 QVariantMap uriParts = metadata->decodeUri(
path() );
254 for (
auto it = mExtraUriParts.constBegin(); it != mExtraUriParts.constEnd(); ++it )
256 uriParts.insert( it.key(), it.value() );
258 const QString updatedUri = metadata->encodeUri( uriParts );
269 else if ( mSublayers.empty() )
285 QMap< QStringList, QgsFileDataCollectionGroupItem * > groupItems;
290 if ( !sublayer.
path().isEmpty() )
292 QStringList currentPath;
293 QStringList remainingPaths = sublayer.
path();
296 while ( !remainingPaths.empty() )
298 currentPath << remainingPaths.takeAt( 0 );
300 auto it = groupItems.constFind( currentPath );
301 if ( it == groupItems.constEnd() )
305 groupItems.insert( currentPath, newGroupItem );
310 groupItem = newGroupItem;
314 groupItem = it.value();
333 mCachedCapabilities = conn->capabilities();
334 mCachedCapabilities2 = conn->capabilities2();
335 mHasCachedCapabilities =
true;
340 QStringList fieldDomains;
343 fieldDomains = conn->fieldDomainNames();
347 domainError = ex.
what();
350 if ( !fieldDomains.empty() || !domainError.isEmpty() )
352 auto domainsItem = std::make_unique< QgsFieldDomainsItem >(
this,
mPath +
"/domains", conn->uri(), QStringLiteral(
"ogr" ) );
354 domainsItem->setSortKey( QString( QChar( 0x10FFFF ) ) );
355 children.append( domainsItem.release() );
360 QString relationError;
361 QList< QgsWeakRelation > relations;
364 relations = conn->relationships();
368 relationError = ex.
what();
371 if ( !relations.empty() || !relationError.isEmpty() )
373 auto relationsItem = std::make_unique< QgsRelationshipsItem >(
this,
mPath +
"/relations", conn->uri(), QStringLiteral(
"ogr" ) );
375 relationsItem->setSortKey( QString( QChar( 0x11FFFF ) ) );
376 children.append( relationsItem.release() );
392 if ( mHasCachedCapabilities )
395 if ( mHasCachedDropSupport )
396 return mCachedSupportsDrop;
401 mHasCachedDropSupport =
true;
402 if ( !QFileInfo(
path() ).isWritable() )
404 mCachedSupportsDrop =
false;
405 return mCachedSupportsDrop;
408 GDALDriverH hDriver = GDALIdentifyDriverEx(
path().toUtf8().constData(), GDAL_OF_VECTOR,
nullptr,
nullptr );
411 mCachedSupportsDrop =
false;
412 return mCachedSupportsDrop;
416 const QString driverName = GDALGetDriverShortName( hDriver );
417 if ( driverName == QLatin1String(
"PDF" )
418 || driverName == QLatin1String(
"DXF" ) )
420 mCachedSupportsDrop =
false;
421 return mCachedSupportsDrop;
425#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3,4,0)
426 const bool isSingleTableDriver = !GDALGetMetadataItem( hDriver, GDAL_DCAP_MULTIPLE_VECTOR_LAYERS,
nullptr );
428 const QFileInfo pathInfo(
path() );
429 const QString suffix = pathInfo.suffix().toLower();
433 if ( isSingleTableDriver )
435 mCachedSupportsDrop =
false;
436 return mCachedSupportsDrop;
440 mCachedSupportsDrop =
true;
441 return mCachedSupportsDrop;
448 collectionUri.
layerType = QStringLiteral(
"collection" );
450 return { collectionUri };
456 if ( OGRGetDriverCount() == 0 )
461 CPLPushErrorHandler( CPLQuietErrorHandler );
463 GDALDriverH hDriver = GDALIdentifyDriverEx(
path().toUtf8().constData(), GDAL_OF_VECTOR,
nullptr,
nullptr );
464 CPLPopErrorHandler();
468 QgsDebugMsgLevel( QStringLiteral(
"GDALIdentifyDriverEx error # %1 : %2 on %3" ).arg( CPLGetLastErrorNo() ).arg( CPLGetLastErrorMsg() ).arg(
path() ), 2 );
472 const QString driverName = GDALGetDriverShortName( hDriver );
473 if ( driverName == QLatin1String(
"PDF" )
474 || driverName == QLatin1String(
"DXF" ) )
482 if ( driverName == QLatin1String(
"SQLite" ) )
498 parts.insert( QStringLiteral(
"path" ),
path() );
507 mHasCachedCapabilities =
true;
515 if ( mHasCachedCapabilities )
516 return mCachedCapabilities;
521 mCachedCapabilities = conn->capabilities();
522 mCachedCapabilities2 = conn->capabilities2();
523 mHasCachedCapabilities =
true;
525 return mCachedCapabilities;
530 if ( mHasCachedCapabilities )
531 return mCachedCapabilities2;
536 mCachedCapabilities = conn->capabilities();
537 mCachedCapabilities2 = conn->capabilities2();
538 mHasCachedCapabilities =
true;
540 return mCachedCapabilities2;
554 return QStringLiteral(
"files" );
569 return createDataItemForPathPrivate( path, parentItem, &allowedProviders, queryFlags, extraUriParts );
572QgsDataItem *QgsFileBasedDataItemProvider::createDataItemForPathPrivate(
const QString &path,
QgsDataItem *parentItem,
const QStringList *allowedProviders,
Qgis::SublayerQueryFlags queryFlags,
const QVariantMap &extraUriParts )
574 if ( path.isEmpty() )
577 const QFileInfo info( path );
578 QString suffix = info.suffix().toLower();
579 const QString
name = info.fileName();
582 if ( suffix.compare( QLatin1String(
"gpkg" ), Qt::CaseInsensitive ) == 0 )
585 QgsGeoPackageCollectionItem *item =
new QgsGeoPackageCollectionItem( parentItem,
name, path );
589 else if ( suffix == QLatin1String(
"txt" ) )
597 else if ( suffix == QLatin1String(
"map" ) || suffix == QLatin1String(
"dat" ) )
599 if ( QFile::exists( QDir( info.path() ).filePath( info.baseName() +
".tab" ) ) || QFile::exists( QDir( info.path() ).filePath( info.baseName() +
".TAB" ) ) )
603 else if ( suffix == QLatin1String(
"dbf" ) || suffix == QLatin1String(
"shx" ) )
605 if ( QFile::exists( QDir( info.path() ).filePath( info.baseName() +
".shp" ) ) || QFile::exists( QDir( info.path() ).filePath( info.baseName() +
".SHP" ) ) )
614 else if ( path.endsWith( QLatin1String(
".shp.zip" ), Qt::CaseInsensitive ) &&
615 GDALIdentifyDriverEx( path.toUtf8().constData(), GDAL_OF_VECTOR,
nullptr,
nullptr ) )
617 suffix = QStringLiteral(
"shp.zip" );
624 QgsSettings settings;
627 if ( ( settings.
value( QStringLiteral(
"qgis/scanItemsInBrowser2" ),
628 "extension" ).toString() == QLatin1String(
"extension" ) ) ||
629 ( parentItem && settings.
value( QStringLiteral(
"qgis/scanItemsFastScanUris" ),
630 QStringList() ).toStringList().contains( parentItem->
path() ) ) )
635 QList<QgsProviderSublayerDetails> sublayers;
636 if ( !allowedProviders )
642 for (
const QString &provider : *allowedProviders )
646 if ( !extraUriParts.empty() )
648 QVariantMap uriParts = metadata->decodeUri( path );
649 for (
auto it = extraUriParts.constBegin(); it != extraUriParts.constEnd(); ++it )
651 uriParts.insert( it.key(), it.value() );
654 sublayers.append( metadata->querySublayers( metadata->encodeUri( uriParts ), queryFlags ) );
658 sublayers.append( metadata->querySublayers( path, queryFlags ) );
664 if ( sublayers.size() == 1
669 QgsProviderSublayerItem *item =
new QgsProviderSublayerItem( parentItem,
name, sublayers.at( 0 ), path );
673 else if ( !sublayers.empty() )
675 QgsFileDataCollectionItem *item =
new QgsFileDataCollectionItem( parentItem,
name, path, sublayers, extraUriParts );
687 QFileInfo info( path );
688 QString suffix = info.suffix().toLower();
690 QStringList dirExtensions = QgsOgrProviderUtils::directoryExtensions();
691 return dirExtensions.contains( suffix );
@ Files
Can provides items which corresponds to files.
@ Directories
Can provides items which corresponds to directories.
@ NotPopulated
Children not yet created.
@ Populated
Children created.
@ Fertile
Can create children. Even items without this capability may have children, but cannot create them,...
@ RefreshChildrenWhenItemIsRefreshed
When the item is refreshed, all its populated children will also be refreshed in turn.
@ ItemRepresentsFile
Item's path() directly represents a file on disk.
@ Fast
CreateChildren() is fast enough to be run in main thread when refreshing items, most root items (wms,...
@ Archive
File archive type (e.g. vsizip).
QFlags< DataItemProviderCapability > DataItemProviderCapabilities
Capabilities for data item providers.
@ FastScan
Indicates that the provider must scan for sublayers using the fastest possible approach – e....
@ ResolveGeometryType
Attempt to resolve the geometry type for vector sublayers.
BrowserLayerType
Browser item layer types.
@ Point
Vector point layer.
@ Plugin
Plugin based layer.
@ TiledScene
Tiled scene layer.
@ Polygon
Vector polygon layer.
@ Vector
Generic vector layer.
@ VectorTile
Vector tile layer.
@ TableLayer
Vector non-spatial layer.
@ PointCloud
Point cloud layer.
QFlags< SublayerQueryFlag > SublayerQueryFlags
Sublayer query flags.
@ Group
Composite group layer. Added in QGIS 3.24.
@ Plugin
Plugin based layer.
@ TiledScene
Tiled scene layer. Added in QGIS 3.34.
@ Annotation
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
@ VectorTile
Vector tile layer. Added in QGIS 3.14.
@ Mesh
Mesh layer. Added in QGIS 3.2.
@ PointCloud
Point cloud layer. Added in QGIS 3.18.
QFlags< DatabaseProviderConnectionCapability2 > DatabaseProviderConnectionCapabilities2
Provides common functionality for database based connections.
Qgis::DatabaseProviderConnectionCapabilities2 capabilities2() const
Returns extended connection capabilities.
@ CreateVectorTable
Can CREATE a vector (or aspatial) table/layer.
@ RetrieveRelationships
Can retrieve relationships from the database.
@ ListFieldDomains
Can return a list of field domain names via fieldDomainNames().
QFlags< Capability > Capabilities
Capabilities capabilities() const
Returns connection capabilities.
QgsDataCollectionItem(QgsDataItem *parent, const QString &name, const QString &path=QString(), const QString &providerKey=QString())
Constructor for QgsDataCollectionItem, with the specified parent item.
Base class for all items in the model.
QVector< QgsDataItem * > children() const
Qgis::BrowserItemCapabilities mCapabilities
QgsDataItem(Qgis::BrowserItemType type, QgsDataItem *parent, const QString &name, const QString &path, const QString &providerKey=QString())
Constructor for QgsDataItem, with the specified parent item.
QString name() const
Returns the name of the item (the displayed text for the item).
virtual void setState(Qgis::BrowserItemState state)
Set item state.
virtual void setCapabilities(Qgis::BrowserItemCapabilities capabilities)
Sets the capabilities for the data item.
virtual void addChildItem(QgsDataItem *child, bool refresh=false)
Inserts a new child item.
QgsDataItem * parent() const
Gets item parent.
QString providerKey() const
Returns the provider key that created this item (e.g.
virtual Qgis::BrowserItemCapabilities capabilities2() const
Returns the capabilities for the data item.
Stores the component parts of a data source URI (e.g.
QString uri(bool expandAuthConfig=true) const
Returns the complete URI as a string.
void setDatabase(const QString &database)
Sets the URI database name.
A browser item which contains a collection of field items.
static QgsDataItem * createLayerItemForPath(const QString &path, QgsDataItem *parentItem, const QStringList &providers, const QVariantMap &extraUriParts, Qgis::SublayerQueryFlags queryFlags)
Static method to create a data item for sublayers corresponding to a file-like path.
Qgis::DataItemProviderCapabilities capabilities() const override
Returns combination of flags from QgsDataProvider::DataCapabilities.
QString name() override
Human-readable name of the provider name.
bool handlesDirectoryPath(const QString &path) override
Returns true if the provider will handle the directory at the specified path.
QgsDataItem * createDataItem(const QString &path, QgsDataItem *parentItem) override
Create a new instance of QgsDataItem (or nullptr) for given path and parent item.
A data collection item for grouping of the content in file based data collections (e....
QgsFileDataCollectionGroupItem(QgsDataItem *parent, const QString &groupName, const QString &path)
Constructor for QgsFileDataCollectionGroupItem.
void appendSublayer(const QgsProviderSublayerDetails &sublayer)
Adds a sublayer to the group.
QgsMimeDataUtils::UriList mimeUris() const override
Returns mime URIs for the data item, most data providers will only return a single URI but some data ...
bool hasDragEnabled() const override
Returns true if the item may be dragged.
bool hasDragEnabled() const override
Returns true if the item may be dragged.
QVector< QgsDataItem * > createChildren() override
Create children.
QgsAbstractDatabaseProviderConnection::Capabilities databaseConnectionCapabilities() const
Returns the associated connection capabilities, if a databaseConnection() is available.
QgsFileDataCollectionItem(QgsDataItem *parent, const QString &name, const QString &path, const QList< QgsProviderSublayerDetails > &sublayers, const QVariantMap &extraUriParts=QVariantMap())
Constructor for QgsFileDataCollectionItem.
QgsMimeDataUtils::UriList mimeUris() const override
Returns mime URIs for the data item, most data providers will only return a single URI but some data ...
QList< QgsProviderSublayerDetails > sublayers() const
Returns the sublayers.
bool canAddVectorLayers() const
Returns true if the file is likely to support addition of vector layers.
QgsAbstractDatabaseProviderConnection * databaseConnection() const override
For data items that represent a DB connection or one of its children, this method returns a connectio...
Qgis::DatabaseProviderConnectionCapabilities2 databaseConnectionCapabilities2() const
Returns extended connection capabilities, if a databaseConnection() is available.
static Qgis::VsiHandlerType vsiHandlerType(const QString &prefix)
Returns the VSI handler type for a given VSI prefix.
static QString vsiPrefixForPath(const QString &path)
Returns a the vsi prefix which corresponds to a file path, or an empty string if the path is not asso...
static QStringList multiLayerFileExtensions()
Returns a list of file extensions which potentially contain multiple layers representing GDAL raster ...
QString uri() const
Returns layer uri or empty string if layer cannot be created.
QgsLayerItem(QgsDataItem *parent, const QString &name, const QString &path, const QString &uri, Qgis::BrowserLayerType layerType, const QString &providerKey)
Constructor for QgsLayerItem.
QList< QgsMimeDataUtils::Uri > UriList
Custom exception class for provider connection related exceptions.
QList< QgsProviderSublayerDetails > querySublayers(const QString &uri, Qgis::SublayerQueryFlags flags=Qgis::SublayerQueryFlags(), QgsFeedback *feedback=nullptr) const
Queries the specified uri and returns a list of any valid sublayers found in the dataset which can be...
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
Contains details about a sub layer available from a dataset.
QStringList path() const
Returns the path to the sublayer.
Qgis::LayerType type() const
Returns the layer type.
Qgis::WkbType wkbType() const
Returns the layer's WKB type, or QgsWkbTypes::Unknown if the WKB type is not application or unknown.
QString uri() const
Returns the layer's URI.
QgsMimeDataUtils::Uri toMimeUri() const
Converts the sublayer details to a QgsMimeDataUtils::Uri representing the sublayer.
QString name() const
Returns the layer's name.
A generic data item for file based layers.
QString layerName() const override
Returns the layer name.
QgsAbstractDatabaseProviderConnection * databaseConnection() const override
For data items that represent a DB connection or one of its children, this method returns a connectio...
QVector< QgsDataItem * > createChildren() override
Create children.
QgsProviderSublayerItem(QgsDataItem *parent, const QString &name, const QgsProviderSublayerDetails &details, const QString &filePath)
Constructor for QgsProviderSublayerItem.
QgsProviderSublayerDetails sublayerDetails() const
Returns the sublayer details for the item.
static bool sublayerDetailsAreIncomplete(const QList< QgsProviderSublayerDetails > &details, QgsProviderUtils::SublayerCompletenessFlags flags=QgsProviderUtils::SublayerCompletenessFlags())
Returns true if the sublayer details are incomplete, and require a more in-depth scan.
@ IgnoreUnknownGeometryType
Indicates that an unknown geometry type should not be considered as incomplete.
@ IgnoreUnknownFeatureCount
Indicates that an unknown feature count should not be considered as incomplete.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
static bool isXmlStyleFile(const QString &path)
Tests if the file at path is a QGIS style XML file.
static Qgis::GeometryType geometryType(Qgis::WkbType type)
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
#define QgsDebugMsgLevel(str, level)
QString filePath
Path to file, if uri is associated with a file.
QString uri
Identifier of the data source recognized by its providerKey.
QString layerType
Type of URI.