30 #include <QPainterPath>
32 #include <QProgressDialog>
36 #include <QStringBuilder>
38 #include <QUndoCommand>
105 #ifdef TESTPROVIDERLIB
111 const QString &qmlStyle,
112 const QString &sldStyle,
113 const QString &styleName,
114 const QString &styleDescription,
115 const QString &uiFileContent,
129 QStringList &descriptions,
147 const QString &baseName,
148 const QString &providerKey,
153 , mAuxiliaryLayer( nullptr )
154 , mAuxiliaryLayerKey( QString() )
155 , mReadExtentFromXml( options.readExtentFromXml )
165 mGeometryOptions = qgis::make_unique<QgsGeometryOptions>();
169 mStoredExpressionManager->setParent(
this );
172 mJoinBuffer->setParent(
this );
177 if ( !vectorLayerPath.isEmpty() && !
mProviderKey.isEmpty() )
183 for (
const QgsField &field : qgis::as_const( mFields ) )
185 mAttributeAliasMap.insert( field.name(), QString() );
191 if ( !mTemporalProperties->
isActive() )
208 mSimplifyMethod.
setThreshold( settings.
value( QStringLiteral(
"qgis/simplifyDrawingTol" ), mSimplifyMethod.
threshold() ).toFloat() );
220 delete mDataProvider;
223 delete mExpressionFieldBuffer;
225 delete mDiagramLayerSettings;
226 delete mDiagramRenderer;
231 delete mConditionalStyles;
232 delete mStoredExpressionManager;
234 if ( mFeatureCounter )
235 mFeatureCounter->
cancel();
261 QList<QgsVectorLayerJoinInfo> joins =
vectorJoins();
262 const auto constJoins = joins;
284 for (
const QgsAction &action : constActions )
320 auto constraintIt = constraints.constBegin();
321 for ( ; constraintIt != constraints.constEnd(); ++ constraintIt )
397 p.setPen( QColor( 50, 100, 120, 200 ) );
398 p.setBrush( QColor( 200, 200, 210, 120 ) );
399 p.drawEllipse( x - m, y - m, m * 2 + 1, m * 2 + 1 );
403 p.setPen( QColor( 255, 0, 0 ) );
404 p.drawLine( x - m, y + m, x + m, y - m );
405 p.drawLine( x - m, y - m, x + m, y + m );
411 mSelectedFeatureIds.insert( fid );
412 mPreviousSelectedFeatureIds.clear();
419 mSelectedFeatureIds.unite( featureIds );
420 mPreviousSelectedFeatureIds.clear();
427 mSelectedFeatureIds.remove( fid );
428 mPreviousSelectedFeatureIds.clear();
435 mSelectedFeatureIds.subtract( featureIds );
436 mPreviousSelectedFeatureIds.clear();
449 .setFilterRect( rect )
451 .setNoAttributes() );
456 newSelection << feat.
id();
485 newSelection << feat.
id();
507 bool matches = exp.
evaluate( &context ).toBool();
511 newSelection << feat.
id();
515 newSelection << feat.
id();
534 newSelection = mSelectedFeatureIds + ids;
538 newSelection = mSelectedFeatureIds - ids;
542 newSelection = mSelectedFeatureIds.intersect( ids );
546 QgsFeatureIds deselectedFeatures = mSelectedFeatureIds - newSelection;
547 mSelectedFeatureIds = newSelection;
548 mPreviousSelectedFeatureIds.clear();
556 if ( !intersectingIds.isEmpty() )
558 QgsDebugMsgLevel( QStringLiteral(
"Trying to select and deselect the same item at the same time. Unsure what to do. Selecting dubious items." ), 3 );
561 mSelectedFeatureIds -= deselectIds;
562 mSelectedFeatureIds += selectIds;
563 mPreviousSelectedFeatureIds.clear();
571 ids.subtract( mSelectedFeatureIds );
586 .setFilterRect( rect )
588 .setNoAttributes() );
596 if ( mSelectedFeatureIds.contains( fet.
id() ) )
598 deselectIds << fet.
id();
602 selectIds << fet.
id();
611 if ( mSelectedFeatureIds.isEmpty() )
616 mPreviousSelectedFeatureIds = previous;
621 if ( mPreviousSelectedFeatureIds.isEmpty() || !mSelectedFeatureIds.empty() )
629 return mDataProvider;
634 return mDataProvider;
639 return mTemporalProperties;
644 if (
mValid && mDataProvider && mDataProvider->
encoding() != encoding )
653 delete mDiagramRenderer;
654 mDiagramRenderer = r;
671 if ( !
mValid || !
isSpatial() || mSelectedFeatureIds.isEmpty() || !mDataProvider )
683 .setFilterFids( mSelectedFeatureIds )
684 .setNoAttributes() );
697 .setNoAttributes() );
701 if ( mSelectedFeatureIds.contains( fet.
id() ) )
712 if ( retval.
width() == 0.0 || retval.
height() == 0.0 )
721 retval.
set( -1.0, -1.0, 1.0, 1.0 );
730 return mLabelsEnabled &&
static_cast< bool >( mLabeling );
735 mLabelsEnabled = enabled;
740 if ( !mDiagramRenderer || !mDiagramLayerSettings )
743 QList<QgsDiagramSettings> settingList = mDiagramRenderer->
diagramSettings();
744 if ( !settingList.isEmpty() )
746 return settingList.at( 0 ).enabled;
753 if ( !mSymbolFeatureCounted )
756 return mSymbolFeatureCountMap.value( legendKey, -1 );
761 if ( !mSymbolFeatureCounted )
764 return mSymbolFeatureIdMap.value( legendKey,
QgsFeatureIds() );
768 if ( ( mSymbolFeatureCounted || mFeatureCounter ) && !( storeSymbolFids && mSymbolFeatureIdMap.isEmpty() ) )
769 return mFeatureCounter;
771 mSymbolFeatureCountMap.clear();
772 mSymbolFeatureIdMap.clear();
777 return mFeatureCounter;
779 if ( !mDataProvider )
782 return mFeatureCounter;
787 return mFeatureCounter;
790 if ( !mFeatureCounter || ( storeSymbolFids && mSymbolFeatureIdMap.isEmpty() ) )
793 connect( mFeatureCounter, &
QgsTask::taskCompleted,
this, &QgsVectorLayer::onFeatureCounterCompleted, Qt::UniqueConnection );
794 connect( mFeatureCounter, &
QgsTask::taskTerminated,
this, &QgsVectorLayer::onFeatureCounterTerminated, Qt::UniqueConnection );
798 return mFeatureCounter;
804 if ( force || !mReadExtentFromXml || ( mReadExtentFromXml && mXmlExtent.
isNull() ) )
805 mValidExtent =
false;
816 if ( !mDefaultValueOnUpdateFields.isEmpty() )
821 int size = mFields.
size();
822 for (
int idx : qgis::as_const( mDefaultValueOnUpdateFields ) )
824 if ( idx < 0 || idx >= size )
841 if ( !mValidExtent && mLazyExtent && mDataProvider && !mDataProvider->
hasMetadata() && mReadExtentFromXml && !mXmlExtent.
isNull() )
848 if ( !mValidExtent && mLazyExtent && mDataProvider && mDataProvider->
isValid() )
865 if ( !
mValid || !mDataProvider )
867 QgsDebugMsgLevel( QStringLiteral(
"invoked with invalid layer or null mDataProvider" ), 3 );
889 if ( it->hasGeometry() )
900 .setNoAttributes() );
935 if ( !
mValid || !mDataProvider )
937 QgsDebugMsgLevel( QStringLiteral(
"invoked with invalid layer or null mDataProvider" ), 3 );
938 return customProperty( QStringLiteral(
"storedSubsetString" ) ).toString();
945 if ( !
mValid || !mDataProvider )
947 QgsDebugMsgLevel( QStringLiteral(
"invoked with invalid layer or null mDataProvider or while editing" ), 3 );
951 else if ( mEditBuffer )
980 double maximumSimplificationScale = mSimplifyMethod.
maximumScale();
983 return !( maximumSimplificationScale > 1 && renderContext.
rendererScale() <= maximumSimplificationScale );
990 return mConditionalStyles;
995 if ( !
mValid || !mDataProvider )
1013 if ( !
mValid || !mEditBuffer || !mDataProvider )
1017 if ( mGeometryOptions->isActive() )
1020 mGeometryOptions->apply( geom );
1024 bool success = mEditBuffer->
addFeature( feature );
1031 success = mJoinBuffer->
addFeature( feature );
1039 if ( !mEditBuffer || !mDataProvider )
1045 if ( currentFeature.
isValid() )
1047 bool hasChanged =
false;
1048 bool hasError =
false;
1060 QgsDebugMsgLevel( QStringLiteral(
"geometry of feature %1 could not be changed." ).arg( updatedFeature.
id() ), 3 );
1067 for (
int attr = 0; attr < fa.count(); ++attr )
1069 if ( fa.at( attr ) != ca.at( attr ) )
1077 QgsDebugMsgLevel( QStringLiteral(
"attribute %1 of feature %2 could not be changed." ).arg( attr ).arg( updatedFeature.
id() ), 3 );
1082 if ( hasChanged && !mDefaultValueOnUpdateFields.isEmpty() && !skipDefaultValues )
1083 updateDefaultValues( updatedFeature.
id(), updatedFeature );
1089 QgsDebugMsgLevel( QStringLiteral(
"feature %1 could not be retrieved" ).arg( updatedFeature.
id() ), 3 );
1097 if ( !
mValid || !mEditBuffer || !mDataProvider )
1101 bool result = utils.
insertVertex( x, y, atFeatureId, beforeVertex );
1110 if ( !
mValid || !mEditBuffer || !mDataProvider )
1114 bool result = utils.
insertVertex( point, atFeatureId, beforeVertex );
1123 if ( !
mValid || !mEditBuffer || !mDataProvider )
1127 bool result = utils.
moveVertex( x, y, atFeatureId, atVertex );
1136 if ( !
mValid || !mEditBuffer || !mDataProvider )
1140 bool result = utils.
moveVertex( p, atFeatureId, atVertex );
1149 if ( !
mValid || !mEditBuffer || !mDataProvider )
1174 int count = mSelectedFeatureIds.size();
1188 *deletedCount = deleted;
1191 return deleted == count;
1194 static const QgsPointSequence vectorPointXY2pointSequence(
const QVector<QgsPointXY> &points )
1197 pts.reserve( points.size() );
1198 QVector<const QgsPointXY>::iterator it = points.constBegin();
1199 while ( it != points.constEnd() )
1208 return addRing( vectorPointXY2pointSequence( ring ), featureId );
1213 if ( !
mValid || !mEditBuffer || !mDataProvider )
1214 return QgsGeometry::OperationResult::LayerNotEditable;
1220 if ( !mSelectedFeatureIds.isEmpty() )
1222 result = utils.
addRing( ring, mSelectedFeatureIds, featureId );
1225 if ( result != QgsGeometry::OperationResult::Success )
1236 if ( !
mValid || !mEditBuffer || !mDataProvider )
1239 return QgsGeometry::OperationResult::LayerNotEditable;
1244 return QgsGeometry::OperationResult::InvalidInputGeometryType;
1250 return QgsGeometry::OperationResult::AddRingNotClosed;
1257 if ( !mSelectedFeatureIds.isEmpty() )
1259 result = utils.
addRing(
static_cast< QgsCurve *
>( ring->
clone() ), mSelectedFeatureIds, featureId );
1262 if ( result != QgsGeometry::OperationResult::Success )
1275 pts.reserve( points.size() );
1276 for ( QList<QgsPointXY>::const_iterator it = points.constBegin(); it != points.constEnd() ; ++it )
1285 return addPart( vectorPointXY2pointSequence( points ) );
1290 if ( !
mValid || !mEditBuffer || !mDataProvider )
1291 return QgsGeometry::OperationResult::LayerNotEditable;
1295 if ( mSelectedFeatureIds.empty() )
1298 return QgsGeometry::OperationResult::SelectionIsEmpty;
1300 else if ( mSelectedFeatureIds.size() > 1 )
1303 return QgsGeometry::OperationResult::SelectionIsGreaterThanOne;
1309 if ( result == QgsGeometry::OperationResult::Success )
1316 if ( !
mValid || !mEditBuffer || !mDataProvider )
1317 return QgsGeometry::OperationResult::LayerNotEditable;
1321 if ( mSelectedFeatureIds.empty() )
1324 return QgsGeometry::OperationResult::SelectionIsEmpty;
1326 else if ( mSelectedFeatureIds.size() > 1 )
1329 return QgsGeometry::OperationResult::SelectionIsGreaterThanOne;
1335 if ( result == QgsGeometry::OperationResult::Success )
1342 if ( !
mValid || !mEditBuffer || !mDataProvider )
1343 return QgsGeometry::OperationResult::LayerNotEditable;
1348 if ( result == QgsGeometry::OperationResult::Success )
1355 return splitParts( vectorPointXY2pointSequence( splitLine ), topologicalEditing );
1359 if ( !
mValid || !mEditBuffer || !mDataProvider )
1360 return QgsGeometry::OperationResult::LayerNotEditable;
1363 return utils.
splitParts( splitLine, topologicalEditing );
1367 return splitFeatures( vectorPointXY2pointSequence( splitLine ), topologicalEditing );
1372 if ( !
mValid || !mEditBuffer || !mDataProvider )
1373 return QgsGeometry::OperationResult::LayerNotEditable;
1376 return utils.
splitFeatures( splitLine, topologicalEditing );
1381 if ( !
mValid || !mEditBuffer || !mDataProvider )
1395 if ( !
mValid || !mEditBuffer || !mDataProvider )
1413 if ( !
mValid || !mDataProvider )
1475 if ( mDataProvider )
1487 if ( !mRenderer->
accept( visitor ) )
1491 if ( !mLabeling->
accept( visitor ) )
1502 QDomNode pkeyNode = layer_node.namedItem( QStringLiteral(
"provider" ) );
1504 if ( pkeyNode.isNull() )
1510 QDomElement pkeyElt = pkeyNode.toElement();
1520 else if (
mDataSource.contains( QLatin1String(
"dbname=" ) ) )
1536 const QDomElement elem = layer_node.toElement();
1539 if ( elem.hasAttribute( QStringLiteral(
"wkbType" ) ) )
1540 mWkbType =
qgsEnumKeyToValue( elem.attribute( QStringLiteral(
"wkbType" ) ), mWkbType );
1543 QDomElement pkeyElem = pkeyNode.toElement();
1544 if ( !pkeyElem.isNull() )
1546 QString encodingString = pkeyElem.attribute( QStringLiteral(
"encoding" ) );
1547 if ( mDataProvider && !encodingString.isEmpty() )
1554 mJoinBuffer->
readXml( layer_node );
1566 QDomNode depsNode = layer_node.namedItem( QStringLiteral(
"dataDependencies" ) );
1567 QDomNodeList depsNodes = depsNode.childNodes();
1568 QSet<QgsMapLayerDependency> sources;
1569 for (
int i = 0; i < depsNodes.count(); i++ )
1571 QString
source = depsNodes.at( i ).toElement().attribute( QStringLiteral(
"id" ) );
1577 QDomElement legendElem = layer_node.firstChildElement( QStringLiteral(
"legend" ) );
1578 if ( !legendElem.isNull() )
1583 if ( mReadExtentFromXml )
1585 QDomNode extentNode = layer_node.namedItem( QStringLiteral(
"extent" ) );
1586 if ( !extentNode.isNull() )
1593 const QDomNode asNode = layer_node.namedItem( QStringLiteral(
"auxiliaryLayer" ) );
1594 const QDomElement asElem = asNode.toElement();
1595 if ( !asElem.isNull() )
1597 mAuxiliaryLayerKey = asElem.attribute( QStringLiteral(
"key" ) );
1601 mServerProperties->readXml( layer_node );
1611 setDataSource( dataSource, baseName, provider, options, loadDefaultStyleFlag );
1620 setDataProvider( provider, options );
1634 bool defaultLoadedFlag =
false;
1639 std::unique_ptr< QgsFeatureRenderer > defaultRenderer( mDataProvider->
createRenderer() );
1640 if ( defaultRenderer )
1642 defaultLoadedFlag =
true;
1649 if ( !defaultLoadedFlag && loadDefaultStyleFlag )
1655 if ( !defaultLoadedFlag &&
isSpatial() )
1665 std::unique_ptr< QgsAbstractVectorLayerLabeling > defaultLabeling( mDataProvider->
createLabeling() );
1666 if ( defaultLabeling )
1683 std::unique_ptr< QgsFeatureRenderer > defaultRenderer( mDataProvider->
createRenderer() );
1684 if ( defaultRenderer )
1699 delete mDataProvider;
1706 if ( provider.compare( QLatin1String(
"postgres" ) ) == 0 )
1708 const QString checkUnicityKey { QStringLiteral(
"checkPrimaryKeyUnicity" ) };
1710 if ( ! uri.hasParam( checkUnicityKey ) )
1712 uri.setParam( checkUnicityKey, mReadExtentFromXml ?
"0" :
"1" );
1718 if ( !mDataProvider )
1725 mDataProvider->setParent(
this );
1728 QgsDebugMsgLevel( QStringLiteral(
"Instantiated the data provider plugin" ), 2 );
1740 QgsDebugMsgLevel( QStringLiteral(
"Set Data provider QgsLayerMetadata identifier[%1]" ).arg(
metadata().identifier() ), 4 );
1747 mWkbType = mDataProvider->
wkbType();
1759 QRegExp reg( R
"lit("[^"]+"\."([^"] + )"( \([^)]+\))?)lit" );
1760 if ( reg.indexIn(
name() ) >= 0 )
1762 QStringList stuff = reg.capturedTexts();
1763 QString lName = stuff[1];
1767 QMap<QString, QgsMapLayer *>::const_iterator it;
1768 for ( it = layers.constBegin(); it != layers.constEnd() && ( *it )->name() != lName; ++it )
1771 if ( it != layers.constEnd() && stuff.size() > 2 )
1773 lName +=
'.' + stuff[2].mid( 2, stuff[2].length() - 3 );
1776 if ( !lName.isEmpty() )
1786 else if ( provider == QLatin1String(
"ogr" ) )
1790 if (
mDataSource.right( 10 ) == QLatin1String(
"|layerid=0" ) )
1793 else if ( provider == QStringLiteral(
"memory" ) )
1810 QDomDocument &document,
1815 QDomElement mapLayerNode = layer_node.toElement();
1817 if ( mapLayerNode.isNull() || (
"maplayer" != mapLayerNode.nodeName() ) )
1823 mapLayerNode.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"vector" ) );
1830 if ( mDataProvider )
1832 QDomElement provider = document.createElement( QStringLiteral(
"provider" ) );
1833 provider.setAttribute( QStringLiteral(
"encoding" ), mDataProvider->
encoding() );
1834 QDomText providerText = document.createTextNode(
providerType() );
1835 provider.appendChild( providerText );
1836 layer_node.appendChild( provider );
1840 mJoinBuffer->
writeXml( layer_node, document );
1843 QDomElement dependenciesElement = document.createElement( QStringLiteral(
"layerDependencies" ) );
1849 QDomElement depElem = document.createElement( QStringLiteral(
"layer" ) );
1850 depElem.setAttribute( QStringLiteral(
"id" ), dep.layerId() );
1851 dependenciesElement.appendChild( depElem );
1853 layer_node.appendChild( dependenciesElement );
1856 QDomElement dataDependenciesElement = document.createElement( QStringLiteral(
"dataDependencies" ) );
1861 QDomElement depElem = document.createElement( QStringLiteral(
"layer" ) );
1862 depElem.setAttribute( QStringLiteral(
"id" ), dep.layerId() );
1863 dataDependenciesElement.appendChild( depElem );
1865 layer_node.appendChild( dataDependenciesElement );
1870 QDomElement legendElement =
legend()->
writeXml( document, context );
1871 if ( !legendElement.isNull() )
1872 layer_node.appendChild( legendElement );
1876 mExpressionFieldBuffer->
writeXml( layer_node, document );
1881 QDomElement asElem = document.createElement( QStringLiteral(
"auxiliaryLayer" ) );
1882 if ( mAuxiliaryLayer )
1884 const QString pkField = mAuxiliaryLayer->joinInfo().targetFieldName();
1885 asElem.setAttribute( QStringLiteral(
"key" ), pkField );
1887 layer_node.appendChild( asElem );
1890 mServerProperties->writeXml( layer_node, document );
1894 return writeSymbology( layer_node, document, errorMsg, context );
1911 QStringList theURIParts = src.split(
'|' );
1913 src = theURIParts.join( QStringLiteral(
"|" ) );
1917 QStringList theURIParts = src.split(
'?' );
1919 src = theURIParts.join( QStringLiteral(
"?" ) );
1921 else if (
providerType() == QLatin1String(
"delimitedtext" ) )
1923 QUrl urlSource = QUrl::fromEncoded( src.toLatin1() );
1925 urlDest.setQuery( urlSource.query() );
1926 src = QString::fromLatin1( urlDest.toEncoded() );
1928 else if (
providerType() == QLatin1String(
"memory" ) )
1933 else if (
providerType() == QLatin1String(
"virtual" ) )
1935 QUrl urlSource = QUrl::fromEncoded( src.toLatin1() );
1936 QStringList theURIParts;
1938 QUrlQuery query = QUrlQuery( urlSource.query() );
1939 QList<QPair<QString, QString> > queryItems = query.queryItems();
1941 for (
int i = 0; i < queryItems.size(); i++ )
1943 QString key = queryItems.at( i ).first;
1944 QString value = queryItems.at( i ).second;
1945 if ( key == QLatin1String(
"layer" ) )
1948 theURIParts = value.split(
':' );
1949 theURIParts[1] = QUrl::fromPercentEncoding( theURIParts[1].toUtf8() );
1951 theURIParts[1] = QUrl::toPercentEncoding( theURIParts[1] );
1952 queryItems[i].second = theURIParts.join( QStringLiteral(
":" ) ) ;
1956 query.setQueryItems( queryItems );
1958 QUrl urlDest = QUrl( urlSource );
1959 urlDest.setQuery( query.query() );
1960 src = QString::fromLatin1( urlDest.toEncoded() );
1974 if ( provider == QLatin1String(
"spatialite" ) )
1980 else if ( provider == QLatin1String(
"ogr" ) )
1982 QStringList theURIParts = src.split(
'|' );
1984 src = theURIParts.join( QStringLiteral(
"|" ) );
1986 else if ( provider == QLatin1String(
"gpx" ) )
1988 QStringList theURIParts = src.split(
'?' );
1990 src = theURIParts.join( QStringLiteral(
"?" ) );
1992 else if ( provider == QLatin1String(
"delimitedtext" ) )
1994 QUrl urlSource = QUrl::fromEncoded( src.toLatin1() );
1996 if ( !src.startsWith( QLatin1String(
"file:" ) ) )
1998 QUrl file = QUrl::fromLocalFile( src.left( src.indexOf(
'?' ) ) );
1999 urlSource.setScheme( QStringLiteral(
"file" ) );
2000 urlSource.setPath( file.path() );
2003 QUrl urlDest = QUrl::fromLocalFile( context.
pathResolver().
readPath( urlSource.toLocalFile() ) );
2004 urlDest.setQuery( urlSource.query() );
2005 src = QString::fromLatin1( urlDest.toEncoded() );
2007 else if ( provider == QLatin1String(
"virtual" ) )
2009 QUrl urlSource = QUrl::fromEncoded( src.toLatin1() );
2010 QStringList theURIParts;
2012 QUrlQuery query = QUrlQuery( urlSource.query() );
2013 QList<QPair<QString, QString> > queryItems = query.queryItems();
2015 for (
int i = 0; i < queryItems.size(); i++ )
2017 QString key = queryItems.at( i ).first;
2018 QString value = queryItems.at( i ).second;
2019 if ( key == QLatin1String(
"layer" ) )
2022 theURIParts = value.split(
':' );
2023 theURIParts[1] = QUrl::fromPercentEncoding( theURIParts[1].toUtf8() );
2025 theURIParts[1] = QUrl::toPercentEncoding( theURIParts[1] );
2026 queryItems[i].second = theURIParts.join( QStringLiteral(
":" ) ) ;
2030 query.setQueryItems( queryItems );
2032 QUrl urlDest = QUrl( urlSource );
2033 urlDest.setQuery( query.query() );
2034 src = QString::fromLatin1( urlDest.toEncoded() );
2058 if ( categories.testFlag(
Fields ) )
2060 if ( !mExpressionFieldBuffer )
2062 mExpressionFieldBuffer->
readXml( layerNode );
2073 QDomNodeList referencedLayersNodeList = layerNode.toElement().elementsByTagName( QStringLiteral(
"referencedLayers" ) );
2074 if ( referencedLayersNodeList.size() > 0 )
2076 const QDomNodeList relationNodes { referencedLayersNodeList.at( 0 ).childNodes() };
2077 for (
int i = 0; i < relationNodes.length(); ++i )
2079 const QDomElement relationElement = relationNodes.at( i ).toElement();
2080 QList<QgsRelation::FieldPair> fieldPairs;
2081 const QDomNodeList fieldPairNodes { relationElement.elementsByTagName( QStringLiteral(
"fieldPair" ) ) };
2082 for (
int j = 0; j < fieldPairNodes.length(); ++j )
2084 const QDomElement fieldPairElement = fieldPairNodes.at( j ).toElement();
2085 fieldPairs.push_back( { fieldPairElement.attribute( QStringLiteral(
"referencing" ) ),
2086 fieldPairElement.attribute( QStringLiteral(
"referenced" ) ) } );
2088 mWeakRelations.push_back(
QgsWeakRelation { relationElement.attribute( QStringLiteral(
"id" ) ),
2089 relationElement.attribute( QStringLiteral(
"name" ) ),
2097 relationElement.attribute( QStringLiteral(
"layerId" ) ),
2098 relationElement.attribute( QStringLiteral(
"layerName" ) ),
2099 relationElement.attribute( QStringLiteral(
"dataSource" ) ),
2100 relationElement.attribute( QStringLiteral(
"providerKey" ) ),
2107 QDomNodeList referencingLayersNodeList = layerNode.toElement().elementsByTagName( QStringLiteral(
"referencingLayers" ) );
2108 if ( referencingLayersNodeList.size() > 0 )
2110 const QDomNodeList relationNodes { referencingLayersNodeList.at( 0 ).childNodes() };
2111 for (
int i = 0; i < relationNodes.length(); ++i )
2113 const QDomElement relationElement = relationNodes.at( i ).toElement();
2114 QList<QgsRelation::FieldPair> fieldPairs;
2115 const QDomNodeList fieldPairNodes { relationElement.elementsByTagName( QStringLiteral(
"fieldPair" ) ) };
2116 for (
int j = 0; j < fieldPairNodes.length(); ++j )
2118 const QDomElement fieldPairElement = fieldPairNodes.at( j ).toElement();
2119 fieldPairs.push_back( { fieldPairElement.attribute( QStringLiteral(
"referencing" ) ),
2120 fieldPairElement.attribute( QStringLiteral(
"referenced" ) ) } );
2122 mWeakRelations.push_back(
QgsWeakRelation { relationElement.attribute( QStringLiteral(
"id" ) ),
2123 relationElement.attribute( QStringLiteral(
"name" ) ),
2126 relationElement.attribute( QStringLiteral(
"layerId" ) ),
2127 relationElement.attribute( QStringLiteral(
"layerName" ) ),
2128 relationElement.attribute( QStringLiteral(
"dataSource" ) ),
2129 relationElement.attribute( QStringLiteral(
"providerKey" ) ),
2141 QDomElement layerElement = layerNode.toElement();
2145 readStyle( layerNode, errorMessage, context, categories );
2147 if ( categories.testFlag(
MapTips ) )
2148 mMapTipTemplate = layerNode.namedItem( QStringLiteral(
"mapTip" ) ).toElement().text();
2151 mDisplayExpression = layerNode.namedItem( QStringLiteral(
"previewExpression" ) ).toElement().text();
2154 QString
displayField = layerNode.namedItem( QStringLiteral(
"displayfield" ) ).toElement().text();
2158 if ( mMapTipTemplate.isEmpty() && categories.testFlag(
MapTips ) )
2168 if ( categories.testFlag(
Actions ) )
2169 mActions->
readXml( layerNode );
2171 if ( categories.testFlag(
Fields ) )
2173 mAttributeAliasMap.clear();
2174 QDomNode aliasesNode = layerNode.namedItem( QStringLiteral(
"aliases" ) );
2175 if ( !aliasesNode.isNull() )
2177 QDomElement aliasElem;
2179 QDomNodeList aliasNodeList = aliasesNode.toElement().elementsByTagName( QStringLiteral(
"alias" ) );
2180 for (
int i = 0; i < aliasNodeList.size(); ++i )
2182 aliasElem = aliasNodeList.at( i ).toElement();
2185 if ( aliasElem.hasAttribute( QStringLiteral(
"field" ) ) )
2187 field = aliasElem.attribute( QStringLiteral(
"field" ) );
2191 int index = aliasElem.attribute( QStringLiteral(
"index" ) ).toInt();
2193 if ( index >= 0 && index <
fields().count() )
2199 if ( !aliasElem.attribute( QStringLiteral(
"name" ) ).isEmpty() )
2202 alias = context.
projectTranslator()->
translate( QStringLiteral(
"project:layers:%1:fieldaliases" ).arg( layerNode.namedItem( QStringLiteral(
"id" ) ).toElement().text() ), aliasElem.attribute( QStringLiteral(
"name" ) ) );
2203 QgsDebugMsgLevel(
"context" + QStringLiteral(
"project:layers:%1:fieldaliases" ).arg( layerNode.namedItem( QStringLiteral(
"id" ) ).toElement().text() ) +
" source " + aliasElem.attribute( QStringLiteral(
"name" ) ), 3 );
2208 alias = context.
projectTranslator()->
translate( QStringLiteral(
"project:layers:%1:fieldaliases" ).arg( layerNode.namedItem( QStringLiteral(
"id" ) ).toElement().text() ), field );
2209 QgsDebugMsgLevel(
"context" + QStringLiteral(
"project:layers:%1:fieldaliases" ).arg( layerNode.namedItem( QStringLiteral(
"id" ) ).toElement().text() ) +
" source " + field, 3 );
2211 if ( alias == aliasElem.attribute( QStringLiteral(
"field" ) ) )
2215 QgsDebugMsgLevel(
"field " + field +
" origalias " + aliasElem.attribute( QStringLiteral(
"name" ) ) +
" trans " + alias, 3 );
2216 mAttributeAliasMap.insert( field, alias );
2221 mDefaultExpressionMap.clear();
2222 QDomNode defaultsNode = layerNode.namedItem( QStringLiteral(
"defaults" ) );
2223 if ( !defaultsNode.isNull() )
2225 QDomNodeList defaultNodeList = defaultsNode.toElement().elementsByTagName( QStringLiteral(
"default" ) );
2226 for (
int i = 0; i < defaultNodeList.size(); ++i )
2228 QDomElement defaultElem = defaultNodeList.at( i ).toElement();
2230 QString field = defaultElem.attribute( QStringLiteral(
"field" ), QString() );
2231 QString expression = defaultElem.attribute( QStringLiteral(
"expression" ), QString() );
2232 bool applyOnUpdate = defaultElem.attribute( QStringLiteral(
"applyOnUpdate" ), QStringLiteral(
"0" ) ) == QLatin1String(
"1" );
2233 if ( field.isEmpty() || expression.isEmpty() )
2236 mDefaultExpressionMap.insert( field,
QgsDefaultValue( expression, applyOnUpdate ) );
2241 mFieldConstraints.clear();
2242 mFieldConstraintStrength.clear();
2243 QDomNode constraintsNode = layerNode.namedItem( QStringLiteral(
"constraints" ) );
2244 if ( !constraintsNode.isNull() )
2246 QDomNodeList constraintNodeList = constraintsNode.toElement().elementsByTagName( QStringLiteral(
"constraint" ) );
2247 for (
int i = 0; i < constraintNodeList.size(); ++i )
2249 QDomElement constraintElem = constraintNodeList.at( i ).toElement();
2251 QString field = constraintElem.attribute( QStringLiteral(
"field" ), QString() );
2252 int constraints = constraintElem.attribute( QStringLiteral(
"constraints" ), QStringLiteral(
"0" ) ).toInt();
2253 if ( field.isEmpty() || constraints == 0 )
2256 mFieldConstraints.insert( field,
static_cast< QgsFieldConstraints::Constraints
>( constraints ) );
2258 int uniqueStrength = constraintElem.attribute( QStringLiteral(
"unique_strength" ), QStringLiteral(
"1" ) ).toInt();
2259 int notNullStrength = constraintElem.attribute( QStringLiteral(
"notnull_strength" ), QStringLiteral(
"1" ) ).toInt();
2260 int expStrength = constraintElem.attribute( QStringLiteral(
"exp_strength" ), QStringLiteral(
"1" ) ).toInt();
2267 mFieldConstraintExpressions.clear();
2268 QDomNode constraintExpressionsNode = layerNode.namedItem( QStringLiteral(
"constraintExpressions" ) );
2269 if ( !constraintExpressionsNode.isNull() )
2271 QDomNodeList constraintNodeList = constraintExpressionsNode.toElement().elementsByTagName( QStringLiteral(
"constraint" ) );
2272 for (
int i = 0; i < constraintNodeList.size(); ++i )
2274 QDomElement constraintElem = constraintNodeList.at( i ).toElement();
2276 QString field = constraintElem.attribute( QStringLiteral(
"field" ), QString() );
2277 QString exp = constraintElem.attribute( QStringLiteral(
"exp" ), QString() );
2278 QString desc = constraintElem.attribute( QStringLiteral(
"desc" ), QString() );
2279 if ( field.isEmpty() || exp.isEmpty() )
2282 mFieldConstraintExpressions.insert( field, qMakePair( exp, desc ) );
2289 mExcludeAttributesWMS.clear();
2290 QDomNode excludeWMSNode = layerNode.namedItem( QStringLiteral(
"excludeAttributesWMS" ) );
2291 if ( !excludeWMSNode.isNull() )
2293 QDomNodeList attributeNodeList = excludeWMSNode.toElement().elementsByTagName( QStringLiteral(
"attribute" ) );
2294 for (
int i = 0; i < attributeNodeList.size(); ++i )
2296 mExcludeAttributesWMS.insert( attributeNodeList.at( i ).toElement().text() );
2300 mExcludeAttributesWFS.clear();
2301 QDomNode excludeWFSNode = layerNode.namedItem( QStringLiteral(
"excludeAttributesWFS" ) );
2302 if ( !excludeWFSNode.isNull() )
2304 QDomNodeList attributeNodeList = excludeWFSNode.toElement().elementsByTagName( QStringLiteral(
"attribute" ) );
2305 for (
int i = 0; i < attributeNodeList.size(); ++i )
2307 mExcludeAttributesWFS.insert( attributeNodeList.at( i ).toElement().text() );
2312 QDomElement widgetsElem = layerNode.namedItem( QStringLiteral(
"fieldConfiguration" ) ).toElement();
2313 QDomNodeList fieldConfigurationElementList = widgetsElem.elementsByTagName( QStringLiteral(
"field" ) );
2314 for (
int i = 0; i < fieldConfigurationElementList.size(); ++i )
2316 const QDomElement fieldConfigElement = fieldConfigurationElementList.at( i ).toElement();
2317 const QDomElement fieldWidgetElement = fieldConfigElement.elementsByTagName( QStringLiteral(
"editWidget" ) ).at( 0 ).toElement();
2319 QString fieldName = fieldConfigElement.attribute( QStringLiteral(
"name" ) );
2321 const QString widgetType = fieldWidgetElement.attribute( QStringLiteral(
"type" ) );
2322 const QDomElement cfgElem = fieldConfigElement.elementsByTagName( QStringLiteral(
"config" ) ).at( 0 ).toElement();
2323 const QDomElement optionsElem = cfgElem.childNodes().at( 0 ).toElement();
2325 if ( widgetType == QStringLiteral(
"ValueRelation" ) )
2327 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() );
2330 mFieldWidgetSetups[fieldName] = setup;
2335 mGeometryOptions->readXml( layerNode.namedItem( QStringLiteral(
"geometryOptions" ) ) );
2337 if ( categories.testFlag(
Forms ) )
2338 mEditFormConfig.
readXml( layerNode, context );
2342 mAttributeTableConfig.
readXml( layerNode );
2343 mConditionalStyles->
readXml( layerNode, context );
2344 mStoredExpressionManager->
readXml( layerNode );
2350 QDomElement mapLayerNode = layerNode.toElement();
2352 && mapLayerNode.attribute( QStringLiteral(
"readOnly" ), QStringLiteral(
"0" ) ).toInt() == 1 )
2375 if ( !rendererElement.isNull() )
2395 if ( categories.testFlag(
Labeling ) )
2397 QDomElement labelingElement = node.firstChildElement( QStringLiteral(
"labeling" ) );
2399 if ( labelingElement.isNull() ||
2400 ( labelingElement.attribute( QStringLiteral(
"type" ) ) == QLatin1String(
"simple" ) && labelingElement.firstChildElement( QStringLiteral(
"settings" ) ).isNull() ) )
2408 labeling = readLabelingFromCustomProperties();
2416 if ( node.toElement().hasAttribute( QStringLiteral(
"labelsEnabled" ) ) )
2417 mLabelsEnabled = node.toElement().attribute( QStringLiteral(
"labelsEnabled" ) ).toInt();
2419 mLabelsEnabled =
true;
2425 QDomNode blendModeNode = node.namedItem( QStringLiteral(
"blendMode" ) );
2426 if ( !blendModeNode.isNull() )
2428 QDomElement e = blendModeNode.toElement();
2433 QDomNode featureBlendModeNode = node.namedItem( QStringLiteral(
"featureBlendMode" ) );
2434 if ( !featureBlendModeNode.isNull() )
2436 QDomElement e = featureBlendModeNode.toElement();
2444 QDomNode layerTransparencyNode = node.namedItem( QStringLiteral(
"layerTransparency" ) );
2445 if ( !layerTransparencyNode.isNull() )
2447 QDomElement e = layerTransparencyNode.toElement();
2448 setOpacity( 1.0 - e.text().toInt() / 100.0 );
2450 QDomNode layerOpacityNode = node.namedItem( QStringLiteral(
"layerOpacity" ) );
2451 if ( !layerOpacityNode.isNull() )
2453 QDomElement e = layerOpacityNode.toElement();
2457 const bool hasScaleBasedVisibiliy { node.attributes().namedItem( QStringLiteral(
"hasScaleBasedVisibilityFlag" ) ).nodeValue() ==
'1' };
2460 const double maxScale { node.attributes().namedItem( QStringLiteral(
"maxScale" ) ).nodeValue().toDouble( &ok ) };
2465 const double minScale { node.attributes().namedItem( QStringLiteral(
"minScale" ) ).nodeValue().toDouble( &ok ) };
2474 QDomElement e = node.toElement();
2477 mSimplifyMethod.
setSimplifyHints(
static_cast< QgsVectorSimplifyMethod::SimplifyHints
>( e.attribute( QStringLiteral(
"simplifyDrawingHints" ), QStringLiteral(
"1" ) ).toInt() ) );
2479 mSimplifyMethod.
setThreshold( e.attribute( QStringLiteral(
"simplifyDrawingTol" ), QStringLiteral(
"1" ) ).toFloat() );
2480 mSimplifyMethod.
setForceLocalOptimization( e.attribute( QStringLiteral(
"simplifyLocal" ), QStringLiteral(
"1" ) ).toInt() );
2481 mSimplifyMethod.
setMaximumScale( e.attribute( QStringLiteral(
"simplifyMaxScale" ), QStringLiteral(
"1" ) ).toFloat() );
2485 if ( categories.testFlag(
Diagrams ) )
2487 delete mDiagramRenderer;
2488 mDiagramRenderer =
nullptr;
2489 QDomElement singleCatDiagramElem = node.firstChildElement( QStringLiteral(
"SingleCategoryDiagramRenderer" ) );
2490 if ( !singleCatDiagramElem.isNull() )
2493 mDiagramRenderer->
readXml( singleCatDiagramElem, context );
2495 QDomElement linearDiagramElem = node.firstChildElement( QStringLiteral(
"LinearlyInterpolatedDiagramRenderer" ) );
2496 if ( !linearDiagramElem.isNull() )
2498 if ( linearDiagramElem.hasAttribute( QStringLiteral(
"classificationAttribute" ) ) )
2501 int idx = linearDiagramElem.attribute( QStringLiteral(
"classificationAttribute" ) ).toInt();
2502 if ( idx >= 0 && idx < mFields.
count() )
2503 linearDiagramElem.setAttribute( QStringLiteral(
"classificationField" ), mFields.
at( idx ).
name() );
2507 mDiagramRenderer->
readXml( linearDiagramElem, context );
2510 if ( mDiagramRenderer )
2512 QDomElement diagramSettingsElem = node.firstChildElement( QStringLiteral(
"DiagramLayerSettings" ) );
2513 if ( !diagramSettingsElem.isNull() )
2515 bool oldXPos = diagramSettingsElem.hasAttribute( QStringLiteral(
"xPosColumn" ) );
2516 bool oldYPos = diagramSettingsElem.hasAttribute( QStringLiteral(
"yPosColumn" ) );
2517 bool oldShow = diagramSettingsElem.hasAttribute( QStringLiteral(
"showColumn" ) );
2518 if ( oldXPos || oldYPos || oldShow )
2524 int xPosColumn = diagramSettingsElem.attribute( QStringLiteral(
"xPosColumn" ) ).toInt();
2525 if ( xPosColumn >= 0 && xPosColumn < mFields.
count() )
2530 int yPosColumn = diagramSettingsElem.attribute( QStringLiteral(
"yPosColumn" ) ).toInt();
2531 if ( yPosColumn >= 0 && yPosColumn < mFields.
count() )
2536 int showColumn = diagramSettingsElem.attribute( QStringLiteral(
"showColumn" ) ).toInt();
2537 if ( showColumn >= 0 && showColumn < mFields.
count() )
2540 QDomElement propertiesElem = diagramSettingsElem.ownerDocument().createElement( QStringLiteral(
"properties" ) );
2547 ddp.
writeXml( propertiesElem, defs );
2548 diagramSettingsElem.appendChild( propertiesElem );
2551 delete mDiagramLayerSettings;
2553 mDiagramLayerSettings->
readXml( diagramSettingsElem );
2566 QDomElement layerElement = node.toElement();
2569 ( void )
writeStyle( node, doc, errorMessage, context, categories );
2572 mGeometryOptions->writeXml( node );
2582 QDomElement referencedLayersElement = doc.createElement( QStringLiteral(
"referencedLayers" ) );
2583 node.appendChild( referencedLayersElement );
2586 for (
const auto &rel : constReferencingRelations )
2589 QDomElement relationElement = doc.createElement( QStringLiteral(
"relation" ) );
2590 referencedLayersElement.appendChild( relationElement );
2592 relationElement.setAttribute( QStringLiteral(
"id" ), rel.id() );
2593 relationElement.setAttribute( QStringLiteral(
"name" ), rel.name() );
2594 relationElement.setAttribute( QStringLiteral(
"strength" ), rel.strength() );
2595 relationElement.setAttribute( QStringLiteral(
"layerId" ), rel.referencedLayer()->id() );
2596 relationElement.setAttribute( QStringLiteral(
"layerName" ), rel.referencedLayer()->name() );
2597 relationElement.setAttribute( QStringLiteral(
"dataSource" ), resolver.writePath( rel.referencedLayer()->publicSource() ) );
2598 relationElement.setAttribute( QStringLiteral(
"providerKey" ), rel.referencedLayer()->providerType() );
2600 const QList<QgsRelation::FieldPair> constFieldPairs { rel.fieldPairs() };
2603 QDomElement fieldPair = doc.createElement( QStringLiteral(
"fieldPair" ) );
2604 relationElement.appendChild( fieldPair );
2605 fieldPair.setAttribute( QStringLiteral(
"referenced" ), fp.referencedField() );
2606 fieldPair.setAttribute( QStringLiteral(
"referencing" ), fp.referencingField() );
2612 QDomElement referencingLayersElement = doc.createElement( QStringLiteral(
"referencingLayers" ) );
2613 node.appendChild( referencingLayersElement );
2616 for (
const auto &rel : constReferencedRelations )
2619 QDomElement relationElement = doc.createElement( QStringLiteral(
"relation" ) );
2620 referencingLayersElement.appendChild( relationElement );
2622 relationElement.setAttribute( QStringLiteral(
"id" ), rel.id() );
2623 relationElement.setAttribute( QStringLiteral(
"name" ), rel.name() );
2624 relationElement.setAttribute( QStringLiteral(
"strength" ), rel.strength() );
2625 relationElement.setAttribute( QStringLiteral(
"layerId" ), rel.referencingLayer()->id() );
2626 relationElement.setAttribute( QStringLiteral(
"layerName" ), rel.referencingLayer()->name() );
2627 relationElement.setAttribute( QStringLiteral(
"dataSource" ), resolver.writePath( rel.referencingLayer()->publicSource() ) );
2628 relationElement.setAttribute( QStringLiteral(
"providerKey" ), rel.referencingLayer()->providerType() );
2630 const QList<QgsRelation::FieldPair> constFieldPairs { rel.fieldPairs() };
2633 QDomElement fieldPair = doc.createElement( QStringLiteral(
"fieldPair" ) );
2634 relationElement.appendChild( fieldPair );
2635 fieldPair.setAttribute( QStringLiteral(
"referenced" ), fp.referencedField() );
2636 fieldPair.setAttribute( QStringLiteral(
"referencing" ), fp.referencingField() );
2642 if ( categories.testFlag(
Fields ) )
2644 QDomElement fieldConfigurationElement = doc.createElement( QStringLiteral(
"fieldConfiguration" ) );
2645 node.appendChild( fieldConfigurationElement );
2648 for (
const QgsField &field : qgis::as_const( mFields ) )
2650 QDomElement fieldElement = doc.createElement( QStringLiteral(
"field" ) );
2651 fieldElement.setAttribute( QStringLiteral(
"name" ), field.name() );
2653 fieldConfigurationElement.appendChild( fieldElement );
2658 QDomElement editWidgetElement = doc.createElement( QStringLiteral(
"editWidget" ) );
2659 fieldElement.appendChild( editWidgetElement );
2660 editWidgetElement.setAttribute( QStringLiteral(
"type" ), field.editorWidgetSetup().type() );
2661 QDomElement editWidgetConfigElement = doc.createElement( QStringLiteral(
"config" ) );
2664 editWidgetElement.appendChild( editWidgetConfigElement );
2671 QDomElement aliasElem = doc.createElement( QStringLiteral(
"aliases" ) );
2672 for (
const QgsField &field : qgis::as_const( mFields ) )
2674 QDomElement aliasEntryElem = doc.createElement( QStringLiteral(
"alias" ) );
2675 aliasEntryElem.setAttribute( QStringLiteral(
"field" ), field.name() );
2676 aliasEntryElem.setAttribute( QStringLiteral(
"index" ), mFields.
indexFromName( field.name() ) );
2677 aliasEntryElem.setAttribute( QStringLiteral(
"name" ), field.alias() );
2678 aliasElem.appendChild( aliasEntryElem );
2680 node.appendChild( aliasElem );
2683 QDomElement excludeWMSElem = doc.createElement( QStringLiteral(
"excludeAttributesWMS" ) );
2684 QSet<QString>::const_iterator attWMSIt = mExcludeAttributesWMS.constBegin();
2685 for ( ; attWMSIt != mExcludeAttributesWMS.constEnd(); ++attWMSIt )
2687 QDomElement attrElem = doc.createElement( QStringLiteral(
"attribute" ) );
2688 QDomText attrText = doc.createTextNode( *attWMSIt );
2689 attrElem.appendChild( attrText );
2690 excludeWMSElem.appendChild( attrElem );
2692 node.appendChild( excludeWMSElem );
2695 QDomElement excludeWFSElem = doc.createElement( QStringLiteral(
"excludeAttributesWFS" ) );
2696 QSet<QString>::const_iterator attWFSIt = mExcludeAttributesWFS.constBegin();
2697 for ( ; attWFSIt != mExcludeAttributesWFS.constEnd(); ++attWFSIt )
2699 QDomElement attrElem = doc.createElement( QStringLiteral(
"attribute" ) );
2700 QDomText attrText = doc.createTextNode( *attWFSIt );
2701 attrElem.appendChild( attrText );
2702 excludeWFSElem.appendChild( attrElem );
2704 node.appendChild( excludeWFSElem );
2707 QDomElement defaultsElem = doc.createElement( QStringLiteral(
"defaults" ) );
2708 for (
const QgsField &field : qgis::as_const( mFields ) )
2710 QDomElement defaultElem = doc.createElement( QStringLiteral(
"default" ) );
2711 defaultElem.setAttribute( QStringLiteral(
"field" ), field.name() );
2712 defaultElem.setAttribute( QStringLiteral(
"expression" ), field.defaultValueDefinition().expression() );
2713 defaultElem.setAttribute( QStringLiteral(
"applyOnUpdate" ), field.defaultValueDefinition().applyOnUpdate() ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
2714 defaultsElem.appendChild( defaultElem );
2716 node.appendChild( defaultsElem );
2719 QDomElement constraintsElem = doc.createElement( QStringLiteral(
"constraints" ) );
2720 for (
const QgsField &field : qgis::as_const( mFields ) )
2722 QDomElement constraintElem = doc.createElement( QStringLiteral(
"constraint" ) );
2723 constraintElem.setAttribute( QStringLiteral(
"field" ), field.name() );
2724 constraintElem.setAttribute( QStringLiteral(
"constraints" ), field.constraints().constraints() );
2728 constraintsElem.appendChild( constraintElem );
2730 node.appendChild( constraintsElem );
2733 QDomElement constraintExpressionsElem = doc.createElement( QStringLiteral(
"constraintExpressions" ) );
2734 for (
const QgsField &field : qgis::as_const( mFields ) )
2736 QDomElement constraintExpressionElem = doc.createElement( QStringLiteral(
"constraint" ) );
2737 constraintExpressionElem.setAttribute( QStringLiteral(
"field" ), field.name() );
2738 constraintExpressionElem.setAttribute( QStringLiteral(
"exp" ), field.constraints().constraintExpression() );
2739 constraintExpressionElem.setAttribute( QStringLiteral(
"desc" ), field.constraints().constraintDescription() );
2740 constraintExpressionsElem.appendChild( constraintExpressionElem );
2742 node.appendChild( constraintExpressionsElem );
2745 if ( !mExpressionFieldBuffer )
2753 mExpressionFieldBuffer->
writeXml( node, doc );
2758 if ( categories.testFlag(
Actions ) )
2763 mAttributeTableConfig.
writeXml( node );
2764 mConditionalStyles->
writeXml( node, doc, context );
2765 mStoredExpressionManager->
writeXml( node );
2768 if ( categories.testFlag(
Forms ) )
2769 mEditFormConfig.
writeXml( node, context );
2773 node.toElement().setAttribute( QStringLiteral(
"readOnly" ), mReadOnly );
2778 QDomElement prevExpElem = doc.createElement( QStringLiteral(
"previewExpression" ) );
2779 QDomText prevExpText = doc.createTextNode( mDisplayExpression );
2780 prevExpElem.appendChild( prevExpText );
2781 node.appendChild( prevExpElem );
2785 if ( categories.testFlag(
MapTips ) )
2787 QDomElement mapTipElem = doc.createElement( QStringLiteral(
"mapTip" ) );
2788 QDomText mapTipText = doc.createTextNode( mMapTipTemplate );
2789 mapTipElem.appendChild( mapTipText );
2790 node.toElement().appendChild( mapTipElem );
2799 QDomElement mapLayerNode = node.toElement();
2812 QDomElement rendererElement = mRenderer->
save( doc, context );
2813 node.appendChild( rendererElement );
2817 if ( categories.testFlag(
Labeling ) )
2821 QDomElement labelingElement = mLabeling->
save( doc, context );
2822 node.appendChild( labelingElement );
2824 mapLayerNode.setAttribute( QStringLiteral(
"labelsEnabled" ), mLabelsEnabled ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
2830 mapLayerNode.setAttribute( QStringLiteral(
"simplifyDrawingHints" ), QString::number( mSimplifyMethod.
simplifyHints() ) );
2831 mapLayerNode.setAttribute( QStringLiteral(
"simplifyAlgorithm" ), QString::number( mSimplifyMethod.
simplifyAlgorithm() ) );
2832 mapLayerNode.setAttribute( QStringLiteral(
"simplifyDrawingTol" ), QString::number( mSimplifyMethod.
threshold() ) );
2833 mapLayerNode.setAttribute( QStringLiteral(
"simplifyLocal" ), mSimplifyMethod.
forceLocalOptimization() ? 1 : 0 );
2834 mapLayerNode.setAttribute( QStringLiteral(
"simplifyMaxScale" ), QString::number( mSimplifyMethod.
maximumScale() ) );
2846 QDomElement blendModeElem = doc.createElement( QStringLiteral(
"blendMode" ) );
2848 blendModeElem.appendChild( blendModeText );
2849 node.appendChild( blendModeElem );
2852 QDomElement featureBlendModeElem = doc.createElement( QStringLiteral(
"featureBlendMode" ) );
2854 featureBlendModeElem.appendChild( featureBlendModeText );
2855 node.appendChild( featureBlendModeElem );
2861 QDomElement layerOpacityElem = doc.createElement( QStringLiteral(
"layerOpacity" ) );
2862 QDomText layerOpacityText = doc.createTextNode( QString::number(
opacity() ) );
2863 layerOpacityElem.appendChild( layerOpacityText );
2864 node.appendChild( layerOpacityElem );
2865 mapLayerNode.setAttribute( QStringLiteral(
"hasScaleBasedVisibilityFlag" ),
hasScaleBasedVisibility() ? 1 : 0 );
2866 mapLayerNode.setAttribute( QStringLiteral(
"maxScale" ),
maximumScale() );
2867 mapLayerNode.setAttribute( QStringLiteral(
"minScale" ),
minimumScale() );
2870 if ( categories.testFlag(
Diagrams ) && mDiagramRenderer )
2872 mDiagramRenderer->
writeXml( mapLayerNode, doc, context );
2873 if ( mDiagramLayerSettings )
2874 mDiagramLayerSettings->
writeXml( mapLayerNode, doc );
2883 QDomElement nameElem = node.firstChildElement( QStringLiteral(
"Name" ) );
2884 if ( nameElem.isNull() )
2886 errorMessage = QStringLiteral(
"Warning: Name element not found within NamedLayer while it's required." );
2898 readSldLabeling( node );
2905 Q_UNUSED( errorMessage )
2916 QDomElement nameNode = doc.createElement( QStringLiteral(
"se:Name" ) );
2917 nameNode.appendChild( doc.createTextNode(
name() ) );
2918 node.appendChild( nameNode );
2920 QDomElement userStyleElem = doc.createElement( QStringLiteral(
"UserStyle" ) );
2921 node.appendChild( userStyleElem );
2923 QDomElement nameElem = doc.createElement( QStringLiteral(
"se:Name" ) );
2924 nameElem.appendChild( doc.createTextNode(
name() ) );
2926 userStyleElem.appendChild( nameElem );
2928 QDomElement featureTypeStyleElem = doc.createElement( QStringLiteral(
"se:FeatureTypeStyle" ) );
2929 userStyleElem.appendChild( featureTypeStyleElem );
2931 mRenderer->
toSld( doc, featureTypeStyleElem, localProps );
2934 mLabeling->
toSld( featureTypeStyleElem, localProps );
2943 if ( !mEditBuffer || !mDataProvider )
2948 if ( mGeometryOptions->isActive() )
2949 mGeometryOptions->apply( geom );
2958 if ( !skipDefaultValue && !mDefaultValueOnUpdateFields.isEmpty() )
2959 updateDefaultValues( fid );
2967 bool result =
false;
2969 switch (
fields().fieldOrigin( field ) )
2981 if ( mEditBuffer && mDataProvider )
2990 if ( result && !skipDefaultValues && !mDefaultValueOnUpdateFields.isEmpty() )
2991 updateDefaultValues( fid );
3006 for (
auto it = newValues.constBegin(); it != newValues.constEnd(); ++it )
3008 const int field = it.key();
3009 const QVariant newValue = it.value();
3012 if ( oldValues.contains( field ) )
3013 oldValue = oldValues[field];
3015 switch (
fields().fieldOrigin( field ) )
3018 newValuesJoin[field] = newValue;
3019 oldValuesJoin[field] = oldValue;
3026 newValuesNotJoin[field] = newValue;
3027 oldValuesNotJoin[field] = oldValue;
3036 if ( ! newValuesJoin.isEmpty() && mJoinBuffer )
3041 if ( ! newValuesNotJoin.isEmpty() && mEditBuffer && mDataProvider )
3046 if ( result && !skipDefaultValues && !mDefaultValueOnUpdateFields.isEmpty() )
3048 updateDefaultValues( fid );
3056 if ( !mEditBuffer || !mDataProvider )
3064 if ( attIndex < 0 || attIndex >=
fields().count() )
3068 mFields[ attIndex ].setAlias( QString() );
3069 if ( mAttributeAliasMap.contains(
name ) )
3071 mAttributeAliasMap.remove(
name );
3073 mEditFormConfig.setFields( mFields );
3080 if ( index < 0 || index >=
fields().count() )
3087 if ( mExpressionFieldBuffer )
3103 if ( !mEditBuffer || !mDataProvider )
3119 if ( attIndex < 0 || attIndex >=
fields().count() )
3124 mAttributeAliasMap.insert(
name, aliasString );
3125 mFields[ attIndex ].setAlias( aliasString );
3126 mEditFormConfig.setFields( mFields );
3132 if ( index < 0 || index >=
fields().count() )
3140 if ( index >= 0 && index < mFields.
count() )
3148 return mAttributeAliasMap;
3153 if ( index < 0 || index >=
fields().count() )
3162 if ( !mEditBuffer || !mDataProvider )
3170 bool deleted =
false;
3173 QList<int> attrList = qgis::setToList( qgis::listToSet( attrs ) );
3175 std::sort( attrList.begin(), attrList.end(), std::greater<int>() );
3177 for (
int attr : qgis::as_const( attrList ) )
3193 if ( context && context->
cascade )
3198 if ( handledFeatureIds.contains( fid ) )
3206 handledFeatureIds << fid;
3227 while ( relatedFeaturesIt.
nextFeature( childFeature ) )
3229 childFeatureIds.insert( childFeature.
id() );
3231 if ( childFeatureIds.count() > 0 )
3233 relation.referencingLayer()->startEditing();
3234 relation.referencingLayer()->deleteFeatures( childFeatureIds, context );
3253 bool res = deleteFeatureCascade( fid, context );
3257 mSelectedFeatureIds.remove( fid );
3267 const auto constFids = fids;
3269 res = deleteFeatureCascade( fid, context ) && res;
3273 mSelectedFeatureIds.subtract( fids );
3288 if ( !mDataProvider )
3289 return pkAttributesList;
3292 for (
int i = 0; i < mFields.
count(); ++i )
3296 pkAttributesList << i;
3299 return pkAttributesList;
3304 if ( ! mDataProvider )
3315 if ( mEditBuffer && !deletedFeatures.empty() )
3317 if ( addedFeatures.size() > deletedFeatures.size() )
3318 return QgsFeatureSource::FeatureAvailability::FeaturesAvailable;
3320 return QgsFeatureSource::FeatureAvailability::FeaturesMaybeAvailable;
3323 if ( ( !mEditBuffer || addedFeatures.empty() ) && mDataProvider && mDataProvider->
empty() )
3324 return QgsFeatureSource::FeatureAvailability::NoFeaturesAvailable;
3326 return QgsFeatureSource::FeatureAvailability::FeaturesAvailable;
3331 mCommitErrors.clear();
3333 if ( !mDataProvider )
3335 mCommitErrors << tr(
"ERROR: no provider" );
3341 mCommitErrors << tr(
"ERROR: layer not editable" );
3347 if ( !mAllowCommit )
3355 mEditBuffer =
nullptr;
3376 return mCommitErrors;
3386 if ( !mDataProvider )
3388 mCommitErrors << tr(
"ERROR: no provider" );
3414 mEditBuffer =
nullptr;
3419 if ( rollbackExtent )
3430 return mSelectedFeatureIds.size();
3435 return mSelectedFeatureIds;
3441 features.reserve( mSelectedFeatureIds.count() );
3444 if ( mSelectedFeatureIds.count() <= 8 )
3448 const auto constMSelectedFeatureIds = mSelectedFeatureIds;
3461 features.push_back( f );
3470 if ( mSelectedFeatureIds.isEmpty() )
3476 if ( mSelectedFeatureIds.count() == 1 )
3477 request.
setFilterFid( *mSelectedFeatureIds.constBegin() );
3486 if ( !mEditBuffer || !mDataProvider )
3489 if ( mGeometryOptions->isActive() )
3491 for (
auto feature = features.begin(); feature != features.end(); ++feature )
3494 mGeometryOptions->apply( geom );
3536 if ( !mDisplayExpression.isEmpty() || mFields.
isEmpty() )
3538 return mDisplayExpression;
3551 static QStringList sCandidates{ QStringLiteral(
"name" ),
3552 QStringLiteral(
"title" ),
3553 QStringLiteral(
"heibt" ),
3554 QStringLiteral(
"desc" ),
3555 QStringLiteral(
"nom" ),
3556 QStringLiteral(
"street" ),
3557 QStringLiteral(
"road" ),
3558 QStringLiteral(
"id" )};
3559 for (
const QString &candidate : sCandidates )
3561 for (
const QgsField &field : qgis::as_const( mFields ) )
3563 QString fldName = field.name();
3564 if ( fldName.indexOf( candidate, 0, Qt::CaseInsensitive ) > -1 )
3571 if ( !idxName.isEmpty() )
3575 if ( !idxName.isNull() )
3588 return ( mEditBuffer && mDataProvider );
3597 bool QgsVectorLayer::isReadOnly()
const
3605 if ( readonly && mEditBuffer )
3608 mReadOnly = readonly;
3616 return mEditBuffer && mEditBuffer->
isModified();
3621 bool auxiliaryField =
false;
3625 return auxiliaryField;
3632 auxiliaryField =
true;
3635 return auxiliaryField;
3646 if ( r != mRenderer )
3650 mSymbolFeatureCounted =
false;
3651 mSymbolFeatureCountMap.clear();
3652 mSymbolFeatureIdMap.clear();
3661 if ( !mDataProvider )
3667 QString ignoredError;
3671 mEditCommandActive =
true;
3677 if ( !mDataProvider )
3682 mEditCommandActive =
false;
3683 if ( !mDeletedFids.isEmpty() )
3686 mDeletedFids.clear();
3693 if ( !mDataProvider )
3704 std::unique_ptr< QUndoCommand > command = qgis::make_unique< QUndoCommand >();
3705 command->setObsolete(
true );
3708 mEditCommandActive =
false;
3709 mDeletedFids.clear();
3715 return mJoinBuffer->
addJoin( joinInfo );
3721 return mJoinBuffer->
removeJoin( joinLayerId );
3751 if ( oi < 0 || oi >= mExpressionFieldBuffer->
expressions().size() )
3754 return mExpressionFieldBuffer->
expressions().at( oi ).cachedExpression.expression();
3765 if ( !mDataProvider )
3770 mFields = mDataProvider->
fields();
3780 if ( mExpressionFieldBuffer )
3784 QMap< QString, QString >::const_iterator aliasIt = mAttributeAliasMap.constBegin();
3785 for ( ; aliasIt != mAttributeAliasMap.constEnd(); ++aliasIt )
3791 mFields[ index ].setAlias( aliasIt.value() );
3795 mDefaultValueOnUpdateFields.clear();
3796 QMap< QString, QgsDefaultValue >::const_iterator defaultIt = mDefaultExpressionMap.constBegin();
3797 for ( ; defaultIt != mDefaultExpressionMap.constEnd(); ++defaultIt )
3799 int index = mFields.
lookupField( defaultIt.key() );
3803 mFields[ index ].setDefaultValueDefinition( defaultIt.value() );
3804 if ( defaultIt.value().applyOnUpdate() )
3805 mDefaultValueOnUpdateFields.insert( index );
3808 QMap< QString, QgsFieldConstraints::Constraints >::const_iterator constraintIt = mFieldConstraints.constBegin();
3809 for ( ; constraintIt != mFieldConstraints.constEnd(); ++constraintIt )
3811 int index = mFields.
lookupField( constraintIt.key() );
3824 mFields[ index ].setConstraints( constraints );
3827 QMap< QString, QPair< QString, QString > >::const_iterator constraintExpIt = mFieldConstraintExpressions.constBegin();
3828 for ( ; constraintExpIt != mFieldConstraintExpressions.constEnd(); ++constraintExpIt )
3830 int index = mFields.
lookupField( constraintExpIt.key() );
3841 mFields[ index ].setConstraints( constraints );
3845 for ( ; constraintStrengthIt != mFieldConstraintStrength.constEnd(); ++constraintStrengthIt )
3847 int index = mFields.
lookupField( constraintStrengthIt.key().first );
3857 constraints.
setConstraintStrength( constraintStrengthIt.key().second, constraintStrengthIt.value() );
3858 mFields[ index ].setConstraints( constraints );
3861 auto fieldWidgetIterator = mFieldWidgetSetups.constBegin();
3862 for ( ; fieldWidgetIterator != mFieldWidgetSetups.constEnd(); ++ fieldWidgetIterator )
3864 int index = mFields.
indexOf( fieldWidgetIterator.key() );
3868 mFields[index].setEditorWidgetSetup( fieldWidgetIterator.value() );
3871 if ( oldFields != mFields )
3874 mEditFormConfig.setFields( mFields );
3881 if ( index < 0 || index >= mFields.
count() || !mDataProvider )
3885 if ( expression.isEmpty() )
3889 std::unique_ptr< QgsExpressionContext > tempContext;
3894 evalContext = tempContext.get();
3927 if ( index < 0 || index >= mFields.
count() )
3932 mDefaultExpressionMap.insert( mFields.
at( index ).
name(), definition );
3936 mDefaultExpressionMap.remove( mFields.
at( index ).
name() );
3943 if ( index < 0 || index >= mFields.
count() )
3952 if ( !mDataProvider )
3971 for (
const QVariant &v : constUniqueValues )
3973 vals << v.toString();
3977 QMapIterator< QgsFeatureId, QgsFeature > addedIt( added );
3978 while ( addedIt.hasNext() && ( limit < 0 ||
uniqueValues.count() < limit ) )
3981 QVariant v = addedIt.value().attribute( index );
3984 QString vs = v.toString();
3985 if ( !vals.contains( vs ) )
3994 while ( it.hasNext() && ( limit < 0 ||
uniqueValues.count() < limit ) )
3997 QVariant v = it.value().value( index );
4000 QString vs = v.toString();
4001 if ( !vals.contains( vs ) )
4033 .setSubsetOfAttributes( attList ) );
4036 QVariant currentValue;
4037 QHash<QString, QVariant> val;
4041 val.insert( currentValue.toString(), currentValue );
4042 if ( limit >= 0 && val.size() >= limit )
4048 return qgis::listToSet( val.values() );
4052 Q_ASSERT_X(
false,
"QgsVectorLayer::uniqueValues()",
"Unknown source of the field!" );
4058 QStringList results;
4059 if ( !mDataProvider )
4077 QMapIterator< QgsFeatureId, QgsFeature > addedIt( added );
4078 while ( addedIt.hasNext() && ( limit < 0 || results.count() < limit ) && ( !feedback || !feedback->
isCanceled() ) )
4081 QVariant v = addedIt.value().attribute( index );
4084 QString vs = v.toString();
4085 if ( vs.contains( substring, Qt::CaseInsensitive ) && !results.contains( vs ) )
4093 while ( it.hasNext() && ( limit < 0 || results.count() < limit ) && ( !feedback || !feedback->
isCanceled() ) )
4096 QVariant v = it.value().value( index );
4099 QString vs = v.toString();
4100 if ( vs.contains( substring, Qt::CaseInsensitive ) && !results.contains( vs ) )
4131 QString fieldName = mFields.
at( index ).
name();
4132 request.
setFilterExpression( QStringLiteral(
"\"%1\" ILIKE '%%2%'" ).arg( fieldName, substring ) );
4136 QString currentValue;
4139 currentValue = f.
attribute( index ).toString();
4140 if ( !results.contains( currentValue ) )
4141 results << currentValue;
4143 if ( ( limit >= 0 && results.size() >= limit ) || ( feedback && feedback->
isCanceled() ) )
4153 Q_ASSERT_X(
false,
"QgsVectorLayer::uniqueStringsMatching()",
"Unknown source of the field!" );
4159 return minimumOrMaximumValue( index,
true );
4164 return minimumOrMaximumValue( index,
false );
4167 QVariant QgsVectorLayer::minimumOrMaximumValue(
int index,
bool minimum )
const
4169 if ( !mDataProvider )
4187 QMapIterator< QgsFeatureId, QgsFeature > addedIt( added );
4188 while ( addedIt.hasNext() )
4191 QVariant v = addedIt.value().attribute( index );
4200 while ( it.hasNext() )
4203 QVariant v = it.value().value( index );
4236 .setSubsetOfAttributes( attList ) );
4240 QVariant currentValue;
4241 bool firstValue =
true;
4245 if ( currentValue.isNull() )
4249 value = currentValue;
4256 value = currentValue;
4264 Q_ASSERT_X(
false,
"QgsVectorLayer::minimumOrMaximum()",
"Unknown source of the field!" );
4275 if ( !mDataProvider )
4281 int attrIndex = mFields.
lookupField( fieldOrExpression );
4282 if ( attrIndex >= 0 )
4289 bool providerOk =
false;
4290 QVariant val = mDataProvider->
aggregate(
aggregate, attrIndex, parameters, context, providerOk, fids );
4304 c.setFidsFilter( *fids );
4305 c.setParameters( parameters );
4306 return c.calculate(
aggregate, fieldOrExpression, context, ok );
4321 return mFeatureBlendMode;
4335 return mLayerOpacity;
4340 void QgsVectorLayer::readSldLabeling(
const QDomNode &node )
4345 QDomElement element = node.toElement();
4346 if ( element.isNull() )
4349 QDomElement userStyleElem = element.firstChildElement( QStringLiteral(
"UserStyle" ) );
4350 if ( userStyleElem.isNull() )
4352 QgsDebugMsgLevel( QStringLiteral(
"Info: UserStyle element not found." ), 4 );
4356 QDomElement featTypeStyleElem = userStyleElem.firstChildElement( QStringLiteral(
"FeatureTypeStyle" ) );
4357 if ( featTypeStyleElem.isNull() )
4359 QgsDebugMsgLevel( QStringLiteral(
"Info: FeatureTypeStyle element not found." ), 4 );
4364 QDomElement mergedFeatTypeStyle = featTypeStyleElem.cloneNode(
false ).toElement();
4369 bool needRuleBasedLabeling =
false;
4372 while ( !featTypeStyleElem.isNull() )
4374 QDomElement ruleElem = featTypeStyleElem.firstChildElement( QStringLiteral(
"Rule" ) );
4375 while ( !ruleElem.isNull() )
4379 bool hasTextSymbolizer =
false;
4380 bool hasRuleBased =
false;
4381 QDomElement ruleChildElem = ruleElem.firstChildElement();
4382 while ( !ruleChildElem.isNull() )
4385 if ( ruleChildElem.localName() == QLatin1String(
"Filter" ) ||
4386 ruleChildElem.localName() == QLatin1String(
"MinScaleDenominator" ) ||
4387 ruleChildElem.localName() == QLatin1String(
"MaxScaleDenominator" ) )
4389 hasRuleBased =
true;
4392 else if ( ruleChildElem.localName() == QLatin1String(
"TextSymbolizer" ) )
4394 QgsDebugMsgLevel( QStringLiteral(
"Info: TextSymbolizer element found" ), 4 );
4395 hasTextSymbolizer =
true;
4398 ruleChildElem = ruleChildElem.nextSiblingElement();
4401 if ( hasTextSymbolizer )
4406 mergedFeatTypeStyle.appendChild( ruleElem.cloneNode().toElement() );
4410 QgsDebugMsgLevel( QStringLiteral(
"Info: Filter or Min/MaxScaleDenominator element found: need a RuleBasedLabeling" ), 4 );
4411 needRuleBasedLabeling =
true;
4416 if ( ruleCount > 1 )
4418 QgsDebugMsgLevel( QStringLiteral(
"Info: More Rule elements found: need a RuleBasedLabeling" ), 4 );
4419 needRuleBasedLabeling =
true;
4423 if ( ruleCount == 0 )
4425 needRuleBasedLabeling =
false;
4428 ruleElem = ruleElem.nextSiblingElement( QStringLiteral(
"Rule" ) );
4430 featTypeStyleElem = featTypeStyleElem.nextSiblingElement( QStringLiteral(
"FeatureTypeStyle" ) );
4433 if ( ruleCount == 0 )
4435 QgsDebugMsgLevel( QStringLiteral(
"Info: No TextSymbolizer element." ), 4 );
4439 QDomElement ruleElem = mergedFeatTypeStyle.firstChildElement( QStringLiteral(
"Rule" ) );
4441 if ( needRuleBasedLabeling )
4445 while ( !ruleElem.isNull() )
4448 QString label, description, filterExp;
4449 int scaleMinDenom = 0, scaleMaxDenom = 0;
4453 QDomElement childElem = ruleElem.firstChildElement();
4454 while ( !childElem.isNull() )
4456 if ( childElem.localName() == QLatin1String(
"Name" ) )
4460 if ( label.isEmpty() )
4461 label = childElem.firstChild().nodeValue();
4463 else if ( childElem.localName() == QLatin1String(
"Description" ) )
4466 QDomElement titleElem = childElem.firstChildElement( QStringLiteral(
"Title" ) );
4467 if ( !titleElem.isNull() )
4469 label = titleElem.firstChild().nodeValue();
4472 QDomElement abstractElem = childElem.firstChildElement( QStringLiteral(
"Abstract" ) );
4473 if ( !abstractElem.isNull() )
4475 description = abstractElem.firstChild().nodeValue();
4478 else if ( childElem.localName() == QLatin1String(
"Abstract" ) )
4481 description = childElem.firstChild().nodeValue();
4483 else if ( childElem.localName() == QLatin1String(
"Title" ) )
4486 label = childElem.firstChild().nodeValue();
4488 else if ( childElem.localName() == QLatin1String(
"Filter" ) )
4504 else if ( childElem.localName() == QLatin1String(
"MinScaleDenominator" ) )
4507 int v = childElem.firstChild().nodeValue().toInt( &ok );
4511 else if ( childElem.localName() == QLatin1String(
"MaxScaleDenominator" ) )
4514 int v = childElem.firstChild().nodeValue().toInt( &ok );
4518 else if ( childElem.localName() == QLatin1String(
"TextSymbolizer" ) )
4520 readSldTextSymbolizer( childElem, settings );
4523 childElem = childElem.nextSiblingElement();
4529 ruleElem = ruleElem.nextSiblingElement();
4539 QDomElement textSymbolizerElem = ruleElem.firstChildElement( QStringLiteral(
"TextSymbolizer" ) );
4541 if ( readSldTextSymbolizer( textSymbolizerElem, s ) )
4549 bool QgsVectorLayer::readSldTextSymbolizer(
const QDomNode &node,
QgsPalLayerSettings &settings )
const
4551 if ( node.localName() != QLatin1String(
"TextSymbolizer" ) )
4553 QgsDebugMsgLevel( QStringLiteral(
"Not a TextSymbolizer element: %1" ).arg( node.localName() ), 3 );
4556 QDomElement textSymbolizerElem = node.toElement();
4558 QDomElement labelElem = textSymbolizerElem.firstChildElement( QStringLiteral(
"Label" ) );
4559 if ( !labelElem.isNull() )
4561 QDomElement propertyNameElem = labelElem.firstChildElement( QStringLiteral(
"PropertyName" ) );
4562 if ( !propertyNameElem.isNull() )
4567 QString labelAttribute = propertyNameElem.text();
4571 int fieldIndex = mFields.
lookupField( labelAttribute );
4572 if ( fieldIndex == -1 )
4576 if ( !exp.hasEvalError() )
4582 QgsDebugMsgLevel( QStringLiteral(
"SLD label attribute error: %1" ).arg( exp.evalErrorString() ), 3 );
4588 QgsDebugMsgLevel( QStringLiteral(
"Info: PropertyName element not found." ), 4 );
4599 if ( textSymbolizerElem.hasAttribute( QStringLiteral(
"uom" ) ) )
4604 QString fontFamily = QStringLiteral(
"Sans-Serif" );
4605 int fontPointSize = 10;
4607 int fontWeight = -1;
4608 bool fontItalic =
false;
4609 bool fontUnderline =
false;
4612 QDomElement fontElem = textSymbolizerElem.firstChildElement( QStringLiteral(
"Font" ) );
4613 if ( !fontElem.isNull() )
4616 for ( QgsStringMap::iterator it = fontSvgParams.begin(); it != fontSvgParams.end(); ++it )
4618 QgsDebugMsgLevel( QStringLiteral(
"found fontSvgParams %1: %2" ).arg( it.key(), it.value() ), 4 );
4620 if ( it.key() == QLatin1String(
"font-family" ) )
4622 fontFamily = it.value();
4624 else if ( it.key() == QLatin1String(
"font-style" ) )
4626 fontItalic = ( it.value() == QLatin1String(
"italic" ) ) || ( it.value() == QLatin1String(
"Italic" ) );
4628 else if ( it.key() == QLatin1String(
"font-size" ) )
4631 int fontSize = it.value().toInt( &ok );
4634 fontPointSize = fontSize;
4635 fontUnitSize = sldUnitSize;
4638 else if ( it.key() == QLatin1String(
"font-weight" ) )
4640 if ( ( it.value() == QLatin1String(
"bold" ) ) || ( it.value() == QLatin1String(
"Bold" ) ) )
4641 fontWeight = QFont::Bold;
4643 else if ( it.key() == QLatin1String(
"font-underline" ) )
4645 fontUnderline = ( it.value() == QLatin1String(
"underline" ) ) || ( it.value() == QLatin1String(
"Underline" ) );
4651 QFont font( fontFamily, fontPointSize, fontWeight, fontItalic );
4652 font.setUnderline( fontUnderline );
4654 format.
setSize( fontPointSize );
4658 QDomElement fillElem = textSymbolizerElem.firstChildElement( QStringLiteral(
"Fill" ) );
4660 Qt::BrushStyle textBrush = Qt::SolidPattern;
4662 if ( textColor.isValid() )
4664 QgsDebugMsgLevel( QStringLiteral(
"Info: textColor %1." ).arg( QVariant( textColor ).toString() ), 4 );
4671 QDomElement haloElem = textSymbolizerElem.firstChildElement( QStringLiteral(
"Halo" ) );
4672 if ( !haloElem.isNull() )
4677 QDomElement radiusElem = haloElem.firstChildElement( QStringLiteral(
"Radius" ) );
4678 if ( !radiusElem.isNull() )
4681 double bufferSize = radiusElem.text().toDouble( &ok );
4684 bufferSettings.
setSize( bufferSize );
4689 QDomElement haloFillElem = haloElem.firstChildElement( QStringLiteral(
"Fill" ) );
4691 Qt::BrushStyle bufferBrush = Qt::SolidPattern;
4693 if ( bufferColor.isValid() )
4695 QgsDebugMsgLevel( QStringLiteral(
"Info: bufferColor %1." ).arg( QVariant( bufferColor ).toString() ), 4 );
4696 bufferSettings.
setColor( bufferColor );
4701 QDomElement labelPlacementElem = textSymbolizerElem.firstChildElement( QStringLiteral(
"LabelPlacement" ) );
4702 if ( !labelPlacementElem.isNull() )
4705 QDomElement pointPlacementElem = labelPlacementElem.firstChildElement( QStringLiteral(
"PointPlacement" ) );
4706 if ( !pointPlacementElem.isNull() )
4714 QDomElement displacementElem = pointPlacementElem.firstChildElement( QStringLiteral(
"Displacement" ) );
4715 if ( !displacementElem.isNull() )
4717 QDomElement displacementXElem = displacementElem.firstChildElement( QStringLiteral(
"DisplacementX" ) );
4718 if ( !displacementXElem.isNull() )
4721 double xOffset = displacementXElem.text().toDouble( &ok );
4728 QDomElement displacementYElem = displacementElem.firstChildElement( QStringLiteral(
"DisplacementY" ) );
4729 if ( !displacementYElem.isNull() )
4732 double yOffset = displacementYElem.text().toDouble( &ok );
4740 QDomElement anchorPointElem = pointPlacementElem.firstChildElement( QStringLiteral(
"AnchorPoint" ) );
4741 if ( !anchorPointElem.isNull() )
4743 QDomElement anchorPointXElem = anchorPointElem.firstChildElement( QStringLiteral(
"AnchorPointX" ) );
4744 if ( !anchorPointXElem.isNull() )
4747 double xOffset = anchorPointXElem.text().toDouble( &ok );
4754 QDomElement anchorPointYElem = anchorPointElem.firstChildElement( QStringLiteral(
"AnchorPointY" ) );
4755 if ( !anchorPointYElem.isNull() )
4758 double yOffset = anchorPointYElem.text().toDouble( &ok );
4767 QDomElement rotationElem = pointPlacementElem.firstChildElement( QStringLiteral(
"Rotation" ) );
4768 if ( !rotationElem.isNull() )
4771 double rotation = rotationElem.text().toDouble( &ok );
4781 QDomElement linePlacementElem = labelPlacementElem.firstChildElement( QStringLiteral(
"LinePlacement" ) );
4782 if ( !linePlacementElem.isNull() )
4791 QDomElement vendorOptionElem = textSymbolizerElem.firstChildElement( QStringLiteral(
"VendorOption" ) );
4792 while ( !vendorOptionElem.isNull() && vendorOptionElem.localName() == QLatin1String(
"VendorOption" ) )
4794 QString optionName = vendorOptionElem.attribute( QStringLiteral(
"name" ) );
4795 QString optionValue;
4796 if ( vendorOptionElem.firstChild().nodeType() == QDomNode::TextNode )
4798 optionValue = vendorOptionElem.firstChild().nodeValue();
4802 if ( vendorOptionElem.firstChild().nodeType() == QDomNode::ElementNode &&
4803 vendorOptionElem.firstChild().localName() == QLatin1String(
"Literal" ) )
4805 QgsDebugMsg( vendorOptionElem.firstChild().localName() );
4806 optionValue = vendorOptionElem.firstChild().firstChild().nodeValue();
4810 QgsDebugMsg( QStringLiteral(
"unexpected child of %1 named %2" ).arg( vendorOptionElem.localName(), optionName ) );
4814 if ( !optionName.isEmpty() && !optionValue.isEmpty() )
4816 vendorOptions[ optionName ] = optionValue;
4819 vendorOptionElem = vendorOptionElem.nextSiblingElement();
4821 if ( !vendorOptions.isEmpty() )
4823 for ( QgsStringMap::iterator it = vendorOptions.begin(); it != vendorOptions.end(); ++it )
4825 if ( it.key() == QLatin1String(
"underlineText" ) && it.value() == QLatin1String(
"true" ) )
4827 font.setUnderline(
true );
4830 else if ( it.key() == QLatin1String(
"strikethroughText" ) && it.value() == QLatin1String(
"true" ) )
4832 font.setStrikeOut(
true );
4835 else if ( it.key() == QLatin1String(
"maxDisplacement" ) )
4839 else if ( it.key() == QLatin1String(
"followLine" ) && it.value() == QLatin1String(
"true" ) )
4850 else if ( it.key() == QLatin1String(
"maxAngleDelta" ) )
4853 double angle = it.value().toDouble( &ok );
4861 else if ( it.key() == QLatin1String(
"conflictResolution" ) && it.value() == QLatin1String(
"false" ) )
4865 else if ( it.key() == QLatin1String(
"forceLeftToRight" ) && it.value() == QLatin1String(
"false" ) )
4869 else if ( it.key() == QLatin1String(
"group" ) && it.value() == QLatin1String(
"yes" ) )
4873 else if ( it.key() == QLatin1String(
"labelAllGroup" ) && it.value() == QLatin1String(
"true" ) )
4887 return mEditFormConfig;
4896 mEditFormConfig.onRelationsLoaded();
4902 return mMapTipTemplate;
4907 if ( mMapTipTemplate == mapTip )
4910 mMapTipTemplate = mapTip;
4945 if ( !mDiagramLayerSettings )
4947 *mDiagramLayerSettings = s;
4953 QString myMetadata = QStringLiteral(
"<html>\n<body>\n" );
4956 myMetadata += QStringLiteral(
"<h1>" ) + tr(
"Information from provider" ) + QStringLiteral(
"</h1>\n<hr>\n" );
4957 myMetadata += QLatin1String(
"<table class=\"list-view\">\n" );
4960 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"Name" ) + QStringLiteral(
"</td><td>" ) +
name() + QStringLiteral(
"</td></tr>\n" );
4965 if ( uriComponents.contains( QStringLiteral(
"path" ) ) )
4967 path = uriComponents[QStringLiteral(
"path" )].toString();
4968 if ( QFile::exists( path ) )
4969 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"Path" ) + QStringLiteral(
"</td><td>%1" ).arg( QStringLiteral(
"<a href=\"%1\">%2</a>" ).arg( QUrl::fromLocalFile( path ).toString(), QDir::toNativeSeparators( path ) ) ) + QStringLiteral(
"</td></tr>\n" );
4971 if ( uriComponents.contains( QStringLiteral(
"url" ) ) )
4973 const QString url = uriComponents[QStringLiteral(
"url" )].toString();
4974 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"URL" ) + QStringLiteral(
"</td><td>%1" ).arg( QStringLiteral(
"<a href=\"%1\">%2</a>" ).arg( QUrl( url ).toString(), url ) ) + QStringLiteral(
"</td></tr>\n" );
4979 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"Source" ) + QStringLiteral(
"</td><td>%1" ).arg(
publicSource() ) + QStringLiteral(
"</td></tr>\n" );
4982 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"Storage" ) + QStringLiteral(
"</td><td>" ) +
storageType() + QStringLiteral(
"</td></tr>\n" );
4985 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"Comment" ) + QStringLiteral(
"</td><td>" ) +
dataComment() + QStringLiteral(
"</td></tr>\n" );
4991 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"Encoding" ) + QStringLiteral(
"</td><td>" ) + provider->
encoding() + QStringLiteral(
"</td></tr>\n" );
5006 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"Geometry" ) + QStringLiteral(
"</td><td>" ) + typeString + QStringLiteral(
"</td></tr>\n" );
5010 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"CRS" ) + QStringLiteral(
"</td><td>" );
5014 if (
crs().isGeographic() )
5015 myMetadata += tr(
"Geographic" );
5017 myMetadata += tr(
"Projected" );
5019 myMetadata += QLatin1String(
"</td></tr>\n" );
5022 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"Extent" ) + QStringLiteral(
"</td><td>" ) +
extent().
toString() + QStringLiteral(
"</td></tr>\n" );
5025 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"Unit" ) + QStringLiteral(
"</td><td>" ) +
QgsUnitTypes::toString(
crs().mapUnits() ) + QStringLiteral(
"</td></tr>\n" );
5030 QLocale locale = QLocale();
5031 locale.setNumberOptions( locale.numberOptions() &= ~QLocale::NumberOption::OmitGroupSeparator );
5032 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" )
5033 + tr(
"Feature count" ) + QStringLiteral(
"</td><td>" )
5035 + QStringLiteral(
"</td></tr>\n" );
5038 myMetadata += QLatin1String(
"</table>\n<br><br>" );
5041 myMetadata += QStringLiteral(
"<h1>" ) + tr(
"Identification" ) + QStringLiteral(
"</h1>\n<hr>\n" );
5043 myMetadata += QLatin1String(
"<br><br>\n" );
5046 myMetadata += QStringLiteral(
"<h1>" ) + tr(
"Extent" ) + QStringLiteral(
"</h1>\n<hr>\n" );
5048 myMetadata += QLatin1String(
"<br><br>\n" );
5051 myMetadata += QStringLiteral(
"<h1>" ) + tr(
"Access" ) + QStringLiteral(
"</h1>\n<hr>\n" );
5053 myMetadata += QLatin1String(
"<br><br>\n" );
5056 myMetadata += QStringLiteral(
"<h1>" ) + tr(
"Fields" ) + QStringLiteral(
"</h1>\n<hr>\n<table class=\"list-view\">\n" );
5060 if ( !pkAttrList.isEmpty() )
5062 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"Primary key attributes" ) + QStringLiteral(
"</td><td>" );
5063 const auto constPkAttrList = pkAttrList;
5064 for (
int idx : constPkAttrList )
5068 myMetadata += QLatin1String(
"</td></tr>\n" );
5074 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"Count" ) + QStringLiteral(
"</td><td>" ) + QString::number( myFields.
size() ) + QStringLiteral(
"</td></tr>\n" );
5076 myMetadata += QLatin1String(
"</table>\n<br><table width=\"100%\" class=\"tabular-view\">\n" );
5077 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" );
5079 for (
int i = 0; i < myFields.
size(); ++i )
5084 rowClass = QStringLiteral(
"class=\"odd-row\"" );
5085 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" );
5089 myMetadata += QLatin1String(
"</table>\n<br><br>" );
5092 myMetadata += QStringLiteral(
"<h1>" ) + tr(
"Contacts" ) + QStringLiteral(
"</h1>\n<hr>\n" );
5094 myMetadata += QLatin1String(
"<br><br>\n" );
5097 myMetadata += QStringLiteral(
"<h1>" ) + tr(
"Links" ) + QStringLiteral(
"</h1>\n<hr>\n" );
5099 myMetadata += QLatin1String(
"<br><br>\n" );
5102 myMetadata += QStringLiteral(
"<h1>" ) + tr(
"History" ) + QStringLiteral(
"</h1>\n<hr>\n" );
5104 myMetadata += QLatin1String(
"<br><br>\n" );
5106 myMetadata += QStringLiteral(
"\n</body>\n</html>\n" );
5110 void QgsVectorLayer::invalidateSymbolCountedFlag()
5112 mSymbolFeatureCounted =
false;
5115 void QgsVectorLayer::onFeatureCounterCompleted()
5118 mFeatureCounter =
nullptr;
5121 void QgsVectorLayer::onFeatureCounterTerminated()
5123 mFeatureCounter =
nullptr;
5126 void QgsVectorLayer::onJoinedFieldsChanged()
5132 void QgsVectorLayer::onFeatureDeleted(
QgsFeatureId fid )
5134 if ( mEditCommandActive )
5135 mDeletedFids << fid;
5142 void QgsVectorLayer::onRelationsLoaded()
5144 mEditFormConfig.onRelationsLoaded();
5147 void QgsVectorLayer::onSymbolsCounted()
5149 if ( mFeatureCounter )
5151 mSymbolFeatureCounted =
true;
5165 return mWeakRelations;
5185 bool useAsDefault,
const QString &uiFileContent, QString &msgError )
5188 QString sldStyle, qmlStyle;
5189 QDomDocument qmlDocument, sldDocument;
5192 if ( !msgError.isNull() )
5196 qmlStyle = qmlDocument.toString();
5199 if ( !msgError.isNull() )
5203 sldStyle = sldDocument.toString();
5207 description, uiFileContent, useAsDefault, msgError );
5221 QString joinKey = mAuxiliaryLayerKey;
5222 if ( !key.isEmpty() )
5225 if ( storage.
isValid() && !joinKey.isEmpty() )
5248 mAuxiliaryLayerKey.clear();
5250 if ( mAuxiliaryLayer )
5263 mAuxiliaryLayer.reset( alayer );
5264 if ( mAuxiliaryLayer )
5265 mAuxiliaryLayer->setParent(
this );
5271 return mAuxiliaryLayer.get();
5276 return mAuxiliaryLayer.get();
5282 QString returnMessage;
5283 QString qml, errorMsg;
5288 if ( !qml.isEmpty() )
5290 QDomDocument myDocument( QStringLiteral(
"qgis" ) );
5291 myDocument.setContent( qml );
5293 returnMessage = QObject::tr(
"Loaded from Provider" );
5303 return returnMessage;
5308 if ( mDataProvider )
5313 void QgsVectorLayer::emitDataChanged()
5315 if ( mDataChangedFired )
5320 mDataChangedFired =
true;
5322 mDataChangedFired =
false;
5327 QSet<QgsMapLayerDependency> deps;
5328 const auto constODeps = oDeps;
5335 QSet<QgsMapLayerDependency> toAdd = deps -
dependencies();
5351 if ( mDataProvider )
5371 if ( ! toAdd.isEmpty() )
5379 if ( fieldIndex < 0 || fieldIndex >= mFields.
count() || !mDataProvider )
5395 QMap< QgsFieldConstraints::Constraint, QgsFieldConstraints::ConstraintStrength > m;
5397 if ( fieldIndex < 0 || fieldIndex >= mFields.
count() )
5400 QString
name = mFields.
at( fieldIndex ).
name();
5403 for ( ; conIt != mFieldConstraintStrength.constEnd(); ++conIt )
5405 if ( conIt.key().first ==
name )
5407 m[ conIt.key().second ] = mFieldConstraintStrength.value( conIt.key() );
5416 if ( index < 0 || index >= mFields.
count() )
5422 QgsFieldConstraints::Constraints constraints = mFieldConstraints.value(
name,
nullptr );
5423 constraints |= constraint;
5424 mFieldConstraints.insert(
name, constraints );
5426 mFieldConstraintStrength.insert( qMakePair(
name, constraint ), strength );
5433 if ( index < 0 || index >= mFields.
count() )
5439 QgsFieldConstraints::Constraints constraints = mFieldConstraints.value(
name,
nullptr );
5440 constraints &= ~constraint;
5441 mFieldConstraints.insert(
name, constraints );
5443 mFieldConstraintStrength.remove( qMakePair(
name, constraint ) );
5450 if ( index < 0 || index >= mFields.
count() )
5458 if ( index < 0 || index >= mFields.
count() )
5466 if ( index < 0 || index >= mFields.
count() )
5469 if ( expression.isEmpty() )
5471 mFieldConstraintExpressions.remove( mFields.
at( index ).
name() );
5475 mFieldConstraintExpressions.insert( mFields.
at( index ).
name(), qMakePair( expression, description ) );
5482 if ( index < 0 || index >= mFields.
count() )
5486 mFieldWidgetSetups.remove( mFields.
at( index ).
name() );
5488 mFieldWidgetSetups.insert( mFields.
at( index ).
name(), setup );
5495 if ( index < 0 || index >= mFields.
count() )
5504 if (
customProperty( QStringLiteral(
"labeling" ) ).toString() == QLatin1String(
"pal" ) )
5506 if (
customProperty( QStringLiteral(
"labeling/enabled" ), QVariant(
false ) ).toBool() )
5510 settings.readFromLayerCustomProperties(
this );
5517 for (
const QString &key : constCustomPropertyKeys )
5519 if ( key.startsWith( QLatin1String(
"labeling/" ) ) )
5529 return mAllowCommit;
5543 return mGeometryOptions.get();
5553 return mReadExtentFromXml;
5556 void QgsVectorLayer::onDirtyTransaction(
const QString &sql,
const QString &name )
5559 if ( tr && mEditBuffer )
5561 qobject_cast<QgsVectorLayerEditPassthrough *>( mEditBuffer )->update( tr, sql,
name );
5567 QList<QgsVectorLayer *> layers;
5568 QMap<QgsVectorLayer *, QgsFeatureIds>::const_iterator i;
5570 layers.append( i.key() );
5576 return mHandledFeatures[layer];