79#include <QApplication> 
   84#include <QTemporaryFile> 
   87#include <QStandardPaths> 
   89#include <QRegularExpression> 
  111  QStringList keyTokens = QStringList( scope );
 
  112#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) 
  113  keyTokens += key.split( 
'/', QString::SkipEmptyParts );
 
  115  keyTokens += key.split( 
'/', Qt::SkipEmptyParts );
 
  119  keyTokens.push_front( QStringLiteral( 
"properties" ) );
 
  122  for ( 
int i = 0; i < keyTokens.size(); ++i )
 
  124    const QString keyToken = keyTokens.at( i );
 
  128    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}])" ) );
 
  129    if ( keyToken.contains( sInvalidRegexp ) )
 
  131      const QString errorString = QObject::tr( 
"Entry token invalid : '%1'. The token will not be saved to file." ).arg( keyToken );
 
 
  159  while ( !keySequence.isEmpty() )
 
  163    if ( keySequence.first() == currentProperty->
name() )
 
  166      keySequence.pop_front();
 
  168      if ( 1 == keySequence.count() )
 
  171        return currentProperty->
find( keySequence.front() );
 
  173      else if ( keySequence.isEmpty() )
 
  178        return currentProperty;
 
  180      else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
 
  182        if ( nextProperty->
isKey() )
 
  186        else if ( nextProperty->
isValue() && 1 == keySequence.count() )
 
  192          return currentProperty;
 
 
  230                             const QVariant &value,
 
  231                             bool &propertiesModified )
 
  240  propertiesModified = 
false;
 
  241  while ( ! keySequence.isEmpty() )
 
  245    if ( keySequence.first() == currentProperty->
name() )
 
  248      keySequence.pop_front();
 
  252      if ( 1 == keySequence.count() )
 
  255        if ( !property || property->value() != value )
 
  257          currentProperty->
setValue( keySequence.front(), value );
 
  258          propertiesModified = 
true;
 
  261        return currentProperty;
 
  265      else if ( keySequence.isEmpty() )
 
  267        if ( currentProperty->
value() != value )
 
  270          propertiesModified = 
true;
 
  273        return currentProperty;
 
  275      else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
 
  279        if ( currentProperty )
 
  290        if ( ( newPropertyKey = currentProperty->
addKey( keySequence.first() ) ) )
 
  292          currentProperty = newPropertyKey;
 
 
  324  while ( ! keySequence.isEmpty() )
 
  328    if ( keySequence.first() == currentProperty->
name() )
 
  331      keySequence.pop_front();
 
  335      if ( 1 == keySequence.count() )
 
  337        currentProperty->
removeKey( keySequence.front() );
 
  342      else if ( keySequence.isEmpty() )
 
  344        previousQgsPropertyKey->
removeKey( currentProperty->
name() );
 
  346      else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
 
  348        previousQgsPropertyKey = currentProperty;
 
  351        if ( currentProperty )
 
 
  375  , mCapabilities( capabilities )
 
  378  , mSnappingConfig( this )
 
  396  mProperties.
setName( QStringLiteral( 
"properties" ) );
 
  399  mMainAnnotationLayer->setParent( 
this );
 
  413  this, [ = ]( 
const QStringList & 
layers ) { mProjectScope.reset(); emit layersWillBeRemoved( layers ); } );
 
  415  this, [ = ]( 
const QList<QgsMapLayer *> &
layers ) { mProjectScope.reset(); emit layersWillBeRemoved( layers ); } );
 
  417  this, [ = ]( 
const QString & layer ) { mProjectScope.reset(); emit layerWillBeRemoved( layer ); } );
 
  419  this, [ = ]( 
QgsMapLayer * layer ) { mProjectScope.reset(); emit layerWillBeRemoved( layer ); } );
 
  421  [ = ]( 
const QStringList & 
layers ) { mProjectScope.reset(); emit layersRemoved( layers ); } );
 
  423  [ = ]( 
const QString & layer ) { mProjectScope.reset(); emit layerRemoved( layer ); } );
 
  425  [ = ]() { mProjectScope.reset(); emit removeAll(); } );
 
  427  [ = ]( 
const QList< QgsMapLayer * > &
layers ) { mProjectScope.reset(); emit layersAdded( layers ); } );
 
  429  [ = ]( 
QgsMapLayer * layer ) { mProjectScope.reset(); emit layerWasAdded( layer ); } );
 
  437           [ = ]( 
const QList<QgsMapLayer *> &
layers )
 
  439    for ( const auto &layer : layers )
 
  441      disconnect( layer, &QgsMapLayer::dataSourceChanged, mRelationManager, &QgsRelationManager::updateRelationsStatus );
 
  446           [ = ]( 
const QList<QgsMapLayer *> &layers )
 
  448    for ( const auto &layer : layers )
 
  450      connect( layer, &QgsMapLayer::dataSourceChanged, mRelationManager, &QgsRelationManager::updateRelationsStatus );
 
  459  mStyleSettings->combinedStyleModel()->addDefaultStyle();
 
 
  465  mIsBeingDeleted = 
true;
 
  468  releaseHandlesToProjectArchive();
 
  469  delete mBadLayerHandler;
 
  470  delete mRelationManager;
 
  471  delete mLayerTreeRegistryBridge;
 
  473  if ( 
this == sProject )
 
 
  504  mProjectScope.reset();
 
 
  515  return mMetadata.
title();
 
 
  524  if ( oldEvaluateDefaultValues != newEvaluateDefaultValues )
 
  527    for ( 
auto layerIt = 
layers.constBegin(); layerIt != 
layers.constEnd(); ++layerIt )
 
  529      if ( 
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layerIt.value() ) )
 
  530        if ( vl->dataProvider() )
 
  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();
 
  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() );
 
  674      for ( 
const QgsField &field : fields )
 
  677        if ( field.alias().isEmpty() )
 
  678          fieldName = field.name();
 
  680          fieldName = field.alias();
 
  682        translationContext->
registerTranslation( QStringLiteral( 
"project:layers:%1:fieldaliases" ).arg( vlayer->
id() ), fieldName );
 
  684        if ( field.editorWidgetSetup().type() == QLatin1String( 
"ValueRelation" ) )
 
  686          translationContext->
registerTranslation( QStringLiteral( 
"project:layers:%1:fields:%2:valuerelationvalue" ).arg( vlayer->
id(), field.name() ), field.editorWidgetSetup().config().value( QStringLiteral( 
"Value" ) ).toString() );
 
  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 );
 
 1028  mProjectScope.reset();
 
 1029  mFile.setFileName( QString() );
 
 1032  mSaveUserFull.clear();
 
 1033  mSaveDateTime = QDateTime();
 
 1036  mCachedHomePath.clear();
 
 1038  mFlags = Qgis::ProjectFlags();
 
 1040  mCustomVariables.clear();
 
 1044  if ( !mSettings.
value( QStringLiteral( 
"projects/anonymize_new_projects" ), 
false, 
QgsSettings::Core ).toBool() )
 
 1063  mEmbeddedLayers.clear();
 
 1064  mRelationManager->
clear();
 
 1065  mAnnotationManager->clear();
 
 1066  mLayoutManager->clear();
 
 1067  m3DViewsManager->clear();
 
 1068  mBookmarkManager->
clear();
 
 1069  mSensorManager->
clear();
 
 1070  mViewSettings->
reset();
 
 1071  mTimeSettings->
reset();
 
 1072  mElevationProperties->
reset();
 
 1073  mDisplaySettings->
reset();
 
 1074  mGpsSettings->
reset();
 
 1075  mSnappingConfig.
reset();
 
 1083  mLabelingEngineSettings->clear();
 
 1087  releaseHandlesToProjectArchive();
 
 1093  mStyleSettings->
reset();
 
 1097  if ( !mIsBeingDeleted )
 
 1105  writeEntry( QStringLiteral( 
"PositionPrecision" ), QStringLiteral( 
"/Automatic" ), 
true );
 
 1106  writeEntry( QStringLiteral( 
"PositionPrecision" ), QStringLiteral( 
"/DecimalPlaces" ), 2 );
 
 1108  const bool defaultRelativePaths = mSettings.
value( QStringLiteral( 
"/qgis/defaultProjectPathsRelative" ), 
true ).toBool();
 
 1111  int red = mSettings.
value( QStringLiteral( 
"qgis/default_canvas_color_red" ), 255 ).toInt();
 
 1112  int green = mSettings.
value( QStringLiteral( 
"qgis/default_canvas_color_green" ), 255 ).toInt();
 
 1113  int blue = mSettings.
value( QStringLiteral( 
"qgis/default_canvas_color_blue" ), 255 ).toInt();
 
 1116  red = mSettings.
value( QStringLiteral( 
"qgis/default_selection_color_red" ), 255 ).toInt();
 
 1117  green = mSettings.
value( QStringLiteral( 
"qgis/default_selection_color_green" ), 255 ).toInt();
 
 1118  blue = mSettings.
value( QStringLiteral( 
"qgis/default_selection_color_blue" ), 0 ).toInt();
 
 1119  const int alpha = mSettings.
value( QStringLiteral( 
"qgis/default_selection_color_alpha" ), 255 ).toInt();
 
 1125  mRootGroup->
clear();
 
 1126  if ( mMainAnnotationLayer )
 
 1127    mMainAnnotationLayer->
reset();
 
 1129  snapSingleBlocker.release();
 
 1131  if ( !mBlockSnappingUpdates )
 
 
 1143  topQgsPropertyKey.
dump();
 
 
 1176  const QDomElement propertiesElem = doc.documentElement().firstChildElement( QStringLiteral( 
"properties" ) );
 
 1178  if ( propertiesElem.isNull() )  
 
 1183  const QDomNodeList scopes = propertiesElem.childNodes();
 
 1185  if ( propertiesElem.firstChild().isNull() )
 
 1187    QgsDebugError( QStringLiteral( 
"empty ``properties'' XML tag ... bailing" ) );
 
 1191  if ( ! project_properties.
readXml( propertiesElem ) )
 
 1193    QgsDebugError( QStringLiteral( 
"Project_properties.readXml() failed" ) );
 
 
 1207  const QDomElement ddElem = doc.documentElement().firstChildElement( QStringLiteral( 
"dataDefinedServerProperties" ) );
 
 1208  if ( !ddElem.isNull() )
 
 1210    if ( !ddServerProperties.
readXml( ddElem, dataDefinedServerPropertyDefinitions ) )
 
 1212      QgsDebugError( QStringLiteral( 
"dataDefinedServerProperties.readXml() failed" ) );
 
 1215  return ddServerProperties;
 
 
 1222static void _getTitle( 
const QDomDocument &doc, QString &title )
 
 1224  const QDomElement titleNode = doc.documentElement().firstChildElement( QStringLiteral( 
"title" ) );
 
 1228  if ( titleNode.isNull() )
 
 1234  if ( !titleNode.hasChildNodes() ) 
 
 1240  const QDomNode titleTextNode = titleNode.firstChild();  
 
 1242  if ( !titleTextNode.isText() )
 
 1248  const QDomText titleText = titleTextNode.toText();
 
 1250  title = titleText.data();
 
 1254static void readProjectFileMetadata( 
const QDomDocument &doc, QString &lastUser, QString &lastUserFull, QDateTime &lastSaveDateTime )
 
 1256  const QDomNodeList nl = doc.elementsByTagName( QStringLiteral( 
"qgis" ) );
 
 1260    QgsDebugError( QStringLiteral( 
"unable to find qgis element" ) );
 
 1264  const QDomNode qgisNode = nl.item( 0 ); 
 
 1266  const QDomElement qgisElement = qgisNode.toElement(); 
 
 1267  lastUser = qgisElement.attribute( QStringLiteral( 
"saveUser" ), QString() );
 
 1268  lastUserFull = qgisElement.attribute( QStringLiteral( 
"saveUserFull" ), QString() );
 
 1269  lastSaveDateTime = QDateTime::fromString( qgisElement.attribute( QStringLiteral( 
"saveDateTime" ), QString() ), Qt::ISODate );
 
 1274  const QDomNodeList nl = doc.elementsByTagName( QStringLiteral( 
"qgis" ) );
 
 1278    QgsDebugError( QStringLiteral( 
" unable to find qgis element in project file" ) );
 
 1282  const QDomNode qgisNode = nl.item( 0 );  
 
 1284  const QDomElement qgisElement = qgisNode.toElement(); 
 
 1285  QgsProjectVersion projectVersion( qgisElement.attribute( QStringLiteral( 
"version" ) ) );
 
 1286  return projectVersion;
 
 
 1293  return mSnappingConfig;
 
 
 1312  if ( mAvoidIntersectionsMode == mode )
 
 1315  mAvoidIntersectionsMode = mode;
 
 
 1319static  QgsMapLayer::ReadFlags projectFlagsToLayerReadFlags( Qgis::ProjectReadFlags projectReadFlags, Qgis::ProjectFlags projectFlags )
 
 1321  QgsMapLayer::ReadFlags layerFlags = QgsMapLayer::ReadFlags();
 
 1344void QgsProject::preloadProviders( 
const QVector<QDomNode> ¶llelLayerNodes,
 
 1346                                   QMap<QString, QgsDataProvider *> &loadedProviders,
 
 1347                                   QgsMapLayer::ReadFlags layerReadFlags,
 
 1348                                   int totalProviderCount )
 
 1353  QMap<QString, LayerToLoad> layersToLoad;
 
 1355  for ( 
const QDomNode &node : parallelLayerNodes )
 
 1359    const QDomElement layerElement = node.toElement();
 
 1361    layerToLoad.
layerId = layerElement.namedItem( QStringLiteral( 
"id" ) ).toElement().text();
 
 1362    layerToLoad.
provider = layerElement.namedItem( QStringLiteral( 
"provider" ) ).toElement().text();
 
 1363    layerToLoad.
dataSource = layerElement.namedItem( QStringLiteral( 
"datasource" ) ).toElement().text();
 
 1374    layersToLoad.insert( layerToLoad.
layerId, layerToLoad );
 
 1377  while ( !layersToLoad.isEmpty() )
 
 1379    const QList<LayerToLoad> layersToAttemptInParallel = layersToLoad.values();
 
 1380    QString layerToAttemptInMainThread;
 
 1382    QHash<QString, QgsRunnableProviderCreator *> runnables;
 
 1383    QThreadPool threadPool;
 
 1386    for ( 
const LayerToLoad &lay : layersToAttemptInParallel )
 
 1389      runnables.insert( lay.layerId, run );
 
 1395          layersToLoad.remove( layId );
 
 1398          Q_ASSERT( finishedRun );
 
 1400          std::unique_ptr<QgsDataProvider> provider( finishedRun->
dataProvider() );
 
 1401          Q_ASSERT( provider && provider->isValid() );
 
 1403          loadedProviders.insert( layId, provider.release() );
 
 1408          if ( layerToAttemptInMainThread.isEmpty() )
 
 1409            layerToAttemptInMainThread = layId;
 
 1413        if ( i == parallelLayerNodes.count() || !isValid )
 
 1416      threadPool.start( run );
 
 1420    threadPool.waitForDone(); 
 
 1422    qDeleteAll( runnables );
 
 1425    auto it = layersToLoad.find( layerToAttemptInMainThread );
 
 1426    if ( it != layersToLoad.end() )
 
 1428      std::unique_ptr<QgsDataProvider> provider;
 
 1432        QgsDataProvider::ReadFlags providerFlags = lay.
flags;
 
 1438        if ( provider && provider->isValid() )
 
 1443        layersToLoad.erase( it );
 
 1446      loadedProviders.insert( layerId, provider.release() );
 
 1454void QgsProject::releaseHandlesToProjectArchive()
 
 1459bool QgsProject::_getMapLayers( 
const QDomDocument &doc, QList<QDomNode> &brokenNodes, Qgis::ProjectReadFlags flags )
 
 1466  QDomElement layerElement = doc.documentElement().firstChildElement( QStringLiteral( 
"projectlayers" ) ).firstChildElement( QStringLiteral( 
"maplayer" ) );
 
 1470  if ( layerElement.isNull() )      
 
 1480  bool returnStatus = 
true;
 
 1483  while ( ! layerElement.isNull() )
 
 1486    layerElement = layerElement.nextSiblingElement( QStringLiteral( 
"maplayer" ) );
 
 1492  if ( depSorter.hasCycle() )
 
 1496  if ( depSorter.hasMissingDependency() )
 
 1497    returnStatus = 
false;
 
 1501  const QVector<QDomNode> sortedLayerNodes = depSorter.sortedLayerNodes();
 
 1502  const int totalLayerCount = sortedLayerNodes.count();
 
 1504  QVector<QDomNode> parallelLoading;
 
 1505  QMap<QString, QgsDataProvider *> loadedProviders;
 
 1509    profile.switchTask( tr( 
"Load providers in parallel" ) );
 
 1510    for ( 
const QDomNode &node : sortedLayerNodes )
 
 1512      const QDomElement element = node.toElement();
 
 1513      if ( element.attribute( QStringLiteral( 
"embedded" ) ) != QLatin1String( 
"1" ) )
 
 1515        const QString layerId = node.namedItem( QStringLiteral( 
"id" ) ).toElement().text();
 
 1516        if ( !depSorter.isLayerDependent( layerId ) )
 
 1518          const QDomNode mnl = element.namedItem( QStringLiteral( 
"provider" ) );
 
 1519          const QDomElement mne = mnl.toElement();
 
 1520          const QString provider = mne.text();
 
 1524            parallelLoading.append( node );
 
 1533    if ( !parallelLoading.isEmpty() )
 
 1534      preloadProviders( parallelLoading, context, loadedProviders, projectFlagsToLayerReadFlags( 
flags, mFlags ), sortedLayerNodes.count() );
 
 1537  int i = loadedProviders.count();
 
 1538  for ( 
const QDomNode &node : std::as_const( sortedLayerNodes ) )
 
 1540    const QDomElement element = node.toElement();
 
 1541    const QString name = 
translate( QStringLiteral( 
"project:layers:%1" ).arg( node.namedItem( QStringLiteral( 
"id" ) ).toElement().text() ), node.namedItem( QStringLiteral( 
"layername" ) ).toElement().text() );
 
 1542    if ( !name.isNull() )
 
 1543      emit 
loadingLayer( tr( 
"Loading layer %1" ).arg( name ) );
 
 1545    profile.switchTask( name );
 
 1546    if ( element.attribute( QStringLiteral( 
"embedded" ) ) == QLatin1String( 
"1" ) )
 
 1548      createEmbeddedLayer( element.attribute( QStringLiteral( 
"id" ) ), 
readPath( element.attribute( QStringLiteral( 
"project" ) ) ), brokenNodes, 
true, 
flags );
 
 1556      QString layerId = element.namedItem( QStringLiteral( 
"id" ) ).toElement().text();
 
 1558      if ( !addLayer( element, brokenNodes, context, 
flags, loadedProviders.take( layerId ) ) )
 
 1560        returnStatus = 
false;
 
 1563      if ( !messages.isEmpty() )
 
 1572  return returnStatus;
 
 1575bool QgsProject::addLayer( 
const QDomElement &layerElem,
 
 1576                           QList<QDomNode> &brokenNodes,
 
 1578                           Qgis::ProjectReadFlags flags,
 
 1583  const QString type = layerElem.attribute( QStringLiteral( 
"type" ) );
 
 1585  std::unique_ptr<QgsMapLayer> 
mapLayer;
 
 1593    QgsDebugError( QStringLiteral( 
"Unknown layer type \"%1\"" ).arg( type ) );
 
 1597  switch ( layerType )
 
 1600      mapLayer = std::make_unique<QgsVectorLayer>();
 
 1604      mapLayer = std::make_unique<QgsRasterLayer>();
 
 1608      mapLayer = std::make_unique<QgsMeshLayer>();
 
 1612      mapLayer = std::make_unique<QgsVectorTileLayer>();
 
 1616      mapLayer = std::make_unique<QgsPointCloudLayer>();
 
 1620      mapLayer = std::make_unique<QgsTiledSceneLayer>();
 
 1625      const QString 
typeName = layerElem.attribute( QStringLiteral( 
"name" ) );
 
 1633      mapLayer = std::make_unique<QgsAnnotationLayer>( QString(), options );
 
 1640      mapLayer = std::make_unique<QgsGroupLayer>( QString(), options );
 
 1647    QgsDebugError( QStringLiteral( 
"Unable to create layer" ) );
 
 1655  const QString layerId { layerElem.namedItem( QStringLiteral( 
"id" ) ).toElement().text() };
 
 1656  Q_ASSERT( ! layerId.isEmpty() );
 
 1660  QgsMapLayer::ReadFlags layerFlags = projectFlagsToLayerReadFlags( 
flags, mFlags );
 
 1662  profile.switchTask( tr( 
"Load layer source" ) );
 
 1669    if ( vl->dataProvider() )
 
 1676  profile.switchTask( tr( 
"Add layer to project" ) );
 
 1677  QList<QgsMapLayer *> newLayers;
 
 1689      vLayer->joinBuffer()->resolveReferences( 
this );
 
 1698    brokenNodes.push_back( layerElem );
 
 1701  const bool wasEditable = layerElem.attribute( QStringLiteral( 
"editable" ), QStringLiteral( 
"0" ) ).toInt();
 
 1713  if ( ! layerWasStored )
 
 1718  return layerIsValid;
 
 1725  mFile.setFileName( filename );
 
 1726  mCachedHomePath.clear();
 
 1727  mProjectScope.reset();
 
 
 1736  const QString filename = mFile.fileName();
 
 1741    QTemporaryFile inDevice;
 
 1742    if ( !inDevice.open() )
 
 1744      setError( tr( 
"Unable to open %1" ).arg( inDevice.fileName() ) );
 
 1750    if ( !storage->readProject( filename, &inDevice, context ) )
 
 1752      QString err = tr( 
"Unable to open %1" ).arg( filename );
 
 1753      QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
 
 1754      if ( !messages.isEmpty() )
 
 1755        err += QStringLiteral( 
"\n\n" ) + messages.last().message();
 
 1759    returnValue = unzip( inDevice.fileName(), 
flags );  
 
 1765      returnValue = unzip( mFile.fileName(), 
flags );
 
 1770      const QFileInfo finfo( mFile.fileName() );
 
 1771      const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( QStringLiteral( 
"%1_attachments.zip" ).arg( finfo.completeBaseName() ) );
 
 1772      if ( QFile( attachmentsZip ).exists() )
 
 1774        std::unique_ptr<QgsArchive> archive( 
new QgsArchive() );
 
 1775        if ( archive->unzip( attachmentsZip ) )
 
 1777          releaseHandlesToProjectArchive();
 
 1778          mArchive = std::move( archive );
 
 1781      returnValue = readProjectFile( mFile.fileName(), 
flags );
 
 1787      mFile.setFileName( filename );
 
 1788      mCachedHomePath.clear();
 
 1789      mProjectScope.reset();
 
 1794      mTranslator.reset( 
nullptr );
 
 
 1801bool QgsProject::readProjectFile( 
const QString &filename, Qgis::ProjectReadFlags flags )
 
 1806  ScopedIntIncrementor snapSignalBlock( &mBlockSnappingUpdates );
 
 1808  QFile projectFile( filename );
 
 1816  if ( QFile( QStringLiteral( 
"%1/%2.qm" ).arg( QFileInfo( projectFile.fileName() ).absolutePath(), localeFileName ) ).exists() )
 
 1818    mTranslator.reset( 
new QTranslator() );
 
 1819    ( void )mTranslator->load( localeFileName, QFileInfo( projectFile.fileName() ).absolutePath() );
 
 1822  profile.switchTask( tr( 
"Reading project file" ) );
 
 1823  std::unique_ptr<QDomDocument> doc( 
new QDomDocument( QStringLiteral( 
"qgis" ) ) );
 
 1825  if ( !projectFile.open( QIODevice::ReadOnly | QIODevice::Text ) )
 
 1827    projectFile.close();
 
 1829    setError( tr( 
"Unable to open %1" ).arg( projectFile.fileName() ) );
 
 1838  if ( !doc->setContent( &projectFile, &errorMsg, &line, &column ) )
 
 1840    const QString errorString = tr( 
"Project file read error in file %1: %2 at line %3 column %4" )
 
 1841                                .arg( projectFile.fileName(), errorMsg ).arg( line ).arg( column );
 
 1845    projectFile.close();
 
 1847    setError( errorString );
 
 1852  projectFile.close();
 
 1860  profile.switchTask( tr( 
"Updating project file" ) );
 
 1861  if ( thisVersion > fileVersion )
 
 1863    const bool isOlderMajorVersion = fileVersion.
majorVersion() < thisVersion.majorVersion();
 
 1865    if ( isOlderMajorVersion )
 
 1868                          "version of qgis (saved in " + fileVersion.
text() +
 
 1870                          "). Problems may occur." );
 
 1881    projectFile.updateRevision( thisVersion );
 
 1883  else if ( fileVersion > thisVersion )
 
 1886                        "version of qgis (saved in " + fileVersion.
text() +
 
 1888                        "). Problems may occur." );
 
 1894  profile.switchTask( tr( 
"Creating auxiliary storage" ) );
 
 1895  const QString 
fileName = mFile.fileName();
 
 1900  std::unique_ptr<QgsAuxiliaryStorage> aStorage = std::move( mAuxiliaryStorage );
 
 1901  std::unique_ptr<QgsArchive> archive = std::move( mArchive );
 
 1907  releaseHandlesToProjectArchive();
 
 1909  mAuxiliaryStorage = std::move( aStorage );
 
 1910  mArchive = std::move( archive );
 
 1915  mCachedHomePath.clear();
 
 1916  mProjectScope.reset();
 
 1917  mSaveVersion = fileVersion;
 
 1920  profile.switchTask( tr( 
"Reading properties" ) );
 
 1929  dump_( mProperties );
 
 1934  _getTitle( *doc, oldTitle );
 
 1936  readProjectFileMetadata( *doc, mSaveUser, mSaveUserFull, mSaveDateTime );
 
 1938  const QDomNodeList homePathNl = doc->elementsByTagName( QStringLiteral( 
"homePath" ) );
 
 1939  if ( homePathNl.count() > 0 )
 
 1941    const QDomElement homePathElement = homePathNl.at( 0 ).toElement();
 
 1942    const QString 
homePath = homePathElement.attribute( QStringLiteral( 
"path" ) );
 
 1952                                readNumEntry( QStringLiteral( 
"Gui" ), QStringLiteral( 
"/CanvasColorGreenPart" ), 255 ),
 
 1953                                readNumEntry( QStringLiteral( 
"Gui" ), QStringLiteral( 
"/CanvasColorBluePart" ), 255 ) );
 
 1956                               readNumEntry( QStringLiteral( 
"Gui" ), QStringLiteral( 
"/SelectionColorGreenPart" ), 255 ),
 
 1957                               readNumEntry( QStringLiteral( 
"Gui" ), QStringLiteral( 
"/SelectionColorBluePart" ), 255 ),
 
 1958                               readNumEntry( QStringLiteral( 
"Gui" ), QStringLiteral( 
"/SelectionColorAlphaPart" ), 255 ) );
 
 1962  const QString distanceUnitString = 
readEntry( QStringLiteral( 
"Measurement" ), QStringLiteral( 
"/DistanceUnits" ), QString() );
 
 1963  if ( !distanceUnitString.isEmpty() )
 
 1966  const QString areaUnitString = 
readEntry( QStringLiteral( 
"Measurement" ), QStringLiteral( 
"/AreaUnits" ), QString() );
 
 1967  if ( !areaUnitString.isEmpty() )
 
 1976  if ( 
readNumEntry( QStringLiteral( 
"SpatialRefSys" ), QStringLiteral( 
"/ProjectionsEnabled" ), 0 ) )
 
 1979    const QDomNode srsNode = doc->documentElement().namedItem( QStringLiteral( 
"projectCrs" ) );
 
 1980    if ( !srsNode.isNull() )
 
 1982      projectCrs.
readXml( srsNode );
 
 1987      const QString projCrsString = 
readEntry( QStringLiteral( 
"SpatialRefSys" ), QStringLiteral( 
"/ProjectCRSProj4String" ) );
 
 1988      const long currentCRS = 
readNumEntry( QStringLiteral( 
"SpatialRefSys" ), QStringLiteral( 
"/ProjectCRSID" ), -1 );
 
 1989      const QString authid = 
readEntry( QStringLiteral( 
"SpatialRefSys" ), QStringLiteral( 
"/ProjectCrs" ) );
 
 1992      const bool isUserAuthId = authid.startsWith( QLatin1String( 
"USER:" ), Qt::CaseInsensitive );
 
 1993      if ( !authid.isEmpty() && !isUserAuthId )
 
 1997      if ( !projectCrs.
isValid() && currentCRS >= 0 )
 
 2003      if ( !projCrsString.isEmpty() && ( authid.isEmpty() || isUserAuthId ) && ( !projectCrs.
isValid() || projectCrs.
toProj() != projCrsString ) )
 
 2017  QStringList datumErrors;
 
 2018  if ( !mTransformContext.
readXml( doc->documentElement(), context, datumErrors ) && !datumErrors.empty() )
 
 2025  const QDomNode elevationShadingNode = doc->documentElement().namedItem( QStringLiteral( 
"elevation-shading-renderer" ) );
 
 2026  if ( !elevationShadingNode.isNull() )
 
 2028    mElevationShadingRenderer.
readXml( elevationShadingNode.toElement(), context );
 
 2035  const QStringList variableNames = 
readListEntry( QStringLiteral( 
"Variables" ), QStringLiteral( 
"/variableNames" ) );
 
 2036  const QStringList variableValues = 
readListEntry( QStringLiteral( 
"Variables" ), QStringLiteral( 
"/variableValues" ) );
 
 2038  mCustomVariables.clear();
 
 2039  if ( variableNames.length() == variableValues.length() )
 
 2041    for ( 
int i = 0; i < variableNames.length(); ++i )
 
 2043      mCustomVariables.insert( variableNames.at( i ), variableValues.at( i ) );
 
 2048    QgsMessageLog::logMessage( tr( 
"Project Variables Invalid" ), tr( 
"The project contains invalid variable settings." ) );
 
 2051  QDomElement element = doc->documentElement().firstChildElement( QStringLiteral( 
"projectMetadata" ) );
 
 2053  if ( !element.isNull() )
 
 2062  if ( mMetadata.
title().isEmpty() && !oldTitle.isEmpty() )
 
 2070  element = doc->documentElement().firstChildElement( QStringLiteral( 
"transaction" ) );
 
 2071  if ( !element.isNull() )
 
 2078    element = doc->documentElement().firstChildElement( QStringLiteral( 
"autotransaction" ) );
 
 2079    if ( ! element.isNull() )
 
 2081      mTransactionMode = 
static_cast<Qgis::TransactionMode>( element.attribute( QStringLiteral( 
"active" ), QStringLiteral( 
"0" ) ).toInt() );
 
 2086  profile.switchTask( tr( 
"Loading layer tree" ) );
 
 2089  QDomElement layerTreeElem = doc->documentElement().firstChildElement( QStringLiteral( 
"layer-tree-group" ) );
 
 2090  if ( !layerTreeElem.isNull() )
 
 2102  mLayerTreeRegistryBridge->
setEnabled( 
false );
 
 2105  profile.switchTask( tr( 
"Reading map layers" ) );
 
 2107  loadProjectFlags( doc.get() );
 
 2109  QList<QDomNode> brokenNodes;
 
 2110  const bool clean = _getMapLayers( *doc, brokenNodes, 
flags );
 
 2115    QgsDebugError( QStringLiteral( 
"Unable to get map layers from project file." ) );
 
 2117    if ( !brokenNodes.isEmpty() )
 
 2119      QgsDebugError( 
"there are " + QString::number( brokenNodes.size() ) + 
" broken layers" );
 
 2127  mMainAnnotationLayer->
readLayerXml( doc->documentElement().firstChildElement( QStringLiteral( 
"main-annotation-layer" ) ), context );
 
 2131  profile.switchTask( tr( 
"Loading embedded layers" ) );
 
 2132  loadEmbeddedNodes( mRootGroup, 
flags );
 
 2136  profile.switchTask( tr( 
"Resolving layer references" ) );
 
 2137  QMap<QString, QgsMapLayer *> 
layers = mLayerStore->mapLayers();
 
 2138  for ( QMap<QString, QgsMapLayer *>::iterator it = 
layers.begin(); it != 
layers.end(); ++it )
 
 2140    it.value()->resolveReferences( 
this );
 
 2143  mLayerTreeRegistryBridge->
setEnabled( 
true );
 
 2146  profile.switchTask( tr( 
"Resolving references" ) );
 
 2157  if ( !layerTreeElem.isNull() )
 
 2163  const QDomElement layerTreeCanvasElem = doc->documentElement().firstChildElement( QStringLiteral( 
"layer-tree-canvas" ) );
 
 2164  if ( !layerTreeCanvasElem.isNull( ) )
 
 2172    const QStringList requiredLayerIds = 
readListEntry( QStringLiteral( 
"RequiredLayers" ), QStringLiteral( 
"Layers" ) );
 
 2173    for ( 
const QString &layerId : requiredLayerIds )
 
 2180    const QStringList disabledLayerIds = 
readListEntry( QStringLiteral( 
"Identify" ), QStringLiteral( 
"/disabledLayers" ) );
 
 2181    for ( 
const QString &layerId : disabledLayerIds )
 
 2194    QString styleName = 
readEntry( QStringLiteral( 
"DefaultStyles" ), QStringLiteral( 
"/Marker" ) );
 
 2195    if ( !styleName.isEmpty() )
 
 2200    styleName = 
readEntry( QStringLiteral( 
"DefaultStyles" ), QStringLiteral( 
"/Line" ) );
 
 2201    if ( !styleName.isEmpty() )
 
 2206    styleName = 
readEntry( QStringLiteral( 
"DefaultStyles" ), QStringLiteral( 
"/Fill" ) );
 
 2207    if ( !styleName.isEmpty() )
 
 2212    styleName = 
readEntry( QStringLiteral( 
"DefaultStyles" ), QStringLiteral( 
"/ColorRamp" ) );
 
 2213    if ( !styleName.isEmpty() )
 
 2223    double opacity = 1.0;
 
 2226    double alpha = 
readDoubleEntry( QStringLiteral( 
"DefaultStyles" ), QStringLiteral( 
"/AlphaInt" ), 255, &ok );
 
 2228      opacity = alpha / 255.0;
 
 2229    double newOpacity = 
readDoubleEntry( QStringLiteral( 
"DefaultStyles" ), QStringLiteral( 
"/Opacity" ), 1.0, &ok );
 
 2231      opacity = newOpacity;
 
 2235    removeEntry( QStringLiteral( 
"DefaultStyles" ), QStringLiteral( 
"/Marker" ) );
 
 2236    removeEntry( QStringLiteral( 
"DefaultStyles" ), QStringLiteral( 
"/Line" ) );
 
 2237    removeEntry( QStringLiteral( 
"DefaultStyles" ), QStringLiteral( 
"/Fill" ) );
 
 2238    removeEntry( QStringLiteral( 
"DefaultStyles" ), QStringLiteral( 
"/ColorRamp" ) );
 
 2239    removeEntry( QStringLiteral( 
"DefaultStyles" ), QStringLiteral( 
"/RandomColors" ) );
 
 2240    removeEntry( QStringLiteral( 
"DefaultStyles" ), QStringLiteral( 
"/AlphaInt" ) );
 
 2241    removeEntry( QStringLiteral( 
"DefaultStyles" ), QStringLiteral( 
"/Opacity" ) );
 
 2249    profile.switchTask( tr( 
"Storing original layer properties" ) );
 
 2255  profile.switchTask( tr( 
"Loading map themes" ) );
 
 2258  mMapThemeCollection->readXml( *doc );
 
 2260  profile.switchTask( tr( 
"Loading label settings" ) );
 
 2261  mLabelingEngineSettings->readSettingsFromProject( 
this );
 
 2264  profile.switchTask( tr( 
"Loading annotations" ) );
 
 2265  mAnnotationManager->readXml( doc->documentElement(), context );
 
 2268    profile.switchTask( tr( 
"Loading layouts" ) );
 
 2269    mLayoutManager->readXml( doc->documentElement(), *doc );
 
 2274    profile.switchTask( tr( 
"Loading 3D Views" ) );
 
 2275    m3DViewsManager->readXml( doc->documentElement(), *doc );
 
 2278  profile.switchTask( tr( 
"Loading bookmarks" ) );
 
 2279  mBookmarkManager->
readXml( doc->documentElement(), *doc );
 
 2281  profile.switchTask( tr( 
"Loading sensors" ) );
 
 2282  mSensorManager->
readXml( doc->documentElement(), *doc );
 
 2285  QMap<QString, QgsMapLayer *> existingMaps = 
mapLayers();
 
 2286  for ( QMap<QString, QgsMapLayer *>::iterator it = existingMaps.begin(); it != existingMaps.end(); ++it )
 
 2288    it.value()->setDependencies( it.value()->dependencies() );
 
 2291  profile.switchTask( tr( 
"Loading snapping settings" ) );
 
 2295  profile.switchTask( tr( 
"Loading view settings" ) );
 
 2298  const QStringList scales = 
readListEntry( QStringLiteral( 
"Scales" ), QStringLiteral( 
"/ScalesList" ) );
 
 2299  QVector<double> res;
 
 2300  for ( 
const QString &scale : scales )
 
 2302    const QStringList parts = scale.split( 
':' );
 
 2303    if ( parts.size() != 2 )
 
 2307    const double denominator = QLocale().toDouble( parts[1], &ok );
 
 2314  const QDomElement viewSettingsElement = doc->documentElement().firstChildElement( QStringLiteral( 
"ProjectViewSettings" ) );
 
 2315  if ( !viewSettingsElement.isNull() )
 
 2316    mViewSettings->
readXml( viewSettingsElement, context );
 
 2319  profile.switchTask( tr( 
"Loading style properties" ) );
 
 2320  const QDomElement styleSettingsElement = doc->documentElement().firstChildElement( QStringLiteral( 
"ProjectStyleSettings" ) );
 
 2321  if ( !styleSettingsElement.isNull() )
 
 2324    mStyleSettings->
readXml( styleSettingsElement, context, 
flags );
 
 2328  profile.switchTask( tr( 
"Loading temporal settings" ) );
 
 2329  const QDomElement timeSettingsElement = doc->documentElement().firstChildElement( QStringLiteral( 
"ProjectTimeSettings" ) );
 
 2330  if ( !timeSettingsElement.isNull() )
 
 2331    mTimeSettings->
readXml( timeSettingsElement, context );
 
 2334  profile.switchTask( tr( 
"Loading elevation properties" ) );
 
 2335  const QDomElement elevationPropertiesElement = doc->documentElement().firstChildElement( QStringLiteral( 
"ElevationProperties" ) );
 
 2336  if ( !elevationPropertiesElement.isNull() )
 
 2337    mElevationProperties->
readXml( elevationPropertiesElement, context );
 
 2340  profile.switchTask( tr( 
"Loading display settings" ) );
 
 2342    const QDomElement displaySettingsElement = doc->documentElement().firstChildElement( QStringLiteral( 
"ProjectDisplaySettings" ) );
 
 2343    if ( !displaySettingsElement.isNull() )
 
 2344      mDisplaySettings->
readXml( displaySettingsElement, context );
 
 2347  profile.switchTask( tr( 
"Loading GPS settings" ) );
 
 2349    const QDomElement gpsSettingsElement = doc->documentElement().firstChildElement( QStringLiteral( 
"ProjectGpsSettings" ) );
 
 2350    if ( !gpsSettingsElement.isNull() )
 
 2351      mGpsSettings->
readXml( gpsSettingsElement, context );
 
 2355  profile.switchTask( tr( 
"Updating variables" ) );
 
 2357  profile.switchTask( tr( 
"Updating CRS" ) );
 
 2362  profile.switchTask( tr( 
"Reading external settings" ) );
 
 2366  profile.switchTask( tr( 
"Updating interface" ) );
 
 2368  snapSignalBlock.release();
 
 2369  if ( !mBlockSnappingUpdates )
 
 2380  QgsDebugMsgLevel( QStringLiteral( 
"Project save user: %1" ).arg( mSaveUser ), 2 );
 
 2381  QgsDebugMsgLevel( QStringLiteral( 
"Project save user: %1" ).arg( mSaveUserFull ), 2 );
 
 2390    const QString newFileName( QStringLiteral( 
"%1/%2.qgs" ).arg( QFileInfo( projectFile.fileName() ).absolutePath(), localeFileName ) );
 
 2405  const QMap<QString, QgsMapLayer *> loadedLayers = 
mapLayers();
 
 2406  for ( 
auto it = loadedLayers.constBegin(); it != loadedLayers.constEnd(); ++it )
 
 2408    if ( it.value()->isValid() && it.value()->customProperty( QStringLiteral( 
"_layer_was_editable" ) ).toBool() )
 
 2410      if ( 
QgsVectorLayer *vl = qobject_cast< QgsVectorLayer * >( it.value() ) )
 
 2412      it.value()->removeCustomProperty( QStringLiteral( 
"_layer_was_editable" ) );
 
 2419bool QgsProject::loadEmbeddedNodes( 
QgsLayerTreeGroup *group, Qgis::ProjectReadFlags flags )
 
 2424  const auto constChildren = group->
children();
 
 2430      if ( childGroup->
customProperty( QStringLiteral( 
"embedded" ) ).toInt() )
 
 2433        const QString projectPath = 
readPath( childGroup->
customProperty( QStringLiteral( 
"embedded_project" ) ).toString() );
 
 2434        childGroup->
setCustomProperty( QStringLiteral( 
"embedded_project" ), projectPath );
 
 2438          QList<QgsLayerTreeNode *> clonedChildren;
 
 2439          const QList<QgsLayerTreeNode *> constChildren = newGroup->
children();
 
 2440          clonedChildren.reserve( constChildren.size() );
 
 2442            clonedChildren << newGroupChild->clone();
 
 2450        loadEmbeddedNodes( childGroup, 
flags );
 
 2455      if ( child->customProperty( QStringLiteral( 
"embedded" ) ).toInt() )
 
 2457        QList<QDomNode> brokenNodes;
 
 2460          valid = valid && 
false;
 
 2475  return mCustomVariables;
 
 
 2482  if ( variables == mCustomVariables )
 
 2486  QStringList variableNames;
 
 2487  QStringList variableValues;
 
 2489  QVariantMap::const_iterator it = variables.constBegin();
 
 2490  for ( ; it != variables.constEnd(); ++it )
 
 2492    variableNames << it.key();
 
 2493    variableValues << it.value().toString();
 
 2496  writeEntry( QStringLiteral( 
"Variables" ), QStringLiteral( 
"/variableNames" ), variableNames );
 
 2497  writeEntry( QStringLiteral( 
"Variables" ), QStringLiteral( 
"/variableValues" ), variableValues );
 
 2499  mCustomVariables = variables;
 
 2500  mProjectScope.reset();
 
 
 2509  *mLabelingEngineSettings = settings;
 
 
 2517  return *mLabelingEngineSettings;
 
 
 2524  mProjectScope.reset();
 
 2525  return mLayerStore.get();
 
 
 2532  return mLayerStore.get();
 
 
 2539  QList<QgsVectorLayer *> 
layers;
 
 2540  const QStringList layerIds = 
readListEntry( QStringLiteral( 
"Digitizing" ), QStringLiteral( 
"/AvoidIntersectionsList" ), QStringList() );
 
 2541  const auto constLayerIds = layerIds;
 
 2542  for ( 
const QString &layerId : constLayerIds )
 
 
 2555  list.reserve( 
layers.size() );
 
 2557    list << layer->id();
 
 2558  writeEntry( QStringLiteral( 
"Digitizing" ), QStringLiteral( 
"/AvoidIntersectionsList" ), list );
 
 
 2580  if ( mProjectScope )
 
 2582    std::unique_ptr< QgsExpressionContextScope > projectScope = std::make_unique< QgsExpressionContextScope >( *mProjectScope );
 
 2589    projectScope->addFunction( QStringLiteral( 
"sensor_data" ), 
new GetSensorData( 
sensorManager()->sensorsData() ) );
 
 2591    return projectScope.release();
 
 2594  mProjectScope = std::make_unique< QgsExpressionContextScope >( QObject::tr( 
"Project" ) );
 
 2598  QVariantMap::const_iterator it = vars.constBegin();
 
 2600  for ( ; it != vars.constEnd(); ++it )
 
 2602    mProjectScope->setVariable( it.key(), it.value(), 
true );
 
 2606  if ( projectPath.isEmpty() )
 
 2607    projectPath = mOriginalPath;
 
 2608  const QString projectFolder = QFileInfo( projectPath ).path();
 
 2609  const QString projectFilename = QFileInfo( projectPath ).fileName();
 
 2610  const QString projectBasename = 
baseName();
 
 2639  QVariantMap keywords;
 
 2641  for ( 
auto it = metadataKeywords.constBegin(); it != metadataKeywords.constEnd(); ++it )
 
 2643    keywords.insert( it.key(), it.value() );
 
 2648  QVariantList layersIds;
 
 2650  const QMap<QString, QgsMapLayer *> layersInProject = mLayerStore->mapLayers();
 
 2651  layersIds.reserve( layersInProject.count() );
 
 2652  layers.reserve( layersInProject.count() );
 
 2653  for ( 
auto it = layersInProject.constBegin(); it != layersInProject.constEnd(); ++it )
 
 2655    layersIds << it.value()->id();
 
 2661  mProjectScope->addFunction( QStringLiteral( 
"project_color" ), 
new GetNamedProjectColor( 
this ) );
 
 
 2666void QgsProject::onMapLayersAdded( 
const QList<QgsMapLayer *> &layers )
 
 2670  const QMap<QString, QgsMapLayer *> existingMaps = 
mapLayers();
 
 2672  const auto constLayers = 
layers;
 
 2675    if ( ! layer->isValid() )
 
 2678    if ( 
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer ) )
 
 2681      if ( vlayer->dataProvider() )
 
 2689    for ( QMap<QString, QgsMapLayer *>::const_iterator it = existingMaps.cbegin(); it != existingMaps.cend(); ++it )
 
 2691      const QSet<QgsMapLayerDependency> deps = it.value()->dependencies();
 
 2692      if ( deps.contains( layer->id() ) )
 
 2695        it.value()->setDependencies( deps );
 
 2700  updateTransactionGroups();
 
 2706void QgsProject::onMapLayersRemoved( 
const QList<QgsMapLayer *> &layers )
 
 2714void QgsProject::cleanTransactionGroups( 
bool force )
 
 2718  bool changed = 
false;
 
 2719  for ( QMap< QPair< QString, QString>, 
QgsTransactionGroup *>::Iterator tg = mTransactionGroups.begin(); tg != mTransactionGroups.end(); )
 
 2721    if ( tg.value()->isEmpty() || force )
 
 2724      tg = mTransactionGroups.erase( tg );
 
 2736void QgsProject::updateTransactionGroups()
 
 2740  mEditBufferGroup.
clear();
 
 2742  switch ( mTransactionMode )
 
 2746      cleanTransactionGroups( 
true );
 
 2751      cleanTransactionGroups( 
true );
 
 2754      cleanTransactionGroups( 
false );
 
 2758  bool tgChanged = 
false;
 
 2759  const auto constLayers = 
mapLayers().values();
 
 2762    if ( ! layer->isValid() )
 
 2765    QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
 
 2769    switch ( mTransactionMode )
 
 2786            mTransactionGroups.insert( qMakePair( key, connString ), tg );
 
 2796          mEditBufferGroup.
addLayer( vlayer );
 
 2812  context.setProjectTranslator( 
this );
 
 2814  QList<QDomNode> brokenNodes;
 
 2815  if ( addLayer( layerNode.toElement(), brokenNodes, context ) )
 
 2819    const QVector<QgsVectorLayer *> vectorLayers = layers<QgsVectorLayer *>();
 
 2823      layer->resolveReferences( 
this );
 
 2825      if ( layer->isValid() && layer->customProperty( QStringLiteral( 
"_layer_was_editable" ) ).toBool() )
 
 2827        layer->startEditing();
 
 2828        layer->removeCustomProperty( QStringLiteral( 
"_layer_was_editable" ) );
 
 
 2840  mFile.setFileName( filename );
 
 2841  mCachedHomePath.clear();
 
 
 2849  mProjectScope.reset();
 
 2855    const QString storageFilePath { storage->filePath( mFile.fileName() ) };
 
 2856    if ( storageFilePath.isEmpty() )
 
 2862    const QString tempPath = QStandardPaths::standardLocations( QStandardPaths::TempLocation ).at( 0 );
 
 2863    const QString tmpZipFilename( tempPath + QDir::separator() + QUuid::createUuid().toString() );
 
 2865    if ( !zip( tmpZipFilename ) )
 
 2868    QFile tmpZipFile( tmpZipFilename );
 
 2869    if ( !tmpZipFile.open( QIODevice::ReadOnly ) )
 
 2871      setError( tr( 
"Unable to read file %1" ).arg( tmpZipFilename ) );
 
 2876    if ( !storage->writeProject( mFile.fileName(), &tmpZipFile, context ) )
 
 2878      QString err = tr( 
"Unable to save project to storage %1" ).arg( mFile.fileName() );
 
 2879      QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
 
 2880      if ( !messages.isEmpty() )
 
 2881        err += QStringLiteral( 
"\n\n" ) + messages.last().message();
 
 2887    QFile::remove( tmpZipFilename );
 
 2894    return zip( mFile.fileName() );
 
 2900    const bool asOk = saveAuxiliaryStorage();
 
 2901    const bool writeOk = writeProjectFile( mFile.fileName() );
 
 2902    bool attachmentsOk = 
true;
 
 2903    if ( !mArchive->files().isEmpty() )
 
 2905      const QFileInfo finfo( mFile.fileName() );
 
 2906      const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( QStringLiteral( 
"%1_attachments.zip" ).arg( finfo.completeBaseName() ) );
 
 2907      attachmentsOk = mArchive->zip( attachmentsZip );
 
 2911    if ( ( !asOk || !attachmentsOk ) && writeOk )
 
 2913      QStringList errorMessage;
 
 2916        const QString err = mAuxiliaryStorage->errorString();
 
 2917        errorMessage.append( tr( 
"Unable to save auxiliary storage ('%1')" ).arg( err ) );
 
 2919      if ( !attachmentsOk )
 
 2921        errorMessage.append( tr( 
"Unable to save attachments archive" ) );
 
 2923      setError( errorMessage.join( 
'\n' ) );
 
 2926    return asOk && writeOk && attachmentsOk;
 
 
 2930bool QgsProject::writeProjectFile( 
const QString &filename )
 
 2934  QFile projectFile( filename );
 
 2940  const QFileInfo myFileInfo( projectFile );
 
 2941  if ( myFileInfo.exists() && !myFileInfo.isWritable() )
 
 2943    setError( tr( 
"%1 is not writable. Please adjust permissions (if possible) and try again." )
 
 2944              .arg( projectFile.fileName() ) );
 
 2952  QDomImplementation::setInvalidDataPolicy( QDomImplementation::DropInvalidChars );
 
 2954  const QDomDocumentType documentType =
 
 2955    QDomImplementation().createDocumentType( QStringLiteral( 
"qgis" ), QStringLiteral( 
"http://mrcc.com/qgis.dtd" ),
 
 2956        QStringLiteral( 
"SYSTEM" ) );
 
 2957  std::unique_ptr<QDomDocument> doc( 
new QDomDocument( documentType ) );
 
 2959  QDomElement qgisNode = doc->createElement( QStringLiteral( 
"qgis" ) );
 
 2960  qgisNode.setAttribute( QStringLiteral( 
"projectname" ), 
title() );
 
 2961  qgisNode.setAttribute( QStringLiteral( 
"version" ), 
Qgis::version() );
 
 2963  if ( !mSettings.
value( QStringLiteral( 
"projects/anonymize_saved_projects" ), 
false, 
QgsSettings::Core ).toBool() )
 
 2967    qgisNode.setAttribute( QStringLiteral( 
"saveUser" ), newSaveUser );
 
 2968    qgisNode.setAttribute( QStringLiteral( 
"saveUserFull" ), newSaveUserFull );
 
 2969    mSaveUser = newSaveUser;
 
 2970    mSaveUserFull = newSaveUserFull;
 
 2971    mSaveDateTime = QDateTime::currentDateTime();
 
 2972    qgisNode.setAttribute( QStringLiteral( 
"saveDateTime" ), mSaveDateTime.toString( Qt::ISODate ) );
 
 2977    mSaveUserFull.clear();
 
 2978    mSaveDateTime = QDateTime();
 
 2980  doc->appendChild( qgisNode );
 
 2983  QDomElement homePathNode = doc->createElement( QStringLiteral( 
"homePath" ) );
 
 2984  homePathNode.setAttribute( QStringLiteral( 
"path" ), mHomePath );
 
 2985  qgisNode.appendChild( homePathNode );
 
 2988  QDomElement titleNode = doc->createElement( QStringLiteral( 
"title" ) );
 
 2989  qgisNode.appendChild( titleNode );
 
 2991  QDomElement transactionNode = doc->createElement( QStringLiteral( 
"transaction" ) );
 
 2992  transactionNode.setAttribute( QStringLiteral( 
"mode" ), 
qgsEnumValueToKey( mTransactionMode ) );
 
 2993  qgisNode.appendChild( transactionNode );
 
 2995  QDomElement flagsNode = doc->createElement( QStringLiteral( 
"projectFlags" ) );
 
 2997  qgisNode.appendChild( flagsNode );
 
 2999  const QDomText titleText = doc->createTextNode( 
title() );  
 
 3000  titleNode.appendChild( titleText );
 
 3003  QDomElement srsNode = doc->createElement( QStringLiteral( 
"projectCrs" ) );
 
 3005  qgisNode.appendChild( srsNode );
 
 3007  QDomElement elevationShadingNode = doc->createElement( QStringLiteral( 
"elevation-shading-renderer" ) );
 
 3008  mElevationShadingRenderer.
writeXml( elevationShadingNode, context );
 
 3009  qgisNode.appendChild( elevationShadingNode );
 
 3016  clonedRoot->
writeXml( qgisNode, context );
 
 3020  writeEntry( QStringLiteral( 
"Digitizing" ), QStringLiteral( 
"/AvoidIntersectionsMode" ), 
static_cast<int>( mAvoidIntersectionsMode ) );
 
 3028  QDomElement annotationLayerNode = doc->createElement( QStringLiteral( 
"main-annotation-layer" ) );
 
 3029  mMainAnnotationLayer->
writeLayerXml( annotationLayerNode, *doc, context );
 
 3030  qgisNode.appendChild( annotationLayerNode );
 
 3034  QDomElement projectLayersNode = doc->createElement( QStringLiteral( 
"projectlayers" ) );
 
 3036  QMap<QString, QgsMapLayer *>::ConstIterator li = 
layers.constBegin();
 
 3037  while ( li != 
layers.end() )
 
 3043      const QHash< QString, QPair< QString, bool> >::const_iterator emIt = mEmbeddedLayers.constFind( ml->
id() );
 
 3044      if ( emIt == mEmbeddedLayers.constEnd() )
 
 3046        QDomElement maplayerElem;
 
 3052          maplayerElem = doc->createElement( QStringLiteral( 
"maplayer" ) );
 
 3056            maplayerElem.setAttribute( QStringLiteral( 
"editable" ), QStringLiteral( 
"1" ) );
 
 3060          QDomDocument document;
 
 3063            maplayerElem = document.firstChildElement();
 
 3067            QgsDebugError( QStringLiteral( 
"Could not restore layer properties for layer %1" ).arg( ml->
id() ) );
 
 3073        projectLayersNode.appendChild( maplayerElem );
 
 3079        if ( emIt.value().second )
 
 3081          QDomElement mapLayerElem = doc->createElement( QStringLiteral( 
"maplayer" ) );
 
 3082          mapLayerElem.setAttribute( QStringLiteral( 
"embedded" ), 1 );
 
 3083          mapLayerElem.setAttribute( QStringLiteral( 
"project" ), 
writePath( emIt.value().first ) );
 
 3084          mapLayerElem.setAttribute( QStringLiteral( 
"id" ), ml->
id() );
 
 3085          projectLayersNode.appendChild( mapLayerElem );
 
 3092  qgisNode.appendChild( projectLayersNode );
 
 3094  QDomElement layerOrderNode = doc->createElement( QStringLiteral( 
"layerorder" ) );
 
 3096  for ( 
QgsMapLayer *layer : constCustomLayerOrder )
 
 3098    QDomElement mapLayerElem = doc->createElement( QStringLiteral( 
"layer" ) );
 
 3099    mapLayerElem.setAttribute( QStringLiteral( 
"id" ), layer->id() );
 
 3100    layerOrderNode.appendChild( mapLayerElem );
 
 3102  qgisNode.appendChild( layerOrderNode );
 
 3104  mLabelingEngineSettings->writeSettingsToProject( 
this );
 
 3106  writeEntry( QStringLiteral( 
"Gui" ), QStringLiteral( 
"/CanvasColorRedPart" ), mBackgroundColor.red() );
 
 3107  writeEntry( QStringLiteral( 
"Gui" ), QStringLiteral( 
"/CanvasColorGreenPart" ), mBackgroundColor.green() );
 
 3108  writeEntry( QStringLiteral( 
"Gui" ), QStringLiteral( 
"/CanvasColorBluePart" ), mBackgroundColor.blue() );
 
 3110  writeEntry( QStringLiteral( 
"Gui" ), QStringLiteral( 
"/SelectionColorRedPart" ), mSelectionColor.red() );
 
 3111  writeEntry( QStringLiteral( 
"Gui" ), QStringLiteral( 
"/SelectionColorGreenPart" ), mSelectionColor.green() );
 
 3112  writeEntry( QStringLiteral( 
"Gui" ), QStringLiteral( 
"/SelectionColorBluePart" ), mSelectionColor.blue() );
 
 3113  writeEntry( QStringLiteral( 
"Gui" ), QStringLiteral( 
"/SelectionColorAlphaPart" ), mSelectionColor.alpha() );
 
 3120  dump_( mProperties );
 
 3123  QgsDebugMsgLevel( QStringLiteral( 
"there are %1 property scopes" ).arg( 
static_cast<int>( mProperties.
count() ) ), 2 );
 
 3128    mProperties.
writeXml( QStringLiteral( 
"properties" ), qgisNode, *doc );
 
 3131  QDomElement ddElem = doc->createElement( QStringLiteral( 
"dataDefinedServerProperties" ) );
 
 3132  mDataDefinedServerProperties.
writeXml( ddElem, dataDefinedServerPropertyDefinitions() );
 
 3133  qgisNode.appendChild( ddElem );
 
 3135  mMapThemeCollection->writeXml( *doc );
 
 3137  mTransformContext.
writeXml( qgisNode, context );
 
 3139  QDomElement metadataElem = doc->createElement( QStringLiteral( 
"projectMetadata" ) );
 
 3141  qgisNode.appendChild( metadataElem );
 
 3144    const QDomElement annotationsElem = mAnnotationManager->writeXml( *doc, context );
 
 3145    qgisNode.appendChild( annotationsElem );
 
 3149    const QDomElement layoutElem = mLayoutManager->writeXml( *doc );
 
 3150    qgisNode.appendChild( layoutElem );
 
 3154    const QDomElement views3DElem = m3DViewsManager->writeXml( *doc );
 
 3155    qgisNode.appendChild( views3DElem );
 
 3159    const QDomElement bookmarkElem = mBookmarkManager->
writeXml( *doc );
 
 3160    qgisNode.appendChild( bookmarkElem );
 
 3164    const QDomElement sensorElem = mSensorManager->
writeXml( *doc );
 
 3165    qgisNode.appendChild( sensorElem );
 
 3169    const QDomElement viewSettingsElem = mViewSettings->
writeXml( *doc, context );
 
 3170    qgisNode.appendChild( viewSettingsElem );
 
 3174    const QDomElement styleSettingsElem = mStyleSettings->
writeXml( *doc, context );
 
 3175    qgisNode.appendChild( styleSettingsElem );
 
 3179    const QDomElement timeSettingsElement = mTimeSettings->
writeXml( *doc, context );
 
 3180    qgisNode.appendChild( timeSettingsElement );
 
 3184    const QDomElement elevationPropertiesElement = mElevationProperties->
writeXml( *doc, context );
 
 3185    qgisNode.appendChild( elevationPropertiesElement );
 
 3189    const QDomElement displaySettingsElem = mDisplaySettings->
writeXml( *doc, context );
 
 3190    qgisNode.appendChild( displaySettingsElem );
 
 3194    const QDomElement gpsSettingsElem = mGpsSettings->
writeXml( *doc, context );
 
 3195    qgisNode.appendChild( gpsSettingsElem );
 
 3204    QFile backupFile( QStringLiteral( 
"%1~" ).arg( filename ) );
 
 3206    ok &= backupFile.open( QIODevice::WriteOnly | QIODevice::Truncate );
 
 3207    ok &= projectFile.open( QIODevice::ReadOnly );
 
 3210    while ( ok && !projectFile.atEnd() )
 
 3212      ba = projectFile.read( 10240 );
 
 3213      ok &= backupFile.write( ba ) == ba.size();
 
 3216    projectFile.close();
 
 3221      setError( tr( 
"Unable to create backup file %1" ).arg( backupFile.fileName() ) );
 
 3226    struct utimbuf tb = { 
static_cast<time_t
>( fi.lastRead().toSecsSinceEpoch() ), 
static_cast<time_t
>( fi.lastModified().toSecsSinceEpoch() ) };
 
 3227    utime( backupFile.fileName().toUtf8().constData(), &tb );
 
 3230  if ( !projectFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
 
 3232    projectFile.close();         
 
 3235    setError( tr( 
"Unable to save to file %1" ).arg( projectFile.fileName() ) );
 
 3239  QTemporaryFile tempFile;
 
 3240  bool ok = tempFile.open();
 
 3243    QTextStream projectFileStream( &tempFile );
 
 3244    doc->save( projectFileStream, 2 );  
 
 3245    ok &= projectFileStream.pos() > -1;
 
 3247    ok &= tempFile.seek( 0 );
 
 3250    while ( ok && !tempFile.atEnd() )
 
 3252      ba = tempFile.read( 10240 );
 
 3253      ok &= projectFile.write( ba ) == ba.size();
 
 3256    ok &= projectFile.error() == QFile::NoError;
 
 3258    projectFile.close();
 
 3265    setError( tr( 
"Unable to save to file %1. Your project " 
 3266                  "may be corrupted on disk. Try clearing some space on the volume and " 
 3267                  "check file permissions before pressing save again." )
 
 3268              .arg( projectFile.fileName() ) );
 
 3282  bool propertiesModified;
 
 3283  const bool success = 
addKey_( scope, key, &mProperties, value, propertiesModified );
 
 3285  if ( propertiesModified )
 
 
 3295  bool propertiesModified;
 
 3296  const bool success = 
addKey_( scope, key, &mProperties, value, propertiesModified );
 
 3298  if ( propertiesModified )
 
 
 3308  bool propertiesModified;
 
 3309  const bool success = 
addKey_( scope, key, &mProperties, value, propertiesModified );
 
 3311  if ( propertiesModified )
 
 
 3321  bool propertiesModified;
 
 3322  const bool success = 
addKey_( scope, key, &mProperties, value, propertiesModified );
 
 3324  if ( propertiesModified )
 
 
 3334  bool propertiesModified;
 
 3335  const bool success = 
addKey_( scope, key, &mProperties, value, propertiesModified );
 
 3337  if ( propertiesModified )
 
 
 3345                                       const QStringList &def,
 
 3357    value = 
property->value();
 
 3359    const bool valid = QVariant::StringList == value.type();
 
 3365      return value.toStringList();
 
 
 3388    value = 
property->value();
 
 3390    const bool valid = value.canConvert( QVariant::String );
 
 3395      return value.toString();
 
 
 3414    value = 
property->value();
 
 3417  const bool valid = value.canConvert( QVariant::Int );
 
 3426    return value.toInt();
 
 
 3441    const QVariant value = 
property->value();
 
 3443    const bool valid = value.canConvert( QVariant::Double );
 
 3448      return value.toDouble();
 
 
 3465    const QVariant value = 
property->value();
 
 3467    const bool valid = value.canConvert( QVariant::Bool );
 
 3472      return value.toBool();
 
 
 3484  if ( 
findKey_( scope, key, mProperties ) )
 
 3490  return !
findKey_( scope, key, mProperties );
 
 
 3499  QStringList entries;
 
 3501  if ( foundProperty )
 
 
 3518  QStringList entries;
 
 3520  if ( foundProperty )
 
 
 3535  dump_( mProperties );
 
 
 3555        filePath = storage->filePath( mFile.fileName() );
 
 
 3582void QgsProject::setError( 
const QString &errorMessage )
 
 3586  mErrorMessage = errorMessage;
 
 3593  return mErrorMessage;
 
 
 3596void QgsProject::clearError()
 
 3600  setError( QString() );
 
 3607  delete mBadLayerHandler;
 
 3608  mBadLayerHandler = handler;
 
 
 3615  const QHash< QString, QPair< QString, bool > >::const_iterator it = mEmbeddedLayers.find( 
id );
 
 3616  if ( it == mEmbeddedLayers.constEnd() )
 
 3620  return it.value().first;
 
 
 3624                                      bool saveFlag, Qgis::ProjectReadFlags flags )
 
 3630  static QString sPrevProjectFilePath;
 
 3631  static QDateTime sPrevProjectFileTimestamp;
 
 3632  static QDomDocument sProjectDocument;
 
 3634  QString qgsProjectFile = projectFilePath;
 
 3636  if ( projectFilePath.endsWith( QLatin1String( 
".qgz" ), Qt::CaseInsensitive ) )
 
 3638    archive.
unzip( projectFilePath );
 
 3642  const QDateTime projectFileTimestamp = QFileInfo( projectFilePath ).lastModified();
 
 3644  if ( projectFilePath != sPrevProjectFilePath || projectFileTimestamp != sPrevProjectFileTimestamp )
 
 3646    sPrevProjectFilePath.clear();
 
 3648    QFile projectFile( qgsProjectFile );
 
 3649    if ( !projectFile.open( QIODevice::ReadOnly ) )
 
 3654    if ( !sProjectDocument.setContent( &projectFile ) )
 
 3659    sPrevProjectFilePath = projectFilePath;
 
 3660    sPrevProjectFileTimestamp = projectFileTimestamp;
 
 3664  bool useAbsolutePaths = 
true;
 
 3666  const QDomElement propertiesElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral( 
"properties" ) );
 
 3667  if ( !propertiesElem.isNull() )
 
 3669    const QDomElement absElem = propertiesElem.firstChildElement( QStringLiteral( 
"Paths" ) ).firstChildElement( QStringLiteral( 
"Absolute" ) );
 
 3670    if ( !absElem.isNull() )
 
 3672      useAbsolutePaths = absElem.text().compare( QLatin1String( 
"true" ), Qt::CaseInsensitive ) == 0;
 
 3677  if ( !useAbsolutePaths )
 
 3682  const QDomElement projectLayersElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral( 
"projectlayers" ) );
 
 3683  if ( projectLayersElem.isNull() )
 
 3688  QDomElement mapLayerElem = projectLayersElem.firstChildElement( QStringLiteral( 
"maplayer" ) );
 
 3689  while ( ! mapLayerElem.isNull() )
 
 3692    const QString 
id = mapLayerElem.firstChildElement( QStringLiteral( 
"id" ) ).text();
 
 3693    if ( 
id == layerId )
 
 3696      if ( mapLayerElem.attribute( QStringLiteral( 
"embedded" ) ) == QLatin1String( 
"1" ) )
 
 3701      mEmbeddedLayers.insert( layerId, qMakePair( projectFilePath, saveFlag ) );
 
 3703      if ( addLayer( mapLayerElem, brokenNodes, embeddedContext, 
flags ) )
 
 3709        mEmbeddedLayers.remove( layerId );
 
 3713    mapLayerElem = mapLayerElem.nextSiblingElement( QStringLiteral( 
"maplayer" ) );
 
 
 3723  QString qgsProjectFile = projectFilePath;
 
 3725  if ( projectFilePath.endsWith( QLatin1String( 
".qgz" ), Qt::CaseInsensitive ) )
 
 3727    archive.
unzip( projectFilePath );
 
 3732  QFile projectFile( qgsProjectFile );
 
 3733  if ( !projectFile.open( QIODevice::ReadOnly ) )
 
 3738  QDomDocument projectDocument;
 
 3739  if ( !projectDocument.setContent( &projectFile ) )
 
 3751  QDomElement layerTreeElem = projectDocument.documentElement().firstChildElement( QStringLiteral( 
"layer-tree-group" ) );
 
 3752  if ( !layerTreeElem.isNull() )
 
 3762  if ( !group || group->
customProperty( QStringLiteral( 
"embedded" ) ).toBool() )
 
 3775  newGroup->
setCustomProperty( QStringLiteral( 
"embedded_project" ), projectFilePath );
 
 3778  mLayerTreeRegistryBridge->
setEnabled( 
false );
 
 3779  initializeEmbeddedSubtree( projectFilePath, newGroup, 
flags );
 
 3780  mLayerTreeRegistryBridge->
setEnabled( 
true );
 
 3783  const auto constFindLayerIds = newGroup->
findLayerIds();
 
 3784  for ( 
const QString &layerId : constFindLayerIds )
 
 
 3797void QgsProject::initializeEmbeddedSubtree( 
const QString &projectFilePath, 
QgsLayerTreeGroup *group, Qgis::ProjectReadFlags flags )
 
 3801  const auto constChildren = group->
children();
 
 3805    child->setCustomProperty( QStringLiteral( 
"embedded" ), 1 );
 
 3814      QList<QDomNode> brokenNodes;
 
 3838  writeEntry( QStringLiteral( 
"Digitizing" ), QStringLiteral( 
"/TopologicalEditing" ), ( enabled ? 1 : 0 ) );
 
 
 3846  return readNumEntry( QStringLiteral( 
"Digitizing" ), QStringLiteral( 
"/TopologicalEditing" ), 0 );
 
 
 3853  if ( mDistanceUnits == unit )
 
 3856  mDistanceUnits = unit;
 
 
 3865  if ( mAreaUnits == unit )
 
 
 3878  if ( !mCachedHomePath.isEmpty() )
 
 3879    return mCachedHomePath;
 
 3883  if ( !mHomePath.isEmpty() )
 
 3885    const QFileInfo homeInfo( mHomePath );
 
 3886    if ( !homeInfo.isRelative() )
 
 3888      mCachedHomePath = mHomePath;
 
 3898      const QString storagePath { storage->filePath( 
fileName() ) };
 
 3899      if ( ! storagePath.isEmpty() && QFileInfo::exists( storagePath ) )
 
 3901        mCachedHomePath = QFileInfo( storagePath ).path();
 
 3902        return mCachedHomePath;
 
 3906    mCachedHomePath = pfi.path();
 
 3907    return mCachedHomePath;
 
 3910  if ( !pfi.exists() )
 
 3912    mCachedHomePath = mHomePath;
 
 3916  if ( !mHomePath.isEmpty() )
 
 3919    mCachedHomePath = QDir::cleanPath( pfi.path() + 
'/' + mHomePath );
 
 3923    mCachedHomePath = pfi.canonicalPath();
 
 3925  return mCachedHomePath;
 
 
 3940  return mRelationManager;
 
 
 3947  return mLayoutManager.get();
 
 
 3954  return mLayoutManager.get();
 
 
 3961  return m3DViewsManager.get();
 
 
 3968  return m3DViewsManager.get();
 
 
 3975  return mBookmarkManager;
 
 
 3982  return mBookmarkManager;
 
 
 3989  return mSensorManager;
 
 
 3996  return mSensorManager;
 
 
 4003  return mViewSettings;
 
 
 4010  return mViewSettings;
 
 
 4017  return mStyleSettings;
 
 
 4025  return mStyleSettings;
 
 
 4032  return mTimeSettings;
 
 
 4039  return mTimeSettings;
 
 
 4046  return mElevationProperties;
 
 
 4053  return mElevationProperties;
 
 
 4060  return mDisplaySettings;
 
 
 4067  return mDisplaySettings;
 
 4074  return mGpsSettings;
 
 
 4081  return mGpsSettings;
 
 
 4095  return mMapThemeCollection.get();
 
 4102  return mAnnotationManager.get();
 
 
 4109  return mAnnotationManager.get();
 
 
 4116  const QMap<QString, QgsMapLayer *> &projectLayers = 
mapLayers();
 
 4117  for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
 
 4122    if ( 
layers.contains( it.value() ) )
 
 4123      it.value()->setFlags( it.value()->flags() & 
~QgsMapLayer::Identifiable );
 
 
 4139  for ( 
const QString &layerId : layerIds )
 
 
 4157  for ( QMap<QString, QgsMapLayer *>::const_iterator it = 
layers.constBegin(); it != 
layers.constEnd(); ++it )
 
 
 4191  updateTransactionGroups();
 
 
 4198  return mTransactionMode;
 
 
 4209  const auto constLayers = 
mapLayers().values();
 
 4212    if ( layer->isEditable() )
 
 4214      QgsLogger::warning( tr( 
"Transaction mode can be changed only if all layers are not editable." ) );
 
 4220  updateTransactionGroups();
 
 
 4228  return mTransactionGroups;
 
 
 4241  return mLayerStore->count();
 
 
 4248  return mLayerStore->validCount();
 
 
 4256  return mLayerStore->mapLayer( layerId );
 
 
 4263  return mLayerStore->mapLayersByName( layerName );
 
 
 4270  QList<QgsMapLayer *> 
layers;
 
 4271  const auto constMapLayers { mLayerStore->mapLayers() };
 
 4272  for ( 
const auto &l : constMapLayers )
 
 4274    if ( ! l->shortName().isEmpty() )
 
 4276      if ( l->shortName() == shortName )
 
 4279    else if ( l->name() == shortName )
 
 
 4287bool QgsProject::unzip( 
const QString &filename, Qgis::ProjectReadFlags flags )
 
 4295  if ( !archive->unzip( filename ) )
 
 4297    setError( tr( 
"Unable to unzip file '%1'" ).arg( filename ) );
 
 4302  if ( archive->projectFile().isEmpty() )
 
 4304    setError( tr( 
"Zip archive does not provide a project file" ) );
 
 4309  releaseHandlesToProjectArchive();
 
 4310  mArchive = std::move( archive );
 
 4327    setError( tr( 
"Cannot read unzipped qgs project file" ) + QStringLiteral( 
": " ) + 
error() );
 
 4337bool QgsProject::zip( 
const QString &filename )
 
 4345  const QString 
baseName = QFileInfo( filename ).baseName();
 
 4346  const QString qgsFileName = QStringLiteral( 
"%1.qgs" ).arg( 
baseName );
 
 4347  QFile qgsFile( QDir( archive->dir() ).filePath( qgsFileName ) );
 
 4349  bool writeOk = 
false;
 
 4350  if ( qgsFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
 
 4352    writeOk = writeProjectFile( qgsFile.fileName() );
 
 4359    setError( tr( 
"Unable to write temporary qgs file" ) );
 
 4364  const QFileInfo info( qgsFile );
 
 4366  const QString asFileName = info.path() + QDir::separator() + info.completeBaseName() + asExt;
 
 4368  bool auxiliaryStorageSavedOk = 
true;
 
 4369  if ( ! saveAuxiliaryStorage( asFileName ) )
 
 4371    const QString err = mAuxiliaryStorage->errorString();
 
 4372    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 ) );
 
 4373    auxiliaryStorageSavedOk = 
false;
 
 4376    if ( !mArchive->exists() )
 
 4378      releaseHandlesToProjectArchive();
 
 4380      mArchive->unzip( mFile.fileName() );
 
 4383      const QString auxiliaryStorageFile = 
static_cast<QgsProjectArchive *
>( mArchive.get() )->auxiliaryStorageFile();
 
 4384      if ( ! auxiliaryStorageFile.isEmpty() )
 
 4386        archive->
addFile( auxiliaryStorageFile );
 
 4395    if ( QFile::exists( asFileName ) )
 
 4397      archive->addFile( asFileName );
 
 4402  archive->addFile( qgsFile.fileName() );
 
 4405  const QStringList &
files = mArchive->files();
 
 4406  for ( 
const QString &file : 
files )
 
 4408    if ( !file.endsWith( QLatin1String( 
".qgs" ), Qt::CaseInsensitive ) && !file.endsWith( asExt, Qt::CaseInsensitive ) )
 
 4410      archive->addFile( file );
 
 4416  if ( !archive->zip( filename ) )
 
 4418    setError( tr( 
"Unable to perform zip" ) );
 
 4422  return auxiliaryStorageSavedOk && zipOk;
 
 4433  const QList<QgsMapLayer *> &layers,
 
 4435  bool takeOwnership )
 
 4439  const QList<QgsMapLayer *> myResultList { mLayerStore->addMapLayers( 
layers, takeOwnership ) };
 
 4440  if ( !myResultList.isEmpty() )
 
 4443    for ( 
auto &l : myResultList )
 
 4453  if ( mAuxiliaryStorage )
 
 4468  mProjectScope.reset();
 
 4470  return myResultList;
 
 
 4476                         bool takeOwnership )
 
 4480  QList<QgsMapLayer *> addedLayers;
 
 4481  addedLayers = 
addMapLayers( QList<QgsMapLayer *>() << layer, addToLegend, takeOwnership );
 
 4482  return addedLayers.isEmpty() ? nullptr : addedLayers[0];
 
 
 4485void QgsProject::removeAuxiliaryLayer( 
const QgsMapLayer *ml )
 
 4492  const QgsVectorLayer *vl = qobject_cast<const QgsVectorLayer *>( ml );
 
 4504  for ( 
const auto &layerId : layerIds )
 
 4505    removeAuxiliaryLayer( mLayerStore->mapLayer( layerId ) );
 
 4507  mProjectScope.reset();
 
 4508  mLayerStore->removeMapLayers( layerIds );
 
 
 4515  for ( 
const auto &layer : 
layers )
 
 4516    removeAuxiliaryLayer( layer );
 
 4518  mProjectScope.reset();
 
 4519  mLayerStore->removeMapLayers( 
layers );
 
 
 4526  removeAuxiliaryLayer( mLayerStore->mapLayer( layerId ) );
 
 4527  mProjectScope.reset();
 
 4528  mLayerStore->removeMapLayer( layerId );
 
 
 4535  removeAuxiliaryLayer( layer );
 
 4536  mProjectScope.reset();
 
 4537  mLayerStore->removeMapLayer( layer );
 
 
 4544  mProjectScope.reset();
 
 4545  return mLayerStore->takeMapLayer( layer );
 
 
 4552  return mMainAnnotationLayer;
 
 
 4559  if ( mLayerStore->count() == 0 )
 
 4562  ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
 
 4563  mProjectScope.reset();
 
 4564  mLayerStore->removeAllMapLayers();
 
 4566  snapSingleBlocker.release();
 
 4568  if ( !mBlockSnappingUpdates )
 
 
 4576  const QMap<QString, QgsMapLayer *> 
layers = mLayerStore->mapLayers();
 
 4577  QMap<QString, QgsMapLayer *>::const_iterator it = 
layers.constBegin();
 
 4578  for ( ; it != 
layers.constEnd(); ++it )
 
 4580    it.value()->reload();
 
 
 4589  return validOnly ? mLayerStore->validMapLayers() : mLayerStore->mapLayers();
 
 
 4596  return mTransactionGroups.value( qMakePair( providerKey, connString ) );
 
 
 4603  return &mEditBufferGroup;
 
 
 4614  if ( mSettings.
value( QStringLiteral( 
"/projections/unknownCrsBehavior" ), QStringLiteral( 
"NoAction" ), 
QgsSettings::App ).toString() == QStringLiteral( 
"UseProjectCrs" )
 
 4615       || mSettings.
value( QStringLiteral( 
"/projections/unknownCrsBehavior" ), 0, 
QgsSettings::App ).toString() == QLatin1String( 
"2" ) )
 
 4623    const QString layerDefaultCrs = mSettings.
value( QStringLiteral( 
"/Projections/layerDefaultCrs" ), 
geoEpsgCrsAuthId() ).toString();
 
 
 4644bool QgsProject::saveAuxiliaryStorage( 
const QString &filename )
 
 4650  for ( 
auto it = 
layers.constBegin(); it != 
layers.constEnd(); ++it )
 
 4655    QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() );
 
 4663  if ( !mAuxiliaryStorage->exists( *
this ) && empty )
 
 4667  else if ( !filename.isEmpty() )
 
 4669    return mAuxiliaryStorage->saveAs( filename );
 
 4673    return mAuxiliaryStorage->saveAs( *
this );
 
 4686  return sPropertyDefinitions;
 
 4699  return mAuxiliaryStorage.get();
 
 
 4706  return mAuxiliaryStorage.get();
 
 
 4713  const QDir archiveDir( mArchive->dir() );
 
 4714  QTemporaryFile tmpFile( archiveDir.filePath( 
"XXXXXX_" + nameTemplate ), 
this );
 
 4715  tmpFile.setAutoRemove( 
false );
 
 4717  mArchive->addFile( tmpFile.fileName() );
 
 4718  return tmpFile.fileName();
 
 
 4725  QStringList attachments;
 
 4727  const QStringList files = mArchive->files();
 
 4728  attachments.reserve( files.size() );
 
 4729  for ( 
const QString &file : files )
 
 4731    if ( QFileInfo( file ).baseName() != 
baseName )
 
 4733      attachments.append( file );
 
 
 4743  return mArchive->removeFile( path );
 
 
 4750  return QStringLiteral( 
"attachment:///%1" ).arg( QFileInfo( attachedFile ).
fileName() );
 
 
 4757  if ( identifier.startsWith( QLatin1String( 
"attachment:///" ) ) )
 
 4759    return QDir( mArchive->dir() ).absoluteFilePath( identifier.mid( 14 ) );
 
 
 4780  mProjectScope.reset();
 
 
 4794  for ( QMap<QString, QgsMapLayer *>::const_iterator it = 
layers.constBegin(); it != 
layers.constEnd(); ++it )
 
 
 4808  const QMap<QString, QgsMapLayer *> &projectLayers = 
mapLayers();
 
 4809  for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
 
 4814    if ( 
layers.contains( it.value() ) )
 
 4815      it.value()->setFlags( it.value()->flags() & 
~QgsMapLayer::Removable );
 
 
 4826  QStringList customColors;
 
 4827  QStringList customColorLabels;
 
 4829  QgsNamedColorList::const_iterator colorIt = colors.constBegin();
 
 4830  for ( ; colorIt != colors.constEnd(); ++colorIt )
 
 4833    const QString label = ( *colorIt ).second;
 
 4834    customColors.append( color );
 
 4835    customColorLabels.append( label );
 
 4837  writeEntry( QStringLiteral( 
"Palette" ), QStringLiteral( 
"/Colors" ), customColors );
 
 4838  writeEntry( QStringLiteral( 
"Palette" ), QStringLiteral( 
"/Labels" ), customColorLabels );
 
 4839  mProjectScope.reset();
 
 
 4847  if ( mBackgroundColor == color )
 
 4850  mBackgroundColor = color;
 
 
 4858  return mBackgroundColor;
 
 
 4865  if ( mSelectionColor == color )
 
 4868  mSelectionColor = color;
 
 
 4876  return mSelectionColor;
 
 
 4913  translationContext.setFileName( QStringLiteral( 
"%1/%2.ts" ).arg( 
absolutePath(), 
baseName() ) );
 
 4917  translationContext.writeTsFile( locale );
 
 
 4920QString 
QgsProject::translate( 
const QString &context, 
const QString &sourceText, 
const char *disambiguation, 
int n )
 const 
 4929  QString result = mTranslator->translate( context.toUtf8(), sourceText.toUtf8(), disambiguation, n );
 
 4931  if ( result.isEmpty() )
 
 
 4945    for ( 
auto it = 
layers.constBegin(); it != 
layers.constEnd(); ++it )
 
 4950        if ( !( ( *it )->accept( visitor ) ) )
 
 4959  if ( !mLayoutManager->accept( visitor ) )
 
 4962  if ( !mAnnotationManager->accept( visitor ) )
 
 
 4970  return mElevationShadingRenderer;
 
 
 4973void QgsProject::loadProjectFlags( 
const QDomDocument *doc )
 
 4977  QDomElement element = doc->documentElement().firstChildElement( QStringLiteral( 
"projectFlags" ) );
 
 4978  Qgis::ProjectFlags 
flags;
 
 4979  if ( !element.isNull() )
 
 4986    element = doc->documentElement().firstChildElement( QStringLiteral( 
"evaluateDefaultValues" ) );
 
 4987    if ( !element.isNull() )
 
 4989      if ( element.attribute( QStringLiteral( 
"active" ), QStringLiteral( 
"0" ) ).toInt() == 1 )
 
 4994    element = doc->documentElement().firstChildElement( QStringLiteral( 
"trust" ) );
 
 4995    if ( !element.isNull() )
 
 4997      if ( element.attribute( QStringLiteral( 
"active" ), QStringLiteral( 
"0" ) ).toInt() == 1 )
 
 5006GetNamedProjectColor::GetNamedProjectColor( 
const QgsProject *project )
 
 5013  QStringList colorStrings = project->
readListEntry( QStringLiteral( 
"Palette" ), QStringLiteral( 
"/Colors" ) );
 
 5014  const QStringList colorLabels = project->
readListEntry( QStringLiteral( 
"Palette" ), QStringLiteral( 
"/Labels" ) );
 
 5018  for ( QStringList::iterator it = colorStrings.begin();
 
 5019        it != colorStrings.end(); ++it )
 
 5023    if ( colorLabels.length() > colorIndex )
 
 5025      label = colorLabels.at( colorIndex );
 
 5028    mColors.insert( label.toLower(), color );
 
 5033GetNamedProjectColor::GetNamedProjectColor( 
const QHash<QString, QColor> &colors )
 
 5041  const QString colorName = values.at( 0 ).toString().toLower();
 
 5042  if ( mColors.contains( colorName ) )
 
 5044    return QStringLiteral( 
"%1,%2,%3" ).arg( mColors.value( colorName ).red() ).arg( mColors.value( colorName ).green() ).arg( mColors.value( colorName ).blue() );
 
 5052  return new GetNamedProjectColor( mColors );
 
 5057GetSensorData::GetSensorData( 
const QMap<QString, QgsAbstractSensor::SensorData> &sensorData )
 
 5060                                 QStringLiteral( 
"Sensors" ) )
 
 5061  , mSensorData( sensorData )
 
 5067  const QString sensorName = values.at( 0 ).toString();
 
 5068  const int expiration = values.at( 1 ).toInt();
 
 5069  const qint64 timestamp = QDateTime::currentMSecsSinceEpoch();
 
 5070  if ( mSensorData.contains( sensorName ) )
 
 5072    if ( expiration <= 0 || ( timestamp - mSensorData[sensorName].lastTimestamp.toMSecsSinceEpoch() ) < expiration )
 
 5074      return mSensorData[sensorName].lastValue;
 
 5083  return new GetSensorData( mSensorData );
 
@ DontLoad3DViews
Skip loading 3D views (since QGIS 3.26)
 
@ DontStoreOriginalStyles
Skip the initial XML style storage for layers. Useful for minimising project load times in non-intera...
 
@ ForceReadOnlyLayers
Open layers in a read-only mode. (since QGIS 3.28)
 
@ TrustLayerMetadata
Trust layer metadata. Improves project read time. Do not use it if layers' extent is not fixed during...
 
@ DontLoadLayouts
Don't load print layouts. Improves project read time if layouts are not required, and allows projects...
 
@ DontResolveLayers
Don't resolve layer paths (i.e. don't load any layer content). Dramatically improves project read tim...
 
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.
 
@ SquareMeters
Square meters.
 
@ Critical
Critical/error message.
 
@ Success
Used for reporting a successful operation.
 
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.
 
@ Group
Composite group layer. Added in QGIS 3.24.
 
@ Plugin
Plugin based layer.
 
@ TiledScene
Tiled scene layer. Added in QGIS 3.34.
 
@ Annotation
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
 
@ VectorTile
Vector tile layer. Added in QGIS 3.14.
 
@ Mesh
Mesh layer. Added in QGIS 3.2.
 
@ PointCloud
Point cloud layer. Added in QGIS 3.18.
 
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.
 
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.
 
Qgis::DistanceUnit mapUnits
 
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.
 
@ ParallelThreadLoading
Skip credentials if the provided one are not valid, let the provider be invalid, avoiding to block th...
 
@ 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.
 
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.
 
void aboutToBeCleared()
Emitted when the project is about to be cleared.
 
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...
 
@ WMSOnlineResource
Alias.
 
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.
 
CORE_EXPORT QgsProjectVersion getVersion(QDomDocument const &doc)
Returns the version string found in the given DOM document.
 
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.