21#include "qgsogrproviderutils.h"
23#include "qgsgeopackagedataitems.h"
39 :
QgsLayerItem( parent, name, filePath.isEmpty() ? details.uri() : filePath, details.uri(), layerTypeFromSublayer( details ), details.providerKey() )
55 if ( mDetails.
driverName() == QLatin1String(
"SQLite" ) )
58 path() + QStringLiteral(
"/columns/ " ),
59 QStringLiteral( R
"(dbname="%1")" ).arg( parent()->path().replace( '"', QLatin1String( R
"(\")" ) ) ),
60 QStringLiteral( "spatialite" ), QString(),
name() ) );
62 else if ( mDetails.
providerKey() == QLatin1String(
"ogr" ) )
67 path() + QStringLiteral(
"/columns/ " ),
69 QStringLiteral(
"ogr" ), QString(),
name() ) );
74 QString relationError;
75 QList< QgsWeakRelation > relations;
78 relations = conn->relationships( QString(), mDetails.
name() );
82 relationError = ex.
what();
85 if ( !relations.empty() || !relationError.isEmpty() )
87 std::unique_ptr< QgsRelationshipsItem > relationsItem = std::make_unique< QgsRelationshipsItem >(
this,
mPath +
"/relations", conn->uri(), QStringLiteral(
"ogr" ), QString(), mDetails.
name() );
89 relationsItem->setSortKey( QString( QChar( 0x11FFFF ) ) );
90 children.append( relationsItem.release() );
111 if ( mDetails.
providerKey() == QLatin1String(
"ogr" ) )
116 parts.insert( QStringLiteral(
"path" ),
path() );
126 switch ( sublayer.
type() )
177 return mDetails.
name();
187 mIconName = QStringLiteral(
"mIconDbSchema.svg" );
192 mSublayers.append( sublayer );
203 res.reserve( mSublayers.size() );
218 , mSublayers( sublayers )
219 , mExtraUriParts( extraUriParts )
228 mIconName = QStringLiteral(
"/mIconZip.svg" );
234 QList< QgsProviderSublayerDetails>
sublayers;
237 QSet< QString > providers;
240 providers.insert( details.providerKey() );
243 for (
const QString &provider : std::as_const( providers ) )
247 if ( !mExtraUriParts.empty() )
249 QVariantMap uriParts = metadata->decodeUri(
path() );
250 for (
auto it = mExtraUriParts.constBegin(); it != mExtraUriParts.constEnd(); ++it )
252 uriParts.insert( it.key(), it.value() );
254 const QString updatedUri = metadata->encodeUri( uriParts );
265 else if ( mSublayers.empty() )
281 QMap< QStringList, QgsFileDataCollectionGroupItem * > groupItems;
286 if ( !sublayer.
path().isEmpty() )
288 QStringList currentPath;
289 QStringList remainingPaths = sublayer.
path();
292 while ( !remainingPaths.empty() )
294 currentPath << remainingPaths.takeAt( 0 );
296 auto it = groupItems.constFind( currentPath );
297 if ( it == groupItems.constEnd() )
301 groupItems.insert( currentPath, newGroupItem );
306 groupItem = newGroupItem;
310 groupItem = it.value();
329 mCachedCapabilities = conn->capabilities();
330 mCachedCapabilities2 = conn->capabilities2();
331 mHasCachedCapabilities =
true;
336 QStringList fieldDomains;
339 fieldDomains = conn->fieldDomainNames();
343 domainError = ex.
what();
346 if ( !fieldDomains.empty() || !domainError.isEmpty() )
348 std::unique_ptr< QgsFieldDomainsItem > domainsItem = std::make_unique< QgsFieldDomainsItem >(
this,
mPath +
"/domains", conn->uri(), QStringLiteral(
"ogr" ) );
350 domainsItem->setSortKey( QString( QChar( 0x10FFFF ) ) );
351 children.append( domainsItem.release() );
356 QString relationError;
357 QList< QgsWeakRelation > relations;
360 relations = conn->relationships();
364 relationError = ex.
what();
367 if ( !relations.empty() || !relationError.isEmpty() )
369 std::unique_ptr< QgsRelationshipsItem > relationsItem = std::make_unique< QgsRelationshipsItem >(
this,
mPath +
"/relations", conn->uri(), QStringLiteral(
"ogr" ) );
371 relationsItem->setSortKey( QString( QChar( 0x11FFFF ) ) );
372 children.append( relationsItem.release() );
388 if ( mHasCachedCapabilities )
391 if ( mHasCachedDropSupport )
392 return mCachedSupportsDrop;
397 mHasCachedDropSupport =
true;
398 if ( !QFileInfo(
path() ).isWritable() )
400 mCachedSupportsDrop =
false;
401 return mCachedSupportsDrop;
404 GDALDriverH hDriver = GDALIdentifyDriverEx(
path().toUtf8().constData(), GDAL_OF_VECTOR,
nullptr,
nullptr );
407 mCachedSupportsDrop =
false;
408 return mCachedSupportsDrop;
412 const QString driverName = GDALGetDriverShortName( hDriver );
413 if ( driverName == QLatin1String(
"PDF" )
414 || driverName == QLatin1String(
"DXF" ) )
416 mCachedSupportsDrop =
false;
417 return mCachedSupportsDrop;
421#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3,4,0)
422 const bool isSingleTableDriver = !GDALGetMetadataItem( hDriver, GDAL_DCAP_MULTIPLE_VECTOR_LAYERS,
nullptr );
424 const QFileInfo pathInfo(
path() );
425 const QString suffix = pathInfo.suffix().toLower();
429 if ( isSingleTableDriver )
431 mCachedSupportsDrop =
false;
432 return mCachedSupportsDrop;
436 mCachedSupportsDrop =
true;
437 return mCachedSupportsDrop;
444 collectionUri.
layerType = QStringLiteral(
"collection" );
446 return { collectionUri };
452 if ( OGRGetDriverCount() == 0 )
457 CPLPushErrorHandler( CPLQuietErrorHandler );
459 GDALDriverH hDriver = GDALIdentifyDriverEx(
path().toUtf8().constData(), GDAL_OF_VECTOR,
nullptr,
nullptr );
460 CPLPopErrorHandler();
464 QgsDebugMsgLevel( QStringLiteral(
"GDALIdentifyDriverEx error # %1 : %2 on %3" ).arg( CPLGetLastErrorNo() ).arg( CPLGetLastErrorMsg() ).arg(
path() ), 2 );
468 const QString driverName = GDALGetDriverShortName( hDriver );
469 if ( driverName == QLatin1String(
"PDF" )
470 || driverName == QLatin1String(
"DXF" ) )
478 if ( driverName == QLatin1String(
"SQLite" ) )
494 parts.insert( QStringLiteral(
"path" ),
path() );
503 mHasCachedCapabilities =
true;
511 if ( mHasCachedCapabilities )
512 return mCachedCapabilities;
517 mCachedCapabilities = conn->capabilities();
518 mCachedCapabilities2 = conn->capabilities2();
519 mHasCachedCapabilities =
true;
521 return mCachedCapabilities;
526 if ( mHasCachedCapabilities )
527 return mCachedCapabilities2;
532 mCachedCapabilities = conn->capabilities();
533 mCachedCapabilities2 = conn->capabilities2();
534 mHasCachedCapabilities =
true;
536 return mCachedCapabilities2;
550 return QStringLiteral(
"files" );
565 return createDataItemForPathPrivate( path, parentItem, &allowedProviders, queryFlags, extraUriParts );
568QgsDataItem *QgsFileBasedDataItemProvider::createDataItemForPathPrivate(
const QString &path,
QgsDataItem *parentItem,
const QStringList *allowedProviders,
Qgis::SublayerQueryFlags queryFlags,
const QVariantMap &extraUriParts )
570 if ( path.isEmpty() )
573 const QFileInfo info( path );
574 QString suffix = info.suffix().toLower();
575 const QString
name = info.fileName();
578 if ( suffix.compare( QLatin1String(
"gpkg" ), Qt::CaseInsensitive ) == 0 )
581 QgsGeoPackageCollectionItem *item =
new QgsGeoPackageCollectionItem( parentItem,
name, path );
585 else if ( suffix == QLatin1String(
"txt" ) )
593 else if ( suffix == QLatin1String(
"map" ) || suffix == QLatin1String(
"dat" ) )
595 if ( QFile::exists( QDir( info.path() ).filePath( info.baseName() +
".tab" ) ) || QFile::exists( QDir( info.path() ).filePath( info.baseName() +
".TAB" ) ) )
599 else if ( suffix == QLatin1String(
"dbf" ) || suffix == QLatin1String(
"shx" ) )
601 if ( QFile::exists( QDir( info.path() ).filePath( info.baseName() +
".shp" ) ) || QFile::exists( QDir( info.path() ).filePath( info.baseName() +
".SHP" ) ) )
610 else if ( path.endsWith( QLatin1String(
".shp.zip" ), Qt::CaseInsensitive ) &&
611 GDALIdentifyDriverEx( path.toUtf8().constData(), GDAL_OF_VECTOR,
nullptr,
nullptr ) )
613 suffix = QStringLiteral(
"shp.zip" );
623 if ( ( settings.
value( QStringLiteral(
"qgis/scanItemsInBrowser2" ),
624 "extension" ).toString() == QLatin1String(
"extension" ) ) ||
625 ( parentItem && settings.
value( QStringLiteral(
"qgis/scanItemsFastScanUris" ),
626 QStringList() ).toStringList().contains( parentItem->
path() ) ) )
631 QList<QgsProviderSublayerDetails> sublayers;
632 if ( !allowedProviders )
638 for (
const QString &provider : *allowedProviders )
642 if ( !extraUriParts.empty() )
644 QVariantMap uriParts = metadata->decodeUri( path );
645 for (
auto it = extraUriParts.constBegin(); it != extraUriParts.constEnd(); ++it )
647 uriParts.insert( it.key(), it.value() );
650 sublayers.append( metadata->querySublayers( metadata->encodeUri( uriParts ), queryFlags ) );
654 sublayers.append( metadata->querySublayers( path, queryFlags ) );
660 if ( sublayers.size() == 1
669 else if ( !sublayers.empty() )
683 QFileInfo info( path );
684 QString suffix = info.suffix().toLower();
686 QStringList dirExtensions = QgsOgrProviderUtils::directoryExtensions();
687 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
The QgsAbstractDatabaseProviderConnection class provides common functionality for DB based connection...
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.
A Collection: logical collection of layers or subcollections, e.g.
Base class for all items in the model.
QVector< QgsDataItem * > children() const
Qgis::BrowserItemCapabilities mCapabilities
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.
virtual Qgis::BrowserItemCapabilities capabilities2() const
Returns the capabilities for the data item.
Class for storing the component parts of a RDBMS 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 collection of field items with some internal logic to retrieve the fields and a the vector layer in...
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.
A data collection item for file based data collections (e.g.
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 ...
Item that represents a layer that can be opened with one of the providers.
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.
QgsProviderMetadata * providerMetadata(const QString &providerKey) const
Returns metadata of the provider or nullptr if not found.
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 driverName() const
Returns the layer's driver name.
QString providerKey() const
Returns the associated data provider key.
QString name() const
Returns the layer's name.
A generic data item for file based layers.
QString layerName() const override
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.
This class is a composition of two QSettings instances:
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.