92#include <QPainterPath>
94#include <QProgressDialog>
98#include <QStringBuilder>
100#include <QUndoCommand>
103#include <QRegularExpression>
120#ifdef TESTPROVIDERLIB
126 const QString &qmlStyle,
127 const QString &sldStyle,
128 const QString &styleName,
129 const QString &styleDescription,
130 const QString &uiFileContent,
144 QStringList &descriptions,
162 const QString &baseName,
163 const QString &providerKey,
168 , mAuxiliaryLayer( nullptr )
169 , mAuxiliaryLayerKey( QString() )
170 , mReadExtentFromXml( options.readExtentFromXml )
171 , mRefreshRendererTimer( new QTimer( this ) )
182 mGeometryOptions = std::make_unique<QgsGeometryOptions>();
186 mStoredExpressionManager->setParent(
this );
189 mJoinBuffer->setParent(
this );
194 if ( !vectorLayerPath.isEmpty() && !
mProviderKey.isEmpty() )
197 QgsDataProvider::ReadFlags providerFlags = QgsDataProvider::ReadFlags();
205 mDataSourceReadOnly =
true;
207 setDataSource( vectorLayerPath, baseName, providerKey, providerOptions, providerFlags );
212 if ( !mAttributeAliasMap.contains(
field.
name() ) )
213 mAttributeAliasMap.insert(
field.
name(), QString() );
219 if ( !mTemporalProperties->
isActive() )
244 connect( mRefreshRendererTimer, &QTimer::timeout,
this, [ = ] {
triggerRepaint(
true ); } );
253 delete mDataProvider;
256 delete mExpressionFieldBuffer;
258 delete mDiagramLayerSettings;
259 delete mDiagramRenderer;
264 delete mConditionalStyles;
265 delete mStoredExpressionManager;
267 if ( mFeatureCounter )
268 mFeatureCounter->
cancel();
270 qDeleteAll( mRendererGenerators );
291 options.forceReadOnly = mDataSourceReadOnly;
299 QList<QgsVectorLayerJoinInfo> joins =
vectorJoins();
300 const auto constJoins = joins;
320 for (
const QgsAction &action : constActions )
357 auto constraintIt = constraints.constBegin();
358 for ( ; constraintIt != constraints.constEnd(); ++ constraintIt )
374 layer->mElevationProperties = mElevationProperties->
clone();
375 layer->mElevationProperties->setParent( layer );
407 return mDataProvider && mDataProvider->
isSqlQuery();
468 p.setPen( QColor( 50, 100, 120, 200 ) );
469 p.setBrush( QColor( 200, 200, 210, 120 ) );
470 p.drawEllipse( x - m, y - m, m * 2 + 1, m * 2 + 1 );
474 p.setPen( QColor( 255, 0, 0 ) );
475 p.drawLine( x - m, y + m, x + m, y - m );
476 p.drawLine( x - m, y - m, x + m, y + m );
488 mSelectedFeatureIds.insert( fid );
489 mPreviousSelectedFeatureIds.clear();
498 mSelectedFeatureIds.unite( featureIds );
499 mPreviousSelectedFeatureIds.clear();
508 mSelectedFeatureIds.remove( fid );
509 mPreviousSelectedFeatureIds.clear();
518 mSelectedFeatureIds.subtract( featureIds );
519 mPreviousSelectedFeatureIds.clear();
534 .setFilterRect( rect )
536 .setNoAttributes() );
541 newSelection << feat.
id();
554 std::optional< QgsExpressionContext > defaultContext;
558 context = &defaultContext.value();
577 newSelection << feat.
id();
599 bool matches = exp.
evaluate( context ).toBool();
603 newSelection << feat.
id();
607 newSelection << feat.
id();
628 newSelection = mSelectedFeatureIds + ids;
632 newSelection = mSelectedFeatureIds - ids;
636 newSelection = mSelectedFeatureIds.intersect( ids );
640 QgsFeatureIds deselectedFeatures = mSelectedFeatureIds - newSelection;
641 mSelectedFeatureIds = newSelection;
642 mPreviousSelectedFeatureIds.clear();
652 if ( !intersectingIds.isEmpty() )
654 QgsDebugMsgLevel( QStringLiteral(
"Trying to select and deselect the same item at the same time. Unsure what to do. Selecting dubious items." ), 3 );
657 mSelectedFeatureIds -= deselectIds;
658 mSelectedFeatureIds += selectIds;
659 mPreviousSelectedFeatureIds.clear();
669 ids.subtract( mSelectedFeatureIds );
688 .setFilterRect( rect )
690 .setNoAttributes() );
698 if ( mSelectedFeatureIds.contains( fet.
id() ) )
700 deselectIds << fet.
id();
704 selectIds << fet.
id();
715 if ( mSelectedFeatureIds.isEmpty() )
720 mPreviousSelectedFeatureIds = previous;
727 if ( mPreviousSelectedFeatureIds.isEmpty() || !mSelectedFeatureIds.empty() )
738 return mDataProvider;
746 return mDataProvider;
753 return mTemporalProperties;
760 return mElevationProperties;
776 if (
isValid() && mDataProvider && mDataProvider->
encoding() != encoding )
787 delete mDiagramRenderer;
788 mDiagramRenderer = r;
812 if ( !
isValid() || !
isSpatial() || mSelectedFeatureIds.isEmpty() || !mDataProvider )
824 .setFilterFids( mSelectedFeatureIds )
825 .setNoAttributes() );
838 .setNoAttributes() );
842 if ( mSelectedFeatureIds.contains( fet.
id() ) )
853 if ( retval.
width() == 0.0 || retval.
height() == 0.0 )
862 retval.
set( -1.0, -1.0, 1.0, 1.0 );
874 return mLabelsEnabled &&
static_cast< bool >( mLabeling );
881 mLabelsEnabled = enabled;
889 if ( !mDiagramRenderer || !mDiagramLayerSettings )
892 QList<QgsDiagramSettings> settingList = mDiagramRenderer->
diagramSettings();
893 if ( !settingList.isEmpty() )
895 return settingList.at( 0 ).enabled;
904 if ( !mSymbolFeatureCounted )
907 return mSymbolFeatureCountMap.value( legendKey, -1 );
914 if ( !mSymbolFeatureCounted )
917 return mSymbolFeatureIdMap.value( legendKey,
QgsFeatureIds() );
923 if ( ( mSymbolFeatureCounted || mFeatureCounter ) && !( storeSymbolFids && mSymbolFeatureIdMap.isEmpty() ) )
924 return mFeatureCounter;
926 mSymbolFeatureCountMap.clear();
927 mSymbolFeatureIdMap.clear();
932 return mFeatureCounter;
934 if ( !mDataProvider )
937 return mFeatureCounter;
942 return mFeatureCounter;
945 if ( !mFeatureCounter || ( storeSymbolFids && mSymbolFeatureIdMap.isEmpty() ) )
948 connect( mFeatureCounter, &
QgsTask::taskCompleted,
this, &QgsVectorLayer::onFeatureCounterCompleted, Qt::UniqueConnection );
949 connect( mFeatureCounter, &
QgsTask::taskTerminated,
this, &QgsVectorLayer::onFeatureCounterTerminated, Qt::UniqueConnection );
953 return mFeatureCounter;
961 if ( force || !mReadExtentFromXml || ( mReadExtentFromXml && mXmlExtent.
isNull() ) )
962 mValidExtent =
false;
977 if ( !mDefaultValueOnUpdateFields.isEmpty() )
982 int size = mFields.
size();
983 for (
int idx : std::as_const( mDefaultValueOnUpdateFields ) )
985 if ( idx < 0 || idx >= size )
1004 if ( !mValidExtent && mLazyExtent && mReadExtentFromXml && !mXmlExtent.
isNull() )
1006 updateExtent( mXmlExtent );
1007 mValidExtent =
true;
1008 mLazyExtent =
false;
1011 if ( !mValidExtent && mLazyExtent && mDataProvider && mDataProvider->
isValid() )
1014 updateExtent( mDataProvider->
extent() );
1015 mValidExtent =
true;
1016 mLazyExtent =
false;
1019 QgsDebugMsgLevel( QStringLiteral(
"Extent of layer: %1" ).arg( mExtent.toString() ), 3 );
1025 if ( !
isValid() || !mDataProvider )
1027 QgsDebugMsgLevel( QStringLiteral(
"invoked with invalid layer or null mDataProvider" ), 3 );
1031 if ( !mEditBuffer ||
1045 if ( mEditBuffer && !mDataProvider->
transaction() )
1048 for ( QgsFeatureMap::const_iterator it = addedFeatures.constBegin(); it != addedFeatures.constEnd(); ++it )
1050 if ( it->hasGeometry() )
1061 .setNoAttributes() );
1074 if ( rect.xMinimum() > rect.xMaximum() && rect.yMinimum() > rect.yMaximum() )
1080 updateExtent( rect );
1081 mValidExtent =
true;
1100 if ( !
isValid() || !mDataProvider )
1102 QgsDebugMsgLevel( QStringLiteral(
"invoked with invalid layer or null mDataProvider" ), 3 );
1103 return customProperty( QStringLiteral(
"storedSubsetString" ) ).toString();
1112 if ( !
isValid() || !mDataProvider )
1114 QgsDebugMsgLevel( QStringLiteral(
"invoked with invalid layer or null mDataProvider or while editing" ), 3 );
1118 else if ( mEditBuffer )
1150 double maximumSimplificationScale = mSimplifyMethod.
maximumScale();
1153 return !( maximumSimplificationScale > 1 && renderContext.
rendererScale() <= maximumSimplificationScale );
1162 return mConditionalStyles;
1170 if ( !
isValid() || !mDataProvider )
1182 if ( feature.isValid() )
1183 return feature.geometry();
1192 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1196 if ( mGeometryOptions->isActive() )
1199 mGeometryOptions->apply( geom );
1203 bool success = mEditBuffer->
addFeature( feature );
1210 success = mJoinBuffer->
addFeature( feature );
1220 if ( !mEditBuffer || !mDataProvider )
1226 if ( currentFeature.
isValid() )
1228 bool hasChanged =
false;
1229 bool hasError =
false;
1241 QgsDebugMsgLevel( QStringLiteral(
"geometry of feature %1 could not be changed." ).arg( updatedFeature.
id() ), 3 );
1248 for (
int attr = 0; attr < fa.count(); ++attr )
1258 QgsDebugMsgLevel( QStringLiteral(
"attribute %1 of feature %2 could not be changed." ).arg( attr ).arg( updatedFeature.
id() ), 3 );
1263 if ( hasChanged && !mDefaultValueOnUpdateFields.isEmpty() && !skipDefaultValues )
1264 updateDefaultValues( updatedFeature.
id(), updatedFeature );
1270 QgsDebugMsgLevel( QStringLiteral(
"feature %1 could not be retrieved" ).arg( updatedFeature.
id() ), 3 );
1280 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1284 bool result = utils.
insertVertex( x, y, atFeatureId, beforeVertex );
1295 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1299 bool result = utils.
insertVertex( point, atFeatureId, beforeVertex );
1310 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1314 bool result = utils.
moveVertex( x, y, atFeatureId, atVertex );
1325 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1329 bool result = utils.
moveVertex( p, atFeatureId, atVertex );
1340 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1367 int count = mSelectedFeatureIds.size();
1380 *deletedCount = deleted;
1383 return deleted == count;
1386static const QgsPointSequence vectorPointXY2pointSequence(
const QVector<QgsPointXY> &points )
1389 pts.reserve( points.size() );
1390 QVector<QgsPointXY>::const_iterator it = points.constBegin();
1391 while ( it != points.constEnd() )
1402 return addRing( vectorPointXY2pointSequence( ring ), featureId );
1409 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1416 if ( !mSelectedFeatureIds.isEmpty() )
1418 result = utils.
addRing( ring, mSelectedFeatureIds, featureId );
1434 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1455 if ( !mSelectedFeatureIds.isEmpty() )
1457 result = utils.
addRing(
static_cast< QgsCurve *
>( ring->
clone() ), mSelectedFeatureIds, featureId );
1475 pts.reserve( points.size() );
1476 for ( QList<QgsPointXY>::const_iterator it = points.constBegin(); it != points.constEnd() ; ++it )
1483#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1488 return addPart( vectorPointXY2pointSequence( points ) );
1496 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1501 if ( mSelectedFeatureIds.empty() )
1506 else if ( mSelectedFeatureIds.size() > 1 )
1524 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1529 if ( mSelectedFeatureIds.empty() )
1534 else if ( mSelectedFeatureIds.size() > 1 )
1553 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1568 return splitParts( vectorPointXY2pointSequence( splitLine ), topologicalEditing );
1575 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1579 return utils.
splitParts( splitLine, topologicalEditing );
1586 return splitFeatures( vectorPointXY2pointSequence( splitLine ), topologicalEditing );
1595 bool preserveCircular =
false;
1596 return splitFeatures( &splitLineString, topologyTestPoints, preserveCircular, topologicalEditing );
1603 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1607 return utils.
splitFeatures( curve, topologyTestPoints, preserveCircular, topologicalEditing );
1614 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1632 if ( !
isValid() || !mEditBuffer || !mDataProvider )
1643 if ( !
mValid || !mEditBuffer || !mDataProvider )
1668 if ( !
isValid() || !mDataProvider )
1702 if ( mDataProvider )
1718 if ( !mRenderer->
accept( visitor ) )
1722 if ( !mLabeling->
accept( visitor ) )
1735 QDomNode pkeyNode = layer_node.namedItem( QStringLiteral(
"provider" ) );
1737 if ( pkeyNode.isNull() )
1743 QDomElement pkeyElt = pkeyNode.toElement();
1753 else if (
mDataSource.contains( QLatin1String(
"dbname=" ) ) )
1762 const QDomElement elem = layer_node.toElement();
1764 QgsDataProvider::ReadFlags
flags;
1772 mDataSourceReadOnly =
true;
1782 if ( elem.hasAttribute( QStringLiteral(
"wkbType" ) ) )
1783 mWkbType =
qgsEnumKeyToValue( elem.attribute( QStringLiteral(
"wkbType" ) ), mWkbType );
1786 QDomElement pkeyElem = pkeyNode.toElement();
1787 if ( !pkeyElem.isNull() )
1789 QString encodingString = pkeyElem.attribute( QStringLiteral(
"encoding" ) );
1790 if ( mDataProvider && !encodingString.isEmpty() )
1797 mJoinBuffer->
readXml( layer_node );
1802 mSetLegendFromStyle =
false;
1812 QDomNode depsNode = layer_node.namedItem( QStringLiteral(
"dataDependencies" ) );
1813 QDomNodeList depsNodes = depsNode.childNodes();
1814 QSet<QgsMapLayerDependency> sources;
1815 for (
int i = 0; i < depsNodes.count(); i++ )
1817 QString
source = depsNodes.at( i ).toElement().attribute( QStringLiteral(
"id" ) );
1822 if ( !mSetLegendFromStyle )
1828 mReadExtentFromXml =
true;
1830 if ( mReadExtentFromXml )
1832 const QDomNode extentNode = layer_node.namedItem( QStringLiteral(
"extent" ) );
1833 if ( !extentNode.isNull() )
1840 const QDomNode asNode = layer_node.namedItem( QStringLiteral(
"auxiliaryLayer" ) );
1841 const QDomElement asElem = asNode.toElement();
1842 if ( !asElem.isNull() )
1844 mAuxiliaryLayerKey = asElem.attribute( QStringLiteral(
"key" ) );
1848 mServerProperties->readXml( layer_node );
1855void QgsVectorLayer::setDataSourcePrivate(
const QString &dataSource,
const QString &baseName,
const QString &provider,
1864 setDataProvider( provider, options,
flags );
1874 bool loadDefaultStyleFlag =
false;
1877 loadDefaultStyleFlag =
true;
1883 std::unique_ptr< QgsScopedRuntimeProfile > profile;
1885 profile = std::make_unique< QgsScopedRuntimeProfile >( tr(
"Load layer style" ), QStringLiteral(
"projectload" ) );
1887 bool defaultLoadedFlag =
false;
1895 mSetLegendFromStyle =
false;
1900 if ( !defaultLoadedFlag && loadDefaultStyleFlag )
1908 std::unique_ptr< QgsFeatureRenderer > defaultRenderer( mDataProvider->
createRenderer() );
1909 if ( defaultRenderer )
1911 defaultLoadedFlag =
true;
1917 if ( !defaultLoadedFlag &&
isSpatial() )
1923 if ( !mSetLegendFromStyle )
1928 std::unique_ptr< QgsAbstractVectorLayerLabeling > defaultLabeling( mDataProvider->
createLabeling() );
1929 if ( defaultLabeling )
1936 styleChangedSignalBlocker.release();
1953 QStringList ids, names, descriptions;
1954 QString errorMessage;
1956 const int relatedStylesCount {
listStylesInDatabase( ids, names, descriptions, errorMessage ) };
1957 Q_ASSERT( ids.count() == names.count() );
1958 const QString currentStyleName { mStyleManager->currentStyle() };
1959 for (
int i = 0; i < relatedStylesCount; ++i )
1961 if ( names.at( i ) == currentStyleName )
1965 errorMessage.clear();
1967 if ( ! styleXml.isEmpty() && errorMessage.isEmpty() )
1973 QgsDebugMsgLevel( QStringLiteral(
"Error retrieving style %1 from DB: %2" ).arg( ids.at( i ), errorMessage ), 2 );
1983 std::unique_ptr< QgsFeatureRenderer > defaultRenderer( mDataProvider->
createRenderer() );
1984 if ( defaultRenderer )
2000 delete mDataProvider;
2007 if ( provider.compare( QLatin1String(
"postgres" ) ) == 0 )
2009 const QString checkUnicityKey { QStringLiteral(
"checkPrimaryKeyUnicity" ) };
2011 if ( ! uri.hasParam( checkUnicityKey ) )
2013 uri.setParam( checkUnicityKey, mReadExtentFromXml ?
"0" :
"1" );
2018 std::unique_ptr< QgsScopedRuntimeProfile > profile;
2020 profile = std::make_unique< QgsScopedRuntimeProfile >( tr(
"Create %1 provider" ).arg( provider ), QStringLiteral(
"projectload" ) );
2023 if ( !mDataProvider )
2030 mDataProvider->setParent(
this );
2033 QgsDebugMsgLevel( QStringLiteral(
"Instantiated the data provider plugin" ), 2 );
2043 profile->switchTask( tr(
"Read layer metadata" ) );
2050 newMetadata.
combine( &mMetadata );
2053 QgsDebugMsgLevel( QStringLiteral(
"Set Data provider QgsLayerMetadata identifier[%1]" ).arg(
metadata().identifier() ), 4 );
2060 mWkbType = mDataProvider->
wkbType();
2076 if ( !mAttributeSplitPolicy.contains(
field.
name() ) )
2083 profile->switchTask( tr(
"Read layer fields" ) );
2094 const QRegularExpression reg( R
"lit("[^"]+"\."([^"] + )"( \([^)]+\))?)lit" );
2095 const QRegularExpressionMatch match = reg.match(
name() );
2096 if ( match.hasMatch() )
2098 QStringList stuff = match.capturedTexts();
2099 QString lName = stuff[1];
2103 QMap<QString, QgsMapLayer *>::const_iterator it;
2104 for ( it = layers.constBegin(); it != layers.constEnd() && ( *it )->name() != lName; ++it )
2107 if ( it != layers.constEnd() && stuff.size() > 2 )
2109 lName +=
'.' + stuff[2].mid( 2, stuff[2].length() - 3 );
2112 if ( !lName.isEmpty() )
2122 else if ( provider == QLatin1String(
"ogr" ) )
2126 if (
mDataSource.right( 10 ) == QLatin1String(
"|layerid=0" ) )
2129 else if ( provider == QLatin1String(
"memory" ) )
2134 else if ( provider == QLatin1String(
"hana" ) )
2151 QDomDocument &document,
2158 QDomElement mapLayerNode = layer_node.toElement();
2160 if ( mapLayerNode.isNull() || (
"maplayer" != mapLayerNode.nodeName() ) )
2173 if ( mDataProvider )
2175 QDomElement provider = document.createElement( QStringLiteral(
"provider" ) );
2176 provider.setAttribute( QStringLiteral(
"encoding" ), mDataProvider->
encoding() );
2177 QDomText providerText = document.createTextNode(
providerType() );
2178 provider.appendChild( providerText );
2179 layer_node.appendChild( provider );
2183 mJoinBuffer->
writeXml( layer_node, document );
2186 QDomElement dependenciesElement = document.createElement( QStringLiteral(
"layerDependencies" ) );
2192 QDomElement depElem = document.createElement( QStringLiteral(
"layer" ) );
2193 depElem.setAttribute( QStringLiteral(
"id" ), dep.layerId() );
2194 dependenciesElement.appendChild( depElem );
2196 layer_node.appendChild( dependenciesElement );
2199 QDomElement dataDependenciesElement = document.createElement( QStringLiteral(
"dataDependencies" ) );
2204 QDomElement depElem = document.createElement( QStringLiteral(
"layer" ) );
2205 depElem.setAttribute( QStringLiteral(
"id" ), dep.layerId() );
2206 dataDependenciesElement.appendChild( depElem );
2208 layer_node.appendChild( dataDependenciesElement );
2211 mExpressionFieldBuffer->
writeXml( layer_node, document );
2216 QDomElement asElem = document.createElement( QStringLiteral(
"auxiliaryLayer" ) );
2217 if ( mAuxiliaryLayer )
2219 const QString pkField = mAuxiliaryLayer->joinInfo().targetFieldName();
2220 asElem.setAttribute( QStringLiteral(
"key" ), pkField );
2222 layer_node.appendChild( asElem );
2225 mServerProperties->writeXml( layer_node, document );
2229 return writeSymbology( layer_node, document, errorMsg, context );
2268 if ( categories.testFlag(
Fields ) )
2270 if ( !mExpressionFieldBuffer )
2272 mExpressionFieldBuffer->
readXml( layerNode );
2284 QDomNodeList referencedLayersNodeList = layerNode.toElement().elementsByTagName( QStringLiteral(
"referencedLayers" ) );
2285 if ( referencedLayersNodeList.size() > 0 )
2287 const QDomNodeList relationNodes { referencedLayersNodeList.at( 0 ).childNodes() };
2288 for (
int i = 0; i < relationNodes.length(); ++i )
2290 const QDomElement relationElement = relationNodes.at( i ).toElement();
2297 QDomNodeList referencingLayersNodeList = layerNode.toElement().elementsByTagName( QStringLiteral(
"referencingLayers" ) );
2298 if ( referencingLayersNodeList.size() > 0 )
2300 const QDomNodeList relationNodes { referencingLayersNodeList.at( 0 ).childNodes() };
2301 for (
int i = 0; i < relationNodes.length(); ++i )
2303 const QDomElement relationElement = relationNodes.at( i ).toElement();
2309 QDomElement layerElement = layerNode.toElement();
2313 readStyle( layerNode, errorMessage, context, categories );
2315 if ( categories.testFlag(
MapTips ) )
2316 mMapTipTemplate = layerNode.namedItem( QStringLiteral(
"mapTip" ) ).toElement().text();
2319 mDisplayExpression = layerNode.namedItem( QStringLiteral(
"previewExpression" ) ).toElement().text();
2322 QString
displayField = layerNode.namedItem( QStringLiteral(
"displayfield" ) ).toElement().text();
2326 if ( mMapTipTemplate.isEmpty() && categories.testFlag(
MapTips ) )
2336 if ( categories.testFlag(
Actions ) )
2337 mActions->
readXml( layerNode );
2339 if ( categories.testFlag(
Fields ) )
2344 QDomNode aliasesNode = layerNode.namedItem( QStringLiteral(
"aliases" ) );
2345 if ( !aliasesNode.isNull() )
2347 QDomElement aliasElem;
2349 QDomNodeList aliasNodeList = aliasesNode.toElement().elementsByTagName( QStringLiteral(
"alias" ) );
2350 for (
int i = 0; i < aliasNodeList.size(); ++i )
2352 aliasElem = aliasNodeList.at( i ).toElement();
2355 if ( aliasElem.hasAttribute( QStringLiteral(
"field" ) ) )
2357 field = aliasElem.attribute( QStringLiteral(
"field" ) );
2361 int index = aliasElem.attribute( QStringLiteral(
"index" ) ).toInt();
2363 if ( index >= 0 && index <
fields().count() )
2369 if ( !aliasElem.attribute( QStringLiteral(
"name" ) ).isEmpty() )
2372 alias = context.
projectTranslator()->
translate( QStringLiteral(
"project:layers:%1:fieldaliases" ).arg( layerNode.namedItem( QStringLiteral(
"id" ) ).toElement().text() ), aliasElem.attribute( QStringLiteral(
"name" ) ) );
2373 QgsDebugMsgLevel(
"context" + QStringLiteral(
"project:layers:%1:fieldaliases" ).arg( layerNode.namedItem( QStringLiteral(
"id" ) ).toElement().text() ) +
" source " + aliasElem.attribute( QStringLiteral(
"name" ) ), 3 );
2378 alias = context.
projectTranslator()->
translate( QStringLiteral(
"project:layers:%1:fieldaliases" ).arg( layerNode.namedItem( QStringLiteral(
"id" ) ).toElement().text() ),
field );
2379 QgsDebugMsgLevel(
"context" + QStringLiteral(
"project:layers:%1:fieldaliases" ).arg( layerNode.namedItem( QStringLiteral(
"id" ) ).toElement().text() ) +
" source " +
field, 3 );
2381 if ( alias == aliasElem.attribute( QStringLiteral(
"field" ) ) )
2385 QgsDebugMsgLevel(
"field " +
field +
" origalias " + aliasElem.attribute( QStringLiteral(
"name" ) ) +
" trans " + alias, 3 );
2386 mAttributeAliasMap.insert(
field, alias );
2393 const QDomNode splitPoliciesNode = layerNode.namedItem( QStringLiteral(
"splitPolicies" ) );
2394 if ( !splitPoliciesNode.isNull() )
2396 const QDomNodeList splitPolicyNodeList = splitPoliciesNode.toElement().elementsByTagName( QStringLiteral(
"policy" ) );
2397 for (
int i = 0; i < splitPolicyNodeList.size(); ++i )
2399 const QDomElement splitPolicyElem = splitPolicyNodeList.at( i ).toElement();
2400 const QString
field = splitPolicyElem.attribute( QStringLiteral(
"field" ) );
2402 mAttributeSplitPolicy.insert(
field, policy );
2407 mDefaultExpressionMap.clear();
2408 QDomNode defaultsNode = layerNode.namedItem( QStringLiteral(
"defaults" ) );
2409 if ( !defaultsNode.isNull() )
2411 QDomNodeList defaultNodeList = defaultsNode.toElement().elementsByTagName( QStringLiteral(
"default" ) );
2412 for (
int i = 0; i < defaultNodeList.size(); ++i )
2414 QDomElement defaultElem = defaultNodeList.at( i ).toElement();
2416 QString
field = defaultElem.attribute( QStringLiteral(
"field" ), QString() );
2417 QString expression = defaultElem.attribute( QStringLiteral(
"expression" ), QString() );
2418 bool applyOnUpdate = defaultElem.attribute( QStringLiteral(
"applyOnUpdate" ), QStringLiteral(
"0" ) ) == QLatin1String(
"1" );
2419 if (
field.isEmpty() || expression.isEmpty() )
2427 mFieldConstraints.clear();
2428 mFieldConstraintStrength.clear();
2429 QDomNode constraintsNode = layerNode.namedItem( QStringLiteral(
"constraints" ) );
2430 if ( !constraintsNode.isNull() )
2432 QDomNodeList constraintNodeList = constraintsNode.toElement().elementsByTagName( QStringLiteral(
"constraint" ) );
2433 for (
int i = 0; i < constraintNodeList.size(); ++i )
2435 QDomElement constraintElem = constraintNodeList.at( i ).toElement();
2437 QString
field = constraintElem.attribute( QStringLiteral(
"field" ), QString() );
2438 int constraints = constraintElem.attribute( QStringLiteral(
"constraints" ), QStringLiteral(
"0" ) ).toInt();
2439 if (
field.isEmpty() || constraints == 0 )
2442 mFieldConstraints.insert(
field,
static_cast< QgsFieldConstraints::Constraints
>( constraints ) );
2444 int uniqueStrength = constraintElem.attribute( QStringLiteral(
"unique_strength" ), QStringLiteral(
"1" ) ).toInt();
2445 int notNullStrength = constraintElem.attribute( QStringLiteral(
"notnull_strength" ), QStringLiteral(
"1" ) ).toInt();
2446 int expStrength = constraintElem.attribute( QStringLiteral(
"exp_strength" ), QStringLiteral(
"1" ) ).toInt();
2453 mFieldConstraintExpressions.clear();
2454 QDomNode constraintExpressionsNode = layerNode.namedItem( QStringLiteral(
"constraintExpressions" ) );
2455 if ( !constraintExpressionsNode.isNull() )
2457 QDomNodeList constraintNodeList = constraintExpressionsNode.toElement().elementsByTagName( QStringLiteral(
"constraint" ) );
2458 for (
int i = 0; i < constraintNodeList.size(); ++i )
2460 QDomElement constraintElem = constraintNodeList.at( i ).toElement();
2462 QString
field = constraintElem.attribute( QStringLiteral(
"field" ), QString() );
2463 QString exp = constraintElem.attribute( QStringLiteral(
"exp" ), QString() );
2464 QString desc = constraintElem.attribute( QStringLiteral(
"desc" ), QString() );
2465 if (
field.isEmpty() || exp.isEmpty() )
2468 mFieldConstraintExpressions.insert(
field, qMakePair( exp, desc ) );
2476 if ( categories.testFlag(
Fields ) || categories.testFlag(
Forms ) )
2480 QDomElement widgetsElem = layerNode.namedItem( QStringLiteral(
"fieldConfiguration" ) ).toElement();
2481 QDomNodeList fieldConfigurationElementList = widgetsElem.elementsByTagName( QStringLiteral(
"field" ) );
2482 for (
int i = 0; i < fieldConfigurationElementList.size(); ++i )
2484 const QDomElement fieldConfigElement = fieldConfigurationElementList.at( i ).toElement();
2485 const QDomElement fieldWidgetElement = fieldConfigElement.elementsByTagName( QStringLiteral(
"editWidget" ) ).at( 0 ).toElement();
2487 QString fieldName = fieldConfigElement.attribute( QStringLiteral(
"name" ) );
2489 if ( categories.testFlag(
Fields ) )
2493 if ( categories.testFlag(
Forms ) )
2495 const QString widgetType = fieldWidgetElement.attribute( QStringLiteral(
"type" ) );
2496 const QDomElement cfgElem = fieldConfigElement.elementsByTagName( QStringLiteral(
"config" ) ).at( 0 ).toElement();
2497 const QDomElement optionsElem = cfgElem.childNodes().at( 0 ).toElement();
2499 if ( widgetType == QLatin1String(
"ValueRelation" ) )
2501 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() );
2504 mFieldWidgetSetups[fieldName] = setup;
2511 if ( categories.testFlag(
Fields ) )
2513 const QList<QPair<QString, QgsField::ConfigurationFlag>> legacyConfig
2518 for (
const auto &config : legacyConfig )
2520 QDomNode excludeNode = layerNode.namedItem( config.first );
2521 if ( !excludeNode.isNull() )
2523 QDomNodeList attributeNodeList = excludeNode.toElement().elementsByTagName( QStringLiteral(
"attribute" ) );
2524 for (
int i = 0; i < attributeNodeList.size(); ++i )
2526 QString fieldName = attributeNodeList.at( i ).toElement().text();
2527 if ( !mFieldConfigurationFlags.contains( fieldName ) )
2528 mFieldConfigurationFlags[fieldName] = config.second;
2530 mFieldConfigurationFlags[fieldName].setFlag( config.second,
true );
2537 mGeometryOptions->readXml( layerNode.namedItem( QStringLiteral(
"geometryOptions" ) ) );
2539 if ( categories.testFlag(
Forms ) )
2540 mEditFormConfig.
readXml( layerNode, context );
2544 mAttributeTableConfig.
readXml( layerNode );
2545 mConditionalStyles->
readXml( layerNode, context );
2546 mStoredExpressionManager->
readXml( layerNode );
2552 QDomElement mapLayerNode = layerNode.toElement();
2554 && mapLayerNode.attribute( QStringLiteral(
"readOnly" ), QStringLiteral(
"0" ) ).toInt() == 1 )
2559 if ( categories.testFlag(
Legend ) )
2563 const QDomElement legendElem = layerNode.firstChildElement( QStringLiteral(
"legend" ) );
2564 if ( !legendElem.isNull() )
2569 mSetLegendFromStyle =
true;
2599 if ( !rendererElement.isNull() )
2619 if ( categories.testFlag(
Labeling ) )
2623 QDomElement labelingElement = node.firstChildElement( QStringLiteral(
"labeling" ) );
2625 if ( labelingElement.isNull() ||
2626 ( labelingElement.attribute( QStringLiteral(
"type" ) ) == QLatin1String(
"simple" ) && labelingElement.firstChildElement( QStringLiteral(
"settings" ) ).isNull() ) )
2634 labeling = readLabelingFromCustomProperties();
2642 if ( node.toElement().hasAttribute( QStringLiteral(
"labelsEnabled" ) ) )
2643 mLabelsEnabled = node.toElement().attribute( QStringLiteral(
"labelsEnabled" ) ).toInt();
2645 mLabelsEnabled =
true;
2651 QDomNode blendModeNode = node.namedItem( QStringLiteral(
"blendMode" ) );
2652 if ( !blendModeNode.isNull() )
2654 QDomElement e = blendModeNode.toElement();
2659 QDomNode featureBlendModeNode = node.namedItem( QStringLiteral(
"featureBlendMode" ) );
2660 if ( !featureBlendModeNode.isNull() )
2662 QDomElement e = featureBlendModeNode.toElement();
2670 QDomNode layerTransparencyNode = node.namedItem( QStringLiteral(
"layerTransparency" ) );
2671 if ( !layerTransparencyNode.isNull() )
2673 QDomElement e = layerTransparencyNode.toElement();
2674 setOpacity( 1.0 - e.text().toInt() / 100.0 );
2676 QDomNode layerOpacityNode = node.namedItem( QStringLiteral(
"layerOpacity" ) );
2677 if ( !layerOpacityNode.isNull() )
2679 QDomElement e = layerOpacityNode.toElement();
2683 const bool hasScaleBasedVisibiliy { node.attributes().namedItem( QStringLiteral(
"hasScaleBasedVisibilityFlag" ) ).nodeValue() ==
'1' };
2686 const double maxScale { node.attributes().namedItem( QStringLiteral(
"maxScale" ) ).nodeValue().toDouble( &ok ) };
2691 const double minScale { node.attributes().namedItem( QStringLiteral(
"minScale" ) ).nodeValue().toDouble( &ok ) };
2697 QDomElement e = node.toElement();
2700 mSimplifyMethod.
setSimplifyHints(
static_cast< QgsVectorSimplifyMethod::SimplifyHints
>( e.attribute( QStringLiteral(
"simplifyDrawingHints" ), QStringLiteral(
"1" ) ).toInt() ) );
2702 mSimplifyMethod.
setThreshold( e.attribute( QStringLiteral(
"simplifyDrawingTol" ), QStringLiteral(
"1" ) ).toFloat() );
2703 mSimplifyMethod.
setForceLocalOptimization( e.attribute( QStringLiteral(
"simplifyLocal" ), QStringLiteral(
"1" ) ).toInt() );
2704 mSimplifyMethod.
setMaximumScale( e.attribute( QStringLiteral(
"simplifyMaxScale" ), QStringLiteral(
"1" ) ).toFloat() );
2707 mRenderer->
setReferenceScale( e.attribute( QStringLiteral(
"symbologyReferenceScale" ), QStringLiteral(
"-1" ) ).toDouble() );
2711 if ( categories.testFlag(
Diagrams ) )
2715 delete mDiagramRenderer;
2716 mDiagramRenderer =
nullptr;
2717 QDomElement singleCatDiagramElem = node.firstChildElement( QStringLiteral(
"SingleCategoryDiagramRenderer" ) );
2718 if ( !singleCatDiagramElem.isNull() )
2721 mDiagramRenderer->
readXml( singleCatDiagramElem, context );
2723 QDomElement linearDiagramElem = node.firstChildElement( QStringLiteral(
"LinearlyInterpolatedDiagramRenderer" ) );
2724 if ( !linearDiagramElem.isNull() )
2726 if ( linearDiagramElem.hasAttribute( QStringLiteral(
"classificationAttribute" ) ) )
2729 int idx = linearDiagramElem.attribute( QStringLiteral(
"classificationAttribute" ) ).toInt();
2730 if ( idx >= 0 && idx < mFields.
count() )
2731 linearDiagramElem.setAttribute( QStringLiteral(
"classificationField" ), mFields.
at( idx ).
name() );
2735 mDiagramRenderer->
readXml( linearDiagramElem, context );
2738 if ( mDiagramRenderer )
2740 QDomElement diagramSettingsElem = node.firstChildElement( QStringLiteral(
"DiagramLayerSettings" ) );
2741 if ( !diagramSettingsElem.isNull() )
2743 bool oldXPos = diagramSettingsElem.hasAttribute( QStringLiteral(
"xPosColumn" ) );
2744 bool oldYPos = diagramSettingsElem.hasAttribute( QStringLiteral(
"yPosColumn" ) );
2745 bool oldShow = diagramSettingsElem.hasAttribute( QStringLiteral(
"showColumn" ) );
2746 if ( oldXPos || oldYPos || oldShow )
2752 int xPosColumn = diagramSettingsElem.attribute( QStringLiteral(
"xPosColumn" ) ).toInt();
2753 if ( xPosColumn >= 0 && xPosColumn < mFields.
count() )
2758 int yPosColumn = diagramSettingsElem.attribute( QStringLiteral(
"yPosColumn" ) ).toInt();
2759 if ( yPosColumn >= 0 && yPosColumn < mFields.
count() )
2764 int showColumn = diagramSettingsElem.attribute( QStringLiteral(
"showColumn" ) ).toInt();
2765 if ( showColumn >= 0 && showColumn < mFields.
count() )
2768 QDomElement propertiesElem = diagramSettingsElem.ownerDocument().createElement( QStringLiteral(
"properties" ) );
2775 ddp.
writeXml( propertiesElem, defs );
2776 diagramSettingsElem.appendChild( propertiesElem );
2779 delete mDiagramLayerSettings;
2781 mDiagramLayerSettings->
readXml( diagramSettingsElem );
2787 styleChangedSignalBlocker.release();
2799 QDomElement layerElement = node.toElement();
2802 ( void )
writeStyle( node, doc, errorMessage, context, categories );
2805 mGeometryOptions->writeXml( node );
2810 if ( !legendElement.isNull() )
2811 node.appendChild( legendElement );
2818 QDomElement referencedLayersElement = doc.createElement( QStringLiteral(
"referencedLayers" ) );
2819 node.appendChild( referencedLayersElement );
2824 switch ( rel.type() )
2835 QDomElement referencingLayersElement = doc.createElement( QStringLiteral(
"referencingLayers" ) );
2836 node.appendChild( referencedLayersElement );
2839 for (
const QgsRelation &rel : referencedRelations )
2841 switch ( rel.type() )
2853 if ( categories.testFlag(
Fields ) || categories.testFlag(
Forms ) )
2855 QDomElement fieldConfigurationElement;
2857 fieldConfigurationElement = doc.createElement( QStringLiteral(
"fieldConfiguration" ) );
2858 node.appendChild( fieldConfigurationElement );
2862 QDomElement fieldElement = doc.createElement( QStringLiteral(
"field" ) );
2863 fieldElement.setAttribute( QStringLiteral(
"name" ),
field.
name() );
2864 fieldConfigurationElement.appendChild( fieldElement );
2866 if ( categories.testFlag(
Fields ) )
2871 if ( categories.testFlag(
Forms ) )
2876 QDomElement editWidgetElement = doc.createElement( QStringLiteral(
"editWidget" ) );
2877 fieldElement.appendChild( editWidgetElement );
2879 QDomElement editWidgetConfigElement = doc.createElement( QStringLiteral(
"config" ) );
2882 editWidgetElement.appendChild( editWidgetConfigElement );
2888 if ( categories.testFlag(
Fields ) )
2891 QDomElement aliasElem = doc.createElement( QStringLiteral(
"aliases" ) );
2894 QDomElement aliasEntryElem = doc.createElement( QStringLiteral(
"alias" ) );
2895 aliasEntryElem.setAttribute( QStringLiteral(
"field" ),
field.
name() );
2897 aliasEntryElem.setAttribute( QStringLiteral(
"name" ),
field.
alias() );
2898 aliasElem.appendChild( aliasEntryElem );
2900 node.appendChild( aliasElem );
2904 QDomElement splitPoliciesElement = doc.createElement( QStringLiteral(
"splitPolicies" ) );
2907 QDomElement splitPolicyElem = doc.createElement( QStringLiteral(
"policy" ) );
2908 splitPolicyElem.setAttribute( QStringLiteral(
"field" ),
field.
name() );
2910 splitPoliciesElement.appendChild( splitPolicyElem );
2912 node.appendChild( splitPoliciesElement );
2916 QDomElement defaultsElem = doc.createElement( QStringLiteral(
"defaults" ) );
2919 QDomElement defaultElem = doc.createElement( QStringLiteral(
"default" ) );
2920 defaultElem.setAttribute( QStringLiteral(
"field" ),
field.
name() );
2923 defaultsElem.appendChild( defaultElem );
2925 node.appendChild( defaultsElem );
2928 QDomElement constraintsElem = doc.createElement( QStringLiteral(
"constraints" ) );
2931 QDomElement constraintElem = doc.createElement( QStringLiteral(
"constraint" ) );
2932 constraintElem.setAttribute( QStringLiteral(
"field" ),
field.
name() );
2937 constraintsElem.appendChild( constraintElem );
2939 node.appendChild( constraintsElem );
2942 QDomElement constraintExpressionsElem = doc.createElement( QStringLiteral(
"constraintExpressions" ) );
2945 QDomElement constraintExpressionElem = doc.createElement( QStringLiteral(
"constraint" ) );
2946 constraintExpressionElem.setAttribute( QStringLiteral(
"field" ),
field.
name() );
2949 constraintExpressionsElem.appendChild( constraintExpressionElem );
2951 node.appendChild( constraintExpressionsElem );
2954 if ( !mExpressionFieldBuffer )
2962 mExpressionFieldBuffer->
writeXml( node, doc );
2967 if ( categories.testFlag(
Actions ) )
2972 mAttributeTableConfig.
writeXml( node );
2973 mConditionalStyles->
writeXml( node, doc, context );
2974 mStoredExpressionManager->
writeXml( node );
2977 if ( categories.testFlag(
Forms ) )
2978 mEditFormConfig.
writeXml( node, context );
2982 node.toElement().setAttribute( QStringLiteral(
"readOnly" ), mReadOnly );
2987 QDomElement prevExpElem = doc.createElement( QStringLiteral(
"previewExpression" ) );
2988 QDomText prevExpText = doc.createTextNode( mDisplayExpression );
2989 prevExpElem.appendChild( prevExpText );
2990 node.appendChild( prevExpElem );
2994 if ( categories.testFlag(
MapTips ) )
2996 QDomElement mapTipElem = doc.createElement( QStringLiteral(
"mapTip" ) );
2997 QDomText mapTipText = doc.createTextNode( mMapTipTemplate );
2998 mapTipElem.appendChild( mapTipText );
2999 node.toElement().appendChild( mapTipElem );
3010 QDomElement mapLayerNode = node.toElement();
3023 QDomElement rendererElement = mRenderer->
save( doc, context );
3024 node.appendChild( rendererElement );
3028 if ( categories.testFlag(
Labeling ) )
3032 QDomElement labelingElement = mLabeling->
save( doc, context );
3033 node.appendChild( labelingElement );
3035 mapLayerNode.setAttribute( QStringLiteral(
"labelsEnabled" ), mLabelsEnabled ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
3041 mapLayerNode.setAttribute( QStringLiteral(
"simplifyDrawingHints" ), QString::number( mSimplifyMethod.
simplifyHints() ) );
3042 mapLayerNode.setAttribute( QStringLiteral(
"simplifyAlgorithm" ), QString::number( mSimplifyMethod.
simplifyAlgorithm() ) );
3043 mapLayerNode.setAttribute( QStringLiteral(
"simplifyDrawingTol" ), QString::number( mSimplifyMethod.
threshold() ) );
3044 mapLayerNode.setAttribute( QStringLiteral(
"simplifyLocal" ), mSimplifyMethod.
forceLocalOptimization() ? 1 : 0 );
3045 mapLayerNode.setAttribute( QStringLiteral(
"simplifyMaxScale" ), QString::number( mSimplifyMethod.
maximumScale() ) );
3057 QDomElement blendModeElem = doc.createElement( QStringLiteral(
"blendMode" ) );
3059 blendModeElem.appendChild( blendModeText );
3060 node.appendChild( blendModeElem );
3063 QDomElement featureBlendModeElem = doc.createElement( QStringLiteral(
"featureBlendMode" ) );
3065 featureBlendModeElem.appendChild( featureBlendModeText );
3066 node.appendChild( featureBlendModeElem );
3072 QDomElement layerOpacityElem = doc.createElement( QStringLiteral(
"layerOpacity" ) );
3073 QDomText layerOpacityText = doc.createTextNode( QString::number(
opacity() ) );
3074 layerOpacityElem.appendChild( layerOpacityText );
3075 node.appendChild( layerOpacityElem );
3076 mapLayerNode.setAttribute( QStringLiteral(
"hasScaleBasedVisibilityFlag" ),
hasScaleBasedVisibility() ? 1 : 0 );
3077 mapLayerNode.setAttribute( QStringLiteral(
"maxScale" ),
maximumScale() );
3078 mapLayerNode.setAttribute( QStringLiteral(
"minScale" ),
minimumScale() );
3080 mapLayerNode.setAttribute( QStringLiteral(
"symbologyReferenceScale" ), mRenderer ? mRenderer->
referenceScale() : -1 );
3083 if ( categories.testFlag(
Diagrams ) && mDiagramRenderer )
3085 mDiagramRenderer->
writeXml( mapLayerNode, doc, context );
3086 if ( mDiagramLayerSettings )
3087 mDiagramLayerSettings->
writeXml( mapLayerNode, doc );
3098 QDomElement nameElem = node.firstChildElement( QStringLiteral(
"Name" ) );
3099 if ( nameElem.isNull() )
3101 errorMessage = QStringLiteral(
"Warning: Name element not found within NamedLayer while it's required." );
3117 readSldLabeling( node );
3119 styleChangedSignalBlocker.release();
3129 Q_UNUSED( errorMessage )
3131 QVariantMap localProps = QVariantMap( props );
3140 QDomElement nameNode = doc.createElement( QStringLiteral(
"se:Name" ) );
3141 nameNode.appendChild( doc.createTextNode(
name() ) );
3142 node.appendChild( nameNode );
3144 QDomElement userStyleElem = doc.createElement( QStringLiteral(
"UserStyle" ) );
3145 node.appendChild( userStyleElem );
3147 QDomElement nameElem = doc.createElement( QStringLiteral(
"se:Name" ) );
3148 nameElem.appendChild( doc.createTextNode(
name() ) );
3150 userStyleElem.appendChild( nameElem );
3152 QDomElement featureTypeStyleElem = doc.createElement( QStringLiteral(
"se:FeatureTypeStyle" ) );
3153 userStyleElem.appendChild( featureTypeStyleElem );
3155 mRenderer->
toSld( doc, featureTypeStyleElem, localProps );
3158 mLabeling->
toSld( featureTypeStyleElem, localProps );
3169 if ( !mEditBuffer || !mDataProvider )
3174 if ( mGeometryOptions->isActive() )
3175 mGeometryOptions->apply( geom );
3184 if ( !skipDefaultValue && !mDefaultValueOnUpdateFields.isEmpty() )
3185 updateDefaultValues( fid );
3195 bool result =
false;
3209 if ( mEditBuffer && mDataProvider )
3218 if ( result && !skipDefaultValues && !mDefaultValueOnUpdateFields.isEmpty() )
3219 updateDefaultValues( fid );
3236 for (
auto it = newValues.constBegin(); it != newValues.constEnd(); ++it )
3238 const int field = it.key();
3239 const QVariant newValue = it.value();
3242 if ( oldValues.contains(
field ) )
3243 oldValue = oldValues[
field];
3248 newValuesJoin[
field] = newValue;
3249 oldValuesJoin[
field] = oldValue;
3256 newValuesNotJoin[
field] = newValue;
3257 oldValuesNotJoin[
field] = oldValue;
3266 if ( ! newValuesJoin.isEmpty() && mJoinBuffer )
3271 if ( ! newValuesNotJoin.isEmpty() )
3273 if ( mEditBuffer && mDataProvider )
3279 if ( result && !skipDefaultValues && !mDefaultValueOnUpdateFields.isEmpty() )
3281 updateDefaultValues( fid );
3291 if ( !mEditBuffer || !mDataProvider )
3301 if ( attIndex < 0 || attIndex >=
fields().count() )
3305 mFields[ attIndex ].setAlias( QString() );
3306 if ( mAttributeAliasMap.contains(
name ) )
3308 mAttributeAliasMap.remove(
name );
3310 mEditFormConfig.setFields( mFields );
3319 if ( index < 0 || index >=
fields().count() )
3326 if ( mExpressionFieldBuffer )
3342 if ( !mEditBuffer || !mDataProvider )
3360 if ( attIndex < 0 || attIndex >=
fields().count() )
3365 mAttributeAliasMap.insert(
name, aliasString );
3366 mFields[ attIndex ].setAlias( aliasString );
3367 mEditFormConfig.setFields( mFields );
3375 if ( index < 0 || index >=
fields().count() )
3385 if ( index >= 0 && index < mFields.
count() )
3395 return mAttributeAliasMap;
3402 if ( index < 0 || index >=
fields().count() )
3407 mAttributeSplitPolicy.insert(
name, policy );
3408 mFields[ index ].setSplitPolicy( policy );
3409 mEditFormConfig.setFields( mFields );
3417 QSet<QString> excludeList;
3418 QMap< QString, QgsField::ConfigurationFlags >::const_iterator flagsIt = mFieldConfigurationFlags.constBegin();
3419 for ( ; flagsIt != mFieldConfigurationFlags.constEnd(); ++flagsIt )
3423 excludeList << flagsIt.key();
3433 QMap< QString, QgsField::ConfigurationFlags >::iterator flagsIt = mFieldConfigurationFlags.begin();
3434 for ( ; flagsIt != mFieldConfigurationFlags.end(); ++flagsIt )
3445 QSet<QString> excludeList;
3446 QMap< QString, QgsField::ConfigurationFlags >::const_iterator flagsIt = mFieldConfigurationFlags.constBegin();
3447 for ( ; flagsIt != mFieldConfigurationFlags.constEnd(); ++flagsIt )
3451 excludeList << flagsIt.key();
3461 QMap< QString, QgsField::ConfigurationFlags >::iterator flagsIt = mFieldConfigurationFlags.begin();
3462 for ( ; flagsIt != mFieldConfigurationFlags.end(); ++flagsIt )
3473 if ( index < 0 || index >=
fields().count() )
3482 if ( !mEditBuffer || !mDataProvider )
3492 bool deleted =
false;
3495 QList<int> attrList = qgis::setToList( qgis::listToSet( attrs ) );
3497 std::sort( attrList.begin(), attrList.end(), std::greater<int>() );
3499 for (
int attr : std::as_const( attrList ) )
3517 if ( context && context->
cascade )
3520 const bool hasRelationsOrJoins = !relations.empty() || mJoinBuffer->
containsJoins();
3521 if ( hasRelationsOrJoins )
3526 if ( handledFeatureIds.contains( fid ) )
3534 handledFeatureIds << fid;
3546 switch ( relation.strength() )
3554 while ( relatedFeaturesIt.
nextFeature( childFeature ) )
3556 childFeatureIds.insert( childFeature.
id() );
3558 if ( childFeatureIds.count() > 0 )
3560 relation.referencingLayer()->startEditing();
3561 relation.referencingLayer()->deleteFeatures( childFeatureIds, context );
3588 bool res = deleteFeatureCascade( fid, context );
3608 res = deleteFeatureCascade( fid, context ) && res;
3617 mSelectedFeatureIds.subtract( fids );
3637 if ( !mDataProvider )
3638 return pkAttributesList;
3641 for (
int i = 0; i < mFields.
count(); ++i )
3645 pkAttributesList << i;
3648 return pkAttributesList;
3655 if ( !mDataProvider )
3668 if ( mEditBuffer && !deletedFeatures.empty() )
3670 if ( addedFeatures.size() > deletedFeatures.size() )
3671 return QgsFeatureSource::FeatureAvailability::FeaturesAvailable;
3673 return QgsFeatureSource::FeatureAvailability::FeaturesMaybeAvailable;
3676 if ( ( !mEditBuffer || addedFeatures.empty() ) && mDataProvider && mDataProvider->
empty() )
3677 return QgsFeatureSource::FeatureAvailability::NoFeaturesAvailable;
3679 return QgsFeatureSource::FeatureAvailability::FeaturesAvailable;
3689 mCommitErrors.clear();
3691 if ( !mDataProvider )
3693 mCommitErrors << tr(
"ERROR: no provider" );
3699 mCommitErrors << tr(
"ERROR: layer not editable" );
3705 if ( !mAllowCommit )
3708 mCommitChangesActive =
true;
3710 bool success =
false;
3716 mCommitChangesActive =
false;
3718 if ( !mDeletedFids.empty() )
3721 mDeletedFids.clear();
3762 return mCommitErrors;
3777 if ( !mDataProvider )
3779 mCommitErrors << tr(
"ERROR: no provider" );
3805 mEditBuffer =
nullptr;
3810 if ( rollbackExtent )
3823 return mSelectedFeatureIds.size();
3831 return mSelectedFeatureIds;
3839 features.reserve( mSelectedFeatureIds.count() );
3846 features.push_back( f );
3856 if ( mSelectedFeatureIds.isEmpty() )
3862 if ( mSelectedFeatureIds.count() == 1 )
3863 request.
setFilterFid( *mSelectedFeatureIds.constBegin() );
3874 if ( !mEditBuffer || !mDataProvider )
3877 if ( mGeometryOptions->isActive() )
3879 for (
auto feature = features.begin(); feature != features.end(); ++feature )
3882 mGeometryOptions->apply( geom );
3909 if ( exp.isField() )
3932 if ( !mDisplayExpression.isEmpty() || mFields.
isEmpty() )
3934 return mDisplayExpression;
3939 if ( !candidateName.isEmpty() )
3962 return ( mEditBuffer && mDataProvider );
3971 return t != Qgis::GeometryType::Null && t != Qgis::GeometryType::Unknown;
3974bool QgsVectorLayer::isReadOnly()
const
3978 return mDataSourceReadOnly || mReadOnly;
3986 if ( readonly && mEditBuffer )
3990 if ( !readonly && mDataSourceReadOnly )
3993 mReadOnly = readonly;
4002 if ( ! mDataProvider )
4005 if ( mDataSourceReadOnly )
4016 return mEditBuffer && mEditBuffer->
isModified();
4023 bool auxiliaryField =
false;
4027 return auxiliaryField;
4034 auxiliaryField =
true;
4037 return auxiliaryField;
4050 if ( r != mRenderer )
4054 mSymbolFeatureCounted =
false;
4055 mSymbolFeatureCountMap.clear();
4056 mSymbolFeatureIdMap.clear();
4061 if ( refreshRate <= 0 )
4063 mRefreshRendererTimer->stop();
4064 mRefreshRendererTimer->setInterval( 0 );
4068 mRefreshRendererTimer->setInterval( 1000 / refreshRate );
4069 mRefreshRendererTimer->start();
4084 mRendererGenerators << generator;
4092 for (
int i = mRendererGenerators.count() - 1; i >= 0; --i )
4094 if ( mRendererGenerators.at( i )->id() ==
id )
4096 delete mRendererGenerators.at( i );
4097 mRendererGenerators.removeAt( i );
4107 QList< const QgsFeatureRendererGenerator * > res;
4117 if ( !mDataProvider )
4123 QString ignoredError;
4127 mEditCommandActive =
true;
4135 if ( !mDataProvider )
4140 mEditCommandActive =
false;
4141 if ( !mDeletedFids.isEmpty() )
4145 mSelectedFeatureIds.subtract( mDeletedFids );
4148 mDeletedFids.clear();
4157 if ( !mDataProvider )
4168 std::unique_ptr< QUndoCommand > command = std::make_unique< QUndoCommand >();
4169 command->setObsolete(
true );
4172 mEditCommandActive =
false;
4173 mDeletedFids.clear();
4181 return mJoinBuffer->
addJoin( joinInfo );
4188 return mJoinBuffer->
removeJoin( joinLayerId );
4229 if ( oi < 0 || oi >= mExpressionFieldBuffer->
expressions().size() )
4232 return mExpressionFieldBuffer->
expressions().at( oi ).cachedExpression.expression();
4248 if ( !mDataProvider )
4253 mFields = mDataProvider->
fields();
4263 if ( mExpressionFieldBuffer )
4267 for (
auto aliasIt = mAttributeAliasMap.constBegin(); aliasIt != mAttributeAliasMap.constEnd(); ++aliasIt )
4273 mFields[ index ].setAlias( aliasIt.value() );
4276 for (
auto splitPolicyIt = mAttributeSplitPolicy.constBegin(); splitPolicyIt != mAttributeSplitPolicy.constEnd(); ++splitPolicyIt )
4278 int index = mFields.
lookupField( splitPolicyIt.key() );
4282 mFields[ index ].setSplitPolicy( splitPolicyIt.value() );
4286 QMap< QString, QgsField::ConfigurationFlags >::const_iterator flagsIt = mFieldConfigurationFlags.constBegin();
4287 for ( ; flagsIt != mFieldConfigurationFlags.constEnd(); ++flagsIt )
4293 mFields[index].setConfigurationFlags( flagsIt.value() );
4297 mDefaultValueOnUpdateFields.clear();
4298 QMap< QString, QgsDefaultValue >::const_iterator defaultIt = mDefaultExpressionMap.constBegin();
4299 for ( ; defaultIt != mDefaultExpressionMap.constEnd(); ++defaultIt )
4301 int index = mFields.
lookupField( defaultIt.key() );
4305 mFields[ index ].setDefaultValueDefinition( defaultIt.value() );
4306 if ( defaultIt.value().applyOnUpdate() )
4307 mDefaultValueOnUpdateFields.insert( index );
4310 QMap< QString, QgsFieldConstraints::Constraints >::const_iterator constraintIt = mFieldConstraints.constBegin();
4311 for ( ; constraintIt != mFieldConstraints.constEnd(); ++constraintIt )
4313 int index = mFields.
lookupField( constraintIt.key() );
4326 mFields[ index ].setConstraints( constraints );
4329 QMap< QString, QPair< QString, QString > >::const_iterator constraintExpIt = mFieldConstraintExpressions.constBegin();
4330 for ( ; constraintExpIt != mFieldConstraintExpressions.constEnd(); ++constraintExpIt )
4332 int index = mFields.
lookupField( constraintExpIt.key() );
4343 mFields[ index ].setConstraints( constraints );
4347 for ( ; constraintStrengthIt != mFieldConstraintStrength.constEnd(); ++constraintStrengthIt )
4349 int index = mFields.
lookupField( constraintStrengthIt.key().first );
4359 constraints.
setConstraintStrength( constraintStrengthIt.key().second, constraintStrengthIt.value() );
4360 mFields[ index ].setConstraints( constraints );
4363 auto fieldWidgetIterator = mFieldWidgetSetups.constBegin();
4364 for ( ; fieldWidgetIterator != mFieldWidgetSetups.constEnd(); ++ fieldWidgetIterator )
4366 int index = mFields.
indexOf( fieldWidgetIterator.key() );
4370 mFields[index].setEditorWidgetSetup( fieldWidgetIterator.value() );
4373 if ( oldFields != mFields )
4376 mEditFormConfig.setFields( mFields );
4385 if ( index < 0 || index >= mFields.
count() || !mDataProvider )
4389 if ( expression.isEmpty() )
4393 std::unique_ptr< QgsExpressionContext > tempContext;
4398 evalContext = tempContext.get();
4433 if ( index < 0 || index >= mFields.
count() )
4438 mDefaultExpressionMap.insert( mFields.
at( index ).
name(), definition );
4442 mDefaultExpressionMap.remove( mFields.
at( index ).
name() );
4451 if ( index < 0 || index >= mFields.
count() )
4462 if ( !mDataProvider )
4477 if ( mEditBuffer && ! mDataProvider->
transaction() )
4481 for (
const QVariant &v : constUniqueValues )
4483 vals << v.toString();
4487 QMapIterator< QgsFeatureId, QgsFeature > addedIt( added );
4488 while ( addedIt.hasNext() && ( limit < 0 ||
uniqueValues.count() < limit ) )
4491 QVariant v = addedIt.value().attribute( index );
4494 QString vs = v.toString();
4495 if ( !vals.contains( vs ) )
4504 while ( it.hasNext() && ( limit < 0 ||
uniqueValues.count() < limit ) )
4507 QVariant v = it.value().value( index );
4510 QString vs = v.toString();
4511 if ( !vals.contains( vs ) )
4544 .setSubsetOfAttributes( attList ) );
4547 QVariant currentValue;
4548 QHash<QString, QVariant> val;
4552 val.insert( currentValue.toString(), currentValue );
4553 if ( limit >= 0 && val.size() >= limit )
4559 return qgis::listToSet( val.values() );
4563 Q_ASSERT_X(
false,
"QgsVectorLayer::uniqueValues()",
"Unknown source of the field!" );
4571 QStringList results;
4572 if ( !mDataProvider )
4587 if ( mEditBuffer && ! mDataProvider->
transaction() )
4590 QMapIterator< QgsFeatureId, QgsFeature > addedIt( added );
4591 while ( addedIt.hasNext() && ( limit < 0 || results.count() < limit ) && ( !feedback || !feedback->
isCanceled() ) )
4594 QVariant v = addedIt.value().attribute( index );
4597 QString vs = v.toString();
4598 if ( vs.contains( substring, Qt::CaseInsensitive ) && !results.contains( vs ) )
4606 while ( it.hasNext() && ( limit < 0 || results.count() < limit ) && ( !feedback || !feedback->
isCanceled() ) )
4609 QVariant v = it.value().value( index );
4612 QString vs = v.toString();
4613 if ( vs.contains( substring, Qt::CaseInsensitive ) && !results.contains( vs ) )
4644 QString fieldName = mFields.
at( index ).
name();
4645 request.
setFilterExpression( QStringLiteral(
"\"%1\" ILIKE '%%2%'" ).arg( fieldName, substring ) );
4649 QString currentValue;
4652 currentValue = f.
attribute( index ).toString();
4653 if ( !results.contains( currentValue ) )
4654 results << currentValue;
4656 if ( ( limit >= 0 && results.size() >= limit ) || ( feedback && feedback->
isCanceled() ) )
4666 Q_ASSERT_X(
false,
"QgsVectorLayer::uniqueStringsMatching()",
"Unknown source of the field!" );
4675 minimumOrMaximumValue( index, &minimum,
nullptr );
4684 minimumOrMaximumValue( index,
nullptr, &maximum );
4692 minimumOrMaximumValue( index, &minimum, &maximum );
4695void QgsVectorLayer::minimumOrMaximumValue(
int index, QVariant *minimum, QVariant *maximum )
const
4700 *minimum = QVariant();
4702 *maximum = QVariant();
4704 if ( !mDataProvider )
4724 if ( mEditBuffer && ! mDataProvider->
transaction() )
4727 QMapIterator< QgsFeatureId, QgsFeature > addedIt( added );
4728 while ( addedIt.hasNext() )
4731 const QVariant v = addedIt.value().attribute( index );
4739 while ( it.hasNext() )
4742 const QVariant v = it.value().value( index );
4778 .setSubsetOfAttributes( attList ) );
4781 bool firstValue =
true;
4784 const QVariant currentValue = f.
attribute( index );
4791 *minimum = currentValue;
4793 *maximum = currentValue;
4798 if ( minimum && currentValue.isValid() &&
qgsVariantLessThan( currentValue, *minimum ) )
4799 *minimum = currentValue;
4801 *maximum = currentValue;
4808 Q_ASSERT_X(
false,
"QgsVectorLayer::minimumOrMaximumValue()",
"Unknown source of the field!" );
4811void QgsVectorLayer::createEditBuffer()
4847void QgsVectorLayer::clearEditBuffer()
4852 mEditBuffer =
nullptr;
4867 if ( !mDataProvider )
4870 *
error = tr(
"Layer is invalid" );
4876 if ( attrIndex >= 0 )
4883 bool providerOk =
false;
4884 QVariant val = mDataProvider->
aggregate(
aggregate, attrIndex, parameters, context, providerOk, fids );
4898 c.setFidsFilter( *fids );
4899 c.setParameters( parameters );
4900 bool aggregateOk =
false;
4901 const QVariant result =
c.calculate(
aggregate, fieldOrExpression, context, &aggregateOk, feedback );
4904 if ( !aggregateOk &&
error )
4927 return mFeatureBlendMode;
4930void QgsVectorLayer::readSldLabeling(
const QDomNode &node )
4937 QDomElement element = node.toElement();
4938 if ( element.isNull() )
4941 QDomElement userStyleElem = element.firstChildElement( QStringLiteral(
"UserStyle" ) );
4942 if ( userStyleElem.isNull() )
4944 QgsDebugMsgLevel( QStringLiteral(
"Info: UserStyle element not found." ), 4 );
4948 QDomElement featTypeStyleElem = userStyleElem.firstChildElement( QStringLiteral(
"FeatureTypeStyle" ) );
4949 if ( featTypeStyleElem.isNull() )
4951 QgsDebugMsgLevel( QStringLiteral(
"Info: FeatureTypeStyle element not found." ), 4 );
4956 QDomElement mergedFeatTypeStyle = featTypeStyleElem.cloneNode(
false ).toElement();
4961 bool needRuleBasedLabeling =
false;
4964 while ( !featTypeStyleElem.isNull() )
4966 QDomElement ruleElem = featTypeStyleElem.firstChildElement( QStringLiteral(
"Rule" ) );
4967 while ( !ruleElem.isNull() )
4971 bool hasTextSymbolizer =
false;
4972 bool hasRuleBased =
false;
4973 QDomElement ruleChildElem = ruleElem.firstChildElement();
4974 while ( !ruleChildElem.isNull() )
4977 if ( ruleChildElem.localName() == QLatin1String(
"Filter" ) ||
4978 ruleChildElem.localName() == QLatin1String(
"MinScaleDenominator" ) ||
4979 ruleChildElem.localName() == QLatin1String(
"MaxScaleDenominator" ) )
4981 hasRuleBased =
true;
4984 else if ( ruleChildElem.localName() == QLatin1String(
"TextSymbolizer" ) )
4986 QgsDebugMsgLevel( QStringLiteral(
"Info: TextSymbolizer element found" ), 4 );
4987 hasTextSymbolizer =
true;
4990 ruleChildElem = ruleChildElem.nextSiblingElement();
4993 if ( hasTextSymbolizer )
4998 mergedFeatTypeStyle.appendChild( ruleElem.cloneNode().toElement() );
5002 QgsDebugMsgLevel( QStringLiteral(
"Info: Filter or Min/MaxScaleDenominator element found: need a RuleBasedLabeling" ), 4 );
5003 needRuleBasedLabeling =
true;
5008 if ( ruleCount > 1 )
5010 QgsDebugMsgLevel( QStringLiteral(
"Info: More Rule elements found: need a RuleBasedLabeling" ), 4 );
5011 needRuleBasedLabeling =
true;
5015 if ( ruleCount == 0 )
5017 needRuleBasedLabeling =
false;
5020 ruleElem = ruleElem.nextSiblingElement( QStringLiteral(
"Rule" ) );
5022 featTypeStyleElem = featTypeStyleElem.nextSiblingElement( QStringLiteral(
"FeatureTypeStyle" ) );
5025 if ( ruleCount == 0 )
5027 QgsDebugMsgLevel( QStringLiteral(
"Info: No TextSymbolizer element." ), 4 );
5031 QDomElement ruleElem = mergedFeatTypeStyle.firstChildElement( QStringLiteral(
"Rule" ) );
5033 if ( needRuleBasedLabeling )
5037 while ( !ruleElem.isNull() )
5040 QString label, description, filterExp;
5041 int scaleMinDenom = 0, scaleMaxDenom = 0;
5045 QDomElement childElem = ruleElem.firstChildElement();
5046 while ( !childElem.isNull() )
5048 if ( childElem.localName() == QLatin1String(
"Name" ) )
5052 if ( label.isEmpty() )
5053 label = childElem.firstChild().nodeValue();
5055 else if ( childElem.localName() == QLatin1String(
"Description" ) )
5058 QDomElement titleElem = childElem.firstChildElement( QStringLiteral(
"Title" ) );
5059 if ( !titleElem.isNull() )
5061 label = titleElem.firstChild().nodeValue();
5064 QDomElement abstractElem = childElem.firstChildElement( QStringLiteral(
"Abstract" ) );
5065 if ( !abstractElem.isNull() )
5067 description = abstractElem.firstChild().nodeValue();
5070 else if ( childElem.localName() == QLatin1String(
"Abstract" ) )
5073 description = childElem.firstChild().nodeValue();
5075 else if ( childElem.localName() == QLatin1String(
"Title" ) )
5078 label = childElem.firstChild().nodeValue();
5080 else if ( childElem.localName() == QLatin1String(
"Filter" ) )
5096 else if ( childElem.localName() == QLatin1String(
"MinScaleDenominator" ) )
5099 int v = childElem.firstChild().nodeValue().toInt( &ok );
5103 else if ( childElem.localName() == QLatin1String(
"MaxScaleDenominator" ) )
5106 int v = childElem.firstChild().nodeValue().toInt( &ok );
5110 else if ( childElem.localName() == QLatin1String(
"TextSymbolizer" ) )
5112 readSldTextSymbolizer( childElem, settings );
5115 childElem = childElem.nextSiblingElement();
5121 ruleElem = ruleElem.nextSiblingElement();
5131 QDomElement textSymbolizerElem = ruleElem.firstChildElement( QStringLiteral(
"TextSymbolizer" ) );
5133 if ( readSldTextSymbolizer( textSymbolizerElem, s ) )
5141bool QgsVectorLayer::readSldTextSymbolizer(
const QDomNode &node,
QgsPalLayerSettings &settings )
const
5145 if ( node.localName() != QLatin1String(
"TextSymbolizer" ) )
5147 QgsDebugMsgLevel( QStringLiteral(
"Not a TextSymbolizer element: %1" ).arg( node.localName() ), 3 );
5150 QDomElement textSymbolizerElem = node.toElement();
5152 QDomElement labelElem = textSymbolizerElem.firstChildElement( QStringLiteral(
"Label" ) );
5153 if ( !labelElem.isNull() )
5155 QDomElement propertyNameElem = labelElem.firstChildElement( QStringLiteral(
"PropertyName" ) );
5156 if ( !propertyNameElem.isNull() )
5161 QString labelAttribute = propertyNameElem.text();
5165 int fieldIndex = mFields.
lookupField( labelAttribute );
5166 if ( fieldIndex == -1 )
5170 if ( !exp.hasEvalError() )
5176 QgsDebugMsgLevel( QStringLiteral(
"SLD label attribute error: %1" ).arg( exp.evalErrorString() ), 3 );
5182 QgsDebugMsgLevel( QStringLiteral(
"Info: PropertyName element not found." ), 4 );
5193 if ( textSymbolizerElem.hasAttribute( QStringLiteral(
"uom" ) ) )
5198 QString fontFamily = QStringLiteral(
"Sans-Serif" );
5199 int fontPointSize = 10;
5201 int fontWeight = -1;
5202 bool fontItalic =
false;
5203 bool fontUnderline =
false;
5206 QDomElement fontElem = textSymbolizerElem.firstChildElement( QStringLiteral(
"Font" ) );
5207 if ( !fontElem.isNull() )
5210 for ( QgsStringMap::iterator it = fontSvgParams.begin(); it != fontSvgParams.end(); ++it )
5212 QgsDebugMsgLevel( QStringLiteral(
"found fontSvgParams %1: %2" ).arg( it.key(), it.value() ), 4 );
5214 if ( it.key() == QLatin1String(
"font-family" ) )
5216 fontFamily = it.value();
5218 else if ( it.key() == QLatin1String(
"font-style" ) )
5220 fontItalic = ( it.value() == QLatin1String(
"italic" ) ) || ( it.value() == QLatin1String(
"Italic" ) );
5222 else if ( it.key() == QLatin1String(
"font-size" ) )
5225 int fontSize = it.value().toInt( &ok );
5228 fontPointSize = fontSize;
5229 fontUnitSize = sldUnitSize;
5232 else if ( it.key() == QLatin1String(
"font-weight" ) )
5234 if ( ( it.value() == QLatin1String(
"bold" ) ) || ( it.value() == QLatin1String(
"Bold" ) ) )
5235 fontWeight = QFont::Bold;
5237 else if ( it.key() == QLatin1String(
"font-underline" ) )
5239 fontUnderline = ( it.value() == QLatin1String(
"underline" ) ) || ( it.value() == QLatin1String(
"Underline" ) );
5245 QFont font( fontFamily, fontPointSize, fontWeight, fontItalic );
5246 font.setUnderline( fontUnderline );
5248 format.
setSize( fontPointSize );
5252 QDomElement fillElem = textSymbolizerElem.firstChildElement( QStringLiteral(
"Fill" ) );
5254 Qt::BrushStyle textBrush = Qt::SolidPattern;
5256 if ( textColor.isValid() )
5258 QgsDebugMsgLevel( QStringLiteral(
"Info: textColor %1." ).arg( QVariant( textColor ).toString() ), 4 );
5265 QDomElement haloElem = textSymbolizerElem.firstChildElement( QStringLiteral(
"Halo" ) );
5266 if ( !haloElem.isNull() )
5271 QDomElement radiusElem = haloElem.firstChildElement( QStringLiteral(
"Radius" ) );
5272 if ( !radiusElem.isNull() )
5275 double bufferSize = radiusElem.text().toDouble( &ok );
5278 bufferSettings.
setSize( bufferSize );
5283 QDomElement haloFillElem = haloElem.firstChildElement( QStringLiteral(
"Fill" ) );
5285 Qt::BrushStyle bufferBrush = Qt::SolidPattern;
5287 if ( bufferColor.isValid() )
5289 QgsDebugMsgLevel( QStringLiteral(
"Info: bufferColor %1." ).arg( QVariant( bufferColor ).toString() ), 4 );
5290 bufferSettings.
setColor( bufferColor );
5295 QDomElement labelPlacementElem = textSymbolizerElem.firstChildElement( QStringLiteral(
"LabelPlacement" ) );
5296 if ( !labelPlacementElem.isNull() )
5299 QDomElement pointPlacementElem = labelPlacementElem.firstChildElement( QStringLiteral(
"PointPlacement" ) );
5300 if ( !pointPlacementElem.isNull() )
5308 QDomElement displacementElem = pointPlacementElem.firstChildElement( QStringLiteral(
"Displacement" ) );
5309 if ( !displacementElem.isNull() )
5311 QDomElement displacementXElem = displacementElem.firstChildElement( QStringLiteral(
"DisplacementX" ) );
5312 if ( !displacementXElem.isNull() )
5315 double xOffset = displacementXElem.text().toDouble( &ok );
5322 QDomElement displacementYElem = displacementElem.firstChildElement( QStringLiteral(
"DisplacementY" ) );
5323 if ( !displacementYElem.isNull() )
5326 double yOffset = displacementYElem.text().toDouble( &ok );
5334 QDomElement anchorPointElem = pointPlacementElem.firstChildElement( QStringLiteral(
"AnchorPoint" ) );
5335 if ( !anchorPointElem.isNull() )
5337 QDomElement anchorPointXElem = anchorPointElem.firstChildElement( QStringLiteral(
"AnchorPointX" ) );
5338 if ( !anchorPointXElem.isNull() )
5341 double xOffset = anchorPointXElem.text().toDouble( &ok );
5348 QDomElement anchorPointYElem = anchorPointElem.firstChildElement( QStringLiteral(
"AnchorPointY" ) );
5349 if ( !anchorPointYElem.isNull() )
5352 double yOffset = anchorPointYElem.text().toDouble( &ok );
5361 QDomElement rotationElem = pointPlacementElem.firstChildElement( QStringLiteral(
"Rotation" ) );
5362 if ( !rotationElem.isNull() )
5365 double rotation = rotationElem.text().toDouble( &ok );
5375 QDomElement linePlacementElem = labelPlacementElem.firstChildElement( QStringLiteral(
"LinePlacement" ) );
5376 if ( !linePlacementElem.isNull() )
5385 QDomElement vendorOptionElem = textSymbolizerElem.firstChildElement( QStringLiteral(
"VendorOption" ) );
5386 while ( !vendorOptionElem.isNull() && vendorOptionElem.localName() == QLatin1String(
"VendorOption" ) )
5388 QString optionName = vendorOptionElem.attribute( QStringLiteral(
"name" ) );
5389 QString optionValue;
5390 if ( vendorOptionElem.firstChild().nodeType() == QDomNode::TextNode )
5392 optionValue = vendorOptionElem.firstChild().nodeValue();
5396 if ( vendorOptionElem.firstChild().nodeType() == QDomNode::ElementNode &&
5397 vendorOptionElem.firstChild().localName() == QLatin1String(
"Literal" ) )
5399 QgsDebugMsg( vendorOptionElem.firstChild().localName() );
5400 optionValue = vendorOptionElem.firstChild().firstChild().nodeValue();
5404 QgsDebugMsg( QStringLiteral(
"unexpected child of %1 named %2" ).arg( vendorOptionElem.localName(), optionName ) );
5408 if ( !optionName.isEmpty() && !optionValue.isEmpty() )
5410 vendorOptions[ optionName ] = optionValue;
5413 vendorOptionElem = vendorOptionElem.nextSiblingElement();
5415 if ( !vendorOptions.isEmpty() )
5417 for ( QgsStringMap::iterator it = vendorOptions.begin(); it != vendorOptions.end(); ++it )
5419 if ( it.key() == QLatin1String(
"underlineText" ) && it.value() == QLatin1String(
"true" ) )
5421 font.setUnderline(
true );
5424 else if ( it.key() == QLatin1String(
"strikethroughText" ) && it.value() == QLatin1String(
"true" ) )
5426 font.setStrikeOut(
true );
5429 else if ( it.key() == QLatin1String(
"maxDisplacement" ) )
5433 else if ( it.key() == QLatin1String(
"followLine" ) && it.value() == QLatin1String(
"true" ) )
5444 else if ( it.key() == QLatin1String(
"maxAngleDelta" ) )
5447 double angle = it.value().toDouble( &ok );
5455 else if ( it.key() == QLatin1String(
"conflictResolution" ) && it.value() == QLatin1String(
"false" ) )
5459 else if ( it.key() == QLatin1String(
"forceLeftToRight" ) && it.value() == QLatin1String(
"false" ) )
5461 settings.
upsidedownLabels = Qgis::UpsideDownLabelHandling::AlwaysAllowUpsideDown;
5463 else if ( it.key() == QLatin1String(
"group" ) && it.value() == QLatin1String(
"yes" ) )
5467 else if ( it.key() == QLatin1String(
"labelAllGroup" ) && it.value() == QLatin1String(
"true" ) )
5483 return mEditFormConfig;
5494 mEditFormConfig.onRelationsLoaded();
5504 if ( config.isEmpty() )
5540 if ( !mDiagramLayerSettings )
5542 *mDiagramLayerSettings = s;
5550 QString myMetadata = QStringLiteral(
"<html><head></head>\n<body>\n" );
5555 myMetadata += QStringLiteral(
"<h1>" ) + tr(
"Information from provider" ) + QStringLiteral(
"</h1>\n<hr>\n" );
5556 myMetadata += QLatin1String(
"<table class=\"list-view\">\n" );
5561 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"Storage" ) + QStringLiteral(
"</td><td>" ) +
storageType() + QStringLiteral(
"</td></tr>\n" );
5567 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"Comment" ) + QStringLiteral(
"</td><td>" ) +
dataComment() + QStringLiteral(
"</td></tr>\n" );
5574 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"Encoding" ) + QStringLiteral(
"</td><td>" ) + provider->
encoding() + QStringLiteral(
"</td></tr>\n" );
5581 if (
static_cast<int>(
type ) < 0 ||
static_cast< int >(
type ) >
static_cast< int >( Qgis::GeometryType::Null ) )
5589 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"Geometry" ) + QStringLiteral(
"</td><td>" ) + typeString + QStringLiteral(
"</td></tr>\n" );
5593 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"Extent" ) + QStringLiteral(
"</td><td>" ) +
extent().
toString() + QStringLiteral(
"</td></tr>\n" );
5597 QLocale locale = QLocale();
5598 locale.setNumberOptions( locale.numberOptions() &= ~QLocale::NumberOption::OmitGroupSeparator );
5599 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" )
5600 + tr(
"Feature count" ) + QStringLiteral(
"</td><td>" )
5602 + QStringLiteral(
"</td></tr>\n" );
5605 myMetadata += QLatin1String(
"</table>\n<br><br>" );
5614 myMetadata += QStringLiteral(
"<h1>" ) + tr(
"Identification" ) + QStringLiteral(
"</h1>\n<hr>\n" );
5615 myMetadata += htmlFormatter.identificationSectionHtml( );
5616 myMetadata += QLatin1String(
"<br><br>\n" );
5619 myMetadata += QStringLiteral(
"<h1>" ) + tr(
"Extent" ) + QStringLiteral(
"</h1>\n<hr>\n" );
5620 myMetadata += htmlFormatter.extentSectionHtml(
isSpatial() );
5621 myMetadata += QLatin1String(
"<br><br>\n" );
5624 myMetadata += QStringLiteral(
"<h1>" ) + tr(
"Access" ) + QStringLiteral(
"</h1>\n<hr>\n" );
5625 myMetadata += htmlFormatter.accessSectionHtml( );
5626 myMetadata += QLatin1String(
"<br><br>\n" );
5629 myMetadata += QStringLiteral(
"<h1>" ) + tr(
"Fields" ) + QStringLiteral(
"</h1>\n<hr>\n<table class=\"list-view\">\n" );
5633 if ( !pkAttrList.isEmpty() )
5635 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"Primary key attributes" ) + QStringLiteral(
"</td><td>" );
5636 const auto constPkAttrList = pkAttrList;
5637 for (
int idx : constPkAttrList )
5641 myMetadata += QLatin1String(
"</td></tr>\n" );
5647 myMetadata += QStringLiteral(
"<tr><td class=\"highlight\">" ) + tr(
"Count" ) + QStringLiteral(
"</td><td>" ) + QString::number( myFields.
size() ) + QStringLiteral(
"</td></tr>\n" );
5649 myMetadata += QLatin1String(
"</table>\n<br><table width=\"100%\" class=\"tabular-view\">\n" );
5650 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" );
5652 for (
int i = 0; i < myFields.
size(); ++i )
5657 rowClass = QStringLiteral(
"class=\"odd-row\"" );
5658 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" );
5662 myMetadata += QLatin1String(
"</table>\n<br><br>" );
5665 myMetadata += QStringLiteral(
"<h1>" ) + tr(
"Contacts" ) + QStringLiteral(
"</h1>\n<hr>\n" );
5666 myMetadata += htmlFormatter.contactsSectionHtml( );