17#include "moc_qgsfilebaseddataitemprovider.cpp"
22#include "qgsogrproviderutils.h"
24#include "qgsgeopackagedataitems.h"
40 :
QgsLayerItem( parent, name, filePath.isEmpty() ? details.uri() : filePath, details.uri(), layerTypeFromSublayer( details ), details.providerKey() )
56 if ( mDetails.
driverName() == QLatin1String(
"SQLite" ) )
59 path() + QStringLiteral(
"/columns/ " ),
60 QStringLiteral( R
"(dbname="%1")" ).arg( parent()->path().replace( '"', QLatin1String( R
"(\")" ) ) ),
61 QStringLiteral( "spatialite" ), QString(),
name() ) );
63 else if ( mDetails.
providerKey() == QLatin1String(
"ogr" ) )
68 path() + QStringLiteral(
"/columns/ " ),
70 QStringLiteral(
"ogr" ), QString(),
name() ) );
75 QString relationError;
76 QList< QgsWeakRelation > relations;
79 relations = conn->relationships( QString(), mDetails.
name() );
83 relationError = ex.
what();
86 if ( !relations.empty() || !relationError.isEmpty() )
88 std::unique_ptr< QgsRelationshipsItem > relationsItem = std::make_unique< QgsRelationshipsItem >(
this,
mPath +
"/relations", conn->uri(), QStringLiteral(
"ogr" ), QString(), mDetails.
name() );
90 relationsItem->setSortKey( QString( QChar( 0x11FFFF ) ) );
91 children.append( relationsItem.release() );
112 if ( mDetails.
providerKey() == QLatin1String(
"ogr" ) )
117 parts.insert( QStringLiteral(
"path" ),
path() );
127 switch ( sublayer.
type() )
178 return mDetails.
name();
188 mIconName = QStringLiteral(
"mIconDbSchema.svg" );
193 mSublayers.append( sublayer );
204 res.reserve( mSublayers.size() );
219 , mSublayers( sublayers )
220 , mExtraUriParts( extraUriParts )
229 mIconName = QStringLiteral(
"/mIconZip.svg" );
235 QList< QgsProviderSublayerDetails>
sublayers;
238 QSet< QString > providers;
241 providers.insert( details.providerKey() );
244 for (
const QString &provider : std::as_const( providers ) )
248 if ( !mExtraUriParts.empty() )
250 QVariantMap uriParts = metadata->decodeUri(
path() );
251 for (
auto it = mExtraUriParts.constBegin(); it != mExtraUriParts.constEnd(); ++it )
253 uriParts.insert( it.key(), it.value() );
255 const QString updatedUri = metadata->encodeUri( uriParts );
266 else if ( mSublayers.empty() )
282 QMap< QStringList, QgsFileDataCollectionGroupItem * > groupItems;
287 if ( !sublayer.
path().isEmpty() )
289 QStringList currentPath;
290 QStringList remainingPaths = sublayer.
path();
293 while ( !remainingPaths.empty() )
295 currentPath << remainingPaths.takeAt( 0 );
297 auto it = groupItems.constFind( currentPath );
298 if ( it == groupItems.constEnd() )
302 groupItems.insert( currentPath, newGroupItem );
307 groupItem = newGroupItem;
311 groupItem = it.value();
330 mCachedCapabilities = conn->capabilities();
331 mCachedCapabilities2 = conn->capabilities2();
332 mHasCachedCapabilities =
true;
337 QStringList fieldDomains;
340 fieldDomains = conn->fieldDomainNames();
344 domainError = ex.
what();
347 if ( !fieldDomains.empty() || !domainError.isEmpty() )
349 std::unique_ptr< QgsFieldDomainsItem > domainsItem = std::make_unique< QgsFieldDomainsItem >(
this,
mPath +
"/domains", conn->uri(), QStringLiteral(
"ogr" ) );
351 domainsItem->setSortKey( QString( QChar( 0x10FFFF ) ) );
352 children.append( domainsItem.release() );
357 QString relationError;
358 QList< QgsWeakRelation > relations;
361 relations = conn->relationships();
365 relationError = ex.
what();
368 if ( !relations.empty() || !relationError.isEmpty() )
370 std::unique_ptr< QgsRelationshipsItem > relationsItem = std::make_unique< QgsRelationshipsItem >(
this,
mPath +
"/relations", conn->uri(), QStringLiteral(
"ogr" ) );
372 relationsItem->setSortKey( QString( QChar( 0x11FFFF ) ) );
373 children.append( relationsItem.release() );
389 if ( mHasCachedCapabilities )
392 if ( mHasCachedDropSupport )
393 return mCachedSupportsDrop;
398 mHasCachedDropSupport =
true;
399 if ( !QFileInfo(
path() ).isWritable() )
401 mCachedSupportsDrop =
false;
402 return mCachedSupportsDrop;
405 GDALDriverH hDriver = GDALIdentifyDriverEx(
path().toUtf8().constData(), GDAL_OF_VECTOR,
nullptr,
nullptr );
408 mCachedSupportsDrop =
false;
409 return mCachedSupportsDrop;
413 const QString driverName = GDALGetDriverShortName( hDriver );
414 if ( driverName == QLatin1String(
"PDF" )
415 || driverName == QLatin1String(
"DXF" ) )
417 mCachedSupportsDrop =
false;
418 return mCachedSupportsDrop;
422#if GDAL_VERSION_NUM >= GDAL_COMPUTE_VERSION(3,4,0)
423 const bool isSingleTableDriver = !GDALGetMetadataItem( hDriver, GDAL_DCAP_MULTIPLE_VECTOR_LAYERS,
nullptr );
425 const QFileInfo pathInfo(
path() );
426 const QString suffix = pathInfo.suffix().toLower();
430 if ( isSingleTableDriver )
432 mCachedSupportsDrop =
false;
433 return mCachedSupportsDrop;
437 mCachedSupportsDrop =
true;
438 return mCachedSupportsDrop;
445 collectionUri.
layerType = QStringLiteral(
"collection" );
447 return { collectionUri };
453 if ( OGRGetDriverCount() == 0 )
458 CPLPushErrorHandler( CPLQuietErrorHandler );
460 GDALDriverH hDriver = GDALIdentifyDriverEx(
path().toUtf8().constData(), GDAL_OF_VECTOR,
nullptr,
nullptr );
461 CPLPopErrorHandler();
465 QgsDebugMsgLevel( QStringLiteral(
"GDALIdentifyDriverEx error # %1 : %2 on %3" ).arg( CPLGetLastErrorNo() ).arg( CPLGetLastErrorMsg() ).arg(
path() ), 2 );
469 const QString driverName = GDALGetDriverShortName( hDriver );
470 if ( driverName == QLatin1String(
"PDF" )
471 || driverName == QLatin1String(
"DXF" ) )
479 if ( driverName == QLatin1String(
"SQLite" ) )
495 parts.insert( QStringLiteral(
"path" ),
path() );
504 mHasCachedCapabilities =
true;
512 if ( mHasCachedCapabilities )
513 return mCachedCapabilities;
518 mCachedCapabilities = conn->capabilities();
519 mCachedCapabilities2 = conn->capabilities2();
520 mHasCachedCapabilities =
true;
522 return mCachedCapabilities;
527 if ( mHasCachedCapabilities )
528 return mCachedCapabilities2;
533 mCachedCapabilities = conn->capabilities();
534 mCachedCapabilities2 = conn->capabilities2();
535 mHasCachedCapabilities =
true;
537 return mCachedCapabilities2;
551 return QStringLiteral(
"files" );
566 return createDataItemForPathPrivate( path, parentItem, &allowedProviders, queryFlags, extraUriParts );
569QgsDataItem *QgsFileBasedDataItemProvider::createDataItemForPathPrivate(
const QString &path,
QgsDataItem *parentItem,
const QStringList *allowedProviders,
Qgis::SublayerQueryFlags queryFlags,
const QVariantMap &extraUriParts )
571 if ( path.isEmpty() )
574 const QFileInfo info( path );
575 QString suffix = info.suffix().toLower();
576 const QString
name = info.fileName();
579 if ( suffix.compare( QLatin1String(
"gpkg" ), Qt::CaseInsensitive ) == 0 )
582 QgsGeoPackageCollectionItem *item =
new QgsGeoPackageCollectionItem( parentItem,
name, path );
586 else if ( suffix == QLatin1String(
"txt" ) )
594 else if ( suffix == QLatin1String(
"map" ) || suffix == QLatin1String(
"dat" ) )
596 if ( QFile::exists( QDir( info.path() ).filePath( info.baseName() +
".tab" ) ) || QFile::exists( QDir( info.path() ).filePath( info.baseName() +
".TAB" ) ) )
600 else if ( suffix == QLatin1String(
"dbf" ) || suffix == QLatin1String(
"shx" ) )
602 if ( QFile::exists( QDir( info.path() ).filePath( info.baseName() +
".shp" ) ) || QFile::exists( QDir( info.path() ).filePath( info.baseName() +
".SHP" ) ) )
611 else if ( path.endsWith( QLatin1String(
".shp.zip" ), Qt::CaseInsensitive ) &&
612 GDALIdentifyDriverEx( path.toUtf8().constData(), GDAL_OF_VECTOR,
nullptr,
nullptr ) )
614 suffix = QStringLiteral(
"shp.zip" );
624 if ( ( settings.
value( QStringLiteral(
"qgis/scanItemsInBrowser2" ),
625 "extension" ).toString() == QLatin1String(
"extension" ) ) ||
626 ( parentItem && settings.
value( QStringLiteral(
"qgis/scanItemsFastScanUris" ),
627 QStringList() ).toStringList().contains( parentItem->
path() ) ) )
632 QList<QgsProviderSublayerDetails> sublayers;
633 if ( !allowedProviders )
639 for (
const QString &provider : *allowedProviders )
643 if ( !extraUriParts.empty() )
645 QVariantMap uriParts = metadata->decodeUri( path );
646 for (
auto it = extraUriParts.constBegin(); it != extraUriParts.constEnd(); ++it )
648 uriParts.insert( it.key(), it.value() );
651 sublayers.append( metadata->querySublayers( metadata->encodeUri( uriParts ), queryFlags ) );
655 sublayers.append( metadata->querySublayers( path, queryFlags ) );
661 if ( sublayers.size() == 1
670 else if ( !sublayers.empty() )
684 QFileInfo info( path );
685 QString suffix = info.suffix().toLower();
687 QStringList dirExtensions = QgsOgrProviderUtils::directoryExtensions();
688 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.