78#include <QApplication>
83#include <QTemporaryFile>
86#include <QStandardPaths>
88#include <QRegularExpression>
110 QStringList keyTokens = QStringList( scope );
111#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
112 keyTokens += key.split(
'/', QString::SkipEmptyParts );
114 keyTokens += key.split(
'/', Qt::SkipEmptyParts );
118 keyTokens.push_front( QStringLiteral(
"properties" ) );
121 for (
int i = 0; i < keyTokens.size(); ++i )
123 const QString keyToken = keyTokens.at( i );
127 const thread_local QRegularExpression sInvalidRegexp = QRegularExpression( QStringLiteral(
"([^:A-Z_a-z\\x{C0}-\\x{D6}\\x{D8}-\\x{F6}\\x{F8}-\\x{2FF}\\x{370}-\\x{37D}\\x{37F}-\\x{1FFF}\\x{200C}-\\x{200D}\\x{2070}-\\x{218F}\\x{2C00}-\\x{2FEF}\\x{3001}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFFD}\\-\\.0-9\\x{B7}\\x{0300}-\\x{036F}\\x{203F}-\\x{2040}]|^[^:A-Z_a-z\\x{C0}-\\x{D6}\\x{D8}-\\x{F6}\\x{F8}-\\x{2FF}\\x{370}-\\x{37D}\\x{37F}-\\x{1FFF}\\x{200C}-\\x{200D}\\x{2070}-\\x{218F}\\x{2C00}-\\x{2FEF}\\x{3001}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFFD}])" ) );
128 if ( keyToken.contains( sInvalidRegexp ) )
130 const QString errorString = QObject::tr(
"Entry token invalid : '%1'. The token will not be saved to file." ).arg( keyToken );
158 while ( !keySequence.isEmpty() )
162 if ( keySequence.first() == currentProperty->
name() )
165 keySequence.pop_front();
167 if ( 1 == keySequence.count() )
170 return currentProperty->
find( keySequence.front() );
172 else if ( keySequence.isEmpty() )
177 return currentProperty;
179 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
181 if ( nextProperty->
isKey() )
185 else if ( nextProperty->
isValue() && 1 == keySequence.count() )
191 return currentProperty;
229 const QVariant &value,
230 bool &propertiesModified )
239 propertiesModified =
false;
240 while ( ! keySequence.isEmpty() )
244 if ( keySequence.first() == currentProperty->
name() )
247 keySequence.pop_front();
251 if ( 1 == keySequence.count() )
254 if ( !property || property->value() != value )
256 currentProperty->
setValue( keySequence.front(), value );
257 propertiesModified =
true;
260 return currentProperty;
264 else if ( keySequence.isEmpty() )
266 if ( currentProperty->
value() != value )
269 propertiesModified =
true;
272 return currentProperty;
274 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
278 if ( currentProperty )
289 if ( ( newPropertyKey = currentProperty->
addKey( keySequence.first() ) ) )
291 currentProperty = newPropertyKey;
323 while ( ! keySequence.isEmpty() )
327 if ( keySequence.first() == currentProperty->
name() )
330 keySequence.pop_front();
334 if ( 1 == keySequence.count() )
336 currentProperty->
removeKey( keySequence.front() );
341 else if ( keySequence.isEmpty() )
343 previousQgsPropertyKey->
removeKey( currentProperty->
name() );
345 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
347 previousQgsPropertyKey = currentProperty;
350 if ( currentProperty )
374 , mCapabilities( capabilities )
377 , mSnappingConfig( this )
395 mProperties.
setName( QStringLiteral(
"properties" ) );
398 mMainAnnotationLayer->setParent(
this );
412 this, [ = ](
const QStringList &
layers ) { mProjectScope.reset(); emit layersWillBeRemoved( layers ); } );
414 this, [ = ](
const QList<QgsMapLayer *> &
layers ) { mProjectScope.reset(); emit layersWillBeRemoved( layers ); } );
416 this, [ = ](
const QString & layer ) { mProjectScope.reset(); emit layerWillBeRemoved( layer ); } );
418 this, [ = ](
QgsMapLayer * layer ) { mProjectScope.reset(); emit layerWillBeRemoved( layer ); } );
420 [ = ](
const QStringList &
layers ) { mProjectScope.reset(); emit layersRemoved( layers ); } );
422 [ = ](
const QString & layer ) { mProjectScope.reset(); emit layerRemoved( layer ); } );
424 [ = ]() { mProjectScope.reset(); emit removeAll(); } );
426 [ = ](
const QList< QgsMapLayer * > &
layers ) { mProjectScope.reset(); emit layersAdded( layers ); } );
428 [ = ](
QgsMapLayer * layer ) { mProjectScope.reset(); emit layerWasAdded( layer ); } );
436 [ = ](
const QList<QgsMapLayer *> &
layers )
438 for ( const auto &layer : layers )
440 disconnect( layer, &QgsMapLayer::dataSourceChanged, mRelationManager, &QgsRelationManager::updateRelationsStatus );
445 [ = ](
const QList<QgsMapLayer *> &layers )
447 for ( const auto &layer : layers )
449 connect( layer, &QgsMapLayer::dataSourceChanged, mRelationManager, &QgsRelationManager::updateRelationsStatus );
458 mStyleSettings->combinedStyleModel()->addDefaultStyle();
464 mIsBeingDeleted =
true;
467 releaseHandlesToProjectArchive();
468 delete mBadLayerHandler;
469 delete mRelationManager;
470 delete mLayerTreeRegistryBridge;
472 if (
this == sProject )
503 mProjectScope.reset();
514 return mMetadata.
title();
523 if ( oldEvaluateDefaultValues != newEvaluateDefaultValues )
526 for (
auto layerIt =
layers.constBegin(); layerIt !=
layers.constEnd(); ++layerIt )
528 if (
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layerIt.value() ) )
537 if ( oldTrustLayerMetadata != newTrustLayerMetadata )
540 for (
auto layerIt =
layers.constBegin(); layerIt !=
layers.constEnd(); ++layerIt )
542 if (
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layerIt.value() ) )
544 vl->setReadExtentFromXml( newTrustLayerMetadata );
549 if ( mFlags !=
flags )
560 Qgis::ProjectFlags newFlags = mFlags;
564 newFlags &= ~(
static_cast< int >( flag ) );
579 return mSaveUserFull;
586 return mSaveDateTime;
607 if ( dirty && mDirtyBlockCount > 0 )
613 if ( mDirty == dirty )
624 if ( path == mHomePath )
628 mCachedHomePath.clear();
629 mProjectScope.reset();
640 const QList<QgsAttributeEditorElement *> elements = parent->
children();
644 if ( element->type() == Qgis::AttributeEditorType::Container )
648 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:formcontainers" ).arg( layerId ), container->
name() );
650 if ( !container->
children().empty() )
665 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1" ).arg( layer->layerId() ), layer->name() );
682 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:fieldaliases" ).arg( vlayer->
id() ), fieldName );
697 const QList<QgsLayerTreeGroup *> groupLayers = mRootGroup->
findGroups();
700 translationContext->
registerTranslation( QStringLiteral(
"project:layergroups" ), groupLayer->name() );
704 const QList<QgsRelation> &relations = mRelationManager->
relations().values();
707 translationContext->
registerTranslation( QStringLiteral(
"project:relations" ), relation.name() );
715 mDataDefinedServerProperties = properties;
722 return mDataDefinedServerProperties;
729 switch ( mTransactionMode )
750 switch ( mTransactionMode )
757 commitErrors.append( tr(
"Trying to commit changes without a layer specified. This only works if the transaction mode is buffered" ) );
766 return mEditBufferGroup.
commitChanges( commitErrors, stopEditing );
776 switch ( mTransactionMode )
783 rollbackErrors.append( tr(
"Trying to roll back changes without a layer specified. This only works if the transaction mode is buffered" ) );
786 bool success = vectorLayer->
rollBack( stopEditing );
792 return mEditBufferGroup.
rollBack( rollbackErrors, stopEditing );
802 if ( name == mFile.fileName() )
805 const QString oldHomePath =
homePath();
807 mFile.setFileName( name );
808 mCachedHomePath.clear();
809 mProjectScope.reset();
813 const QString newHomePath =
homePath();
814 if ( newHomePath != oldHomePath )
825 return mFile.fileName();
832 mOriginalPath = path;
839 return mOriginalPath;
846 return QFileInfo( mFile );
864 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
869 return QFileInfo( mFile.fileName() ).lastModified();
880 if ( mFile.fileName().isEmpty() )
883 return QFileInfo( mFile.fileName() ).absolutePath();
894 if ( mFile.fileName().isEmpty() )
897 return QFileInfo( mFile.fileName() ).absoluteFilePath();
908 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
913 return QFileInfo( mFile.fileName() ).completeBaseName();
921 const bool absolutePaths =
readBoolEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
false );
932 writeEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
true );
935 writeEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
false );
955 writeEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectionsEnabled" ),
crs.
isValid() ? 1 : 0 );
956 mProjectScope.reset();
967 if ( adjustEllipsoid )
976 if ( !
crs().isValid() )
979 return readEntry( QStringLiteral(
"Measure" ), QStringLiteral(
"/Ellipsoid" ),
geoNone() );
986 if (
ellipsoid ==
readEntry( QStringLiteral(
"Measure" ), QStringLiteral(
"/Ellipsoid" ) ) )
989 mProjectScope.reset();
999 return mTransformContext;
1006 if ( context == mTransformContext )
1009 mTransformContext = context;
1010 mProjectScope.reset();
1013 for (
auto &layer : mLayerStore.get()->mapLayers() )
1015 layer->setTransformContext( context );
1024 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
1026 mProjectScope.reset();
1027 mFile.setFileName( QString() );
1030 mSaveUserFull.clear();
1031 mSaveDateTime = QDateTime();
1034 mCachedHomePath.clear();
1036 mFlags = Qgis::ProjectFlags();
1038 mCustomVariables.clear();
1042 if ( !mSettings.
value( QStringLiteral(
"projects/anonymize_new_projects" ),
false,
QgsSettings::Core ).toBool() )
1061 mEmbeddedLayers.clear();
1062 mRelationManager->
clear();
1063 mAnnotationManager->clear();
1064 mLayoutManager->clear();
1065 m3DViewsManager->clear();
1066 mBookmarkManager->
clear();
1067 mSensorManager->
clear();
1068 mViewSettings->
reset();
1069 mTimeSettings->
reset();
1070 mElevationProperties->
reset();
1071 mDisplaySettings->
reset();
1072 mGpsSettings->
reset();
1073 mSnappingConfig.
reset();
1081 mLabelingEngineSettings->clear();
1085 releaseHandlesToProjectArchive();
1091 mStyleSettings->
reset();
1095 if ( !mIsBeingDeleted )
1103 writeEntry( QStringLiteral(
"PositionPrecision" ), QStringLiteral(
"/Automatic" ),
true );
1104 writeEntry( QStringLiteral(
"PositionPrecision" ), QStringLiteral(
"/DecimalPlaces" ), 2 );
1106 const bool defaultRelativePaths = mSettings.
value( QStringLiteral(
"/qgis/defaultProjectPathsRelative" ),
true ).toBool();
1109 int red = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_red" ), 255 ).toInt();
1110 int green = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_green" ), 255 ).toInt();
1111 int blue = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_blue" ), 255 ).toInt();
1114 red = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_red" ), 255 ).toInt();
1115 green = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_green" ), 255 ).toInt();
1116 blue = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_blue" ), 0 ).toInt();
1117 const int alpha = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_alpha" ), 255 ).toInt();
1123 mRootGroup->
clear();
1124 if ( mMainAnnotationLayer )
1125 mMainAnnotationLayer->
reset();
1127 snapSingleBlocker.release();
1129 if ( !mBlockSnappingUpdates )
1141 topQgsPropertyKey.
dump();
1174 const QDomElement propertiesElem = doc.documentElement().firstChildElement( QStringLiteral(
"properties" ) );
1176 if ( propertiesElem.isNull() )
1181 const QDomNodeList scopes = propertiesElem.childNodes();
1183 if ( propertiesElem.firstChild().isNull() )
1185 QgsDebugError( QStringLiteral(
"empty ``properties'' XML tag ... bailing" ) );
1189 if ( ! project_properties.
readXml( propertiesElem ) )
1191 QgsDebugError( QStringLiteral(
"Project_properties.readXml() failed" ) );
1205 const QDomElement ddElem = doc.documentElement().firstChildElement( QStringLiteral(
"dataDefinedServerProperties" ) );
1206 if ( !ddElem.isNull() )
1208 if ( !ddServerProperties.
readXml( ddElem, dataDefinedServerPropertyDefinitions ) )
1210 QgsDebugError( QStringLiteral(
"dataDefinedServerProperties.readXml() failed" ) );
1213 return ddServerProperties;
1220static void _getTitle(
const QDomDocument &doc, QString &title )
1222 const QDomElement titleNode = doc.documentElement().firstChildElement( QStringLiteral(
"title" ) );
1226 if ( titleNode.isNull() )
1232 if ( !titleNode.hasChildNodes() )
1238 const QDomNode titleTextNode = titleNode.firstChild();
1240 if ( !titleTextNode.isText() )
1246 const QDomText titleText = titleTextNode.toText();
1248 title = titleText.data();
1252static void readProjectFileMetadata(
const QDomDocument &doc, QString &lastUser, QString &lastUserFull, QDateTime &lastSaveDateTime )
1254 const QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"qgis" ) );
1258 QgsDebugError( QStringLiteral(
"unable to find qgis element" ) );
1262 const QDomNode qgisNode = nl.item( 0 );
1264 const QDomElement qgisElement = qgisNode.toElement();
1265 lastUser = qgisElement.attribute( QStringLiteral(
"saveUser" ), QString() );
1266 lastUserFull = qgisElement.attribute( QStringLiteral(
"saveUserFull" ), QString() );
1267 lastSaveDateTime = QDateTime::fromString( qgisElement.attribute( QStringLiteral(
"saveDateTime" ), QString() ), Qt::ISODate );
1272 const QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"qgis" ) );
1276 QgsDebugError( QStringLiteral(
" unable to find qgis element in project file" ) );
1280 const QDomNode qgisNode = nl.item( 0 );
1282 const QDomElement qgisElement = qgisNode.toElement();
1283 QgsProjectVersion projectVersion( qgisElement.attribute( QStringLiteral(
"version" ) ) );
1284 return projectVersion;
1291 return mSnappingConfig;
1310 if ( mAvoidIntersectionsMode == mode )
1313 mAvoidIntersectionsMode = mode;
1317static QgsMapLayer::ReadFlags projectFlagsToLayerReadFlags( Qgis::ProjectReadFlags projectReadFlags, Qgis::ProjectFlags projectFlags )
1319 QgsMapLayer::ReadFlags layerFlags = QgsMapLayer::ReadFlags();
1320 if ( projectReadFlags & Qgis::ProjectReadFlag::DontResolveLayers )
1342void QgsProject::preloadProviders(
const QVector<QDomNode> ¶llelLayerNodes,
1344 QMap<QString, QgsDataProvider *> &loadedProviders,
1345 QgsMapLayer::ReadFlags layerReadFlags,
1346 int totalProviderCount )
1351 QMap<QString, LayerToLoad> layersToLoad;
1353 for (
const QDomNode &node : parallelLayerNodes )
1357 const QDomElement layerElement = node.toElement();
1359 layerToLoad.
layerId = layerElement.namedItem( QStringLiteral(
"id" ) ).toElement().text();
1360 layerToLoad.
provider = layerElement.namedItem( QStringLiteral(
"provider" ) ).toElement().text();
1361 layerToLoad.
dataSource = layerElement.namedItem( QStringLiteral(
"datasource" ) ).toElement().text();
1371 layersToLoad.insert( layerToLoad.
layerId, layerToLoad );
1374 while ( !layersToLoad.isEmpty() )
1376 const QList<LayerToLoad> layersToAttemptInParallel = layersToLoad.values();
1377 QString layerToAttemptInMainThread;
1379 QHash<QString, QgsRunnableProviderCreator *> runnables;
1380 QThreadPool threadPool;
1383 for (
const LayerToLoad &lay : layersToAttemptInParallel )
1386 runnables.insert( lay.layerId, run );
1392 layersToLoad.remove( layId );
1395 Q_ASSERT( finishedRun );
1397 std::unique_ptr<QgsDataProvider> provider( finishedRun->
dataProvider() );
1398 Q_ASSERT( provider && provider->isValid() );
1400 loadedProviders.insert( layId, provider.release() );
1405 if ( layerToAttemptInMainThread.isEmpty() )
1406 layerToAttemptInMainThread = layId;
1410 if ( i == parallelLayerNodes.count() || !isValid )
1413 threadPool.start( run );
1417 threadPool.waitForDone();
1419 qDeleteAll( runnables );
1422 QMap<QString, LayerToLoad>::ConstIterator it = layersToLoad.find( layerToAttemptInMainThread );
1423 if ( it != layersToLoad.constEnd() )
1426 QgsDataProvider::ReadFlags providerFlags = lay.
flags;
1431 if ( provider && provider->isValid() )
1435 layersToLoad.remove( lay.
layerId );
1436 loadedProviders.insert( lay.
layerId, provider.release() );
1444void QgsProject::releaseHandlesToProjectArchive()
1449bool QgsProject::_getMapLayers(
const QDomDocument &doc, QList<QDomNode> &brokenNodes, Qgis::ProjectReadFlags flags )
1456 QDomElement layerElement = doc.documentElement().firstChildElement( QStringLiteral(
"projectlayers" ) ).firstChildElement( QStringLiteral(
"maplayer" ) );
1460 if ( layerElement.isNull() )
1470 bool returnStatus =
true;
1473 while ( ! layerElement.isNull() )
1476 layerElement = layerElement.nextSiblingElement( QStringLiteral(
"maplayer" ) );
1482 if ( depSorter.hasCycle() )
1486 if ( depSorter.hasMissingDependency() )
1487 returnStatus =
false;
1491 const QVector<QDomNode> sortedLayerNodes = depSorter.sortedLayerNodes();
1492 const int totalLayerCount = sortedLayerNodes.count();
1494 QVector<QDomNode> parallelLoading;
1495 QMap<QString, QgsDataProvider *> loadedProviders;
1499 profile.switchTask( tr(
"Load providers in parallel" ) );
1500 for (
const QDomNode &node : sortedLayerNodes )
1502 const QDomElement element = node.toElement();
1503 if ( element.attribute( QStringLiteral(
"embedded" ) ) != QLatin1String(
"1" ) )
1505 const QString layerId = node.namedItem( QStringLiteral(
"id" ) ).toElement().text();
1506 if ( !depSorter.isLayerDependent( layerId ) )
1508 const QDomNode mnl = element.namedItem( QStringLiteral(
"provider" ) );
1509 const QDomElement mne = mnl.toElement();
1510 const QString provider = mne.text();
1514 parallelLoading.append( node );
1523 if ( !parallelLoading.isEmpty() )
1524 preloadProviders( parallelLoading, context, loadedProviders, projectFlagsToLayerReadFlags(
flags, mFlags ), sortedLayerNodes.count() );
1527 int i = loadedProviders.count();
1528 for (
const QDomNode &node : std::as_const( sortedLayerNodes ) )
1530 const QDomElement element = node.toElement();
1531 const QString name =
translate( QStringLiteral(
"project:layers:%1" ).arg( node.namedItem( QStringLiteral(
"id" ) ).toElement().text() ), node.namedItem( QStringLiteral(
"layername" ) ).toElement().text() );
1532 if ( !name.isNull() )
1533 emit
loadingLayer( tr(
"Loading layer %1" ).arg( name ) );
1535 profile.switchTask( name );
1536 if ( element.attribute( QStringLiteral(
"embedded" ) ) == QLatin1String(
"1" ) )
1538 createEmbeddedLayer( element.attribute( QStringLiteral(
"id" ) ),
readPath( element.attribute( QStringLiteral(
"project" ) ) ), brokenNodes,
true,
flags );
1546 QString layerId = element.namedItem( QStringLiteral(
"id" ) ).toElement().text();
1548 if ( !addLayer( element, brokenNodes, context,
flags, loadedProviders.take( layerId ) ) )
1550 returnStatus =
false;
1553 if ( !messages.isEmpty() )
1562 return returnStatus;
1565bool QgsProject::addLayer(
const QDomElement &layerElem,
1566 QList<QDomNode> &brokenNodes,
1568 Qgis::ProjectReadFlags flags,
1573 const QString type = layerElem.attribute( QStringLiteral(
"type" ) );
1575 std::unique_ptr<QgsMapLayer>
mapLayer;
1583 QgsDebugError( QStringLiteral(
"Unknown layer type \"%1\"" ).arg( type ) );
1587 switch ( layerType )
1589 case Qgis::LayerType::Vector:
1590 mapLayer = std::make_unique<QgsVectorLayer>();
1593 case Qgis::LayerType::Raster:
1594 mapLayer = std::make_unique<QgsRasterLayer>();
1597 case Qgis::LayerType::Mesh:
1598 mapLayer = std::make_unique<QgsMeshLayer>();
1601 case Qgis::LayerType::VectorTile:
1602 mapLayer = std::make_unique<QgsVectorTileLayer>();
1605 case Qgis::LayerType::PointCloud:
1606 mapLayer = std::make_unique<QgsPointCloudLayer>();
1609 case Qgis::LayerType::Plugin:
1611 const QString
typeName = layerElem.attribute( QStringLiteral(
"name" ) );
1616 case Qgis::LayerType::Annotation:
1619 mapLayer = std::make_unique<QgsAnnotationLayer>( QString(), options );
1623 case Qgis::LayerType::Group:
1626 mapLayer = std::make_unique<QgsGroupLayer>( QString(), options );
1633 QgsDebugError( QStringLiteral(
"Unable to create layer" ) );
1641 const QString layerId { layerElem.namedItem( QStringLiteral(
"id" ) ).toElement().text() };
1642 Q_ASSERT( ! layerId.isEmpty() );
1646 QgsMapLayer::ReadFlags layerFlags = projectFlagsToLayerReadFlags(
flags, mFlags );
1648 profile.switchTask( tr(
"Load layer source" ) );
1655 if ( vl->dataProvider() )
1662 profile.switchTask( tr(
"Add layer to project" ) );
1663 QList<QgsMapLayer *> newLayers;
1665 if ( layerIsValid ||
flags & Qgis::ProjectReadFlag::DontResolveLayers )
1675 vLayer->joinBuffer()->resolveReferences(
this );
1684 brokenNodes.push_back( layerElem );
1687 const bool wasEditable = layerElem.attribute( QStringLiteral(
"editable" ), QStringLiteral(
"0" ) ).toInt();
1699 if ( ! layerWasStored )
1704 return layerIsValid;
1711 mFile.setFileName( filename );
1712 mCachedHomePath.clear();
1713 mProjectScope.reset();
1722 const QString filename = mFile.fileName();
1727 QTemporaryFile inDevice;
1728 if ( !inDevice.open() )
1730 setError( tr(
"Unable to open %1" ).arg( inDevice.fileName() ) );
1736 if ( !storage->readProject( filename, &inDevice, context ) )
1738 QString err = tr(
"Unable to open %1" ).arg( filename );
1739 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
1740 if ( !messages.isEmpty() )
1741 err += QStringLiteral(
"\n\n" ) + messages.last().message();
1745 returnValue = unzip( inDevice.fileName(),
flags );
1751 returnValue = unzip( mFile.fileName(),
flags );
1756 const QFileInfo finfo( mFile.fileName() );
1757 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( QStringLiteral(
"%1_attachments.zip" ).arg( finfo.completeBaseName() ) );
1758 if ( QFile( attachmentsZip ).exists() )
1760 std::unique_ptr<QgsArchive> archive(
new QgsArchive() );
1761 if ( archive->unzip( attachmentsZip ) )
1763 releaseHandlesToProjectArchive();
1764 mArchive = std::move( archive );
1767 returnValue = readProjectFile( mFile.fileName(),
flags );
1773 mFile.setFileName( filename );
1774 mCachedHomePath.clear();
1775 mProjectScope.reset();
1780 mTranslator.reset(
nullptr );
1787bool QgsProject::readProjectFile(
const QString &filename, Qgis::ProjectReadFlags flags )
1792 ScopedIntIncrementor snapSignalBlock( &mBlockSnappingUpdates );
1794 QFile projectFile( filename );
1802 if ( QFile( QStringLiteral(
"%1/%2.qm" ).arg( QFileInfo( projectFile.fileName() ).absolutePath(), localeFileName ) ).exists() )
1804 mTranslator.reset(
new QTranslator() );
1805 ( void )mTranslator->load( localeFileName, QFileInfo( projectFile.fileName() ).absolutePath() );
1808 profile.switchTask( tr(
"Reading project file" ) );
1809 std::unique_ptr<QDomDocument> doc(
new QDomDocument( QStringLiteral(
"qgis" ) ) );
1811 if ( !projectFile.open( QIODevice::ReadOnly | QIODevice::Text ) )
1813 projectFile.close();
1815 setError( tr(
"Unable to open %1" ).arg( projectFile.fileName() ) );
1824 if ( !doc->setContent( &projectFile, &errorMsg, &line, &column ) )
1826 const QString errorString = tr(
"Project file read error in file %1: %2 at line %3 column %4" )
1827 .arg( projectFile.fileName(), errorMsg ).arg( line ).arg( column );
1831 projectFile.close();
1833 setError( errorString );
1838 projectFile.close();
1846 profile.switchTask( tr(
"Updating project file" ) );
1847 if ( thisVersion > fileVersion )
1849 const bool isOlderMajorVersion = fileVersion.
majorVersion() < thisVersion.majorVersion();
1851 if ( isOlderMajorVersion )
1854 "version of qgis (saved in " + fileVersion.
text() +
1856 "). Problems may occur." );
1867 projectFile.updateRevision( thisVersion );
1869 else if ( fileVersion > thisVersion )
1872 "version of qgis (saved in " + fileVersion.
text() +
1874 "). Problems may occur." );
1880 profile.switchTask( tr(
"Creating auxiliary storage" ) );
1881 const QString
fileName = mFile.fileName();
1886 std::unique_ptr<QgsAuxiliaryStorage> aStorage = std::move( mAuxiliaryStorage );
1887 std::unique_ptr<QgsArchive> archive = std::move( mArchive );
1893 releaseHandlesToProjectArchive();
1895 mAuxiliaryStorage = std::move( aStorage );
1896 mArchive = std::move( archive );
1901 mCachedHomePath.clear();
1902 mProjectScope.reset();
1903 mSaveVersion = fileVersion;
1906 profile.switchTask( tr(
"Reading properties" ) );
1915 dump_( mProperties );
1920 _getTitle( *doc, oldTitle );
1922 readProjectFileMetadata( *doc, mSaveUser, mSaveUserFull, mSaveDateTime );
1924 const QDomNodeList homePathNl = doc->elementsByTagName( QStringLiteral(
"homePath" ) );
1925 if ( homePathNl.count() > 0 )
1927 const QDomElement homePathElement = homePathNl.at( 0 ).toElement();
1928 const QString
homePath = homePathElement.attribute( QStringLiteral(
"path" ) );
1938 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorGreenPart" ), 255 ),
1939 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorBluePart" ), 255 ) );
1942 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorGreenPart" ), 255 ),
1943 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorBluePart" ), 255 ),
1944 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorAlphaPart" ), 255 ) );
1948 const QString distanceUnitString =
readEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/DistanceUnits" ), QString() );
1949 if ( !distanceUnitString.isEmpty() )
1952 const QString areaUnitString =
readEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/AreaUnits" ), QString() );
1953 if ( !areaUnitString.isEmpty() )
1962 if (
readNumEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectionsEnabled" ), 0 ) )
1965 const QDomNode srsNode = doc->documentElement().namedItem( QStringLiteral(
"projectCrs" ) );
1966 if ( !srsNode.isNull() )
1968 projectCrs.
readXml( srsNode );
1973 const QString projCrsString =
readEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCRSProj4String" ) );
1974 const long currentCRS =
readNumEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCRSID" ), -1 );
1975 const QString authid =
readEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCrs" ) );
1978 const bool isUserAuthId = authid.startsWith( QLatin1String(
"USER:" ), Qt::CaseInsensitive );
1979 if ( !authid.isEmpty() && !isUserAuthId )
1983 if ( !projectCrs.
isValid() && currentCRS >= 0 )
1989 if ( !projCrsString.isEmpty() && ( authid.isEmpty() || isUserAuthId ) && ( !projectCrs.
isValid() || projectCrs.
toProj() != projCrsString ) )
2003 QStringList datumErrors;
2004 if ( !mTransformContext.
readXml( doc->documentElement(), context, datumErrors ) && !datumErrors.empty() )
2011 const QDomNode elevationShadingNode = doc->documentElement().namedItem( QStringLiteral(
"elevation-shading-renderer" ) );
2012 if ( !elevationShadingNode.isNull() )
2014 mElevationShadingRenderer.
readXml( elevationShadingNode.toElement(), context );
2021 const QStringList variableNames =
readListEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableNames" ) );
2022 const QStringList variableValues =
readListEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableValues" ) );
2024 mCustomVariables.clear();
2025 if ( variableNames.length() == variableValues.length() )
2027 for (
int i = 0; i < variableNames.length(); ++i )
2029 mCustomVariables.insert( variableNames.at( i ), variableValues.at( i ) );
2034 QgsMessageLog::logMessage( tr(
"Project Variables Invalid" ), tr(
"The project contains invalid variable settings." ) );
2037 QDomElement element = doc->documentElement().firstChildElement( QStringLiteral(
"projectMetadata" ) );
2039 if ( !element.isNull() )
2048 if ( mMetadata.
title().isEmpty() && !oldTitle.isEmpty() )
2056 element = doc->documentElement().firstChildElement( QStringLiteral(
"transaction" ) );
2057 if ( !element.isNull() )
2064 element = doc->documentElement().firstChildElement( QStringLiteral(
"autotransaction" ) );
2065 if ( ! element.isNull() )
2067 mTransactionMode =
static_cast<Qgis::TransactionMode>( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() );
2072 profile.switchTask( tr(
"Loading layer tree" ) );
2075 QDomElement layerTreeElem = doc->documentElement().firstChildElement( QStringLiteral(
"layer-tree-group" ) );
2076 if ( !layerTreeElem.isNull() )
2088 mLayerTreeRegistryBridge->
setEnabled(
false );
2091 profile.switchTask( tr(
"Reading map layers" ) );
2093 loadProjectFlags( doc.get() );
2095 QList<QDomNode> brokenNodes;
2096 const bool clean = _getMapLayers( *doc, brokenNodes,
flags );
2099 if ( !clean && !(
flags & Qgis::ProjectReadFlag::DontResolveLayers ) )
2101 QgsDebugError( QStringLiteral(
"Unable to get map layers from project file." ) );
2103 if ( !brokenNodes.isEmpty() )
2105 QgsDebugError(
"there are " + QString::number( brokenNodes.size() ) +
" broken layers" );
2113 mMainAnnotationLayer->
readLayerXml( doc->documentElement().firstChildElement( QStringLiteral(
"main-annotation-layer" ) ), context );
2117 profile.switchTask( tr(
"Loading embedded layers" ) );
2118 loadEmbeddedNodes( mRootGroup,
flags );
2122 profile.switchTask( tr(
"Resolving layer references" ) );
2123 QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
2124 for ( QMap<QString, QgsMapLayer *>::iterator it =
layers.begin(); it !=
layers.end(); ++it )
2126 it.value()->resolveReferences(
this );
2129 mLayerTreeRegistryBridge->
setEnabled(
true );
2132 profile.switchTask( tr(
"Resolving references" ) );
2143 if ( !layerTreeElem.isNull() )
2149 const QDomElement layerTreeCanvasElem = doc->documentElement().firstChildElement( QStringLiteral(
"layer-tree-canvas" ) );
2150 if ( !layerTreeCanvasElem.isNull( ) )
2158 const QStringList requiredLayerIds =
readListEntry( QStringLiteral(
"RequiredLayers" ), QStringLiteral(
"Layers" ) );
2159 for (
const QString &layerId : requiredLayerIds )
2166 const QStringList disabledLayerIds =
readListEntry( QStringLiteral(
"Identify" ), QStringLiteral(
"/disabledLayers" ) );
2167 for (
const QString &layerId : disabledLayerIds )
2180 QString styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Marker" ) );
2181 if ( !styleName.isEmpty() )
2186 styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Line" ) );
2187 if ( !styleName.isEmpty() )
2192 styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Fill" ) );
2193 if ( !styleName.isEmpty() )
2198 styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/ColorRamp" ) );
2199 if ( !styleName.isEmpty() )
2209 double opacity = 1.0;
2212 double alpha =
readDoubleEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/AlphaInt" ), 255, &ok );
2214 opacity = alpha / 255.0;
2215 double newOpacity =
readDoubleEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Opacity" ), 1.0, &ok );
2217 opacity = newOpacity;
2221 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Marker" ) );
2222 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Line" ) );
2223 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Fill" ) );
2224 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/ColorRamp" ) );
2225 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/RandomColors" ) );
2226 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/AlphaInt" ) );
2227 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Opacity" ) );
2233 if ( !(
flags & Qgis::ProjectReadFlag::DontStoreOriginalStyles ) )
2235 profile.switchTask( tr(
"Storing original layer properties" ) );
2241 profile.switchTask( tr(
"Loading map themes" ) );
2244 mMapThemeCollection->readXml( *doc );
2246 profile.switchTask( tr(
"Loading label settings" ) );
2247 mLabelingEngineSettings->readSettingsFromProject(
this );
2250 profile.switchTask( tr(
"Loading annotations" ) );
2251 mAnnotationManager->readXml( doc->documentElement(), context );
2252 if ( !(
flags & Qgis::ProjectReadFlag::DontLoadLayouts ) )
2254 profile.switchTask( tr(
"Loading layouts" ) );
2255 mLayoutManager->readXml( doc->documentElement(), *doc );
2258 if ( !(
flags & Qgis::ProjectReadFlag::DontLoad3DViews ) )
2260 profile.switchTask( tr(
"Loading 3D Views" ) );
2261 m3DViewsManager->readXml( doc->documentElement(), *doc );
2264 profile.switchTask( tr(
"Loading bookmarks" ) );
2265 mBookmarkManager->
readXml( doc->documentElement(), *doc );
2267 profile.switchTask( tr(
"Loading sensors" ) );
2268 mSensorManager->
readXml( doc->documentElement(), *doc );
2271 QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
2272 for ( QMap<QString, QgsMapLayer *>::iterator it = existingMaps.begin(); it != existingMaps.end(); ++it )
2274 it.value()->setDependencies( it.value()->dependencies() );
2277 profile.switchTask( tr(
"Loading snapping settings" ) );
2281 profile.switchTask( tr(
"Loading view settings" ) );
2284 const QStringList scales =
readListEntry( QStringLiteral(
"Scales" ), QStringLiteral(
"/ScalesList" ) );
2285 QVector<double> res;
2286 for (
const QString &scale : scales )
2288 const QStringList parts = scale.split(
':' );
2289 if ( parts.size() != 2 )
2293 const double denominator = QLocale().toDouble( parts[1], &ok );
2300 const QDomElement viewSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectViewSettings" ) );
2301 if ( !viewSettingsElement.isNull() )
2302 mViewSettings->
readXml( viewSettingsElement, context );
2305 profile.switchTask( tr(
"Loading style properties" ) );
2306 const QDomElement styleSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectStyleSettings" ) );
2307 if ( !styleSettingsElement.isNull() )
2310 mStyleSettings->
readXml( styleSettingsElement, context,
flags );
2314 profile.switchTask( tr(
"Loading temporal settings" ) );
2315 const QDomElement timeSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectTimeSettings" ) );
2316 if ( !timeSettingsElement.isNull() )
2317 mTimeSettings->
readXml( timeSettingsElement, context );
2320 profile.switchTask( tr(
"Loading elevation properties" ) );
2321 const QDomElement elevationPropertiesElement = doc->documentElement().firstChildElement( QStringLiteral(
"ElevationProperties" ) );
2322 if ( !elevationPropertiesElement.isNull() )
2323 mElevationProperties->
readXml( elevationPropertiesElement, context );
2326 profile.switchTask( tr(
"Loading display settings" ) );
2328 const QDomElement displaySettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectDisplaySettings" ) );
2329 if ( !displaySettingsElement.isNull() )
2330 mDisplaySettings->
readXml( displaySettingsElement, context );
2333 profile.switchTask( tr(
"Loading GPS settings" ) );
2335 const QDomElement gpsSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectGpsSettings" ) );
2336 if ( !gpsSettingsElement.isNull() )
2337 mGpsSettings->
readXml( gpsSettingsElement, context );
2341 profile.switchTask( tr(
"Updating variables" ) );
2343 profile.switchTask( tr(
"Updating CRS" ) );
2348 profile.switchTask( tr(
"Reading external settings" ) );
2352 profile.switchTask( tr(
"Updating interface" ) );
2354 snapSignalBlock.release();
2355 if ( !mBlockSnappingUpdates )
2366 QgsDebugMsgLevel( QStringLiteral(
"Project save user: %1" ).arg( mSaveUser ), 2 );
2367 QgsDebugMsgLevel( QStringLiteral(
"Project save user: %1" ).arg( mSaveUserFull ), 2 );
2376 const QString newFileName( QStringLiteral(
"%1/%2.qgs" ).arg( QFileInfo( projectFile.fileName() ).absolutePath(), localeFileName ) );
2382 QgsMessageLog::logMessage( tr(
"Translated project saved with locale prefix %1" ).arg( newFileName ), QObject::tr(
"Project translation" ), Qgis::MessageLevel::Success );
2386 QgsMessageLog::logMessage( tr(
"Error saving translated project with locale prefix %1" ).arg( newFileName ), QObject::tr(
"Project translation" ), Qgis::MessageLevel::Critical );
2391 const QMap<QString, QgsMapLayer *> loadedLayers =
mapLayers();
2392 for (
auto it = loadedLayers.constBegin(); it != loadedLayers.constEnd(); ++it )
2394 if ( it.value()->isValid() && it.value()->customProperty( QStringLiteral(
"_layer_was_editable" ) ).toBool() )
2396 if (
QgsVectorLayer *vl = qobject_cast< QgsVectorLayer * >( it.value() ) )
2398 it.value()->removeCustomProperty( QStringLiteral(
"_layer_was_editable" ) );
2405bool QgsProject::loadEmbeddedNodes(
QgsLayerTreeGroup *group, Qgis::ProjectReadFlags flags )
2410 const auto constChildren = group->
children();
2416 if ( childGroup->
customProperty( QStringLiteral(
"embedded" ) ).toInt() )
2419 const QString projectPath =
readPath( childGroup->
customProperty( QStringLiteral(
"embedded_project" ) ).toString() );
2420 childGroup->
setCustomProperty( QStringLiteral(
"embedded_project" ), projectPath );
2424 QList<QgsLayerTreeNode *> clonedChildren;
2425 const QList<QgsLayerTreeNode *> constChildren = newGroup->
children();
2426 clonedChildren.reserve( constChildren.size() );
2428 clonedChildren << newGroupChild->clone();
2436 loadEmbeddedNodes( childGroup,
flags );
2441 if ( child->customProperty( QStringLiteral(
"embedded" ) ).toInt() )
2443 QList<QDomNode> brokenNodes;
2446 valid = valid &&
false;
2461 return mCustomVariables;
2468 if ( variables == mCustomVariables )
2472 QStringList variableNames;
2473 QStringList variableValues;
2475 QVariantMap::const_iterator it = variables.constBegin();
2476 for ( ; it != variables.constEnd(); ++it )
2478 variableNames << it.key();
2479 variableValues << it.value().toString();
2482 writeEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableNames" ), variableNames );
2483 writeEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableValues" ), variableValues );
2485 mCustomVariables = variables;
2486 mProjectScope.reset();
2495 *mLabelingEngineSettings = settings;
2503 return *mLabelingEngineSettings;
2510 mProjectScope.reset();
2511 return mLayerStore.get();
2518 return mLayerStore.get();
2525 QList<QgsVectorLayer *>
layers;
2526 const QStringList layerIds =
readListEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsList" ), QStringList() );
2527 const auto constLayerIds = layerIds;
2528 for (
const QString &layerId : constLayerIds )
2541 list.reserve(
layers.size() );
2543 list << layer->id();
2544 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsList" ), list );
2566 if ( mProjectScope )
2568 std::unique_ptr< QgsExpressionContextScope > projectScope = std::make_unique< QgsExpressionContextScope >( *mProjectScope );
2575 projectScope->addFunction( QStringLiteral(
"sensor_data" ),
new GetSensorData(
sensorManager()->sensorsData() ) );
2577 return projectScope.release();
2580 mProjectScope = std::make_unique< QgsExpressionContextScope >( QObject::tr(
"Project" ) );
2584 QVariantMap::const_iterator it = vars.constBegin();
2586 for ( ; it != vars.constEnd(); ++it )
2588 mProjectScope->setVariable( it.key(), it.value(),
true );
2592 if ( projectPath.isEmpty() )
2593 projectPath = mOriginalPath;
2594 const QString projectFolder = QFileInfo( projectPath ).path();
2595 const QString projectFilename = QFileInfo( projectPath ).fileName();
2596 const QString projectBasename =
baseName();
2625 QVariantMap keywords;
2627 for (
auto it = metadataKeywords.constBegin(); it != metadataKeywords.constEnd(); ++it )
2629 keywords.insert( it.key(), it.value() );
2634 QVariantList layersIds;
2636 const QMap<QString, QgsMapLayer *> layersInProject = mLayerStore->mapLayers();
2637 layersIds.reserve( layersInProject.count() );
2638 layers.reserve( layersInProject.count() );
2639 for (
auto it = layersInProject.constBegin(); it != layersInProject.constEnd(); ++it )
2641 layersIds << it.value()->id();
2647 mProjectScope->addFunction( QStringLiteral(
"project_color" ),
new GetNamedProjectColor(
this ) );
2652void QgsProject::onMapLayersAdded(
const QList<QgsMapLayer *> &layers )
2656 const QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
2658 const auto constLayers =
layers;
2661 if ( ! layer->isValid() )
2667 for ( QMap<QString, QgsMapLayer *>::const_iterator it = existingMaps.cbegin(); it != existingMaps.cend(); ++it )
2669 const QSet<QgsMapLayerDependency> deps = it.value()->dependencies();
2670 if ( deps.contains( layer->id() ) )
2673 it.value()->setDependencies( deps );
2678 updateTransactionGroups();
2684void QgsProject::onMapLayersRemoved(
const QList<QgsMapLayer *> &layers )
2692void QgsProject::cleanTransactionGroups(
bool force )
2696 bool changed =
false;
2697 for ( QMap< QPair< QString, QString>,
QgsTransactionGroup *>::Iterator tg = mTransactionGroups.begin(); tg != mTransactionGroups.end(); )
2699 if ( tg.value()->isEmpty() || force )
2702 tg = mTransactionGroups.erase( tg );
2714void QgsProject::updateTransactionGroups()
2718 mEditBufferGroup.
clear();
2720 switch ( mTransactionMode )
2724 cleanTransactionGroups(
true );
2729 cleanTransactionGroups(
true );
2732 cleanTransactionGroups(
false );
2736 bool tgChanged =
false;
2737 const auto constLayers =
mapLayers().values();
2740 if ( ! layer->isValid() )
2743 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
2747 switch ( mTransactionMode )
2764 mTransactionGroups.insert( qMakePair( key, connString ), tg );
2774 mEditBufferGroup.
addLayer( vlayer );
2790 context.setProjectTranslator(
this );
2792 QList<QDomNode> brokenNodes;
2793 if ( addLayer( layerNode.toElement(), brokenNodes, context ) )
2797 const QVector<QgsVectorLayer *> vectorLayers = layers<QgsVectorLayer *>();
2801 layer->resolveReferences(
this );
2803 if ( layer->isValid() && layer->customProperty( QStringLiteral(
"_layer_was_editable" ) ).toBool() )
2805 layer->startEditing();
2806 layer->removeCustomProperty( QStringLiteral(
"_layer_was_editable" ) );
2818 mFile.setFileName( filename );
2819 mCachedHomePath.clear();
2827 mProjectScope.reset();
2833 const QString storageFilePath { storage->filePath( mFile.fileName() ) };
2834 if ( storageFilePath.isEmpty() )
2840 const QString tempPath = QStandardPaths::standardLocations( QStandardPaths::TempLocation ).at( 0 );
2841 const QString tmpZipFilename( tempPath + QDir::separator() + QUuid::createUuid().toString() );
2843 if ( !zip( tmpZipFilename ) )
2846 QFile tmpZipFile( tmpZipFilename );
2847 if ( !tmpZipFile.open( QIODevice::ReadOnly ) )
2849 setError( tr(
"Unable to read file %1" ).arg( tmpZipFilename ) );
2854 if ( !storage->writeProject( mFile.fileName(), &tmpZipFile, context ) )
2856 QString err = tr(
"Unable to save project to storage %1" ).arg( mFile.fileName() );
2857 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
2858 if ( !messages.isEmpty() )
2859 err += QStringLiteral(
"\n\n" ) + messages.last().message();
2865 QFile::remove( tmpZipFilename );
2872 return zip( mFile.fileName() );
2878 const bool asOk = saveAuxiliaryStorage();
2879 const bool writeOk = writeProjectFile( mFile.fileName() );
2880 bool attachmentsOk =
true;
2881 if ( !mArchive->files().isEmpty() )
2883 const QFileInfo finfo( mFile.fileName() );
2884 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( QStringLiteral(
"%1_attachments.zip" ).arg( finfo.completeBaseName() ) );
2885 attachmentsOk = mArchive->zip( attachmentsZip );
2889 if ( ( !asOk || !attachmentsOk ) && writeOk )
2891 QStringList errorMessage;
2894 const QString err = mAuxiliaryStorage->errorString();
2895 errorMessage.append( tr(
"Unable to save auxiliary storage ('%1')" ).arg( err ) );
2897 if ( !attachmentsOk )
2899 errorMessage.append( tr(
"Unable to save attachments archive" ) );
2901 setError( errorMessage.join(
'\n' ) );
2904 return asOk && writeOk && attachmentsOk;
2908bool QgsProject::writeProjectFile(
const QString &filename )
2912 QFile projectFile( filename );
2918 const QFileInfo myFileInfo( projectFile );
2919 if ( myFileInfo.exists() && !myFileInfo.isWritable() )
2921 setError( tr(
"%1 is not writable. Please adjust permissions (if possible) and try again." )
2922 .arg( projectFile.fileName() ) );
2930 QDomImplementation::setInvalidDataPolicy( QDomImplementation::DropInvalidChars );
2932 const QDomDocumentType documentType =
2933 QDomImplementation().createDocumentType( QStringLiteral(
"qgis" ), QStringLiteral(
"http://mrcc.com/qgis.dtd" ),
2934 QStringLiteral(
"SYSTEM" ) );
2935 std::unique_ptr<QDomDocument> doc(
new QDomDocument( documentType ) );
2937 QDomElement qgisNode = doc->createElement( QStringLiteral(
"qgis" ) );
2938 qgisNode.setAttribute( QStringLiteral(
"projectname" ),
title() );
2939 qgisNode.setAttribute( QStringLiteral(
"version" ),
Qgis::version() );
2941 if ( !mSettings.
value( QStringLiteral(
"projects/anonymize_saved_projects" ),
false,
QgsSettings::Core ).toBool() )
2945 qgisNode.setAttribute( QStringLiteral(
"saveUser" ), newSaveUser );
2946 qgisNode.setAttribute( QStringLiteral(
"saveUserFull" ), newSaveUserFull );
2947 mSaveUser = newSaveUser;
2948 mSaveUserFull = newSaveUserFull;
2949 mSaveDateTime = QDateTime::currentDateTime();
2950 qgisNode.setAttribute( QStringLiteral(
"saveDateTime" ), mSaveDateTime.toString( Qt::ISODate ) );
2955 mSaveUserFull.clear();
2956 mSaveDateTime = QDateTime();
2958 doc->appendChild( qgisNode );
2961 QDomElement homePathNode = doc->createElement( QStringLiteral(
"homePath" ) );
2962 homePathNode.setAttribute( QStringLiteral(
"path" ), mHomePath );
2963 qgisNode.appendChild( homePathNode );
2966 QDomElement titleNode = doc->createElement( QStringLiteral(
"title" ) );
2967 qgisNode.appendChild( titleNode );
2969 QDomElement transactionNode = doc->createElement( QStringLiteral(
"transaction" ) );
2970 transactionNode.setAttribute( QStringLiteral(
"mode" ),
qgsEnumValueToKey( mTransactionMode ) );
2971 qgisNode.appendChild( transactionNode );
2973 QDomElement flagsNode = doc->createElement( QStringLiteral(
"projectFlags" ) );
2975 qgisNode.appendChild( flagsNode );
2977 const QDomText titleText = doc->createTextNode(
title() );
2978 titleNode.appendChild( titleText );
2981 QDomElement srsNode = doc->createElement( QStringLiteral(
"projectCrs" ) );
2983 qgisNode.appendChild( srsNode );
2985 QDomElement elevationShadingNode = doc->createElement( QStringLiteral(
"elevation-shading-renderer" ) );
2986 mElevationShadingRenderer.
writeXml( elevationShadingNode, context );
2987 qgisNode.appendChild( elevationShadingNode );
2994 clonedRoot->
writeXml( qgisNode, context );
2998 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsMode" ),
static_cast<int>( mAvoidIntersectionsMode ) );
3006 QDomElement annotationLayerNode = doc->createElement( QStringLiteral(
"main-annotation-layer" ) );
3007 mMainAnnotationLayer->
writeLayerXml( annotationLayerNode, *doc, context );
3008 qgisNode.appendChild( annotationLayerNode );
3012 QDomElement projectLayersNode = doc->createElement( QStringLiteral(
"projectlayers" ) );
3014 QMap<QString, QgsMapLayer *>::ConstIterator li =
layers.constBegin();
3015 while ( li !=
layers.end() )
3021 const QHash< QString, QPair< QString, bool> >::const_iterator emIt = mEmbeddedLayers.constFind( ml->
id() );
3022 if ( emIt == mEmbeddedLayers.constEnd() )
3024 QDomElement maplayerElem;
3030 maplayerElem = doc->createElement( QStringLiteral(
"maplayer" ) );
3034 maplayerElem.setAttribute( QStringLiteral(
"editable" ), QStringLiteral(
"1" ) );
3038 QDomDocument document;
3041 maplayerElem = document.firstChildElement();
3045 QgsDebugError( QStringLiteral(
"Could not restore layer properties for layer %1" ).arg( ml->
id() ) );
3051 projectLayersNode.appendChild( maplayerElem );
3057 if ( emIt.value().second )
3059 QDomElement mapLayerElem = doc->createElement( QStringLiteral(
"maplayer" ) );
3060 mapLayerElem.setAttribute( QStringLiteral(
"embedded" ), 1 );
3061 mapLayerElem.setAttribute( QStringLiteral(
"project" ),
writePath( emIt.value().first ) );
3062 mapLayerElem.setAttribute( QStringLiteral(
"id" ), ml->
id() );
3063 projectLayersNode.appendChild( mapLayerElem );
3070 qgisNode.appendChild( projectLayersNode );
3072 QDomElement layerOrderNode = doc->createElement( QStringLiteral(
"layerorder" ) );
3074 for (
QgsMapLayer *layer : constCustomLayerOrder )
3076 QDomElement mapLayerElem = doc->createElement( QStringLiteral(
"layer" ) );
3077 mapLayerElem.setAttribute( QStringLiteral(
"id" ), layer->id() );
3078 layerOrderNode.appendChild( mapLayerElem );
3080 qgisNode.appendChild( layerOrderNode );
3082 mLabelingEngineSettings->writeSettingsToProject(
this );
3084 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorRedPart" ), mBackgroundColor.red() );
3085 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorGreenPart" ), mBackgroundColor.green() );
3086 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorBluePart" ), mBackgroundColor.blue() );
3088 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorRedPart" ), mSelectionColor.red() );
3089 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorGreenPart" ), mSelectionColor.green() );
3090 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorBluePart" ), mSelectionColor.blue() );
3091 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorAlphaPart" ), mSelectionColor.alpha() );
3098 dump_( mProperties );
3101 QgsDebugMsgLevel( QStringLiteral(
"there are %1 property scopes" ).arg(
static_cast<int>( mProperties.
count() ) ), 2 );
3106 mProperties.
writeXml( QStringLiteral(
"properties" ), qgisNode, *doc );
3109 QDomElement ddElem = doc->createElement( QStringLiteral(
"dataDefinedServerProperties" ) );
3110 mDataDefinedServerProperties.
writeXml( ddElem, dataDefinedServerPropertyDefinitions() );
3111 qgisNode.appendChild( ddElem );
3113 mMapThemeCollection->writeXml( *doc );
3115 mTransformContext.
writeXml( qgisNode, context );
3117 QDomElement metadataElem = doc->createElement( QStringLiteral(
"projectMetadata" ) );
3119 qgisNode.appendChild( metadataElem );
3122 const QDomElement annotationsElem = mAnnotationManager->writeXml( *doc, context );
3123 qgisNode.appendChild( annotationsElem );
3127 const QDomElement layoutElem = mLayoutManager->writeXml( *doc );
3128 qgisNode.appendChild( layoutElem );
3132 const QDomElement views3DElem = m3DViewsManager->writeXml( *doc );
3133 qgisNode.appendChild( views3DElem );
3137 const QDomElement bookmarkElem = mBookmarkManager->
writeXml( *doc );
3138 qgisNode.appendChild( bookmarkElem );
3142 const QDomElement sensorElem = mSensorManager->
writeXml( *doc );
3143 qgisNode.appendChild( sensorElem );
3147 const QDomElement viewSettingsElem = mViewSettings->
writeXml( *doc, context );
3148 qgisNode.appendChild( viewSettingsElem );
3152 const QDomElement styleSettingsElem = mStyleSettings->
writeXml( *doc, context );
3153 qgisNode.appendChild( styleSettingsElem );
3157 const QDomElement timeSettingsElement = mTimeSettings->
writeXml( *doc, context );
3158 qgisNode.appendChild( timeSettingsElement );
3162 const QDomElement elevationPropertiesElement = mElevationProperties->
writeXml( *doc, context );
3163 qgisNode.appendChild( elevationPropertiesElement );
3167 const QDomElement displaySettingsElem = mDisplaySettings->
writeXml( *doc, context );
3168 qgisNode.appendChild( displaySettingsElem );
3172 const QDomElement gpsSettingsElem = mGpsSettings->
writeXml( *doc, context );
3173 qgisNode.appendChild( gpsSettingsElem );
3182 QFile backupFile( QStringLiteral(
"%1~" ).arg( filename ) );
3184 ok &= backupFile.open( QIODevice::WriteOnly | QIODevice::Truncate );
3185 ok &= projectFile.open( QIODevice::ReadOnly );
3188 while ( ok && !projectFile.atEnd() )
3190 ba = projectFile.read( 10240 );
3191 ok &= backupFile.write( ba ) == ba.size();
3194 projectFile.close();
3199 setError( tr(
"Unable to create backup file %1" ).arg( backupFile.fileName() ) );
3204 struct utimbuf tb = {
static_cast<time_t
>( fi.lastRead().toSecsSinceEpoch() ),
static_cast<time_t
>( fi.lastModified().toSecsSinceEpoch() ) };
3205 utime( backupFile.fileName().toUtf8().constData(), &tb );
3208 if ( !projectFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
3210 projectFile.close();
3213 setError( tr(
"Unable to save to file %1" ).arg( projectFile.fileName() ) );
3217 QTemporaryFile tempFile;
3218 bool ok = tempFile.open();
3221 QTextStream projectFileStream( &tempFile );
3222 doc->save( projectFileStream, 2 );
3223 ok &= projectFileStream.pos() > -1;
3225 ok &= tempFile.seek( 0 );
3228 while ( ok && !tempFile.atEnd() )
3230 ba = tempFile.read( 10240 );
3231 ok &= projectFile.write( ba ) == ba.size();
3234 ok &= projectFile.error() == QFile::NoError;
3236 projectFile.close();
3243 setError( tr(
"Unable to save to file %1. Your project "
3244 "may be corrupted on disk. Try clearing some space on the volume and "
3245 "check file permissions before pressing save again." )
3246 .arg( projectFile.fileName() ) );
3260 bool propertiesModified;
3261 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3263 if ( propertiesModified )
3273 bool propertiesModified;
3274 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3276 if ( propertiesModified )
3286 bool propertiesModified;
3287 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3289 if ( propertiesModified )
3299 bool propertiesModified;
3300 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3302 if ( propertiesModified )
3312 bool propertiesModified;
3313 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3315 if ( propertiesModified )
3323 const QStringList &def,
3335 value =
property->value();
3337 const bool valid = QVariant::StringList == value.type();
3343 return value.toStringList();
3366 value =
property->value();
3368 const bool valid = value.canConvert( QVariant::String );
3373 return value.toString();
3392 value =
property->value();
3395 const bool valid = value.canConvert( QVariant::Int );
3404 return value.toInt();
3419 const QVariant value =
property->value();
3421 const bool valid = value.canConvert( QVariant::Double );
3426 return value.toDouble();
3443 const QVariant value =
property->value();
3445 const bool valid = value.canConvert( QVariant::Bool );
3450 return value.toBool();
3462 if (
findKey_( scope, key, mProperties ) )
3468 return !
findKey_( scope, key, mProperties );
3477 QStringList entries;
3479 if ( foundProperty )
3496 QStringList entries;
3498 if ( foundProperty )
3513 dump_( mProperties );
3533 filePath = storage->filePath( mFile.fileName() );
3560void QgsProject::setError(
const QString &errorMessage )
3564 mErrorMessage = errorMessage;
3571 return mErrorMessage;
3574void QgsProject::clearError()
3578 setError( QString() );
3585 delete mBadLayerHandler;
3586 mBadLayerHandler = handler;
3593 const QHash< QString, QPair< QString, bool > >::const_iterator it = mEmbeddedLayers.find(
id );
3594 if ( it == mEmbeddedLayers.constEnd() )
3598 return it.value().first;
3602 bool saveFlag, Qgis::ProjectReadFlags flags )
3608 static QString sPrevProjectFilePath;
3609 static QDateTime sPrevProjectFileTimestamp;
3610 static QDomDocument sProjectDocument;
3612 QString qgsProjectFile = projectFilePath;
3614 if ( projectFilePath.endsWith( QLatin1String(
".qgz" ), Qt::CaseInsensitive ) )
3616 archive.
unzip( projectFilePath );
3620 const QDateTime projectFileTimestamp = QFileInfo( projectFilePath ).lastModified();
3622 if ( projectFilePath != sPrevProjectFilePath || projectFileTimestamp != sPrevProjectFileTimestamp )
3624 sPrevProjectFilePath.clear();
3626 QFile projectFile( qgsProjectFile );
3627 if ( !projectFile.open( QIODevice::ReadOnly ) )
3632 if ( !sProjectDocument.setContent( &projectFile ) )
3637 sPrevProjectFilePath = projectFilePath;
3638 sPrevProjectFileTimestamp = projectFileTimestamp;
3642 bool useAbsolutePaths =
true;
3644 const QDomElement propertiesElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral(
"properties" ) );
3645 if ( !propertiesElem.isNull() )
3647 const QDomElement absElem = propertiesElem.firstChildElement( QStringLiteral(
"Paths" ) ).firstChildElement( QStringLiteral(
"Absolute" ) );
3648 if ( !absElem.isNull() )
3650 useAbsolutePaths = absElem.text().compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0;
3655 if ( !useAbsolutePaths )
3660 const QDomElement projectLayersElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral(
"projectlayers" ) );
3661 if ( projectLayersElem.isNull() )
3666 QDomElement mapLayerElem = projectLayersElem.firstChildElement( QStringLiteral(
"maplayer" ) );
3667 while ( ! mapLayerElem.isNull() )
3670 const QString
id = mapLayerElem.firstChildElement( QStringLiteral(
"id" ) ).text();
3671 if (
id == layerId )
3674 if ( mapLayerElem.attribute( QStringLiteral(
"embedded" ) ) == QLatin1String(
"1" ) )
3679 mEmbeddedLayers.insert( layerId, qMakePair( projectFilePath, saveFlag ) );
3681 if ( addLayer( mapLayerElem, brokenNodes, embeddedContext,
flags ) )
3687 mEmbeddedLayers.remove( layerId );
3691 mapLayerElem = mapLayerElem.nextSiblingElement( QStringLiteral(
"maplayer" ) );
3701 QString qgsProjectFile = projectFilePath;
3703 if ( projectFilePath.endsWith( QLatin1String(
".qgz" ), Qt::CaseInsensitive ) )
3705 archive.
unzip( projectFilePath );
3710 QFile projectFile( qgsProjectFile );
3711 if ( !projectFile.open( QIODevice::ReadOnly ) )
3716 QDomDocument projectDocument;
3717 if ( !projectDocument.setContent( &projectFile ) )
3729 QDomElement layerTreeElem = projectDocument.documentElement().firstChildElement( QStringLiteral(
"layer-tree-group" ) );
3730 if ( !layerTreeElem.isNull() )
3740 if ( !group || group->
customProperty( QStringLiteral(
"embedded" ) ).toBool() )
3753 newGroup->
setCustomProperty( QStringLiteral(
"embedded_project" ), projectFilePath );
3756 mLayerTreeRegistryBridge->
setEnabled(
false );
3757 initializeEmbeddedSubtree( projectFilePath, newGroup,
flags );
3758 mLayerTreeRegistryBridge->
setEnabled(
true );
3761 const auto constFindLayerIds = newGroup->
findLayerIds();
3762 for (
const QString &layerId : constFindLayerIds )
3775void QgsProject::initializeEmbeddedSubtree(
const QString &projectFilePath,
QgsLayerTreeGroup *group, Qgis::ProjectReadFlags flags )
3779 const auto constChildren = group->
children();
3783 child->setCustomProperty( QStringLiteral(
"embedded" ), 1 );
3792 QList<QDomNode> brokenNodes;
3816 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/TopologicalEditing" ), ( enabled ? 1 : 0 ) );
3824 return readNumEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/TopologicalEditing" ), 0 );
3831 if ( mDistanceUnits == unit )
3834 mDistanceUnits = unit;
3843 if ( mAreaUnits == unit )
3856 if ( !mCachedHomePath.isEmpty() )
3857 return mCachedHomePath;
3861 if ( !mHomePath.isEmpty() )
3863 const QFileInfo homeInfo( mHomePath );
3864 if ( !homeInfo.isRelative() )
3866 mCachedHomePath = mHomePath;
3876 const QString storagePath { storage->filePath(
fileName() ) };
3877 if ( ! storagePath.isEmpty() && QFileInfo::exists( storagePath ) )
3879 mCachedHomePath = QFileInfo( storagePath ).path();
3880 return mCachedHomePath;
3884 mCachedHomePath = pfi.path();
3885 return mCachedHomePath;
3888 if ( !pfi.exists() )
3890 mCachedHomePath = mHomePath;
3894 if ( !mHomePath.isEmpty() )
3897 mCachedHomePath = QDir::cleanPath( pfi.path() +
'/' + mHomePath );
3901 mCachedHomePath = pfi.canonicalPath();
3903 return mCachedHomePath;
3918 return mRelationManager;
3925 return mLayoutManager.get();
3932 return mLayoutManager.get();
3939 return m3DViewsManager.get();
3946 return m3DViewsManager.get();
3953 return mBookmarkManager;
3960 return mBookmarkManager;
3967 return mSensorManager;
3974 return mSensorManager;
3981 return mViewSettings;
3988 return mViewSettings;
3995 return mStyleSettings;
4003 return mStyleSettings;
4010 return mTimeSettings;
4017 return mTimeSettings;
4024 return mElevationProperties;
4031 return mElevationProperties;
4038 return mDisplaySettings;
4045 return mDisplaySettings;
4052 return mGpsSettings;
4059 return mGpsSettings;
4073 return mMapThemeCollection.get();
4080 return mAnnotationManager.get();
4087 return mAnnotationManager.get();
4094 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
4095 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
4100 if (
layers.contains( it.value() ) )
4117 for (
const QString &layerId : layerIds )
4135 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
4169 updateTransactionGroups();
4176 return mTransactionMode;
4187 const auto constLayers =
mapLayers().values();
4190 if ( layer->isEditable() )
4192 QgsLogger::warning( tr(
"Transaction mode can be changed only if all layers are not editable." ) );
4198 updateTransactionGroups();
4206 return mTransactionGroups;
4219 return mLayerStore->count();
4226 return mLayerStore->validCount();
4234 return mLayerStore->mapLayer( layerId );
4241 return mLayerStore->mapLayersByName( layerName );
4248 QList<QgsMapLayer *>
layers;
4249 const auto constMapLayers { mLayerStore->mapLayers() };
4250 for (
const auto &l : constMapLayers )
4252 if ( ! l->shortName().isEmpty() )
4254 if ( l->shortName() == shortName )
4257 else if ( l->name() == shortName )
4265bool QgsProject::unzip(
const QString &filename, Qgis::ProjectReadFlags flags )
4273 if ( !archive->unzip( filename ) )
4275 setError( tr(
"Unable to unzip file '%1'" ).arg( filename ) );
4280 if ( archive->projectFile().isEmpty() )
4282 setError( tr(
"Zip archive does not provide a project file" ) );
4287 releaseHandlesToProjectArchive();
4288 mArchive = std::move( archive );
4305 setError( tr(
"Cannot read unzipped qgs project file" ) + QStringLiteral(
": " ) +
error() );
4315bool QgsProject::zip(
const QString &filename )
4323 const QString
baseName = QFileInfo( filename ).baseName();
4324 const QString qgsFileName = QStringLiteral(
"%1.qgs" ).arg(
baseName );
4325 QFile qgsFile( QDir( archive->dir() ).filePath( qgsFileName ) );
4327 bool writeOk =
false;
4328 if ( qgsFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
4330 writeOk = writeProjectFile( qgsFile.fileName() );
4337 setError( tr(
"Unable to write temporary qgs file" ) );
4342 const QFileInfo info( qgsFile );
4344 const QString asFileName = info.path() + QDir::separator() + info.completeBaseName() + asExt;
4346 bool auxiliaryStorageSavedOk =
true;
4347 if ( ! saveAuxiliaryStorage( asFileName ) )
4349 const QString err = mAuxiliaryStorage->errorString();
4350 setError( tr(
"Unable to save auxiliary storage file ('%1'). The project has been saved but the latest changes to auxiliary data cannot be recovered. It is recommended to reload the project." ).arg( err ) );
4351 auxiliaryStorageSavedOk =
false;
4354 if ( !mArchive->exists() )
4356 releaseHandlesToProjectArchive();
4358 mArchive->unzip( mFile.fileName() );
4361 const QString auxiliaryStorageFile =
static_cast<QgsProjectArchive *
>( mArchive.get() )->auxiliaryStorageFile();
4362 if ( ! auxiliaryStorageFile.isEmpty() )
4364 archive->
addFile( auxiliaryStorageFile );
4373 if ( QFile::exists( asFileName ) )
4375 archive->addFile( asFileName );
4380 archive->addFile( qgsFile.fileName() );
4383 const QStringList &
files = mArchive->files();
4384 for (
const QString &file :
files )
4386 if ( !file.endsWith( QLatin1String(
".qgs" ), Qt::CaseInsensitive ) && !file.endsWith( asExt, Qt::CaseInsensitive ) )
4388 archive->addFile( file );
4394 if ( !archive->zip( filename ) )
4396 setError( tr(
"Unable to perform zip" ) );
4400 return auxiliaryStorageSavedOk && zipOk;
4411 const QList<QgsMapLayer *> &layers,
4413 bool takeOwnership )
4417 const QList<QgsMapLayer *> myResultList { mLayerStore->addMapLayers(
layers, takeOwnership ) };
4418 if ( !myResultList.isEmpty() )
4421 for (
auto &l : myResultList )
4431 if ( mAuxiliaryStorage )
4435 if ( mlayer->type() != Qgis::LayerType::Vector )
4446 mProjectScope.reset();
4448 return myResultList;
4454 bool takeOwnership )
4458 QList<QgsMapLayer *> addedLayers;
4459 addedLayers =
addMapLayers( QList<QgsMapLayer *>() << layer, addToLegend, takeOwnership );
4460 return addedLayers.isEmpty() ? nullptr : addedLayers[0];
4463void QgsProject::removeAuxiliaryLayer(
const QgsMapLayer *ml )
4467 if ( ! ml || ml->
type() != Qgis::LayerType::Vector )
4470 const QgsVectorLayer *vl = qobject_cast<const QgsVectorLayer *>( ml );
4482 for (
const auto &layerId : layerIds )
4483 removeAuxiliaryLayer( mLayerStore->mapLayer( layerId ) );
4485 mProjectScope.reset();
4486 mLayerStore->removeMapLayers( layerIds );
4493 for (
const auto &layer :
layers )
4494 removeAuxiliaryLayer( layer );
4496 mProjectScope.reset();
4497 mLayerStore->removeMapLayers(
layers );
4504 removeAuxiliaryLayer( mLayerStore->mapLayer( layerId ) );
4505 mProjectScope.reset();
4506 mLayerStore->removeMapLayer( layerId );
4513 removeAuxiliaryLayer( layer );
4514 mProjectScope.reset();
4515 mLayerStore->removeMapLayer( layer );
4522 mProjectScope.reset();
4523 return mLayerStore->takeMapLayer( layer );
4530 return mMainAnnotationLayer;
4537 if ( mLayerStore->count() == 0 )
4540 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
4541 mProjectScope.reset();
4542 mLayerStore->removeAllMapLayers();
4544 snapSingleBlocker.release();
4546 if ( !mBlockSnappingUpdates )
4554 const QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
4555 QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin();
4556 for ( ; it !=
layers.constEnd(); ++it )
4558 it.value()->reload();
4567 return validOnly ? mLayerStore->validMapLayers() : mLayerStore->mapLayers();
4574 return mTransactionGroups.value( qMakePair( providerKey, connString ) );
4581 return &mEditBufferGroup;
4592 if ( mSettings.
value( QStringLiteral(
"/projections/unknownCrsBehavior" ), QStringLiteral(
"NoAction" ),
QgsSettings::App ).toString() == QStringLiteral(
"UseProjectCrs" )
4593 || mSettings.
value( QStringLiteral(
"/projections/unknownCrsBehavior" ), 0,
QgsSettings::App ).toString() == QLatin1String(
"2" ) )
4601 const QString layerDefaultCrs = mSettings.
value( QStringLiteral(
"/Projections/layerDefaultCrs" ),
geoEpsgCrsAuthId() ).toString();
4622bool QgsProject::saveAuxiliaryStorage(
const QString &filename )
4628 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
4630 if ( it.value()->type() != Qgis::LayerType::Vector )
4633 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() );
4641 if ( !mAuxiliaryStorage->exists( *
this ) && empty )
4645 else if ( !filename.isEmpty() )
4647 return mAuxiliaryStorage->saveAs( filename );
4651 return mAuxiliaryStorage->saveAs( *
this );
4660 QgsProject::DataDefinedServerProperty::WMSOnlineResource,
4664 return sPropertyDefinitions;
4677 return mAuxiliaryStorage.get();
4684 return mAuxiliaryStorage.get();
4691 const QDir archiveDir( mArchive->dir() );
4692 QTemporaryFile tmpFile( archiveDir.filePath(
"XXXXXX_" + nameTemplate ),
this );
4693 tmpFile.setAutoRemove(
false );
4695 mArchive->addFile( tmpFile.fileName() );
4696 return tmpFile.fileName();
4703 QStringList attachments;
4705 const QStringList
files = mArchive->files();
4706 attachments.reserve(
files.size() );
4707 for (
const QString &file :
files )
4711 attachments.append( file );
4721 return mArchive->removeFile( path );
4728 return QStringLiteral(
"attachment:///%1" ).arg( QFileInfo( attachedFile ).
fileName() );
4735 if ( identifier.startsWith( QLatin1String(
"attachment:///" ) ) )
4737 return QDir( mArchive->dir() ).absoluteFilePath( identifier.mid( 14 ) );
4758 mProjectScope.reset();
4772 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
4786 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
4787 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
4792 if (
layers.contains( it.value() ) )
4804 QStringList customColors;
4805 QStringList customColorLabels;
4807 QgsNamedColorList::const_iterator colorIt = colors.constBegin();
4808 for ( ; colorIt != colors.constEnd(); ++colorIt )
4811 const QString label = ( *colorIt ).second;
4812 customColors.append( color );
4813 customColorLabels.append( label );
4815 writeEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Colors" ), customColors );
4816 writeEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Labels" ), customColorLabels );
4817 mProjectScope.reset();
4825 if ( mBackgroundColor == color )
4828 mBackgroundColor = color;
4836 return mBackgroundColor;
4843 if ( mSelectionColor == color )
4846 mSelectionColor = color;
4854 return mSelectionColor;
4891 translationContext.setFileName( QStringLiteral(
"%1/%2.ts" ).arg(
absolutePath(),
baseName() ) );
4895 translationContext.writeTsFile( locale );
4898QString
QgsProject::translate(
const QString &context,
const QString &sourceText,
const char *disambiguation,
int n )
const
4907 QString result = mTranslator->translate( context.toUtf8(), sourceText.toUtf8(), disambiguation, n );
4909 if ( result.isEmpty() )
4923 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
4928 if ( !( ( *it )->accept( visitor ) ) )
4937 if ( !mLayoutManager->accept( visitor ) )
4940 if ( !mAnnotationManager->accept( visitor ) )
4948 return mElevationShadingRenderer;
4951void QgsProject::loadProjectFlags(
const QDomDocument *doc )
4955 QDomElement element = doc->documentElement().firstChildElement( QStringLiteral(
"projectFlags" ) );
4956 Qgis::ProjectFlags
flags;
4957 if ( !element.isNull() )
4964 element = doc->documentElement().firstChildElement( QStringLiteral(
"evaluateDefaultValues" ) );
4965 if ( !element.isNull() )
4967 if ( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
4972 element = doc->documentElement().firstChildElement( QStringLiteral(
"trust" ) );
4973 if ( !element.isNull() )
4975 if ( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
4984GetNamedProjectColor::GetNamedProjectColor(
const QgsProject *project )
4991 QStringList colorStrings = project->
readListEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Colors" ) );
4992 const QStringList colorLabels = project->
readListEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Labels" ) );
4996 for ( QStringList::iterator it = colorStrings.begin();
4997 it != colorStrings.end(); ++it )
5001 if ( colorLabels.length() > colorIndex )
5003 label = colorLabels.at( colorIndex );
5006 mColors.insert( label.toLower(), color );
5011GetNamedProjectColor::GetNamedProjectColor(
const QHash<QString, QColor> &colors )
5019 const QString colorName = values.at( 0 ).toString().toLower();
5020 if ( mColors.contains( colorName ) )
5022 return QStringLiteral(
"%1,%2,%3" ).arg( mColors.value( colorName ).red() ).arg( mColors.value( colorName ).green() ).arg( mColors.value( colorName ).blue() );
5030 return new GetNamedProjectColor( mColors );
5035GetSensorData::GetSensorData(
const QMap<QString, QgsAbstractSensor::SensorData> &sensorData )
5038 QStringLiteral(
"Sensors" ) )
5039 , mSensorData( sensorData )
5045 const QString sensorName = values.at( 0 ).toString();
5046 const int expiration = values.at( 1 ).toInt();
5047 const qint64 timestamp = QDateTime::currentMSecsSinceEpoch();
5048 if ( mSensorData.contains( sensorName ) )
5050 if ( expiration <= 0 || ( timestamp - mSensorData[sensorName].lastTimestamp.toMSecsSinceEpoch() ) < expiration )
5052 return mSensorData[sensorName].lastValue;
5061 return new GetSensorData( mSensorData );
@ ForceReadOnlyLayers
Open layers in a read-only mode. (since QGIS 3.28)
static QString version()
Version string.
DistanceUnit
Units of distance.
FilePathType
File path types.
TransactionMode
Transaction mode.
@ AutomaticGroups
Automatic transactional editing means that on supported datasources (postgres and geopackage database...
@ BufferedGroups
Buffered transactional editing means that all editable layers in the buffered transaction group are t...
@ Disabled
Edits are buffered locally and sent to the provider when toggling layer editing mode.
AvoidIntersectionsMode
Flags which control how intersections of pre-existing feature are handled when digitizing new feature...
@ AvoidIntersectionsLayers
Overlap with features from a specified list of layers when digitizing new features not allowed.
@ AllowIntersections
Overlap with any feature allowed when digitizing new features.
ProjectFlag
Flags which control the behavior of QgsProjects.
@ RememberLayerEditStatusBetweenSessions
If set, then any layers set to be editable will be stored in the project and immediately made editabl...
@ EvaluateDefaultValuesOnProviderSide
If set, default values for fields will be evaluated on the provider side when features from the proje...
@ TrustStoredLayerStatistics
If set, then layer statistics (such as the layer extent) will be read from values stored in the proje...
LayerType
Types of layers that can be added to a map.
virtual bool readXml(const QDomElement &collectionElem, const QgsPropertiesDefinition &definitions)
Reads property collection state from an XML element.
virtual bool writeXml(QDomElement &collectionElem, const QgsPropertiesDefinition &definitions) const
Writes the current state of the property collection into an XML element.
Represents a map layer containing a set of georeferenced annotations, e.g.
void setTransformContext(const QgsCoordinateTransformContext &context) override
Sets the coordinate transform context to transformContext.
void reset()
Resets the annotation layer to a default state, and clears all items from it.
bool isEmpty() const
Returns true if the annotation layer is empty and contains no annotations.
Manages storage of a set of QgsAnnotation annotation objects.
static QgsApplication * instance()
Returns the singleton instance of the QgsApplication.
static QgsProjectStorageRegistry * projectStorageRegistry()
Returns registry of available project storage implementations.
static const QgsSettingsEntryString * settingsLocaleUserLocale
Settings entry locale user locale.
static QgsRuntimeProfiler * profiler()
Returns the application runtime profiler.
void collectTranslatableObjects(QgsTranslationContext *translationContext)
Emits the signal to collect all the strings of .qgs to be included in ts file.
static QgsPluginLayerRegistry * pluginLayerRegistry()
Returns the application's plugin layer registry, used for managing plugin layer types.
void requestForTranslatableObjects(QgsTranslationContext *translationContext)
Emitted when project strings which require translation are being collected for inclusion in a ....
static QString userFullName()
Returns the user's operating system login account full display name.
static QString userLoginName()
Returns the user's operating system login account name.
Class allowing to manage the zip/unzip actions.
void addFile(const QString &filename)
Add a new file to this archive.
This is a container for attribute editors, used to group them visually in the attribute form if it is...
QList< QgsAttributeEditorElement * > children() const
Gets a list of the children elements of this container.
This is an abstract base class for any elements of a drag and drop form.
QString name() const
Returns the name of this element.
QgsFields auxiliaryFields() const
Returns a list of all auxiliary fields currently managed by the layer.
bool save()
Commits changes and starts editing then.
Class providing some utility methods to manage auxiliary storage.
static QString extension()
Returns the extension used for auxiliary databases.
static bool deleteTable(const QgsDataSourceUri &uri)
Removes a table from the auxiliary storage.
Manages storage of a set of bookmarks.
bool readXml(const QDomElement &element, const QDomDocument &doc)
Reads the manager's state from a DOM element, restoring all bookmarks present in the XML document.
void clear()
Removes and deletes all bookmarks from the manager.
QDomElement writeXml(QDomDocument &doc) const
Returns a DOM element representing the state of the manager.
This class represents a coordinate reference system (CRS).
static QgsCoordinateReferenceSystem fromOgcWmsCrs(const QString &ogcCrs)
Creates a CRS from a given OGC WMS-format Coordinate Reference System string.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
Q_GADGET Qgis::DistanceUnit mapUnits
QString toProj() const
Returns a Proj string representation of this CRS.
bool readXml(const QDomNode &node)
Restores state from the given DOM node.
QString ellipsoidAcronym() const
Returns the ellipsoid acronym for the ellipsoid used by the CRS.
QString projectionAcronym() const
Returns the projection acronym for the projection used by the CRS.
static QgsCoordinateReferenceSystem fromProj(const QString &proj)
Creates a CRS from a proj style formatted string.
@ WKT_PREFERRED
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
bool writeXml(QDomNode &node, QDomDocument &doc) const
Stores state to the given Dom node in the given document.
static QgsCoordinateReferenceSystem fromSrsId(long srsId)
Creates a CRS from a specified QGIS SRS ID.
QString toWkt(WktVariant variant=WKT1_GDAL, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
Contains information about the context in which a coordinate transform is executed.
void readSettings()
Reads the context's state from application settings.
void writeXml(QDomElement &element, const QgsReadWriteContext &context) const
Writes the context's state to a DOM element.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context, QStringList &missingTransforms)
Reads the context's state from a DOM element.
Abstract base class for spatial data provider implementations.
@ EvaluateDefaultValues
Evaluate default values on provider side when calling QgsVectorDataProvider::defaultValue( int index ...
Class for storing the component parts of a RDBMS data source URI (e.g.
This class can render elevation shading on an image with different methods (eye dome lighting,...
void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const
Writes configuration on a DOM element.
void readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads configuration from a DOM element.
Single scope for storing variables and functions for use within a QgsExpressionContext.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
A abstract base class for defining QgsExpression functions.
An expression node for expression functions.
Class for parsing and evaluation of expressions (formerly called "search strings").
Encapsulate a field in an attribute table or data source.
QgsEditorWidgetSetup editorWidgetSetup() const
Gets the editor widget setup for the field.
Container of fields for a vector layer.
bool isEmpty() const
Checks whether the container is empty.
Stores global configuration for labeling engine.
Class used to work with layer dependencies stored in a XML project or layer definition file.
Layer tree group node serves as a container for layers and further groups.
void resolveReferences(const QgsProject *project, bool looseMatching=false) override
Calls resolveReferences() on child tree nodes.
QgsLayerTreeGroup * findGroup(const QString &name)
Find group node with specified name.
QList< QgsLayerTreeGroup * > findGroups(bool recursive=false) const
Find group layer nodes.
QString name() const override
Returns the group's name.
QStringList findLayerIds() const
Find layer IDs used in all layer nodes.
void insertChildNodes(int index, const QList< QgsLayerTreeNode * > &nodes)
Insert existing nodes at specified position.
void readChildrenFromXml(QDomElement &element, const QgsReadWriteContext &context)
Read children from XML and append them to the group.
QgsLayerTreeGroup * clone() const override
Returns a clone of the group.
QList< QgsLayerTreeLayer * > findLayers() const
Find all layer nodes.
QgsLayerTreeLayer * findLayer(QgsMapLayer *layer) const
Find layer node representing the map layer.
Layer tree node points to a map layer.
void resolveReferences(const QgsProject *project, bool looseMatching=false) override
Resolves reference to layer from stored layer ID (if it has not been resolved already)
This class is a base class for nodes in a layer tree.
QList< QgsLayerTreeNode * > abandonChildren()
Removes the childrens, disconnect all the forwarded and external signals and sets their parent to nul...
void setCustomProperty(const QString &key, const QVariant &value)
Sets a custom property for the node. Properties are stored in a map and saved in project file.
virtual void writeXml(QDomElement &parentElement, const QgsReadWriteContext &context)=0
Write layer tree to XML.
QList< QgsLayerTreeNode * > children()
Gets list of children of the node. Children are owned by the parent.
void removeCustomProperty(const QString &key)
Remove a custom property from layer. Properties are stored in a map and saved in project file.
QVariant customProperty(const QString &key, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer. Properties are stored in a map and saved in project file.
void setItemVisibilityChecked(bool checked)
Check or uncheck a node (independently of its ancestors or children)
Listens to the updates in map layer registry and does changes in layer tree.
void setEnabled(bool enabled)
static void replaceChildrenOfEmbeddedGroups(QgsLayerTreeGroup *group)
Remove subtree of embedded groups and replaces it with a custom property embedded-visible-layers.
static void storeOriginalLayersProperties(QgsLayerTreeGroup *group, const QDomDocument *doc)
Stores in a layer's originalXmlProperties the layer properties information.
static void updateEmbeddedGroupsProjectPath(QgsLayerTreeGroup *group, const QgsProject *project)
Updates an embedded group from a project.
static bool readOldLegend(QgsLayerTreeGroup *root, const QDomElement &legendElem)
Try to load layer tree from.
Namespace with helper functions for layer tree operations.
void readLayerOrderFromXml(const QDomElement &doc)
Load the layer order from an XML element.
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
void clear()
Clear any information from this layer tree.
static bool isLayer(const QgsLayerTreeNode *node)
Check whether the node is a valid layer node.
static bool isGroup(QgsLayerTreeNode *node)
Check whether the node is a valid group node.
static QgsLayerTreeGroup * toGroup(QgsLayerTreeNode *node)
Cast node to a group.
QList< QgsMapLayer * > customLayerOrder() const
The order in which layers will be rendered on the canvas.
QgsLayerTree * clone() const override
Create a copy of the node. Returns new instance.
Manages storage of a set of layouts.
static void warning(const QString &msg)
Goes to qWarning.
static Qgis::LayerType typeFromString(const QString &string, bool &ok)
Returns the map layer type corresponding a string value.
A storage object for map layers, in which the layers are owned by the store and have their lifetime b...
void layersWillBeRemoved(const QStringList &layerIds)
Emitted when one or more layers are about to be removed from the store.
void layerWillBeRemoved(const QString &layerId)
Emitted when a layer is about to be removed from the store.
void layersRemoved(const QStringList &layerIds)
Emitted after one or more layers were removed from the store.
void allLayersRemoved()
Emitted when all layers are removed, before layersWillBeRemoved() and layerWillBeRemoved() signals ar...
void layerRemoved(const QString &layerId)
Emitted after a layer was removed from the store.
void layerWasAdded(QgsMapLayer *layer)
Emitted when a layer was added to the store.
QgsMapLayer * mapLayer(const QString &id) const
Retrieve a pointer to a layer by layer id.
void layersAdded(const QList< QgsMapLayer * > &layers)
Emitted when one or more layers were added to the store.
Base class for all map layer types.
QString source() const
Returns the source for the layer.
QString providerType() const
Returns the provider type (provider key) for this layer.
void removeCustomProperty(const QString &key)
Remove a custom property from layer.
void configChanged()
Emitted whenever the configuration is changed.
QgsCoordinateReferenceSystem crs
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
QString originalXmlProperties() const
Returns the XML properties of the original layer as they were when the layer was first read from the ...
Q_INVOKABLE void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
virtual bool isEditable() const
Returns true if the layer can be edited.
bool writeLayerXml(QDomElement &layerElement, QDomDocument &document, const QgsReadWriteContext &context) const
Stores state in DOM node.
@ Identifiable
If the layer is identifiable using the identify map tool and as a WMS layer.
@ Removable
If the layer can be removed from the project. The layer will not be removable from the legend menu en...
@ FlagTrustLayerMetadata
Trust layer metadata. Improves layer load time by skipping expensive checks like primary key unicity,...
@ FlagForceReadOnly
Force open as read only.
@ FlagDontResolveLayers
Don't resolve layer paths or create data providers for layers.
bool readLayerXml(const QDomElement &layerElement, QgsReadWriteContext &context, QgsMapLayer::ReadFlags flags=QgsMapLayer::ReadFlags(), QgsDataProvider *preloadedProvider=nullptr)
Sets state from DOM document.
void setCrs(const QgsCoordinateReferenceSystem &srs, bool emitSignal=true)
Sets layer's spatial reference system.
static QgsDataProvider::ReadFlags providerReadFlags(const QDomNode &layerNode, QgsMapLayer::ReadFlags layerReadFlags)
Returns provider read flag deduced from layer read flags layerReadFlags and a dom node layerNode that...
Container class that allows storage of map themes consisting of visible map layers and layer styles.
Manages storage of a set of views.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Resolves relative paths into absolute paths and vice versa.
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
Class allowing to manage the zip/unzip actions on project file.
QString projectFile() const
Returns the current .qgs project file or an empty string if there's none.
QString auxiliaryStorageFile() const
Returns the current .qgd auxiliary storage file or an empty string if there's none.
bool unzip(const QString &zipFilename) override
Clear the current content of this archive and unzip.
Interface for classes that handle missing layer files when reading project file.
virtual void handleBadLayers(const QList< QDomNode > &layers)
This method will be called whenever the project tries to load layers which cannot be accessed.
Contains settings and properties relating to how a QgsProject should display values such as map coord...
void reset()
Resets the settings to a default state.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads the settings's state from a DOM element.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Returns a DOM element representing the settings.
Contains elevation properties for a QgsProject.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads the property state from a DOM element.
void reset()
Resets the properties to a default state.
QDomElement writeXml(QDomDocument &document, const QgsReadWriteContext &context) const
Returns a DOM element representing the properties.
void resolveReferences(const QgsProject *project)
Resolves reference to layers from stored layer ID.
Contains settings and properties relating to how a QgsProject should interact with a GPS device.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads the settings's state from a DOM element.
void reset()
Resets the settings to a default state.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Returns a DOM element representing the settings.
void resolveReferences(const QgsProject *project)
Resolves reference to layers from stored layer ID (if it has not been resolved already)
Project property key node.
QString name() const
The name of the property is used as identifier.
QgsProjectProperty * find(const QString &propertyName) const
Attempts to find a property with a matching sub-key name.
void removeKey(const QString &keyName)
Removes the specified key.
void dump(int tabs=0) const override
Dumps out the keys and values.
bool isEmpty() const
Returns true if this property contains no sub-keys.
virtual void clearKeys()
Deletes any sub-nodes from the property.
bool writeXml(const QString &nodeName, QDomElement &element, QDomDocument &document) override
Writes the property hierarchy to a specified DOM element.
void subkeyList(QStringList &entries) const
Returns any sub-keys contained by this property which themselves contain other keys.
void setName(const QString &name)
The name of the property is used as identifier.
QgsProjectPropertyKey * addKey(const QString &keyName)
Adds the specified property key as a sub-key.
QVariant value() const override
If this key has a value, it will be stored by its name in its properties.
QgsProjectPropertyValue * setValue(const QString &name, const QVariant &value)
Sets the value associated with this key.
void entryList(QStringList &entries) const
Returns any sub-keys contained by this property that do not contain other keys.
int count() const
Returns the number of sub-keys contained by this property.
bool readXml(const QDomNode &keyNode) override
Restores the property hierarchy from a specified DOM node.
An Abstract Base Class for QGIS project property hierarchys.
virtual bool isKey() const =0
Returns true if the property is a QgsProjectPropertyKey.
virtual bool isValue() const =0
Returns true if the property is a QgsProjectPropertyValue.
QgsProjectStorage * projectStorageFromUri(const QString &uri)
Returns storage implementation if the URI matches one. Returns nullptr otherwise (it is a normal file...
Abstract interface for project storage - to be implemented by various backends and registered in QgsP...
Contains settings and properties relating to how a QgsProject should handle styling.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Returns a DOM element representing the settings.
void setDefaultSymbol(Qgis::SymbolType symbolType, QgsSymbol *symbol)
Sets the project default symbol for a given type.
void reset()
Resets the settings to a default state.
void removeProjectStyle()
Removes and deletes the project style database.
void setRandomizeDefaultSymbolColor(bool randomized)
Sets whether the default symbol fill color is randomized.
void setDefaultColorRamp(QgsColorRamp *colorRamp)
Sets the project default color ramp.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context, Qgis::ProjectReadFlags flags=Qgis::ProjectReadFlags())
Reads the settings's state from a DOM element.
void setDefaultSymbolOpacity(double opacity)
Sets the default symbol opacity.
Contains temporal settings and properties for the project, this may be used when animating maps or sh...
bool readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads the settings's state from a DOM element.
void reset()
Resets the settings to a default state.
QDomElement writeXml(QDomDocument &document, const QgsReadWriteContext &context) const
Returns a DOM element representing the settings.
A class to describe the version of a project.
QString text() const
Returns a string representation of the version.
int majorVersion() const
Returns the major version number.
Contains settings and properties relating to how a QgsProject should be displayed inside map canvas,...
bool useProjectScales() const
Returns true if project mapScales() are enabled.
void reset()
Resets the settings to a default state.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads the settings's state from a DOM element.
void setMapScales(const QVector< double > &scales)
Sets the list of custom project map scales.
void setUseProjectScales(bool enabled)
Sets whether project mapScales() are enabled.
QVector< double > mapScales() const
Returns the list of custom project map scales.
void mapScalesChanged()
Emitted when the list of custom project map scales changes.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Returns a DOM element representing the settings.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
bool isZipped() const
Returns true if the project comes from a zip archive, false otherwise.
bool removeAttachedFile(const QString &path)
Removes the attached file.
QgsRelationManager * relationManager
bool write()
Writes the project to its current associated file (see fileName() ).
QgsProject(QObject *parent=nullptr, Qgis::ProjectCapabilities capabilities=Qgis::ProjectCapability::ProjectStyles)
Create a new QgsProject.
void removeMapLayer(const QString &layerId)
Remove a layer from the registry by layer ID.
Q_DECL_DEPRECATED bool evaluateDefaultValues() const
Should default values be evaluated on provider side when requested and not when committed.
Qgis::DistanceUnit distanceUnits
void layersRemoved(const QStringList &layerIds)
Emitted after one or more layers were removed from the registry.
void clear()
Clears the project, removing all settings and resetting it back to an empty, default state.
QString error() const
Returns error message from previous read/write.
Q_DECL_DEPRECATED void setUseProjectScales(bool enabled)
Sets whether project mapScales() are enabled.
int readNumEntry(const QString &scope, const QString &key, int def=0, bool *ok=nullptr) const
Reads an integer from the specified scope and key.
Q_DECL_DEPRECATED void setNonIdentifiableLayers(const QList< QgsMapLayer * > &layers)
Set a list of layers which should not be taken into account on map identification.
QList< QgsMapLayer * > addMapLayers(const QList< QgsMapLayer * > &mapLayers, bool addToLegend=true, bool takeOwnership=true)
Add a list of layers to the map of loaded layers.
Qgis::ProjectFlags flags() const
Returns the project's flags, which dictate the behavior of the project.
Q_DECL_DEPRECATED QFileInfo fileInfo() const
Returns QFileInfo object for the project's associated file.
QString presetHomePath() const
Returns any manual project home path setting, or an empty string if not set.
void setBackgroundColor(const QColor &color)
Sets the default background color used by default map canvases.
void setCrs(const QgsCoordinateReferenceSystem &crs, bool adjustEllipsoid=false)
Sets the project's native coordinate reference system.
QString title() const
Returns the project's title.
bool commitChanges(QStringList &commitErrors, bool stopEditing=true, QgsVectorLayer *vectorLayer=nullptr)
Attempts to commit to the underlying data provider any buffered changes made since the last to call t...
void mapThemeCollectionChanged()
Emitted when the map theme collection changes.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Qgis::FilePathType filePathStorage() const
Returns the type of paths used when storing file paths in a QGS/QGZ project file.
QString createAttachedFile(const QString &nameTemplate)
Attaches a file to the project.
Q_DECL_DEPRECATED void mapScalesChanged()
Emitted when the list of custom project map scales changes.
void readVersionMismatchOccurred(const QString &fileVersion)
Emitted when a project is read and the version of QGIS used to save the project differs from the curr...
void fileNameChanged()
Emitted when the file name of the project changes.
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
void writeMapLayer(QgsMapLayer *mapLayer, QDomElement &layerElem, QDomDocument &doc)
Emitted when a layer is being saved.
const QgsSensorManager * sensorManager() const
Returns the project's sensor manager, which manages sensors within the project.
void setSnappingConfig(const QgsSnappingConfig &snappingConfig)
The snapping configuration for this project.
void areaUnitsChanged()
Emitted when the default area units changes.
QgsPropertyCollection dataDefinedServerProperties() const
Returns the data defined properties used for overrides in user defined server parameters.
Q_DECL_DEPRECATED void nonIdentifiableLayersChanged(QStringList nonIdentifiableLayers)
Emitted when the list of layer which are excluded from map identification changes.
void layersWillBeRemoved(const QStringList &layerIds)
Emitted when one or more layers are about to be removed from the registry.
QString attachmentIdentifier(const QString &attachedFile) const
Returns an identifier for an attachment file path An attachment identifier is a string which does not...
QgsVectorLayerEditBufferGroup * editBufferGroup()
Returns the edit buffer group.
void setSelectionColor(const QColor &color)
Sets the color used to highlight selected features.
bool rollBack(QStringList &rollbackErrors, bool stopEditing=true, QgsVectorLayer *vectorLayer=nullptr)
Stops a current editing operation on vectorLayer and discards any uncommitted edits.
void snappingConfigChanged(const QgsSnappingConfig &config)
Emitted whenever the configuration for snapping has changed.
QgsPathResolver pathResolver() const
Returns path resolver object with considering whether the project uses absolute or relative paths and...
void setBadLayerHandler(QgsProjectBadLayerHandler *handler)
Change handler for missing layers.
Q_DECL_DEPRECATED void setEvaluateDefaultValues(bool evaluateDefaultValues)
Defines if default values should be evaluated on provider side when requested and not when committed.
void crsChanged()
Emitted when the CRS of the project has changed.
QString translate(const QString &context, const QString &sourceText, const char *disambiguation=nullptr, int n=-1) const override
Translates the project with QTranslator and qm file.
const QgsProjectStyleSettings * styleSettings() const
Returns the project's style settings, which contains settings and properties relating to how a QgsPro...
QgsSnappingConfig snappingConfig
const QgsProjectGpsSettings * gpsSettings() const
Returns the project's GPS settings, which contains settings and properties relating to how a QgsProje...
void setFileName(const QString &name)
Sets the file name associated with the project.
void avoidIntersectionsLayersChanged()
Emitted whenever avoidIntersectionsLayers has changed.
void setDataDefinedServerProperties(const QgsPropertyCollection &properties)
Sets the data defined properties used for overrides in user defined server parameters to properties.
void registerTranslatableObjects(QgsTranslationContext *translationContext)
Registers the objects that require translation into the translationContext.
void distanceUnitsChanged()
Emitted when the default distance units changes.
QgsAnnotationLayer * mainAnnotationLayer()
Returns the main annotation layer associated with the project.
const QgsBookmarkManager * bookmarkManager() const
Returns the project's bookmark manager, which manages bookmarks within the project.
void readMapLayer(QgsMapLayer *mapLayer, const QDomElement &layerNode)
Emitted after the basic initialization of a layer from the project file is done.
Q_DECL_DEPRECATED void setAutoTransaction(bool autoTransaction)
Transactional editing means that on supported datasources (postgres databases) the edit state of all ...
bool startEditing(QgsVectorLayer *vectorLayer=nullptr)
Makes the layer editable.
Q_DECL_DEPRECATED void setTrustLayerMetadata(bool trust)
Sets the trust option allowing to indicate if the extent has to be read from the XML document when da...
void cleared()
Emitted when the project is cleared (and additionally when an open project is cleared just before a n...
Q_DECL_DEPRECATED void oldProjectVersionWarning(const QString &)
Emitted when an old project file is read.
void setLabelingEngineSettings(const QgsLabelingEngineSettings &settings)
Sets project's global labeling engine settings.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
void metadataChanged()
Emitted when the project's metadata is changed.
QString resolveAttachmentIdentifier(const QString &identifier) const
Resolves an attachment identifier to a attachment file path.
const QgsProjectElevationProperties * elevationProperties() const
Returns the project's elevation properties, which contains the project's elevation related settings.
QString absolutePath() const
Returns full absolute path to the project folder if the project is stored in a file system - derived ...
void removeMapLayers(const QStringList &layerIds)
Remove a set of layers from the registry by layer ID.
Q_DECL_DEPRECATED void setRequiredLayers(const QSet< QgsMapLayer * > &layers)
Configures a set of map layers that are required in the project and therefore they should not get rem...
bool createEmbeddedLayer(const QString &layerId, const QString &projectFilePath, QList< QDomNode > &brokenNodes, bool saveFlag=true, Qgis::ProjectReadFlags flags=Qgis::ProjectReadFlags())
Creates a maplayer instance defined in an arbitrary project file.
QList< QgsVectorLayer * > avoidIntersectionsLayers
QString readEntry(const QString &scope, const QString &key, const QString &def=QString(), bool *ok=nullptr) const
Reads a string from the specified scope and key.
QgsExpressionContextScope * createExpressionContextScope() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
QString baseName() const
Returns the base name of the project file without the path and without extension - derived from fileN...
void ellipsoidChanged(const QString &ellipsoid)
Emitted when the project ellipsoid is changed.
QgsMapThemeCollection * mapThemeCollection
void generateTsFile(const QString &locale)
Triggers the collection strings of .qgs to be included in ts file and calls writeTsFile()
QStringList entryList(const QString &scope, const QString &key) const
Returns a list of child keys with values which exist within the the specified scope and key.
QgsAnnotationManager * annotationManager()
Returns pointer to the project's annotation manager.
QgsProjectDisplaySettings * displaySettings
Qgis::TransactionMode transactionMode() const
Returns the transaction mode.
QgsProjectMetadata metadata
void projectColorsChanged()
Emitted whenever the project's color scheme has been changed.
QString saveUser() const
Returns the user name that did the last save.
QVector< T > layers() const
Returns a list of registered map layers with a specified layer type.
void setProjectColors(const QgsNamedColorList &colors)
Sets the colors for the project's color scheme (see QgsProjectColorScheme).
bool setTransactionMode(Qgis::TransactionMode transactionMode)
Set transaction mode.
QgsCoordinateTransformContext transformContext
void labelingEngineSettingsChanged()
Emitted when global configuration of the labeling engine changes.
void customVariablesChanged()
Emitted whenever the expression variables stored in the project have been changed.
QgsLayerTree * layerTreeRoot() const
Returns pointer to the root (invisible) node of the project's layer tree.
bool readBoolEntry(const QString &scope, const QString &key, bool def=false, bool *ok=nullptr) const
Reads a boolean from the specified scope and key.
QgsMapLayerStore * layerStore()
Returns a pointer to the project's internal layer store.
void readProject(const QDomDocument &)
Emitted when a project is being read.
QString originalPath() const
Returns the original path associated with the project.
void setOriginalPath(const QString &path)
Sets the original path associated with the project.
void dumpProperties() const
Dump out current project properties to stderr.
QgsElevationShadingRenderer elevationShadingRenderer() const
Returns the elevation shading renderer used for map shading.
const QgsMapViewsManager * viewsManager() const
Returns the project's views manager, which manages map views (including 3d maps) in the project.
static void setInstance(QgsProject *project)
Set the current project singleton instance to project.
int validCount() const
Returns the number of registered valid layers.
const QgsLayoutManager * layoutManager() const
Returns the project's layout manager, which manages print layouts, atlases and reports within the pro...
void elevationShadingRendererChanged()
Emitted when the map shading renderer changes.
QList< QgsMapLayer * > mapLayersByName(const QString &layerName) const
Retrieve a list of matching registered layers by layer name.
Q_DECL_DEPRECATED bool autoTransaction() const
Transactional editing means that on supported datasources (postgres databases) the edit state of all ...
bool accept(QgsStyleEntityVisitorInterface *visitor) const
Accepts the specified style entity visitor, causing it to visit all style entities associated with th...
QStringList attachedFiles() const
Returns a map of all attached files with identifier and real paths.
void setMetadata(const QgsProjectMetadata &metadata)
Sets the project's metadata store.
void missingDatumTransforms(const QStringList &missingTransforms)
Emitted when datum transforms stored in the project are not available locally.
QgsTransactionGroup * transactionGroup(const QString &providerKey, const QString &connString)
Returns the matching transaction group from a provider key and connection string.
QgsCoordinateReferenceSystem crs
void readProjectWithContext(const QDomDocument &, QgsReadWriteContext &context)
Emitted when a project is being read.
QgsMapLayer * addMapLayer(QgsMapLayer *mapLayer, bool addToLegend=true, bool takeOwnership=true)
Add a layer to the map of loaded layers.
QStringList nonIdentifiableLayers
void setAvoidIntersectionsMode(const Qgis::AvoidIntersectionsMode mode)
Sets the avoid intersections mode.
void transactionGroupsChanged()
Emitted whenever a new transaction group has been created or a transaction group has been removed.
const QgsAuxiliaryStorage * auxiliaryStorage() const
Returns the current const auxiliary storage.
void reloadAllLayers()
Reload all registered layer's provider data caches, synchronising the layer with any changes in the d...
int count() const
Returns the number of registered layers.
void loadingLayerMessageReceived(const QString &layerName, const QList< QgsReadWriteContext::ReadWriteMessage > &messages)
Emitted when loading layers has produced some messages.
void setAreaUnits(Qgis::AreaUnit unit)
Sets the default area measurement units for the project.
void setTitle(const QString &title)
Sets the project's title.
QMap< QPair< QString, QString >, QgsTransactionGroup * > transactionGroups()
Map of transaction groups.
void writeProject(QDomDocument &)
Emitted when the project is being written.
void setFlag(Qgis::ProjectFlag flag, bool enabled=true)
Sets whether a project flag is enabled.
QDateTime lastModified() const
Returns last modified time of the project file as returned by the file system (or other project stora...
bool readLayer(const QDomNode &layerNode)
Reads the layer described in the associated DOM node.
double readDoubleEntry(const QString &scope, const QString &key, double def=0, bool *ok=nullptr) const
Reads a double from the specified scope and key.
bool writeEntry(const QString &scope, const QString &key, bool value)
Write a boolean value to the project file.
QString absoluteFilePath() const
Returns full absolute path to the project file if the project is stored in a file system - derived fr...
QDateTime lastSaveDateTime() const
Returns the date and time when the project was last saved.
void projectSaved()
Emitted when the project file has been written and closed.
Q_DECL_DEPRECATED bool trustLayerMetadata() const
Returns true if the trust option is activated, false otherwise.
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
void setEllipsoid(const QString &ellipsoid)
Sets the project's ellipsoid from a proj string representation, e.g., "WGS84".
void setTransformContext(const QgsCoordinateTransformContext &context)
Sets the project's coordinate transform context, which stores various information regarding which dat...
void layerLoaded(int i, int n)
Emitted when a layer from a projects was read.
QStringList subkeyList(const QString &scope, const QString &key) const
Returns a list of child keys which contain other keys that exist within the the specified scope and k...
bool read(const QString &filename, Qgis::ProjectReadFlags flags=Qgis::ProjectReadFlags())
Reads given project file from the given file.
QStringList readListEntry(const QString &scope, const QString &key, const QStringList &def=QStringList(), bool *ok=nullptr) const
Reads a string list from the specified scope and key.
void selectionColorChanged()
Emitted whenever the project's selection color has been changed.
const QgsLabelingEngineSettings & labelingEngineSettings() const
Returns project's global labeling engine settings.
void removeAllMapLayers()
Removes all registered layers.
Q_DECL_DEPRECATED QVector< double > mapScales() const
Returns the list of custom project map scales.
void setDirty(bool b=true)
Flag the project as dirty (modified).
void backgroundColorChanged()
Emitted whenever the project's canvas background color has been changed.
QgsLayerTreeGroup * createEmbeddedGroup(const QString &groupName, const QString &projectFilePath, const QStringList &invisibleLayers, Qgis::ProjectReadFlags flags=Qgis::ProjectReadFlags())
Create layer group instance defined in an arbitrary project file.
const QgsProjectViewSettings * viewSettings() const
Returns the project's view settings, which contains settings and properties relating to how a QgsProj...
QString readPath(const QString &filename) const
Transforms a filename read from the project file to an absolute path.
void registerTranslatableContainers(QgsTranslationContext *translationContext, QgsAttributeEditorContainer *parent, const QString &layerId)
Registers the containers that require translation into the translationContext.
void setElevationShadingRenderer(const QgsElevationShadingRenderer &elevationShadingRenderer)
Sets the elevation shading renderer used for global map shading.
void setFilePathStorage(Qgis::FilePathType type)
Sets the type of paths used when storing file paths in a QGS/QGZ project file.
Q_DECL_DEPRECATED QSet< QgsMapLayer * > requiredLayers() const
Returns a set of map layers that are required in the project and therefore they should not get remove...
void transformContextChanged()
Emitted when the project transformContext() is changed.
void setTopologicalEditing(bool enabled)
Convenience function to set topological editing.
void legendLayersAdded(const QList< QgsMapLayer * > &layers)
Emitted, when a layer was added to the registry and the legend.
QVariantMap customVariables() const
A map of custom project variables.
void setAvoidIntersectionsLayers(const QList< QgsVectorLayer * > &layers)
Sets the list of layers with which intersections should be avoided.
void homePathChanged()
Emitted when the home path of the project changes.
void dirtySet()
Emitted when setDirty(true) is called.
void setCustomVariables(const QVariantMap &customVariables)
A map of custom project variables.
QgsCoordinateReferenceSystem defaultCrsForNewLayers() const
Returns the default CRS for new layers based on the settings and the current project CRS.
QString saveUserFullName() const
Returns the full user name that did the last save.
void layersAdded(const QList< QgsMapLayer * > &layers)
Emitted when one or more layers were added to the registry.
QMap< QString, QgsMapLayer * > mapLayers(const bool validOnly=false) const
Returns a map of all registered layers by layer ID.
bool isDirty() const
Returns true if the project has been modified since the last write()
QgsMapLayer * takeMapLayer(QgsMapLayer *layer)
Takes a layer from the registry.
void isDirtyChanged(bool dirty)
Emitted when the project dirty status changes.
void setDistanceUnits(Qgis::DistanceUnit unit)
Sets the default distance measurement units for the project.
Q_DECL_DEPRECATED bool useProjectScales() const
Returns true if project mapScales() are enabled.
Q_DECL_DEPRECATED void setMapScales(const QVector< double > &scales)
Sets the list of custom project map scales.
void setPresetHomePath(const QString &path)
Sets the project's home path.
void setFlags(Qgis::ProjectFlags flags)
Sets the project's flags, which dictate the behavior of the project.
QList< QgsMapLayer * > mapLayersByShortName(const QString &shortName) const
Retrieves a list of matching registered layers by layer shortName.
QgsProjectStorage * projectStorage() const
Returns pointer to project storage implementation that handles read/write of the project file.
QString layerIsEmbedded(const QString &id) const
Returns the source project file path if the layer with matching id is embedded from other project fil...
const QgsProjectTimeSettings * timeSettings() const
Returns the project's time settings, which contains the project's temporal range and other time based...
void topologicalEditingChanged()
Emitted when the topological editing flag has changed.
bool removeEntry(const QString &scope, const QString &key)
Remove the given key from the specified scope.
QgsProjectVersion lastSaveVersion() const
Returns the QGIS version which the project was last saved using.
void avoidIntersectionsModeChanged()
Emitted whenever the avoid intersections mode has changed.
void loadingLayer(const QString &layerName)
Emitted when a layer is loaded.
A grouped map of multiple QgsProperty objects, each referenced by a integer key value.
Definition for a property.
@ String
Any string value.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
QString relativeToAbsoluteUri(const QString &providerKey, const QString &uri, const QgsReadWriteContext &context) const
Converts relative path(s) to absolute path(s) in the given provider-specific URI.
QgsProviderMetadata * providerMetadata(const QString &providerKey) const
Returns metadata of the provider or nullptr if not found.
The class is used as a container of context for various read/write operations on other objects.
void setTransformContext(const QgsCoordinateTransformContext &transformContext)
Sets data coordinate transform context to transformContext.
QgsCoordinateTransformContext transformContext() const
Returns data provider coordinate transform context.
QList< QgsReadWriteContext::ReadWriteMessage > takeMessages()
Returns the stored messages and remove them.
void setProjectTranslator(QgsProjectTranslator *projectTranslator)
Sets the project translator.
void setPathResolver(const QgsPathResolver &resolver)
Sets up path resolver for conversion between relative and absolute paths.
This class manages a set of relations between layers.
void clear()
Remove any relation managed by this class.
QMap< QString, QgsRelation > relations() const
Gets access to the relations managed by this class.
The QgsRunnableProviderCreator class is used when reading a project to create asynchronously provider...
void providerCreated(bool isValid, const QString &layerId)
Emitted when a provider is created with isValid set to True when the provider is valid.
QgsDataProvider * dataProvider()
Returns the created data provider.
void clear(const QString &group="startup")
clear Clear all profile data.
Expression function for use within a QgsExpressionContextScope.
Scoped object for logging of the runtime for a single operation or group of operations.
QDomElement writeXml(QDomDocument &document) const
Returns a DOM element representing the state of the manager.
void clear()
Deregisters and removes all sensors from the manager.
bool readXml(const QDomElement &element, const QDomDocument &document)
Reads the manager's state from a DOM element, restoring all sensors present in the XML document.
T value(const QString &dynamicKeyPart=QString()) const
Returns settings value.
static const QgsSettingsEntryInteger * settingsLayerParallelLoadingMaxCount
Settings entry maximum thread count used to load layer in parallel.
static const QgsSettingsEntryBool * settingsLayerParallelLoading
Settings entry whether layer are loading in parallel.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
This is a container for configuration of the snapping of the project.
bool addLayers(const QList< QgsMapLayer * > &layers)
Adds the specified layers as individual layers to the configuration with standard configuration.
void readProject(const QDomDocument &doc)
Reads the configuration from the specified QGIS project document.
void reset()
reset to default values
void writeProject(QDomDocument &doc)
Writes the configuration to the specified QGIS project document.
void clearIndividualLayerSettings()
Removes all individual layer snapping settings.
bool removeLayers(const QList< QgsMapLayer * > &layers)
Removes the specified layers from the individual layer configuration.
An interface for classes which can visit style entity (e.g.
virtual bool visitExit(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor stops visiting a node.
virtual bool visitEnter(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor starts visiting a node.
static QgsStyle * defaultStyle()
Returns default application-wide style.
void triggerIconRebuild()
Triggers emission of the rebuildIconPreviews() signal.
static QColor decodeColor(const QString &str)
static QString encodeColor(const QColor &color)
bool addLayer(QgsVectorLayer *layer)
Add a layer to this transaction group.
static bool supportsTransaction(const QgsVectorLayer *layer)
Checks if the provider of a given layer supports transactions.
QString connectionString() const
Returns the connection string of the transaction.
Used for the collecting of strings from projects for translation and creation of ts files.
void registerTranslation(const QString &context, const QString &source)
Registers the source to be translated.
void setProject(QgsProject *project)
Sets the project being translated.
static Q_INVOKABLE QString toString(Qgis::DistanceUnit unit)
Returns a translated string representing a distance unit.
static Q_INVOKABLE Qgis::AreaUnit decodeAreaUnit(const QString &string, bool *ok=nullptr)
Decodes an areal unit from a string.
static Q_INVOKABLE QString encodeUnit(Qgis::DistanceUnit unit)
Encodes a distance unit to a string.
static Q_INVOKABLE Qgis::DistanceUnit decodeDistanceUnit(const QString &string, bool *ok=nullptr)
Decodes a distance unit from a string.
The edit buffer group manages a group of edit buffers.
bool commitChanges(QStringList &commitErrors, bool stopEditing=true)
Attempts to commit any changes to disk.
bool startEditing()
Start editing.
void clear()
Remove all layers from this edit buffer group.
bool rollBack(QStringList &rollbackErrors, bool stopEditing=true)
Stop editing and discard the edits.
void addLayer(QgsVectorLayer *layer)
Add a layer to this edit buffer group.
Represents a vector layer which manages a vector based data sets.
Q_INVOKABLE bool startEditing()
Makes the layer editable.
bool loadAuxiliaryLayer(const QgsAuxiliaryStorage &storage, const QString &key=QString())
Loads the auxiliary layer for this vector layer.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
QgsAuxiliaryLayer * auxiliaryLayer()
Returns the current auxiliary layer.
QStringList commitErrors() const
Returns a list containing any error messages generated when attempting to commit changes to the layer...
Q_INVOKABLE bool rollBack(bool deleteBuffer=true)
Stops a current editing operation and discards any uncommitted edits.
Q_INVOKABLE bool commitChanges(bool stopEditing=true)
Attempts to commit to the underlying data provider any buffered changes made since the last to call t...
QgsEditFormConfig editFormConfig
QList< QPair< QColor, QString > > QgsNamedColorList
List of colors paired with a friendly display name identifying the color.
CORE_EXPORT bool isZipFile(const QString &filename)
Returns true if the file name is a zipped file ( i.e with a '.qgz' extension, false otherwise.
CORE_EXPORT const QStringList files(const QString &zip)
Returns the list of files within a zip file.
CONSTLATIN1STRING geoNone()
Constant that holds the string representation for "No ellips/No CRS".
T qgsEnumKeyToValue(const QString &key, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given key of an enum.
#define Q_NOWARN_DEPRECATED_POP
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
QString qgsFlagValueToKeys(const T &value, bool *returnOk=nullptr)
Returns the value for the given keys of a flag.
T qgsFlagKeysToValue(const QString &keys, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given keys of a flag.
#define Q_NOWARN_DEPRECATED_PUSH
CONSTLATIN1STRING geoEpsgCrsAuthId()
Geographic coord sys from EPSG authority.
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)
QPointer< QgsMapLayer > QgsWeakMapLayerPointer
Weak pointer for QgsMapLayer.
void _getProperties(const QDomDocument &doc, QgsProjectPropertyKey &project_properties)
Restores any optional properties found in "doc" to "properties".
QgsPropertyCollection getDataDefinedServerProperties(const QDomDocument &doc, const QgsPropertiesDefinition &dataDefinedServerPropertyDefinitions)
Returns the data defined server properties collection found in "doc" to "dataDefinedServerProperties"...
void removeKey_(const QString &scope, const QString &key, QgsProjectPropertyKey &rootProperty)
Removes a given key.
QgsProjectVersion getVersion(const QDomDocument &doc)
Returns the version string found in the given DOM document.
QStringList makeKeyTokens_(const QString &scope, const QString &key)
Takes the given scope and key and convert them to a string list of key tokens that will be used to na...
void dump_(const QgsProjectPropertyKey &topQgsPropertyKey)
QgsProjectProperty * findKey_(const QString &scope, const QString &key, QgsProjectPropertyKey &rootProperty)
Returns the property that matches the given key sequence, if any.
QgsProjectProperty * addKey_(const QString &scope, const QString &key, QgsProjectPropertyKey *rootProperty, const QVariant &value, bool &propertiesModified)
Adds the given key and value.
QMap< int, QgsPropertyDefinition > QgsPropertiesDefinition
Definition of available properties.
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS_NON_FATAL
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS
const QgsCoordinateReferenceSystem & crs
QgsDataProvider::ReadFlags flags
QgsDataProvider::ProviderOptions options
Setting options for loading annotation layers.
Setting options for creating vector data providers.
Single variable definition for use within a QgsExpressionContextScope.
Setting options for loading group layers.
Contains information relating to a node (i.e.