91#include <QPainterPath>
93#include <QProgressDialog>
97#include <QStringBuilder>
99#include <QUndoCommand>
102#include <QRegularExpression>
108#ifdef TESTPROVIDERLIB
114 const QString &qmlStyle,
115 const QString &sldStyle,
116 const QString &styleName,
117 const QString &styleDescription,
118 const QString &uiFileContent,
132 QStringList &descriptions,
150 const QString &baseName,
151 const QString &providerKey,
156 , mAuxiliaryLayer( nullptr )
157 , mAuxiliaryLayerKey( QString() )
158 , mReadExtentFromXml( options.readExtentFromXml )
159 , mRefreshRendererTimer( new QTimer( this ) )
169 mGeometryOptions = std::make_unique<QgsGeometryOptions>();
173 mStoredExpressionManager->setParent(
this );
176 mJoinBuffer->setParent(
this );
181 if ( !vectorLayerPath.isEmpty() && !
mProviderKey.isEmpty() )
184 QgsDataProvider::ReadFlags providerFlags = QgsDataProvider::ReadFlags();
189 setDataSource( vectorLayerPath, baseName, providerKey, providerOptions, providerFlags );
194 if ( !mAttributeAliasMap.contains(
field.
name() ) )
195 mAttributeAliasMap.insert(
field.
name(), QString() );
201 if ( !mTemporalProperties->
isActive() )
222 mSimplifyMethod.
setThreshold( settings.
value( QStringLiteral(
"qgis/simplifyDrawingTol" ), mSimplifyMethod.
threshold() ).toFloat() );
226 connect( mRefreshRendererTimer, &QTimer::timeout,
this, [ = ] {
triggerRepaint(
true ); } );
235 delete mDataProvider;
238 delete mExpressionFieldBuffer;
240 delete mDiagramLayerSettings;
241 delete mDiagramRenderer;
246 delete mConditionalStyles;
247 delete mStoredExpressionManager;
249 if ( mFeatureCounter )
250 mFeatureCounter->
cancel();
252 qDeleteAll( mRendererGenerators );
278 QList<QgsVectorLayerJoinInfo> joins =
vectorJoins();
279 const auto constJoins = joins;
299 for (
const QgsAction &action : constActions )
336 auto constraintIt = constraints.constBegin();
337 for ( ; constraintIt != constraints.constEnd(); ++ constraintIt )
353 layer->mElevationProperties = mElevationProperties->
clone();
354 layer->mElevationProperties->setParent( layer );
380 return mDataProvider && mDataProvider->
isSqlQuery();
427 p.setPen( QColor( 50, 100, 120, 200 ) );
428 p.setBrush( QColor( 200, 200, 210, 120 ) );
429 p.drawEllipse( x - m, y - m, m * 2 + 1, m * 2 + 1 );
433 p.setPen( QColor( 255, 0, 0 ) );
434 p.drawLine( x - m, y + m, x + m, y - m );
435 p.drawLine( x - m, y - m, x + m, y + m );
445 mSelectedFeatureIds.insert( fid );
446 mPreviousSelectedFeatureIds.clear();
453 mSelectedFeatureIds.unite( featureIds );
454 mPreviousSelectedFeatureIds.clear();
461 mSelectedFeatureIds.remove( fid );
462 mPreviousSelectedFeatureIds.clear();
469 mSelectedFeatureIds.subtract( featureIds );
470 mPreviousSelectedFeatureIds.clear();
483 .setFilterRect( rect )
485 .setNoAttributes() );
490 newSelection << feat.
id();
501 std::optional< QgsExpressionContext > defaultContext;
505 context = &defaultContext.value();
524 newSelection << feat.
id();
546 bool matches = exp.
evaluate( context ).toBool();
550 newSelection << feat.
id();
554 newSelection << feat.
id();
573 newSelection = mSelectedFeatureIds + ids;
577 newSelection = mSelectedFeatureIds - ids;
581 newSelection = mSelectedFeatureIds.intersect( ids );
585 QgsFeatureIds deselectedFeatures = mSelectedFeatureIds - newSelection;
586 mSelectedFeatureIds = newSelection;
587 mPreviousSelectedFeatureIds.clear();
595 if ( !intersectingIds.isEmpty() )
597 QgsDebugMsgLevel( QStringLiteral(
"Trying to select and deselect the same item at the same time. Unsure what to do. Selecting dubious items." ), 3 );
600 mSelectedFeatureIds -= deselectIds;
601 mSelectedFeatureIds += selectIds;
602 mPreviousSelectedFeatureIds.clear();
610 ids.subtract( mSelectedFeatureIds );
625 .setFilterRect( rect )
627 .setNoAttributes() );
635 if ( mSelectedFeatureIds.contains( fet.
id() ) )
637 deselectIds << fet.
id();
641 selectIds << fet.
id();
650 if ( mSelectedFeatureIds.isEmpty() )
655 mPreviousSelectedFeatureIds = previous;
660 if ( mPreviousSelectedFeatureIds.isEmpty() || !mSelectedFeatureIds.empty() )
668 return mDataProvider;
673 return mDataProvider;
678 return mTemporalProperties;
683 return mElevationProperties;
695 if (
isValid() && mDataProvider && mDataProvider->
encoding() != encoding )
704 delete mDiagramRenderer;
705 mDiagramRenderer = r;
722 if ( !
isValid() || !
isSpatial() || mSelectedFeatureIds.isEmpty() || !mDataProvider )
734 .setFilterFids( mSelectedFeatureIds )
735 .setNoAttributes() );
748 .setNoAttributes() );
752 if ( mSelectedFeatureIds.contains( fet.
id() ) )
763 if ( retval.
width() == 0.0 || retval.
height() == 0.0 )
772 retval.
set( -1.0, -1.0, 1.0, 1.0 );
781 return mLabelsEnabled &&
static_cast< bool >( mLabeling );
786 mLabelsEnabled = enabled;
791 if ( !mDiagramRenderer || !mDiagramLayerSettings )
794 QList<QgsDiagramSettings> settingList = mDiagramRenderer->
diagramSettings();
795 if ( !settingList.isEmpty() )
797 return settingList.at( 0 ).enabled;
804 if ( !mSymbolFeatureCounted )
807 return mSymbolFeatureCountMap.value( legendKey, -1 );
812 if ( !mSymbolFeatureCounted )
815 return mSymbolFeatureIdMap.value( legendKey,
QgsFeatureIds() );
819 if ( ( mSymbolFeatureCounted || mFeatureCounter ) && !( storeSymbolFids && mSymbolFeatureIdMap.isEmpty() ) )
820 return mFeatureCounter;
822 mSymbolFeatureCountMap.clear();
823 mSymbolFeatureIdMap.clear();
828 return mFeatureCounter;
830 if ( !mDataProvider )
833 return mFeatureCounter;
838 return mFeatureCounter;
841 if ( !mFeatureCounter || ( storeSymbolFids && mSymbolFeatureIdMap.isEmpty() ) )
844 connect( mFeatureCounter, &
QgsTask::taskCompleted,
this, &QgsVectorLayer::onFeatureCounterCompleted, Qt::UniqueConnection );
845 connect( mFeatureCounter, &
QgsTask::taskTerminated,
this, &QgsVectorLayer::onFeatureCounterTerminated, Qt::UniqueConnection );
849 return mFeatureCounter;
855 if ( force || !mReadExtentFromXml || ( mReadExtentFromXml && mXmlExtent.
isNull() ) )
856 mValidExtent =
false;
867 if ( !mDefaultValueOnUpdateFields.isEmpty() )
872 int size = mFields.
size();
873 for (
int idx : std::as_const( mDefaultValueOnUpdateFields ) )
875 if ( idx < 0 || idx >= size )
892 if ( !mValidExtent && mLazyExtent && mReadExtentFromXml && !mXmlExtent.
isNull() )
894 updateExtent( mXmlExtent );
899 if ( !mValidExtent && mLazyExtent && mDataProvider && mDataProvider->
isValid() )
902 updateExtent( mDataProvider->
extent() );
907 QgsDebugMsgLevel( QStringLiteral(
"Extent of layer: %1" ).arg( mExtent.toString() ), 3 );
913 if ( !
isValid() || !mDataProvider )
915 QgsDebugMsgLevel( QStringLiteral(
"invoked with invalid layer or null mDataProvider" ), 3 );
933 if ( mEditBuffer && !mDataProvider->
transaction() )
936 for ( QgsFeatureMap::const_iterator it = addedFeatures.constBegin(); it != addedFeatures.constEnd(); ++it )
938 if ( it->hasGeometry() )
949 .setNoAttributes() );
968 updateExtent( rect );
984 if ( !
isValid() || !mDataProvider )
986 QgsDebugMsgLevel( QStringLiteral(
"invoked with invalid layer or null mDataProvider" ), 3 );
987 return customProperty( QStringLiteral(
"storedSubsetString" ) ).toString();
994 if ( !
isValid() || !mDataProvider )
996 QgsDebugMsgLevel( QStringLiteral(
"invoked with invalid layer or null mDataProvider or while editing" ), 3 );
1000 else if ( mEditBuffer )
1029 double maximumSimplificationScale = mSimplifyMethod.
maximumScale();
1032 return !( maximumSimplificationScale > 1 && renderContext.
rendererScale() <= maximumSimplificationScale );
1039 return mConditionalStyles;
1044 if ( !
isValid() || !mDataProvider )
1062 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1066 if ( mGeometryOptions->isActive() )
1069 mGeometryOptions->apply( geom );
1073 bool success = mEditBuffer->
addFeature( feature );
1080 success = mJoinBuffer->
addFeature( feature );
1088 if ( !mEditBuffer || !mDataProvider )
1094 if ( currentFeature.
isValid() )
1096 bool hasChanged =
false;
1097 bool hasError =
false;
1109 QgsDebugMsgLevel( QStringLiteral(
"geometry of feature %1 could not be changed." ).arg( updatedFeature.
id() ), 3 );
1116 for (
int attr = 0; attr < fa.count(); ++attr )
1126 QgsDebugMsgLevel( QStringLiteral(
"attribute %1 of feature %2 could not be changed." ).arg( attr ).arg( updatedFeature.
id() ), 3 );
1131 if ( hasChanged && !mDefaultValueOnUpdateFields.isEmpty() && !skipDefaultValues )
1132 updateDefaultValues( updatedFeature.
id(), updatedFeature );
1138 QgsDebugMsgLevel( QStringLiteral(
"feature %1 could not be retrieved" ).arg( updatedFeature.
id() ), 3 );
1146 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1150 bool result = utils.
insertVertex( x, y, atFeatureId, beforeVertex );
1159 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1163 bool result = utils.
insertVertex( point, atFeatureId, beforeVertex );
1172 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1176 bool result = utils.
moveVertex( x, y, atFeatureId, atVertex );
1185 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1189 bool result = utils.
moveVertex( p, atFeatureId, atVertex );
1198 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1223 int count = mSelectedFeatureIds.size();
1236 *deletedCount = deleted;
1239 return deleted == count;
1242static const QgsPointSequence vectorPointXY2pointSequence(
const QVector<QgsPointXY> &points )
1245 pts.reserve( points.size() );
1246 QVector<QgsPointXY>::const_iterator it = points.constBegin();
1247 while ( it != points.constEnd() )
1256 return addRing( vectorPointXY2pointSequence( ring ), featureId );
1261 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1268 if ( !mSelectedFeatureIds.isEmpty() )
1270 result = utils.
addRing( ring, mSelectedFeatureIds, featureId );
1284 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1305 if ( !mSelectedFeatureIds.isEmpty() )
1307 result = utils.
addRing(
static_cast< QgsCurve *
>( ring->
clone() ), mSelectedFeatureIds, featureId );
1323 pts.reserve( points.size() );
1324 for ( QList<QgsPointXY>::const_iterator it = points.constBegin(); it != points.constEnd() ; ++it )
1331#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1334 return addPart( vectorPointXY2pointSequence( points ) );
1340 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1345 if ( mSelectedFeatureIds.empty() )
1350 else if ( mSelectedFeatureIds.size() > 1 )
1366 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1371 if ( mSelectedFeatureIds.empty() )
1376 else if ( mSelectedFeatureIds.size() > 1 )
1393 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1406 return splitParts( vectorPointXY2pointSequence( splitLine ), topologicalEditing );
1411 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1415 return utils.
splitParts( splitLine, topologicalEditing );
1420 return splitFeatures( vectorPointXY2pointSequence( splitLine ), topologicalEditing );
1427 bool preserveCircular =
false;
1428 return splitFeatures( &splitLineString, topologyTestPoints, preserveCircular, topologicalEditing );
1433 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1437 return utils.
splitFeatures( curve, topologyTestPoints, preserveCircular, topologicalEditing );
1442 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1456 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1465 if ( !
mValid || !mEditBuffer || !mDataProvider )
1486 if ( !
isValid() || !mDataProvider )
1518 if ( mDataProvider )
1530 if ( !mRenderer->
accept( visitor ) )
1534 if ( !mLabeling->
accept( visitor ) )
1545 QDomNode pkeyNode = layer_node.namedItem( QStringLiteral(
"provider" ) );
1547 if ( pkeyNode.isNull() )
1553 QDomElement pkeyElt = pkeyNode.toElement();
1563 else if (
mDataSource.contains( QLatin1String(
"dbname=" ) ) )
1573 QgsDataProvider::ReadFlags
flags;
1584 const QDomElement elem = layer_node.toElement();
1587 if ( elem.hasAttribute( QStringLiteral(
"wkbType" ) ) )
1588 mWkbType =
qgsEnumKeyToValue( elem.attribute( QStringLiteral(
"wkbType" ) ), mWkbType );
1591 QDomElement pkeyElem = pkeyNode.toElement();
1592 if ( !pkeyElem.isNull() )
1594 QString encodingString = pkeyElem.attribute( QStringLiteral(
"encoding" ) );
1595 if ( mDataProvider && !encodingString.isEmpty() )
1602 mJoinBuffer->
readXml( layer_node );
1607 mSetLegendFromStyle =
false;
1617 QDomNode depsNode = layer_node.namedItem( QStringLiteral(
"dataDependencies" ) );
1618 QDomNodeList depsNodes = depsNode.childNodes();
1619 QSet<QgsMapLayerDependency> sources;
1620 for (
int i = 0; i < depsNodes.count(); i++ )
1622 QString
source = depsNodes.at( i ).toElement().attribute( QStringLiteral(
"id" ) );
1627 if ( !mSetLegendFromStyle )
1633 mReadExtentFromXml =
true;
1635 if ( mReadExtentFromXml )
1637 const QDomNode extentNode = layer_node.namedItem( QStringLiteral(
"extent" ) );
1638 if ( !extentNode.isNull() )
1645 const QDomNode asNode = layer_node.namedItem( QStringLiteral(
"auxiliaryLayer" ) );
1646 const QDomElement asElem = asNode.toElement();
1647 if ( !asElem.isNull() )
1649 mAuxiliaryLayerKey = asElem.attribute( QStringLiteral(
"key" ) );
1653 mServerProperties->readXml( layer_node );
1660void QgsVectorLayer::setDataSourcePrivate(
const QString &dataSource,
const QString &baseName,
const QString &provider,
1667 setDataProvider( provider, options,
flags );
1677 bool loadDefaultStyleFlag =
false;
1680 loadDefaultStyleFlag =
true;
1686 std::unique_ptr< QgsScopedRuntimeProfile > profile;
1688 profile = std::make_unique< QgsScopedRuntimeProfile >( tr(
"Load layer style" ), QStringLiteral(
"projectload" ) );
1690 bool defaultLoadedFlag =
false;
1698 mSetLegendFromStyle =
false;
1703 if ( !defaultLoadedFlag && loadDefaultStyleFlag )
1711 std::unique_ptr< QgsFeatureRenderer > defaultRenderer( mDataProvider->
createRenderer() );
1712 if ( defaultRenderer )
1714 defaultLoadedFlag =
true;
1720 if ( !defaultLoadedFlag &&
isSpatial() )
1726 if ( !mSetLegendFromStyle )
1731 std::unique_ptr< QgsAbstractVectorLayerLabeling > defaultLabeling( mDataProvider->
createLabeling() );
1732 if ( defaultLabeling )
1739 styleChangedSignalBlocker.release();
1754 std::unique_ptr< QgsFeatureRenderer > defaultRenderer( mDataProvider->
createRenderer() );
1755 if ( defaultRenderer )
1769 delete mDataProvider;
1776 if ( provider.compare( QLatin1String(
"postgres" ) ) == 0 )
1778 const QString checkUnicityKey { QStringLiteral(
"checkPrimaryKeyUnicity" ) };
1780 if ( ! uri.hasParam( checkUnicityKey ) )
1782 uri.setParam( checkUnicityKey, mReadExtentFromXml ?
"0" :
"1" );
1787 std::unique_ptr< QgsScopedRuntimeProfile > profile;
1789 profile = std::make_unique< QgsScopedRuntimeProfile >( tr(
"Create %1 provider" ).arg( provider ), QStringLiteral(
"projectload" ) );
1792 if ( !mDataProvider )
1799 mDataProvider->setParent(
this );
1802 QgsDebugMsgLevel( QStringLiteral(
"Instantiated the data provider plugin" ), 2 );
1812 profile->switchTask( tr(
"Read layer metadata" ) );
1819 newMetadata.
combine( &mMetadata );
1822 QgsDebugMsgLevel( QStringLiteral(
"Set Data provider QgsLayerMetadata identifier[%1]" ).arg(
metadata().identifier() ), 4 );
1829 mWkbType = mDataProvider->
wkbType();
1848 profile->switchTask( tr(
"Read layer fields" ) );
1859 const QRegularExpression reg( R
"lit("[^"]+"\."([^"] + )"( \([^)]+\))?)lit" );
1860 const QRegularExpressionMatch match = reg.match(
name() );
1861 if ( match.hasMatch() )
1863 QStringList stuff = match.capturedTexts();
1864 QString lName = stuff[1];
1868 QMap<QString, QgsMapLayer *>::const_iterator it;
1869 for ( it = layers.constBegin(); it != layers.constEnd() && ( *it )->name() != lName; ++it )
1872 if ( it != layers.constEnd() && stuff.size() > 2 )
1874 lName +=
'.' + stuff[2].mid( 2, stuff[2].length() - 3 );
1877 if ( !lName.isEmpty() )
1887 else if ( provider == QLatin1String(
"ogr" ) )
1891 if (
mDataSource.right( 10 ) == QLatin1String(
"|layerid=0" ) )
1894 else if ( provider == QLatin1String(
"memory" ) )
1899 else if ( provider == QLatin1String(
"hana" ) )
1916 QDomDocument &document,
1921 QDomElement mapLayerNode = layer_node.toElement();
1923 if ( mapLayerNode.isNull() || (
"maplayer" != mapLayerNode.nodeName() ) )
1936 if ( mDataProvider )
1938 QDomElement provider = document.createElement( QStringLiteral(
"provider" ) );
1939 provider.setAttribute( QStringLiteral(
"encoding" ), mDataProvider->
encoding() );
1940 QDomText providerText = document.createTextNode(
providerType() );
1941 provider.appendChild( providerText );
1942 layer_node.appendChild( provider );
1946 mJoinBuffer->
writeXml( layer_node, document );
1949 QDomElement dependenciesElement = document.createElement( QStringLiteral(
"layerDependencies" ) );
1955 QDomElement depElem = document.createElement( QStringLiteral(
"layer" ) );
1956 depElem.setAttribute( QStringLiteral(
"id" ), dep.layerId() );
1957 dependenciesElement.appendChild( depElem );
1959 layer_node.appendChild( dependenciesElement );
1962 QDomElement dataDependenciesElement = document.createElement( QStringLiteral(
"dataDependencies" ) );
1967 QDomElement depElem = document.createElement( QStringLiteral(
"layer" ) );
1968 depElem.setAttribute( QStringLiteral(
"id" ), dep.layerId() );
1969 dataDependenciesElement.appendChild( depElem );
1971 layer_node.appendChild( dataDependenciesElement );
1974 mExpressionFieldBuffer->
writeXml( layer_node, document );
1979 QDomElement asElem = document.createElement( QStringLiteral(
"auxiliaryLayer" ) );
1980 if ( mAuxiliaryLayer )
1982 const QString pkField = mAuxiliaryLayer->joinInfo().targetFieldName();
1983 asElem.setAttribute( QStringLiteral(
"key" ), pkField );
1985 layer_node.appendChild( asElem );
1988 mServerProperties->writeXml( layer_node, document );
1992 return writeSymbology( layer_node, document, errorMsg, context );
2009 QStringList theURIParts = src.split(
'|' );
2011 src = theURIParts.join( QLatin1Char(
'|' ) );
2015 QStringList theURIParts = src.split(
'?' );
2017 src = theURIParts.join( QLatin1Char(
'?' ) );
2019 else if (
providerType() == QLatin1String(
"delimitedtext" ) )
2021 QUrl urlSource = QUrl::fromEncoded( src.toLatin1() );
2023 urlDest.setQuery( urlSource.query() );
2024 src = QString::fromLatin1( urlDest.toEncoded() );
2026 else if (
providerType() == QLatin1String(
"memory" ) )
2031 else if (
providerType() == QLatin1String(
"virtual" ) )
2033 QUrl urlSource = QUrl::fromEncoded( src.toLatin1() );
2034 QStringList theURIParts;
2036 QUrlQuery query = QUrlQuery( urlSource.query() );
2037 QList<QPair<QString, QString> > queryItems = query.queryItems();
2039 for (
int i = 0; i < queryItems.size(); i++ )
2041 QString key = queryItems.at( i ).first;
2042 QString value = queryItems.at( i ).second;
2043 if ( key == QLatin1String(
"layer" ) )
2046 theURIParts = value.split(
':' );
2047 theURIParts[1] = QUrl::fromPercentEncoding( theURIParts[1].toUtf8() );
2049 if ( theURIParts[0] == QLatin1String(
"delimitedtext" ) )
2051 QUrl urlSource = QUrl( theURIParts[1] );
2053 urlDest.setQuery( urlSource.query() );
2054 theURIParts[1] = QUrl::toPercentEncoding( urlDest.toString(), QByteArray(
"" ), QByteArray(
":" ) );
2059 theURIParts[1] = QUrl::toPercentEncoding( theURIParts[1] );
2062 queryItems[i].second = theURIParts.join( QLatin1Char(
':' ) ) ;
2066 query.setQueryItems( queryItems );
2068 QUrl urlDest = QUrl( urlSource );
2069 urlDest.setQuery( query.query() );
2070 src = QString::fromLatin1( urlDest.toEncoded() );
2084 if ( provider == QLatin1String(
"spatialite" ) )
2090 else if ( provider == QLatin1String(
"ogr" ) )
2092 QStringList theURIParts = src.split(
'|' );
2094 src = theURIParts.join( QLatin1Char(
'|' ) );
2096 else if ( provider == QLatin1String(
"gpx" ) )
2098 QStringList theURIParts = src.split(
'?' );
2100 src = theURIParts.join( QLatin1Char(
'?' ) );
2102 else if ( provider == QLatin1String(
"delimitedtext" ) )
2104 QUrl urlSource = QUrl::fromEncoded( src.toLatin1() );
2106 if ( !src.startsWith( QLatin1String(
"file:" ) ) )
2108 QUrl file = QUrl::fromLocalFile( src.left( src.indexOf(
'?' ) ) );
2109 urlSource.setScheme( QStringLiteral(
"file" ) );
2110 urlSource.setPath( file.path() );
2113 QUrl urlDest = QUrl::fromLocalFile( context.
pathResolver().
readPath( urlSource.toLocalFile() ) );
2114 urlDest.setQuery( urlSource.query() );
2115 src = QString::fromLatin1( urlDest.toEncoded() );
2117 else if ( provider == QLatin1String(
"virtual" ) )
2119 QUrl urlSource = QUrl::fromEncoded( src.toLatin1() );
2120 QStringList theURIParts;
2122 QUrlQuery query = QUrlQuery( urlSource.query() );
2123 QList<QPair<QString, QString> > queryItems = query.queryItems();
2125 for (
int i = 0; i < queryItems.size(); i++ )
2127 QString key = queryItems.at( i ).first;
2128 QString value = queryItems.at( i ).second;
2129 if ( key == QLatin1String(
"layer" ) )
2132 theURIParts = value.split(
':' );
2133 theURIParts[1] = QUrl::fromPercentEncoding( theURIParts[1].toUtf8() );
2135 if ( theURIParts[0] == QLatin1String(
"delimitedtext" ) )
2137 QUrl urlSource = QUrl( theURIParts[1] );
2139 if ( !theURIParts[1].startsWith( QLatin1String(
"file:" ) ) )
2141 QUrl file = QUrl::fromLocalFile( theURIParts[1].left( theURIParts[1].indexOf(
'?' ) ) );
2142 urlSource.setScheme( QStringLiteral(
"file" ) );
2143 urlSource.setPath( file.path() );
2146 QUrl urlDest = QUrl::fromLocalFile( context.
pathResolver().
readPath( urlSource.toLocalFile() ) );
2147 urlDest.setQuery( urlSource.query() );
2149 theURIParts[1] = urlDest.toString();
2156 theURIParts[1] = QUrl::toPercentEncoding( theURIParts[1] );
2157 queryItems[i].second = theURIParts.join( QLatin1Char(
':' ) ) ;
2161 query.setQueryItems( queryItems );
2163 QUrl urlDest = QUrl( urlSource );
2164 urlDest.setQuery( query.query() );
2165 src = QString::fromLatin1( urlDest.toEncoded() );
2187 if ( categories.testFlag(
Fields ) )
2189 if ( !mExpressionFieldBuffer )
2191 mExpressionFieldBuffer->
readXml( layerNode );
2203 QDomNodeList referencedLayersNodeList = layerNode.toElement().elementsByTagName( QStringLiteral(
"referencedLayers" ) );
2204 if ( referencedLayersNodeList.size() > 0 )
2206 const QDomNodeList relationNodes { referencedLayersNodeList.at( 0 ).childNodes() };
2207 for (
int i = 0; i < relationNodes.length(); ++i )
2209 const QDomElement relationElement = relationNodes.at( i ).toElement();
2216 QDomNodeList referencingLayersNodeList = layerNode.toElement().elementsByTagName( QStringLiteral(
"referencingLayers" ) );
2217 if ( referencingLayersNodeList.size() > 0 )
2219 const QDomNodeList relationNodes { referencingLayersNodeList.at( 0 ).childNodes() };
2220 for (
int i = 0; i < relationNodes.length(); ++i )
2222 const QDomElement relationElement = relationNodes.at( i ).toElement();
2228 QDomElement layerElement = layerNode.toElement();
2232 readStyle( layerNode, errorMessage, context, categories );
2234 if ( categories.testFlag(
MapTips ) )
2235 mMapTipTemplate = layerNode.namedItem( QStringLiteral(
"mapTip" ) ).toElement().text();
2238 mDisplayExpression = layerNode.namedItem( QStringLiteral(
"previewExpression" ) ).toElement().text();
2241 QString
displayField = layerNode.namedItem( QStringLiteral(
"displayfield" ) ).toElement().text();
2245 if ( mMapTipTemplate.isEmpty() && categories.testFlag(
MapTips ) )
2255 if ( categories.testFlag(
Actions ) )
2256 mActions->
readXml( layerNode );
2258 if ( categories.testFlag(
Fields ) )
2263 QDomNode aliasesNode = layerNode.namedItem( QStringLiteral(
"aliases" ) );
2264 if ( !aliasesNode.isNull() )
2266 QDomElement aliasElem;
2268 QDomNodeList aliasNodeList = aliasesNode.toElement().elementsByTagName( QStringLiteral(
"alias" ) );
2269 for (
int i = 0; i < aliasNodeList.size(); ++i )
2271 aliasElem = aliasNodeList.at( i ).toElement();
2274 if ( aliasElem.hasAttribute( QStringLiteral(
"field" ) ) )
2276 field = aliasElem.attribute( QStringLiteral(
"field" ) );
2280 int index = aliasElem.attribute( QStringLiteral(
"index" ) ).toInt();
2282 if ( index >= 0 && index <
fields().count() )
2288 if ( !aliasElem.attribute( QStringLiteral(
"name" ) ).isEmpty() )
2291 alias = context.
projectTranslator()->
translate( QStringLiteral(
"project:layers:%1:fieldaliases" ).arg( layerNode.namedItem( QStringLiteral(
"id" ) ).toElement().text() ), aliasElem.attribute( QStringLiteral(
"name" ) ) );
2292 QgsDebugMsgLevel(
"context" + QStringLiteral(
"project:layers:%1:fieldaliases" ).arg( layerNode.namedItem( QStringLiteral(
"id" ) ).toElement().text() ) +
" source " + aliasElem.attribute( QStringLiteral(
"name" ) ), 3 );
2297 alias = context.
projectTranslator()->
translate( QStringLiteral(
"project:layers:%1:fieldaliases" ).arg( layerNode.namedItem( QStringLiteral(
"id" ) ).toElement().text() ),
field );
2298 QgsDebugMsgLevel(
"context" + QStringLiteral(
"project:layers:%1:fieldaliases" ).arg( layerNode.namedItem( QStringLiteral(
"id" ) ).toElement().text() ) +
" source " +
field, 3 );
2300 if ( alias == aliasElem.attribute( QStringLiteral(
"field" ) ) )
2304 QgsDebugMsgLevel(
"field " +
field +
" origalias " + aliasElem.attribute( QStringLiteral(
"name" ) ) +
" trans " + alias, 3 );
2305 mAttributeAliasMap.insert(
field, alias );
2310 mDefaultExpressionMap.clear();
2311 QDomNode defaultsNode = layerNode.namedItem( QStringLiteral(
"defaults" ) );
2312 if ( !defaultsNode.isNull() )
2314 QDomNodeList defaultNodeList = defaultsNode.toElement().elementsByTagName( QStringLiteral(
"default" ) );
2315 for (
int i = 0; i < defaultNodeList.size(); ++i )
2317 QDomElement defaultElem = defaultNodeList.at( i ).toElement();
2319 QString
field = defaultElem.attribute( QStringLiteral(
"field" ), QString() );
2320 QString expression = defaultElem.attribute( QStringLiteral(
"expression" ), QString() );
2321 bool applyOnUpdate = defaultElem.attribute( QStringLiteral(
"applyOnUpdate" ), QStringLiteral(
"0" ) ) == QLatin1String(
"1" );
2322 if (
field.isEmpty() || expression.isEmpty() )
2330 mFieldConstraints.clear();
2331 mFieldConstraintStrength.clear();
2332 QDomNode constraintsNode = layerNode.namedItem( QStringLiteral(
"constraints" ) );
2333 if ( !constraintsNode.isNull() )
2335 QDomNodeList constraintNodeList = constraintsNode.toElement().elementsByTagName( QStringLiteral(
"constraint" ) );
2336 for (
int i = 0; i < constraintNodeList.size(); ++i )
2338 QDomElement constraintElem = constraintNodeList.at( i ).toElement();
2340 QString
field = constraintElem.attribute( QStringLiteral(
"field" ), QString() );
2341 int constraints = constraintElem.attribute( QStringLiteral(
"constraints" ), QStringLiteral(
"0" ) ).toInt();
2342 if (
field.isEmpty() || constraints == 0 )
2345 mFieldConstraints.insert(
field,
static_cast< QgsFieldConstraints::Constraints
>( constraints ) );
2347 int uniqueStrength = constraintElem.attribute( QStringLiteral(
"unique_strength" ), QStringLiteral(
"1" ) ).toInt();
2348 int notNullStrength = constraintElem.attribute( QStringLiteral(
"notnull_strength" ), QStringLiteral(
"1" ) ).toInt();
2349 int expStrength = constraintElem.attribute( QStringLiteral(
"exp_strength" ), QStringLiteral(
"1" ) ).toInt();
2356 mFieldConstraintExpressions.clear();
2357 QDomNode constraintExpressionsNode = layerNode.namedItem( QStringLiteral(
"constraintExpressions" ) );
2358 if ( !constraintExpressionsNode.isNull() )
2360 QDomNodeList constraintNodeList = constraintExpressionsNode.toElement().elementsByTagName( QStringLiteral(
"constraint" ) );
2361 for (
int i = 0; i < constraintNodeList.size(); ++i )
2363 QDomElement constraintElem = constraintNodeList.at( i ).toElement();
2365 QString
field = constraintElem.attribute( QStringLiteral(
"field" ), QString() );
2366 QString exp = constraintElem.attribute( QStringLiteral(
"exp" ), QString() );
2367 QString desc = constraintElem.attribute( QStringLiteral(
"desc" ), QString() );
2368 if (
field.isEmpty() || exp.isEmpty() )
2371 mFieldConstraintExpressions.insert(
field, qMakePair( exp, desc ) );
2379 if ( categories.testFlag(
Fields ) || categories.testFlag(
Forms ) )
2383 QDomElement widgetsElem = layerNode.namedItem( QStringLiteral(
"fieldConfiguration" ) ).toElement();
2384 QDomNodeList fieldConfigurationElementList = widgetsElem.elementsByTagName( QStringLiteral(
"field" ) );
2385 for (
int i = 0; i < fieldConfigurationElementList.size(); ++i )
2387 const QDomElement fieldConfigElement = fieldConfigurationElementList.at( i ).toElement();
2388 const QDomElement fieldWidgetElement = fieldConfigElement.elementsByTagName( QStringLiteral(
"editWidget" ) ).at( 0 ).toElement();
2390 QString fieldName = fieldConfigElement.attribute( QStringLiteral(
"name" ) );
2392 if ( categories.testFlag(
Fields ) )
2396 if ( categories.testFlag(
Forms ) )
2398 const QString widgetType = fieldWidgetElement.attribute( QStringLiteral(
"type" ) );
2399 const QDomElement cfgElem = fieldConfigElement.elementsByTagName( QStringLiteral(
"config" ) ).at( 0 ).toElement();
2400 const QDomElement optionsElem = cfgElem.childNodes().at( 0 ).toElement();
2402 if ( widgetType == QLatin1String(
"ValueRelation" ) )
2404 optionsMap[ QStringLiteral(
"Value" ) ] = context.
projectTranslator()->
translate( QStringLiteral(
"project:layers:%1:fields:%2:valuerelationvalue" ).arg( layerNode.namedItem( QStringLiteral(
"id" ) ).toElement().text(), fieldName ), optionsMap[ QStringLiteral(
"Value" ) ].toString() );
2407 mFieldWidgetSetups[fieldName] = setup;
2414 if ( categories.testFlag(
Fields ) )
2416 const QList<QPair<QString, QgsField::ConfigurationFlag>> legacyConfig
2421 for (
const auto &config : legacyConfig )
2423 QDomNode excludeNode = layerNode.namedItem( config.first );
2424 if ( !excludeNode.isNull() )
2426 QDomNodeList attributeNodeList = excludeNode.toElement().elementsByTagName( QStringLiteral(
"attribute" ) );
2427 for (
int i = 0; i < attributeNodeList.size(); ++i )
2429 QString fieldName = attributeNodeList.at( i ).toElement().text();
2430 if ( !mFieldConfigurationFlags.contains( fieldName ) )
2431 mFieldConfigurationFlags[fieldName] = config.second;
2433 mFieldConfigurationFlags[fieldName].setFlag( config.second,
true );
2440 mGeometryOptions->readXml( layerNode.namedItem( QStringLiteral(
"geometryOptions" ) ) );
2442 if ( categories.testFlag(
Forms ) )
2443 mEditFormConfig.
readXml( layerNode, context );
2447 mAttributeTableConfig.
readXml( layerNode );
2448 mConditionalStyles->
readXml( layerNode, context );
2449 mStoredExpressionManager->
readXml( layerNode );
2455 QDomElement mapLayerNode = layerNode.toElement();
2457 && mapLayerNode.attribute( QStringLiteral(
"readOnly" ), QStringLiteral(
"0" ) ).toInt() == 1 )
2462 if ( categories.testFlag(
Legend ) )
2466 const QDomElement legendElem = layerNode.firstChildElement( QStringLiteral(
"legend" ) );
2467 if ( !legendElem.isNull() )
2472 mSetLegendFromStyle =
true;
2500 if ( !rendererElement.isNull() )
2520 if ( categories.testFlag(
Labeling ) )
2524 QDomElement labelingElement = node.firstChildElement( QStringLiteral(
"labeling" ) );
2526 if ( labelingElement.isNull() ||
2527 ( labelingElement.attribute( QStringLiteral(
"type" ) ) == QLatin1String(
"simple" ) && labelingElement.firstChildElement( QStringLiteral(
"settings" ) ).isNull() ) )
2535 labeling = readLabelingFromCustomProperties();
2543 if ( node.toElement().hasAttribute( QStringLiteral(
"labelsEnabled" ) ) )
2544 mLabelsEnabled = node.toElement().attribute( QStringLiteral(
"labelsEnabled" ) ).toInt();
2546 mLabelsEnabled =
true;
2552 QDomNode blendModeNode = node.namedItem( QStringLiteral(
"blendMode" ) );
2553 if ( !blendModeNode.isNull() )
2555 QDomElement e = blendModeNode.toElement();
2560 QDomNode featureBlendModeNode = node.namedItem( QStringLiteral(
"featureBlendMode" ) );
2561 if ( !featureBlendModeNode.isNull() )
2563 QDomElement e = featureBlendModeNode.toElement();
2571 QDomNode layerTransparencyNode = node.namedItem( QStringLiteral(
"layerTransparency" ) );
2572 if ( !layerTransparencyNode.isNull() )
2574 QDomElement e = layerTransparencyNode.toElement();
2575 setOpacity( 1.0 - e.text().toInt() / 100.0 );
2577 QDomNode layerOpacityNode = node.namedItem( QStringLiteral(
"layerOpacity" ) );
2578 if ( !layerOpacityNode.isNull() )
2580 QDomElement e = layerOpacityNode.toElement();
2584 const bool hasScaleBasedVisibiliy { node.attributes().namedItem( QStringLiteral(
"hasScaleBasedVisibilityFlag" ) ).nodeValue() ==
'1' };
2587 const double maxScale { node.attributes().namedItem( QStringLiteral(
"maxScale" ) ).nodeValue().toDouble( &ok ) };
2592 const double minScale { node.attributes().namedItem( QStringLiteral(
"minScale" ) ).nodeValue().toDouble( &ok ) };
2598 QDomElement e = node.toElement();
2601 mSimplifyMethod.
setSimplifyHints(
static_cast< QgsVectorSimplifyMethod::SimplifyHints
>( e.attribute( QStringLiteral(
"simplifyDrawingHints" ), QStringLiteral(
"1" ) ).toInt() ) );
2603 mSimplifyMethod.
setThreshold( e.attribute( QStringLiteral(
"simplifyDrawingTol" ), QStringLiteral(
"1" ) ).toFloat() );
2604 mSimplifyMethod.
setForceLocalOptimization( e.attribute( QStringLiteral(
"simplifyLocal" ), QStringLiteral(
"1" ) ).toInt() );
2605 mSimplifyMethod.
setMaximumScale( e.attribute( QStringLiteral(
"simplifyMaxScale" ), QStringLiteral(
"1" ) ).toFloat() );
2608 mRenderer->
setReferenceScale( e.attribute( QStringLiteral(
"symbologyReferenceScale" ), QStringLiteral(
"-1" ) ).toDouble() );
2612 if ( categories.testFlag(
Diagrams ) )
2616 delete mDiagramRenderer;
2617 mDiagramRenderer =
nullptr;
2618 QDomElement singleCatDiagramElem = node.firstChildElement( QStringLiteral(
"SingleCategoryDiagramRenderer" ) );
2619 if ( !singleCatDiagramElem.isNull() )
2622 mDiagramRenderer->
readXml( singleCatDiagramElem, context );
2624 QDomElement linearDiagramElem = node.firstChildElement( QStringLiteral(
"LinearlyInterpolatedDiagramRenderer" ) );
2625 if ( !linearDiagramElem.isNull() )
2627 if ( linearDiagramElem.hasAttribute( QStringLiteral(
"classificationAttribute" ) ) )
2630 int idx = linearDiagramElem.attribute( QStringLiteral(
"classificationAttribute" ) ).toInt();
2631 if ( idx >= 0 && idx < mFields.
count() )
2632 linearDiagramElem.setAttribute( QStringLiteral(
"classificationField" ), mFields.
at( idx ).
name() );
2636 mDiagramRenderer->
readXml( linearDiagramElem, context );
2639 if ( mDiagramRenderer )
2641 QDomElement diagramSettingsElem = node.firstChildElement( QStringLiteral(
"DiagramLayerSettings" ) );
2642 if ( !diagramSettingsElem.isNull() )
2644 bool oldXPos = diagramSettingsElem.hasAttribute( QStringLiteral(
"xPosColumn" ) );
2645 bool oldYPos = diagramSettingsElem.hasAttribute( QStringLiteral(
"yPosColumn" ) );
2646 bool oldShow = diagramSettingsElem.hasAttribute( QStringLiteral(
"showColumn" ) );
2647 if ( oldXPos || oldYPos || oldShow )
2653 int xPosColumn = diagramSettingsElem.attribute( QStringLiteral(
"xPosColumn" ) ).toInt();
2654 if ( xPosColumn >= 0 && xPosColumn < mFields.
count() )
2659 int yPosColumn = diagramSettingsElem.attribute( QStringLiteral(
"yPosColumn" ) ).toInt();
2660 if ( yPosColumn >= 0 && yPosColumn < mFields.
count() )
2665 int showColumn = diagramSettingsElem.attribute( QStringLiteral(
"showColumn" ) ).toInt();
2666 if ( showColumn >= 0 && showColumn < mFields.
count() )
2669 QDomElement propertiesElem = diagramSettingsElem.ownerDocument().createElement( QStringLiteral(
"properties" ) );
2676 ddp.
writeXml( propertiesElem, defs );
2677 diagramSettingsElem.appendChild( propertiesElem );
2680 delete mDiagramLayerSettings;
2682 mDiagramLayerSettings->
readXml( diagramSettingsElem );
2688 styleChangedSignalBlocker.release();
2698 QDomElement layerElement = node.toElement();
2701 ( void )
writeStyle( node, doc, errorMessage, context, categories );
2704 mGeometryOptions->writeXml( node );
2709 if ( !legendElement.isNull() )
2710 node.appendChild( legendElement );
2717 QDomElement referencedLayersElement = doc.createElement( QStringLiteral(
"referencedLayers" ) );
2718 node.appendChild( referencedLayersElement );
2723 switch ( rel.type() )
2734 QDomElement referencingLayersElement = doc.createElement( QStringLiteral(
"referencingLayers" ) );
2735 node.appendChild( referencedLayersElement );
2738 for (
const QgsRelation &rel : referencedRelations )
2740 switch ( rel.type() )
2752 if ( categories.testFlag(
Fields ) || categories.testFlag(
Forms ) )
2754 QDomElement fieldConfigurationElement;
2756 fieldConfigurationElement = doc.createElement( QStringLiteral(
"fieldConfiguration" ) );
2757 node.appendChild( fieldConfigurationElement );
2761 QDomElement fieldElement = doc.createElement( QStringLiteral(
"field" ) );
2762 fieldElement.setAttribute( QStringLiteral(
"name" ),
field.
name() );
2763 fieldConfigurationElement.appendChild( fieldElement );
2765 if ( categories.testFlag(
Fields ) )
2770 if ( categories.testFlag(
Forms ) )
2775 QDomElement editWidgetElement = doc.createElement( QStringLiteral(
"editWidget" ) );
2776 fieldElement.appendChild( editWidgetElement );
2778 QDomElement editWidgetConfigElement = doc.createElement( QStringLiteral(
"config" ) );
2781 editWidgetElement.appendChild( editWidgetConfigElement );
2787 if ( categories.testFlag(
Fields ) )
2790 QDomElement aliasElem = doc.createElement( QStringLiteral(
"aliases" ) );
2793 QDomElement aliasEntryElem = doc.createElement( QStringLiteral(
"alias" ) );
2794 aliasEntryElem.setAttribute( QStringLiteral(
"field" ),
field.
name() );
2796 aliasEntryElem.setAttribute( QStringLiteral(
"name" ),
field.
alias() );
2797 aliasElem.appendChild( aliasEntryElem );
2799 node.appendChild( aliasElem );
2802 QDomElement defaultsElem = doc.createElement( QStringLiteral(
"defaults" ) );
2805 QDomElement defaultElem = doc.createElement( QStringLiteral(
"default" ) );
2806 defaultElem.setAttribute( QStringLiteral(
"field" ),
field.
name() );
2809 defaultsElem.appendChild( defaultElem );
2811 node.appendChild( defaultsElem );
2814 QDomElement constraintsElem = doc.createElement( QStringLiteral(
"constraints" ) );
2817 QDomElement constraintElem = doc.createElement( QStringLiteral(
"constraint" ) );
2818 constraintElem.setAttribute( QStringLiteral(
"field" ),
field.
name() );
2823 constraintsElem.appendChild( constraintElem );
2825 node.appendChild( constraintsElem );
2828 QDomElement constraintExpressionsElem = doc.createElement( QStringLiteral(
"constraintExpressions" ) );
2831 QDomElement constraintExpressionElem = doc.createElement( QStringLiteral(
"constraint" ) );
2832 constraintExpressionElem.setAttribute( QStringLiteral(
"field" ),
field.
name() );
2835 constraintExpressionsElem.appendChild( constraintExpressionElem );
2837 node.appendChild( constraintExpressionsElem );
2840 if ( !mExpressionFieldBuffer )
2848 mExpressionFieldBuffer->
writeXml( node, doc );
2853 if ( categories.testFlag(
Actions ) )
2858 mAttributeTableConfig.
writeXml( node );
2859 mConditionalStyles->
writeXml( node, doc, context );
2860 mStoredExpressionManager->
writeXml( node );
2863 if ( categories.testFlag(
Forms ) )
2864 mEditFormConfig.
writeXml( node, context );
2868 node.toElement().setAttribute( QStringLiteral(
"readOnly" ), mReadOnly );
2873 QDomElement prevExpElem = doc.createElement( QStringLiteral(
"previewExpression" ) );
2874 QDomText prevExpText = doc.createTextNode( mDisplayExpression );
2875 prevExpElem.appendChild( prevExpText );
2876 node.appendChild( prevExpElem );
2880 if ( categories.testFlag(
MapTips ) )
2882 QDomElement mapTipElem = doc.createElement( QStringLiteral(
"mapTip" ) );
2883 QDomText mapTipText = doc.createTextNode( mMapTipTemplate );
2884 mapTipElem.appendChild( mapTipText );
2885 node.toElement().appendChild( mapTipElem );
2894 QDomElement mapLayerNode = node.toElement();
2907 QDomElement rendererElement = mRenderer->
save( doc, context );
2908 node.appendChild( rendererElement );
2912 if ( categories.testFlag(
Labeling ) )
2916 QDomElement labelingElement = mLabeling->
save( doc, context );
2917 node.appendChild( labelingElement );
2919 mapLayerNode.setAttribute( QStringLiteral(
"labelsEnabled" ), mLabelsEnabled ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
2925 mapLayerNode.setAttribute( QStringLiteral(
"simplifyDrawingHints" ), QString::number( mSimplifyMethod.
simplifyHints() ) );
2926 mapLayerNode.setAttribute( QStringLiteral(
"simplifyAlgorithm" ), QString::number( mSimplifyMethod.
simplifyAlgorithm() ) );
2927 mapLayerNode.setAttribute( QStringLiteral(
"simplifyDrawingTol" ), QString::number( mSimplifyMethod.
threshold() ) );
2928 mapLayerNode.setAttribute( QStringLiteral(
"simplifyLocal" ), mSimplifyMethod.
forceLocalOptimization() ? 1 : 0 );
2929 mapLayerNode.setAttribute( QStringLiteral(
"simplifyMaxScale" ), QString::number( mSimplifyMethod.
maximumScale() ) );
2941 QDomElement blendModeElem = doc.createElement( QStringLiteral(
"blendMode" ) );
2943 blendModeElem.appendChild( blendModeText );
2944 node.appendChild( blendModeElem );
2947 QDomElement featureBlendModeElem = doc.createElement( QStringLiteral(
"featureBlendMode" ) );
2949 featureBlendModeElem.appendChild( featureBlendModeText );
2950 node.appendChild( featureBlendModeElem );
2956 QDomElement layerOpacityElem = doc.createElement( QStringLiteral(
"layerOpacity" ) );
2957 QDomText layerOpacityText = doc.createTextNode( QString::number(
opacity() ) );
2958 layerOpacityElem.appendChild( layerOpacityText );
2959 node.appendChild( layerOpacityElem );
2960 mapLayerNode.setAttribute( QStringLiteral(
"hasScaleBasedVisibilityFlag" ),
hasScaleBasedVisibility() ? 1 : 0 );
2961 mapLayerNode.setAttribute( QStringLiteral(
"maxScale" ),
maximumScale() );
2962 mapLayerNode.setAttribute( QStringLiteral(
"minScale" ),
minimumScale() );
2964 mapLayerNode.setAttribute( QStringLiteral(
"symbologyReferenceScale" ), mRenderer ? mRenderer->
referenceScale() : -1 );
2967 if ( categories.testFlag(
Diagrams ) && mDiagramRenderer )
2969 mDiagramRenderer->
writeXml( mapLayerNode, doc, context );
2970 if ( mDiagramLayerSettings )
2971 mDiagramLayerSettings->
writeXml( mapLayerNode, doc );
2980 QDomElement nameElem = node.firstChildElement( QStringLiteral(
"Name" ) );
2981 if ( nameElem.isNull() )
2983 errorMessage = QStringLiteral(
"Warning: Name element not found within NamedLayer while it's required." );
2999 readSldLabeling( node );
3001 styleChangedSignalBlocker.release();
3009 Q_UNUSED( errorMessage )
3011 QVariantMap localProps = QVariantMap( props );
3020 QDomElement nameNode = doc.createElement( QStringLiteral(
"se:Name" ) );
3021 nameNode.appendChild( doc.createTextNode(
name() ) );
3022 node.appendChild( nameNode );
3024 QDomElement userStyleElem = doc.createElement( QStringLiteral(
"UserStyle" ) );
3025 node.appendChild( userStyleElem );
3027 QDomElement nameElem = doc.createElement( QStringLiteral(
"se:Name" ) );
3028 nameElem.appendChild( doc.createTextNode(
name() ) );
3030 userStyleElem.appendChild( nameElem );
3032 QDomElement featureTypeStyleElem = doc.createElement( QStringLiteral(
"se:FeatureTypeStyle" ) );
3033 userStyleElem.appendChild( featureTypeStyleElem );
3035 mRenderer->
toSld( doc, featureTypeStyleElem, localProps );
3038 mLabeling->
toSld( featureTypeStyleElem, localProps );
3047 if ( !mEditBuffer || !mDataProvider )
3052 if ( mGeometryOptions->isActive() )
3053 mGeometryOptions->apply( geom );
3062 if ( !skipDefaultValue && !mDefaultValueOnUpdateFields.isEmpty() )
3063 updateDefaultValues( fid );
3071 bool result =
false;
3085 if ( mEditBuffer && mDataProvider )
3094 if ( result && !skipDefaultValues && !mDefaultValueOnUpdateFields.isEmpty() )
3095 updateDefaultValues( fid );
3110 for (
auto it = newValues.constBegin(); it != newValues.constEnd(); ++it )
3112 const int field = it.key();
3113 const QVariant newValue = it.value();
3116 if ( oldValues.contains(
field ) )
3117 oldValue = oldValues[
field];
3122 newValuesJoin[
field] = newValue;
3123 oldValuesJoin[
field] = oldValue;
3130 newValuesNotJoin[
field] = newValue;
3131 oldValuesNotJoin[
field] = oldValue;
3140 if ( ! newValuesJoin.isEmpty() && mJoinBuffer )
3145 if ( ! newValuesNotJoin.isEmpty() && mEditBuffer && mDataProvider )
3150 if ( result && !skipDefaultValues && !mDefaultValueOnUpdateFields.isEmpty() )
3152 updateDefaultValues( fid );
3160 if ( !mEditBuffer || !mDataProvider )
3168 if ( attIndex < 0 || attIndex >=
fields().count() )
3172 mFields[ attIndex ].setAlias( QString() );
3173 if ( mAttributeAliasMap.contains(
name ) )
3175 mAttributeAliasMap.remove(
name );
3177 mEditFormConfig.setFields( mFields );
3184 if ( index < 0 || index >=
fields().count() )
3191 if ( mExpressionFieldBuffer )
3207 if ( !mEditBuffer || !mDataProvider )
3223 if ( attIndex < 0 || attIndex >=
fields().count() )
3228 mAttributeAliasMap.insert(
name, aliasString );
3229 mFields[ attIndex ].setAlias( aliasString );
3230 mEditFormConfig.setFields( mFields );
3236 if ( index < 0 || index >=
fields().count() )
3244 if ( index >= 0 && index < mFields.
count() )
3252 return mAttributeAliasMap;
3257 QSet<QString> excludeList;
3258 QMap< QString, QgsField::ConfigurationFlags >::const_iterator flagsIt = mFieldConfigurationFlags.constBegin();
3259 for ( ; flagsIt != mFieldConfigurationFlags.constEnd(); ++flagsIt )
3263 excludeList << flagsIt.key();
3271 QMap< QString, QgsField::ConfigurationFlags >::iterator flagsIt = mFieldConfigurationFlags.begin();
3272 for ( ; flagsIt != mFieldConfigurationFlags.end(); ++flagsIt )
3281 QSet<QString> excludeList;
3282 QMap< QString, QgsField::ConfigurationFlags >::const_iterator flagsIt = mFieldConfigurationFlags.constBegin();
3283 for ( ; flagsIt != mFieldConfigurationFlags.constEnd(); ++flagsIt )
3287 excludeList << flagsIt.key();
3295 QMap< QString, QgsField::ConfigurationFlags >::iterator flagsIt = mFieldConfigurationFlags.begin();
3296 for ( ; flagsIt != mFieldConfigurationFlags.end(); ++flagsIt )
3305 if ( index < 0 || index >=
fields().count() )
3314 if ( !mEditBuffer || !mDataProvider )
3322 bool deleted =
false;
3325 QList<int> attrList = qgis::setToList( qgis::listToSet( attrs ) );
3327 std::sort( attrList.begin(), attrList.end(), std::greater<int>() );
3329 for (
int attr : std::as_const( attrList ) )
3345 if ( context && context->
cascade )
3348 const bool hasRelationsOrJoins = !relations.empty() || mJoinBuffer->
containsJoins();
3349 if ( hasRelationsOrJoins )
3354 if ( handledFeatureIds.contains( fid ) )
3362 handledFeatureIds << fid;
3374 switch ( relation.strength() )
3382 while ( relatedFeaturesIt.
nextFeature( childFeature ) )
3384 childFeatureIds.insert( childFeature.
id() );
3386 if ( childFeatureIds.count() > 0 )
3388 relation.referencingLayer()->startEditing();
3389 relation.referencingLayer()->deleteFeatures( childFeatureIds, context );
3414 bool res = deleteFeatureCascade( fid, context );
3427 const auto constFids = fids;
3429 res = deleteFeatureCascade( fid, context ) && res;
3433 mSelectedFeatureIds.subtract( fids );
3448 if ( !mDataProvider )
3449 return pkAttributesList;
3452 for (
int i = 0; i < mFields.
count(); ++i )
3456 pkAttributesList << i;
3459 return pkAttributesList;
3464 if ( !mDataProvider )
3475 if ( mEditBuffer && !deletedFeatures.empty() )
3477 if ( addedFeatures.size() > deletedFeatures.size() )
3478 return QgsFeatureSource::FeatureAvailability::FeaturesAvailable;
3480 return QgsFeatureSource::FeatureAvailability::FeaturesMaybeAvailable;
3483 if ( ( !mEditBuffer || addedFeatures.empty() ) && mDataProvider && mDataProvider->
empty() )
3484 return QgsFeatureSource::FeatureAvailability::NoFeaturesAvailable;
3486 return QgsFeatureSource::FeatureAvailability::FeaturesAvailable;
3494 mCommitErrors.clear();
3496 if ( !mDataProvider )
3498 mCommitErrors << tr(
"ERROR: no provider" );
3504 mCommitErrors << tr(
"ERROR: layer not editable" );
3510 if ( !mAllowCommit )
3513 mCommitChangesActive =
true;
3515 bool success =
false;
3521 mCommitChangesActive =
false;
3523 if ( !mDeletedFids.empty() )
3526 mDeletedFids.clear();
3565 return mCommitErrors;
3578 if ( !mDataProvider )
3580 mCommitErrors << tr(
"ERROR: no provider" );
3606 mEditBuffer =
nullptr;
3611 if ( rollbackExtent )
3622 return mSelectedFeatureIds.size();
3627 return mSelectedFeatureIds;
3633 features.reserve( mSelectedFeatureIds.count() );
3636 if ( mSelectedFeatureIds.count() <= 8 )
3640 const auto constMSelectedFeatureIds = mSelectedFeatureIds;
3653 features.push_back( f );
3662 if ( mSelectedFeatureIds.isEmpty() )
3668 if ( mSelectedFeatureIds.count() == 1 )
3669 request.
setFilterFid( *mSelectedFeatureIds.constBegin() );
3678 if ( !mEditBuffer || !mDataProvider )
3681 if ( mGeometryOptions->isActive() )
3683 for (
auto feature = features.begin(); feature != features.end(); ++feature )
3686 mGeometryOptions->apply( geom );
3728 if ( !mDisplayExpression.isEmpty() || mFields.
isEmpty() )
3730 return mDisplayExpression;
3735 if ( !candidateName.isEmpty() )
3748 return ( mEditBuffer && mDataProvider );
3757bool QgsVectorLayer::isReadOnly()
const
3765 if ( readonly && mEditBuffer )
3768 mReadOnly = readonly;
3775 if ( ! mDataProvider )
3784 return mEditBuffer && mEditBuffer->
isModified();
3789 bool auxiliaryField =
false;
3793 return auxiliaryField;
3800 auxiliaryField =
true;
3803 return auxiliaryField;
3814 if ( r != mRenderer )
3818 mSymbolFeatureCounted =
false;
3819 mSymbolFeatureCountMap.clear();
3820 mSymbolFeatureIdMap.clear();
3825 if ( refreshRate <= 0 )
3827 mRefreshRendererTimer->stop();
3828 mRefreshRendererTimer->setInterval( 0 );
3832 mRefreshRendererTimer->setInterval( 1000 / refreshRate );
3833 mRefreshRendererTimer->start();
3846 mRendererGenerators << generator;
3852 for (
int i = mRendererGenerators.count() - 1; i >= 0; --i )
3854 if ( mRendererGenerators.at( i )->id() ==
id )
3856 delete mRendererGenerators.at( i );
3857 mRendererGenerators.removeAt( i );
3864 QList< const QgsFeatureRendererGenerator * > res;
3872 if ( !mDataProvider )
3878 QString ignoredError;
3882 mEditCommandActive =
true;
3888 if ( !mDataProvider )
3893 mEditCommandActive =
false;
3894 if ( !mDeletedFids.isEmpty() )
3898 mSelectedFeatureIds.subtract( mDeletedFids );
3901 mDeletedFids.clear();
3908 if ( !mDataProvider )
3919 std::unique_ptr< QUndoCommand > command = std::make_unique< QUndoCommand >();
3920 command->setObsolete(
true );
3923 mEditCommandActive =
false;
3924 mDeletedFids.clear();
3930 return mJoinBuffer->
addJoin( joinInfo );
3936 return mJoinBuffer->
removeJoin( joinLayerId );
3969 if ( oi < 0 || oi >= mExpressionFieldBuffer->
expressions().size() )
3972 return mExpressionFieldBuffer->
expressions().at( oi ).cachedExpression.expression();
3983 if ( !mDataProvider )
3988 mFields = mDataProvider->
fields();
3998 if ( mExpressionFieldBuffer )
4002 QMap< QString, QString >::const_iterator aliasIt = mAttributeAliasMap.constBegin();
4003 for ( ; aliasIt != mAttributeAliasMap.constEnd(); ++aliasIt )
4009 mFields[ index ].setAlias( aliasIt.value() );
4013 QMap< QString, QgsField::ConfigurationFlags >::const_iterator flagsIt = mFieldConfigurationFlags.constBegin();
4014 for ( ; flagsIt != mFieldConfigurationFlags.constEnd(); ++flagsIt )
4020 mFields[index].setConfigurationFlags( flagsIt.value() );
4024 mDefaultValueOnUpdateFields.clear();
4025 QMap< QString, QgsDefaultValue >::const_iterator defaultIt = mDefaultExpressionMap.constBegin();
4026 for ( ; defaultIt != mDefaultExpressionMap.constEnd(); ++defaultIt )
4028 int index = mFields.
lookupField( defaultIt.key() );
4032 mFields[ index ].setDefaultValueDefinition( defaultIt.value() );
4033 if ( defaultIt.value().applyOnUpdate() )
4034 mDefaultValueOnUpdateFields.insert( index );
4037 QMap< QString, QgsFieldConstraints::Constraints >::const_iterator constraintIt = mFieldConstraints.constBegin();
4038 for ( ; constraintIt != mFieldConstraints.constEnd(); ++constraintIt )
4040 int index = mFields.
lookupField( constraintIt.key() );
4053 mFields[ index ].setConstraints( constraints );
4056 QMap< QString, QPair< QString, QString > >::const_iterator constraintExpIt = mFieldConstraintExpressions.constBegin();
4057 for ( ; constraintExpIt != mFieldConstraintExpressions.constEnd(); ++constraintExpIt )
4059 int index = mFields.
lookupField( constraintExpIt.key() );
4070 mFields[ index ].setConstraints( constraints );
4074 for ( ; constraintStrengthIt != mFieldConstraintStrength.constEnd(); ++constraintStrengthIt )
4076 int index = mFields.
lookupField( constraintStrengthIt.key().first );
4086 constraints.
setConstraintStrength( constraintStrengthIt.key().second, constraintStrengthIt.value() );
4087 mFields[ index ].setConstraints( constraints );
4090 auto fieldWidgetIterator = mFieldWidgetSetups.constBegin();
4091 for ( ; fieldWidgetIterator != mFieldWidgetSetups.constEnd(); ++ fieldWidgetIterator )
4093 int index = mFields.
indexOf( fieldWidgetIterator.key() );
4097 mFields[index].setEditorWidgetSetup( fieldWidgetIterator.value() );
4100 if ( oldFields != mFields )
4103 mEditFormConfig.setFields( mFields );
4111 if ( index < 0 || index >= mFields.
count() || !mDataProvider )
4115 if ( expression.isEmpty() )
4119 std::unique_ptr< QgsExpressionContext > tempContext;
4124 evalContext = tempContext.get();
4157 if ( index < 0 || index >= mFields.
count() )
4162 mDefaultExpressionMap.insert( mFields.
at( index ).
name(), definition );
4166 mDefaultExpressionMap.remove( mFields.
at( index ).
name() );
4173 if ( index < 0 || index >= mFields.
count() )
4182 if ( !mDataProvider )
4197 if ( mEditBuffer && ! mDataProvider->
transaction() )
4201 for (
const QVariant &v : constUniqueValues )
4203 vals << v.toString();
4207 QMapIterator< QgsFeatureId, QgsFeature > addedIt( added );
4208 while ( addedIt.hasNext() && ( limit < 0 ||
uniqueValues.count() < limit ) )
4211 QVariant v = addedIt.value().attribute( index );
4214 QString vs = v.toString();
4215 if ( !vals.contains( vs ) )
4224 while ( it.hasNext() && ( limit < 0 ||
uniqueValues.count() < limit ) )
4227 QVariant v = it.value().value( index );
4230 QString vs = v.toString();
4231 if ( !vals.contains( vs ) )
4264 .setSubsetOfAttributes( attList ) );
4267 QVariant currentValue;
4268 QHash<QString, QVariant> val;
4272 val.insert( currentValue.toString(), currentValue );
4273 if ( limit >= 0 && val.size() >= limit )
4279 return qgis::listToSet( val.values() );
4283 Q_ASSERT_X(
false,
"QgsVectorLayer::uniqueValues()",
"Unknown source of the field!" );
4289 QStringList results;
4290 if ( !mDataProvider )
4305 if ( mEditBuffer && ! mDataProvider->
transaction() )
4308 QMapIterator< QgsFeatureId, QgsFeature > addedIt( added );
4309 while ( addedIt.hasNext() && ( limit < 0 || results.count() < limit ) && ( !feedback || !feedback->
isCanceled() ) )
4312 QVariant v = addedIt.value().attribute( index );
4315 QString vs = v.toString();
4316 if ( vs.contains( substring, Qt::CaseInsensitive ) && !results.contains( vs ) )
4324 while ( it.hasNext() && ( limit < 0 || results.count() < limit ) && ( !feedback || !feedback->
isCanceled() ) )
4327 QVariant v = it.value().value( index );
4330 QString vs = v.toString();
4331 if ( vs.contains( substring, Qt::CaseInsensitive ) && !results.contains( vs ) )
4362 QString fieldName = mFields.
at( index ).
name();
4363 request.
setFilterExpression( QStringLiteral(
"\"%1\" ILIKE '%%2%'" ).arg( fieldName, substring ) );
4367 QString currentValue;
4370 currentValue = f.
attribute( index ).toString();
4371 if ( !results.contains( currentValue ) )
4372 results << currentValue;
4374 if ( ( limit >= 0 && results.size() >= limit ) || ( feedback && feedback->
isCanceled() ) )
4384 Q_ASSERT_X(
false,
"QgsVectorLayer::uniqueStringsMatching()",
"Unknown source of the field!" );
4391 minimumOrMaximumValue( index, &minimum,
nullptr );
4398 minimumOrMaximumValue( index,
nullptr, &maximum );
4404 minimumOrMaximumValue( index, &minimum, &maximum );
4407void QgsVectorLayer::minimumOrMaximumValue(
int index, QVariant *minimum, QVariant *maximum )
const
4410 *minimum = QVariant();
4412 *maximum = QVariant();
4414 if ( !mDataProvider )
4434 if ( mEditBuffer && ! mDataProvider->
transaction() )
4437 QMapIterator< QgsFeatureId, QgsFeature > addedIt( added );
4438 while ( addedIt.hasNext() )
4441 const QVariant v = addedIt.value().attribute( index );
4449 while ( it.hasNext() )
4452 const QVariant v = it.value().value( index );
4488 .setSubsetOfAttributes( attList ) );
4491 bool firstValue =
true;
4494 const QVariant currentValue = f.
attribute( index );
4495 if ( currentValue.isNull() )
4501 *minimum = currentValue;
4503 *maximum = currentValue;
4508 if ( minimum && currentValue.isValid() &&
qgsVariantLessThan( currentValue, *minimum ) )
4509 *minimum = currentValue;
4511 *maximum = currentValue;
4518 Q_ASSERT_X(
false,
"QgsVectorLayer::minimumOrMaximumValue()",
"Unknown source of the field!" );
4521void QgsVectorLayer::createEditBuffer()
4555void QgsVectorLayer::clearEditBuffer()
4558 mEditBuffer =
nullptr;
4570 if ( !mDataProvider )
4573 *
error = tr(
"Layer is invalid" );
4579 if ( attrIndex >= 0 )
4586 bool providerOk =
false;
4587 QVariant val = mDataProvider->
aggregate(
aggregate, attrIndex, parameters, context, providerOk, fids );
4601 c.setFidsFilter( *fids );
4602 c.setParameters( parameters );
4603 bool aggregateOk =
false;
4604 const QVariant result =
c.calculate(
aggregate, fieldOrExpression, context, &aggregateOk, feedback );
4607 if ( !aggregateOk &&
error )
4625 return mFeatureBlendMode;
4628void QgsVectorLayer::readSldLabeling(
const QDomNode &node )
4633 QDomElement element = node.toElement();
4634 if ( element.isNull() )
4637 QDomElement userStyleElem = element.firstChildElement( QStringLiteral(
"UserStyle" ) );
4638 if ( userStyleElem.isNull() )
4640 QgsDebugMsgLevel( QStringLiteral(
"Info: UserStyle element not found." ), 4 );
4644 QDomElement featTypeStyleElem = userStyleElem.firstChildElement( QStringLiteral(
"FeatureTypeStyle" ) );
4645 if ( featTypeStyleElem.isNull() )
4647 QgsDebugMsgLevel( QStringLiteral(
"Info: FeatureTypeStyle element not found." ), 4 );
4652 QDomElement mergedFeatTypeStyle = featTypeStyleElem.cloneNode(
false ).toElement();
4657 bool needRuleBasedLabeling =
false;
4660 while ( !featTypeStyleElem.isNull() )
4662 QDomElement ruleElem = featTypeStyleElem.firstChildElement( QStringLiteral(
"Rule" ) );
4663 while ( !ruleElem.isNull() )
4667 bool hasTextSymbolizer =
false;
4668 bool hasRuleBased =
false;
4669 QDomElement ruleChildElem = ruleElem.firstChildElement();
4670 while ( !ruleChildElem.isNull() )
4673 if ( ruleChildElem.localName() == QLatin1String(
"Filter" ) ||
4674 ruleChildElem.localName() == QLatin1String(
"MinScaleDenominator" ) ||
4675 ruleChildElem.localName() == QLatin1String(
"MaxScaleDenominator" ) )
4677 hasRuleBased =
true;
4680 else if ( ruleChildElem.localName() == QLatin1String(
"TextSymbolizer" ) )
4682 QgsDebugMsgLevel( QStringLiteral(
"Info: TextSymbolizer element found" ), 4 );
4683 hasTextSymbolizer =
true;
4686 ruleChildElem = ruleChildElem.nextSiblingElement();
4689 if ( hasTextSymbolizer )
4694 mergedFeatTypeStyle.appendChild( ruleElem.cloneNode().toElement() );
4698 QgsDebugMsgLevel( QStringLiteral(
"Info: Filter or Min/MaxScaleDenominator element found: need a RuleBasedLabeling" ), 4 );
4699 needRuleBasedLabeling =
true;
4704 if ( ruleCount > 1 )
4706 QgsDebugMsgLevel( QStringLiteral(
"Info: More Rule elements found: need a RuleBasedLabeling" ), 4 );
4707 needRuleBasedLabeling =
true;
4711 if ( ruleCount == 0 )
4713 needRuleBasedLabeling =
false;
4716 ruleElem = ruleElem.nextSiblingElement( QStringLiteral(
"Rule" ) );
4718 featTypeStyleElem = featTypeStyleElem.nextSiblingElement( QStringLiteral(
"FeatureTypeStyle" ) );
4721 if ( ruleCount == 0 )
4723 QgsDebugMsgLevel( QStringLiteral(
"Info: No TextSymbolizer element." ), 4 );
4727 QDomElement ruleElem = mergedFeatTypeStyle.firstChildElement( QStringLiteral(
"Rule" ) );
4729 if ( needRuleBasedLabeling )
4733 while ( !ruleElem.isNull() )
4736 QString label, description, filterExp;
4737 int scaleMinDenom = 0, scaleMaxDenom = 0;
4741 QDomElement childElem = ruleElem.firstChildElement();
4742 while ( !childElem.isNull() )
4744 if ( childElem.localName() == QLatin1String(
"Name" ) )
4748 if ( label.isEmpty() )
4749 label = childElem.firstChild().nodeValue();
4751 else if ( childElem.localName() == QLatin1String(
"Description" ) )
4754 QDomElement titleElem = childElem.firstChildElement( QStringLiteral(
"Title" ) );
4755 if ( !titleElem.isNull() )
4757 label = titleElem.firstChild().nodeValue();
4760 QDomElement abstractElem = childElem.firstChildElement( QStringLiteral(
"Abstract" ) );
4761 if ( !abstractElem.isNull() )
4763 description = abstractElem.firstChild().nodeValue();
4766 else if ( childElem.localName() == QLatin1String(
"Abstract" ) )
4769 description = childElem.firstChild().nodeValue();
4771 else if ( childElem.localName() == QLatin1String(
"Title" ) )
4774 label = childElem.firstChild().nodeValue();
4776 else if ( childElem.localName() == QLatin1String(
"Filter" ) )
4792 else if ( childElem.localName() == QLatin1String(
"MinScaleDenominator" ) )
4795 int v = childElem.firstChild().nodeValue().toInt( &ok );
4799 else if ( childElem.localName() == QLatin1String(
"MaxScaleDenominator" ) )
4802 int v = childElem.firstChild().nodeValue().toInt( &ok );
4806 else if ( childElem.localName() == QLatin1String(
"TextSymbolizer" ) )
4808 readSldTextSymbolizer( childElem, settings );
4811 childElem = childElem.nextSiblingElement();
4817 ruleElem = ruleElem.nextSiblingElement();
4827 QDomElement textSymbolizerElem = ruleElem.firstChildElement( QStringLiteral(
"TextSymbolizer" ) );
4829 if ( readSldTextSymbolizer( textSymbolizerElem, s ) )
4837bool QgsVectorLayer::readSldTextSymbolizer(
const QDomNode &node,
QgsPalLayerSettings &settings )
const
4839 if ( node.localName() != QLatin1String(
"TextSymbolizer" ) )
4841 QgsDebugMsgLevel( QStringLiteral(
"Not a TextSymbolizer element: %1" ).arg( node.localName() ), 3 );
4844 QDomElement textSymbolizerElem = node.toElement();
4846 QDomElement labelElem = textSymbolizerElem.firstChildElement( QStringLiteral(
"Label" ) );
4847 if ( !labelElem.isNull() )
4849 QDomElement propertyNameElem = labelElem.firstChildElement( QStringLiteral(
"PropertyName" ) );
4850 if ( !propertyNameElem.isNull() )
4855 QString labelAttribute = propertyNameElem.text();
4859 int fieldIndex = mFields.
lookupField( labelAttribute );
4860 if ( fieldIndex == -1 )
4864 if ( !exp.hasEvalError() )
4870 QgsDebugMsgLevel( QStringLiteral(
"SLD label attribute error: %1" ).arg( exp.evalErrorString() ), 3 );
4876 QgsDebugMsgLevel( QStringLiteral(
"Info: PropertyName element not found." ), 4 );
4887 if ( textSymbolizerElem.hasAttribute( QStringLiteral(
"uom" ) ) )
4892 QString fontFamily = QStringLiteral(
"Sans-Serif" );
4893 int fontPointSize = 10;
4895 int fontWeight = -1;
4896 bool fontItalic =
false;
4897 bool fontUnderline =
false;
4900 QDomElement fontElem = textSymbolizerElem.firstChildElement( QStringLiteral(
"Font" ) );
4901 if ( !fontElem.isNull() )
4904 for ( QgsStringMap::iterator it = fontSvgParams.begin(); it != fontSvgParams.end(); ++it )
4906 QgsDebugMsgLevel( QStringLiteral(
"found fontSvgParams %1: %2" ).arg( it.key(), it.value() ), 4 );
4908 if ( it.key() == QLatin1String(
"font-family" ) )
4910 fontFamily = it.value();
4912 else if ( it.key() == QLatin1String(
"font-style" ) )
4914 fontItalic = ( it.value() == QLatin1String(
"italic" ) ) || ( it.value() == QLatin1String(
"Italic" ) );
4916 else if ( it.key() == QLatin1String(
"font-size" ) )
4919 int fontSize = it.value().toInt( &ok );
4922 fontPointSize = fontSize;
4923 fontUnitSize = sldUnitSize;
4926 else if ( it.key() == QLatin1String(
"font-weight" ) )
4928 if ( ( it.value() == QLatin1String(
"bold" ) ) || ( it.value() == QLatin1String(
"Bold" ) ) )
4929 fontWeight = QFont::Bold;
4931 else if ( it.key() == QLatin1String(
"font-underline" ) )
4933 fontUnderline = ( it.value() == QLatin1String(
"underline" ) ) || ( it.value() == QLatin1String(
"Underline" ) );
4939 QFont font( fontFamily, fontPointSize, fontWeight, fontItalic );
4940 font.setUnderline( fontUnderline );
4942 format.
setSize( fontPointSize );
4946 QDomElement fillElem = textSymbolizerElem.firstChildElement( QStringLiteral(
"Fill" ) );
4948 Qt::BrushStyle textBrush = Qt::SolidPattern;
4950 if ( textColor.isValid() )
4952 QgsDebugMsgLevel( QStringLiteral(
"Info: textColor %1." ).arg( QVariant( textColor ).toString() ), 4 );
4959 QDomElement haloElem = textSymbolizerElem.firstChildElement( QStringLiteral(
"Halo" ) );
4960 if ( !haloElem.isNull() )
4965 QDomElement radiusElem = haloElem.firstChildElement( QStringLiteral(
"Radius" ) );
4966 if ( !radiusElem.isNull() )
4969 double bufferSize = radiusElem.text().toDouble( &ok );
4972 bufferSettings.
setSize( bufferSize );
4977 QDomElement haloFillElem = haloElem.firstChildElement( QStringLiteral(
"Fill" ) );
4979 Qt::BrushStyle bufferBrush = Qt::SolidPattern;
4981 if ( bufferColor.isValid() )
4983 QgsDebugMsgLevel( QStringLiteral(
"Info: bufferColor %1." ).arg( QVariant( bufferColor ).toString() ), 4 );
4984 bufferSettings.
setColor( bufferColor );
4989 QDomElement labelPlacementElem = textSymbolizerElem.firstChildElement( QStringLiteral(
"LabelPlacement" ) );
4990 if ( !labelPlacementElem.isNull() )
4993 QDomElement pointPlacementElem = labelPlacementElem.firstChildElement( QStringLiteral(
"PointPlacement" ) );
4994 if ( !pointPlacementElem.isNull() )
5002 QDomElement displacementElem = pointPlacementElem.firstChildElement( QStringLiteral(
"Displacement" ) );
5003 if ( !displacementElem.isNull() )
5005 QDomElement displacementXElem = displacementElem.firstChildElement( QStringLiteral(
"DisplacementX" ) );
5006 if ( !displacementXElem.isNull() )
5009 double xOffset = displacementXElem.text().toDouble( &ok );
5016 QDomElement displacementYElem = displacementElem.firstChildElement( QStringLiteral(
"DisplacementY" ) );
5017 if ( !displacementYElem.isNull() )
5020 double yOffset = displacementYElem.text().toDouble( &ok );
5028 QDomElement anchorPointElem = pointPlacementElem.firstChildElement( QStringLiteral(
"AnchorPoint" ) );
5029 if ( !anchorPointElem.isNull() )
5031 QDomElement anchorPointXElem = anchorPointElem.firstChildElement( QStringLiteral(
"AnchorPointX" ) );
5032 if ( !anchorPointXElem.isNull() )
5035 double xOffset = anchorPointXElem.text().toDouble( &ok );
5042 QDomElement anchorPointYElem = anchorPointElem.firstChildElement( QStringLiteral(
"AnchorPointY" ) );
5043 if ( !anchorPointYElem.isNull() )
5046 double yOffset = anchorPointYElem.text().toDouble( &ok );
5055 QDomElement rotationElem = pointPlacementElem.firstChildElement( QStringLiteral(
"Rotation" ) );
5056 if ( !rotationElem.isNull() )
5059 double rotation = rotationElem.text().toDouble( &ok );
5069 QDomElement linePlacementElem = labelPlacementElem.firstChildElement( QStringLiteral(
"LinePlacement" ) );
5070 if ( !linePlacementElem.isNull() )
5079 QDomElement vendorOptionElem = textSymbolizerElem.firstChildElement( QStringLiteral(
"VendorOption" ) );
5080 while ( !vendorOptionElem.isNull() && vendorOptionElem.localName() == QLatin1String(
"VendorOption" ) )
5082 QString optionName = vendorOptionElem.attribute( QStringLiteral(
"name" ) );
5083 QString optionValue;
5084 if ( vendorOptionElem.firstChild().nodeType() == QDomNode::TextNode )
5086 optionValue = vendorOptionElem.firstChild().nodeValue();
5090 if ( vendorOptionElem.firstChild().nodeType() == QDomNode::ElementNode &&
5091 vendorOptionElem.firstChild().localName() == QLatin1String(
"Literal" ) )
5093 QgsDebugMsg( vendorOptionElem.firstChild().localName() );
5094 optionValue = vendorOptionElem.firstChild().firstChild().nodeValue();
5098 QgsDebugMsg( QStringLiteral(
"unexpected child of %1 named %2" ).arg( vendorOptionElem.localName(), optionName ) );
5102 if ( !optionName.isEmpty() && !optionValue.isEmpty() )
5104 vendorOptions[ optionName ] = optionValue;
5107 vendorOptionElem = vendorOptionElem.nextSiblingElement();
5109 if ( !vendorOptions.isEmpty() )
5111 for ( QgsStringMap::iterator it = vendorOptions.begin(); it != vendorOptions.end(); ++it )
5113 if ( it.key() == QLatin1String(
"underlineText" ) && it.value() == QLatin1String(
"true" ) )
5115 font.setUnderline(
true );
5118 else if ( it.key() == QLatin1String(
"strikethroughText" ) && it.value() == QLatin1String(
"true" ) )
5120 font.setStrikeOut(
true );
5123 else if ( it.key() == QLatin1String(
"maxDisplacement" ) )
5127 else if ( it.key() == QLatin1String(
"followLine" ) && it.value() == QLatin1String(
"true" ) )
5138 else if ( it.key() == QLatin1String(
"maxAngleDelta" ) )
5141 double angle = it.value().toDouble( &ok );
5149 else if ( it.key() == QLatin1String(
"conflictResolution" ) && it.value() == QLatin1String(
"false" ) )
5153 else if ( it.key() == QLatin1String(
"forceLeftToRight" ) && it.value() == QLatin1String(
"false" ) )
5155 settings.
upsidedownLabels = Qgis::UpsideDownLabelHandling::AlwaysAllowUpsideDown;
5157 else if ( it.key() == QLatin1String(
"group" ) && it.value() == QLatin1String(
"yes" ) )
5161 else if ( it.key() == QLatin1String(
"labelAllGroup" ) && it.value() == QLatin1String(
"true" ) )
5175 return mEditFormConfig;
5184 mEditFormConfig.onRelationsLoaded();
5190 return mMapTipTemplate;
5195 if ( mMapTipTemplate == mapTip )
5198 mMapTipTemplate = mapTip;
5233 if ( !mDiagramLayerSettings )
5235 *mDiagramLayerSettings = s;
5241 QString myMetadata = QStringLiteral(
"<html><head></head>\n<body>\n" );
5246 myMetadata += QStringLiteral(
"<h1>" ) + tr(
"Information from provider" ) + QStringLiteral(
"</h1>\n<hr>\n" );
5247 myMetadata += QLatin1String(
"<table class=\"list-view\">\n" );
5252 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"Storage" ) + QStringLiteral(
"</td><td>" ) +
storageType() + QStringLiteral(
"</td></tr>\n" );
5258 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"Comment" ) + QStringLiteral(
"</td><td>" ) +
dataComment() + QStringLiteral(
"</td></tr>\n" );
5265 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"Encoding" ) + QStringLiteral(
"</td><td>" ) + provider->
encoding() + QStringLiteral(
"</td></tr>\n" );
5280 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"Geometry" ) + QStringLiteral(
"</td><td>" ) + typeString + QStringLiteral(
"</td></tr>\n" );
5284 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"Extent" ) + QStringLiteral(
"</td><td>" ) +
extent().
toString() + QStringLiteral(
"</td></tr>\n" );
5288 QLocale locale = QLocale();
5289 locale.setNumberOptions( locale.numberOptions() &= ~QLocale::NumberOption::OmitGroupSeparator );
5290 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" )
5291 + tr(
"Feature count" ) + QStringLiteral(
"</td><td>" )
5293 + QStringLiteral(
"</td></tr>\n" );
5296 myMetadata += QLatin1String(
"</table>\n<br><br>" );
5305 myMetadata += QStringLiteral(
"<h1>" ) + tr(
"Identification" ) + QStringLiteral(
"</h1>\n<hr>\n" );
5307 myMetadata += QLatin1String(
"<br><br>\n" );
5310 myMetadata += QStringLiteral(
"<h1>" ) + tr(
"Extent" ) + QStringLiteral(
"</h1>\n<hr>\n" );
5312 myMetadata += QLatin1String(
"<br><br>\n" );
5315 myMetadata += QStringLiteral(
"<h1>" ) + tr(
"Access" ) + QStringLiteral(
"</h1>\n<hr>\n" );
5317 myMetadata += QLatin1String(
"<br><br>\n" );
5320 myMetadata += QStringLiteral(
"<h1>" ) + tr(
"Fields" ) + QStringLiteral(
"</h1>\n<hr>\n<table class=\"list-view\">\n" );
5324 if ( !pkAttrList.isEmpty() )
5326 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"Primary key attributes" ) + QStringLiteral(
"</td><td>" );
5327 const auto constPkAttrList = pkAttrList;
5328 for (
int idx : constPkAttrList )
5332 myMetadata += QLatin1String(
"</td></tr>\n" );
5338 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"Count" ) + QStringLiteral(
"</td><td>" ) + QString::number( myFields.
size() ) + QStringLiteral(
"</td></tr>\n" );
5340 myMetadata += QLatin1String(
"</table>\n<br><table width=\"100%\" class=\"tabular-view\">\n" );
5341 myMetadata += QLatin1String(
"<tr><th>" ) + tr(
"Field" ) + QLatin1String(
"</th><th>" ) + tr(
"Type" ) + QLatin1String(
"</th><th>" ) + tr(
"Length" ) + QLatin1String(
"</th><th>" ) + tr(
"Precision" ) + QLatin1String(
"</th><th>" ) + tr(
"Comment" ) + QLatin1String(
"</th></tr>\n" );
5343 for (
int i = 0; i < myFields.
size(); ++i )
5348 rowClass = QStringLiteral(
"class=\"odd-row\"" );
5349 myMetadata += QLatin1String(
"<tr " ) + rowClass + QLatin1String(
"><td>" ) + myField.
name() + QLatin1String(
"</td><td>" ) + myField.
typeName() + QLatin1String(
"</td><td>" ) + QString::number( myField.
length() ) + QLatin1String(
"</td><td>" ) + QString::number( myField.
precision() ) + QLatin1String(
"</td><td>" ) + myField.
comment() + QLatin1String(
"</td></tr>\n" );
5353 myMetadata += QLatin1String(
"</table>\n<br><br>" );
5356 myMetadata += QStringLiteral(
"<h1>" ) + tr(
"Contacts" ) + QStringLiteral(
"</h1>\n<hr>\n" );
5358 myMetadata += QLatin1String(
"<br><br>\n" );
5361 myMetadata += QStringLiteral(
"<h1>" ) + tr(
"Links" ) + QStringLiteral(
"</h1>\n<hr>\n" );
5363 myMetadata += QLatin1String(
"<br><br>\n" );
5366 myMetadata += QStringLiteral(
"<h1>" ) + tr(
"History" ) + QStringLiteral(
"</h1>\n<hr>\n" );
5368 myMetadata += QLatin1String(
"<br><br>\n" );
5370 myMetadata += QLatin1String(
"\n</body>\n</html>\n" );
5374void QgsVectorLayer::invalidateSymbolCountedFlag()
5376 mSymbolFeatureCounted =
false;
5379void QgsVectorLayer::onFeatureCounterCompleted()
5382 mFeatureCounter =
nullptr;
5385void QgsVectorLayer::onFeatureCounterTerminated()
5387 mFeatureCounter =
nullptr;
5390void QgsVectorLayer::onJoinedFieldsChanged()
5396void QgsVectorLayer::onFeatureDeleted(
QgsFeatureId fid )
5398 if ( mEditCommandActive || mCommitChangesActive )
5400 mDeletedFids << fid;
5404 mSelectedFeatureIds.remove( fid );
5411void QgsVectorLayer::onRelationsLoaded()
5413 mEditFormConfig.onRelationsLoaded();
5416void QgsVectorLayer::onSymbolsCounted()
5418 if ( mFeatureCounter )
5420 mSymbolFeatureCounted =
true;
5434 return mWeakRelations;
5454 bool useAsDefault,
const QString &uiFileContent, QString &msgError, QgsMapLayer::StyleCategories categories )
5457 QString sldStyle, qmlStyle;
5458 QDomDocument qmlDocument, sldDocument;
5461 if ( !msgError.isNull() )
5465 qmlStyle = qmlDocument.toString();
5468 if ( !msgError.isNull() )
5472 sldStyle = sldDocument.toString();
5476 description, uiFileContent, useAsDefault, msgError );
5490 QString joinKey = mAuxiliaryLayerKey;
5491 if ( !key.isEmpty() )
5494 if ( storage.
isValid() && !joinKey.isEmpty() )
5517 mAuxiliaryLayerKey.clear();
5519 if ( mAuxiliaryLayer )
5532 mAuxiliaryLayer.reset( alayer );
5533 if ( mAuxiliaryLayer )
5534 mAuxiliaryLayer->setParent(
this );
5540 return mAuxiliaryLayer.get();
5545 return mAuxiliaryLayer.get();
5551 QString returnMessage;
5552 QString qml, errorMsg;
5557 if ( !qml.isEmpty() )
5559 QDomDocument myDocument( QStringLiteral(
"qgis" ) );
5560 myDocument.setContent( qml );
5562 returnMessage = QObject::tr(
"Loaded from Provider" );
5572 return returnMessage;
5577 if ( mDataProvider )
5582void QgsVectorLayer::emitDataChanged()
5584 if ( mDataChangedFired )
5589 mDataChangedFired =
true;
5591 mDataChangedFired =
false;
5594void QgsVectorLayer::onAfterCommitChangesDependency()
5596 mDataChangedFired =
true;
5598 mDataChangedFired =
false;
5603 QSet<QgsMapLayerDependency> deps;
5604 const auto constODeps = oDeps;
5611 QSet<QgsMapLayerDependency> toAdd = deps -
dependencies();
5628 if ( mDataProvider )
5649 if ( ! toAdd.isEmpty() )