87#include <QApplication>
92#include <QRegularExpression>
93#include <QStandardPaths>
95#include <QTemporaryFile>
101#include "moc_qgsproject.cpp"
103using namespace Qt::StringLiterals;
106#include <sys/utime.h>
122QStringList makeKeyTokens_(
const QString &scope,
const QString &key )
124 QStringList keyTokens = QStringList( scope );
125 keyTokens += key.split(
'/', Qt::SkipEmptyParts );
128 keyTokens.push_front( u
"properties"_s );
148 QStringList keySequence = makeKeyTokens_( scope, key );
150 while ( !keySequence.isEmpty() )
154 if ( keySequence.first() == currentProperty->
name() )
157 keySequence.pop_front();
159 if ( 1 == keySequence.count() )
162 return currentProperty->
find( keySequence.front() );
164 else if ( keySequence.isEmpty() )
169 return currentProperty;
171 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
173 if ( nextProperty->
isKey() )
177 else if ( nextProperty->
isValue() && 1 == keySequence.count() )
183 return currentProperty;
219 QStringList keySequence = makeKeyTokens_( scope, key );
226 propertiesModified =
false;
227 while ( !keySequence.isEmpty() )
231 if ( keySequence.first() == currentProperty->
name() )
234 keySequence.pop_front();
238 if ( 1 == keySequence.count() )
241 if ( !property || property->value() != value )
243 currentProperty->
setValue( keySequence.front(), value );
244 propertiesModified =
true;
247 return currentProperty;
251 else if ( keySequence.isEmpty() )
253 if ( currentProperty->
value() != value )
256 propertiesModified =
true;
259 return currentProperty;
261 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
265 if ( currentProperty )
276 if ( ( newPropertyKey = currentProperty->
addKey( keySequence.first() ) ) )
278 currentProperty = newPropertyKey;
306 QStringList keySequence = makeKeyTokens_( scope, key );
308 while ( !keySequence.isEmpty() )
312 if ( keySequence.first() == currentProperty->
name() )
315 keySequence.pop_front();
319 if ( 1 == keySequence.count() )
321 currentProperty->
removeKey( keySequence.front() );
326 else if ( keySequence.isEmpty() )
328 previousQgsPropertyKey->
removeKey( currentProperty->
name() );
330 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
332 previousQgsPropertyKey = currentProperty;
335 if ( currentProperty )
362 , mSnappingConfig( this )
382 mProperties.setName( u
"properties"_s );
385 mMainAnnotationLayer->setParent(
this );
392 mLayerTreeRegistryBridge = std::make_unique<QgsLayerTreeRegistryBridge>( mRootGroup.get(),
this,
this );
399 mProjectScope.reset();
400 emit layersWillBeRemoved( layers );
403 mProjectScope.reset();
404 emit layersWillBeRemoved( layers );
407 mProjectScope.reset();
408 emit layerWillBeRemoved( layer );
411 mProjectScope.reset();
412 emit layerWillBeRemoved( layer );
415 mProjectScope.reset();
416 emit layersRemoved( layers );
419 mProjectScope.reset();
420 emit layerRemoved( layer );
423 mProjectScope.reset();
427 mProjectScope.reset();
428 emit layersAdded( layers );
431 mProjectScope.reset();
432 emit layerWasAdded( layer );
441 for ( const auto &layer : layers )
443 disconnect( layer, &QgsMapLayer::dataSourceChanged, mRelationManager.get(), &QgsRelationManager::updateRelationsStatus );
446 connect( mLayerStore.get(), qOverload<
const QList<QgsMapLayer *> & >( &
QgsMapLayerStore::layersAdded ),
this, [
this](
const QList<QgsMapLayer *> &layers ) {
447 for ( const auto &layer : layers )
449 connect( layer, &QgsMapLayer::dataSourceChanged, mRelationManager.get(), &QgsRelationManager::updateRelationsStatus );
457 mStyleSettings->combinedStyleModel()->addDefaultStyle();
463 mIsBeingDeleted =
true;
466 releaseHandlesToProjectArchive();
468 if (
this == sProject )
495 if (
title == mMetadata.title() )
498 mMetadata.setTitle(
title );
499 mProjectScope.reset();
511 return mMetadata.title();
520 if ( oldEvaluateDefaultValues != newEvaluateDefaultValues )
523 for (
auto layerIt =
layers.constBegin(); layerIt !=
layers.constEnd(); ++layerIt )
525 if (
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layerIt.value() ) )
526 if ( vl->dataProvider() )
533 if ( oldTrustLayerMetadata != newTrustLayerMetadata )
536 for (
auto layerIt =
layers.constBegin(); layerIt !=
layers.constEnd(); ++layerIt )
538 if (
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layerIt.value() ) )
540 vl->setReadExtentFromXml( newTrustLayerMetadata );
545 if ( mFlags !=
flags )
560 newFlags &= ~(
static_cast< int >( flag ) );
575 return mSaveUserFull;
582 return mSaveDateTime;
603 if ( dirty && mDirtyBlockCount > 0 )
609 if ( mDirty == dirty )
620 if ( path == mHomePath )
624 mCachedHomePath.clear();
625 mProjectScope.reset();
636 const QList<QgsAttributeEditorElement *> elements = parent->
children();
644 translationContext->
registerTranslation( u
"project:layers:%1:formcontainers"_s.arg( layerId ), container->
name() );
646 if ( !container->
children().empty() )
657 const QList<QgsLayerTreeLayer *>
layers = mRootGroup->findLayers();
661 translationContext->
registerTranslation( u
"project:layers:%1"_s.arg( layer->layerId() ), layer->name() );
673 for (
const QgsField &field : fields )
678 if ( field.alias().isEmpty() )
679 fieldName = field.name();
681 fieldName = field.alias();
683 translationContext->
registerTranslation( u
"project:layers:%1:fieldaliases"_s.arg( vlayer->
id() ), fieldName );
686 if ( !field.constraints().constraintDescription().isEmpty() )
687 translationContext->
registerTranslation( u
"project:layers:%1:constraintdescriptions"_s.arg( vlayer->
id() ), field.constraints().constraintDescription() );
691 if ( field.editorWidgetSetup().type() ==
"ValueRelation"_L1 )
693 translationContext->
registerTranslation( u
"project:layers:%1:fields:%2:valuerelationvalue"_s.arg( vlayer->
id(), field.name() ), field.editorWidgetSetup().config().value( u
"Value"_s ).toString() );
695 ->
registerTranslation( u
"project:layers:%1:fields:%2:valuerelationdescription"_s.arg( vlayer->
id(), field.name() ), field.editorWidgetSetup().config().value( u
"Description"_s ).toString() );
699 if ( field.editorWidgetSetup().type() ==
"ValueMap"_L1 )
701 if ( field.editorWidgetSetup().config().value( u
"map"_s ).canConvert<QList<QVariant>>() )
703 const QList<QVariant> valueList = field.editorWidgetSetup().config().value( u
"map"_s ).toList();
705 for (
int i = 0, row = 0; i < valueList.count(); i++, row++ )
707 translationContext->
registerTranslation( u
"project:layers:%1:fields:%2:valuemapdescriptions"_s.arg( vlayer->
id(), field.name() ), valueList[i].toMap().constBegin().key() );
719 translationContext->
registerTranslation( u
"project:layers:%1:actiondescriptions"_s.arg( vlayer->
id() ), action.name() );
720 translationContext->
registerTranslation( u
"project:layers:%1:actionshorttitles"_s.arg( vlayer->
id() ), action.shortTitle() );
728 translationContext->
registerTranslation( u
"project:layers:%1:legendsymbollabels"_s.arg( vlayer->
id() ), item.label() );
746 mapLayer->metadata().registerTranslations( translationContext );
751 const QList<QgsLayerTreeGroup *> groupLayers = mRootGroup->findGroups(
true );
758 const QList<QgsRelation> &relations = mRelationManager->relations().values();
765 mMetadata.registerTranslations( translationContext );
772 mDataDefinedServerProperties = properties;
779 return mDataDefinedServerProperties;
786 switch ( mTransactionMode )
797 return mEditBufferGroup.startEditing();
807 switch ( mTransactionMode )
814 commitErrors.append( tr(
"Trying to commit changes without a layer specified. This only works if the transaction mode is buffered" ) );
823 return mEditBufferGroup.commitChanges( commitErrors, stopEditing );
833 switch ( mTransactionMode )
840 rollbackErrors.append( tr(
"Trying to roll back changes without a layer specified. This only works if the transaction mode is buffered" ) );
843 bool success = vectorLayer->
rollBack( stopEditing );
849 return mEditBufferGroup.rollBack( rollbackErrors, stopEditing );
859 if ( name == mFile.fileName() )
862 const QString oldHomePath =
homePath();
864 mFile.setFileName( name );
865 mCachedHomePath.clear();
866 mProjectScope.reset();
870 const QString newHomePath =
homePath();
871 if ( newHomePath != oldHomePath )
882 return mFile.fileName();
889 mOriginalPath = path;
896 return mOriginalPath;
903 return QFileInfo( mFile );
921 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
926 return QFileInfo( mFile.fileName() ).lastModified();
937 if ( mFile.fileName().isEmpty() )
940 return QFileInfo( mFile.fileName() ).absolutePath();
951 if ( mFile.fileName().isEmpty() )
954 return QFileInfo( mFile.fileName() ).absoluteFilePath();
965 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
970 return QFileInfo( mFile.fileName() ).completeBaseName();
978 const bool absolutePaths =
readBoolEntry( u
"Paths"_s, u
"/Absolute"_s,
false );
989 writeEntry( u
"Paths"_s, u
"/Absolute"_s,
true );
992 writeEntry( u
"Paths"_s, u
"/Absolute"_s,
false );
1009 return mCrs3D.isValid() ? mCrs3D : mCrs;
1021 writeEntry( u
"SpatialRefSys"_s, u
"/ProjectionsEnabled"_s,
crs.isValid() ? 1 : 0 );
1022 mProjectScope.reset();
1026 if ( !mMainAnnotationLayer->crs().isValid() || mMainAnnotationLayer->isEmpty() )
1027 mMainAnnotationLayer->setCrs(
crs );
1036 if ( oldCrs3D != mCrs3D )
1040 if ( adjustEllipsoid )
1049 if ( !
crs().isValid() )
1062 mProjectScope.reset();
1072 switch ( mCrs.type() )
1075 QgsDebugError( u
"Project has a vertical CRS set as the horizontal CRS!"_s );
1079 return mCrs.verticalCrs();
1094 return mVerticalCrs;
1101 if (
crs.isValid() )
1104 switch (
crs.type() )
1122 *errorMessage = QObject::tr(
"Specified CRS is a %1 CRS, not a Vertical CRS" ).arg(
qgsEnumValueToKey(
crs.type() ) );
1127 if (
crs != mVerticalCrs )
1132 switch ( mCrs.type() )
1135 if (
crs != oldVerticalCrs )
1138 *errorMessage = QObject::tr(
"Project CRS is a Compound CRS, specified Vertical CRS will be ignored" );
1144 if (
crs != oldVerticalCrs )
1147 *errorMessage = QObject::tr(
"Project CRS is a Geographic 3D CRS, specified Vertical CRS will be ignored" );
1153 if (
crs != oldVerticalCrs )
1156 *errorMessage = QObject::tr(
"Project CRS is a Geocentric CRS, specified Vertical CRS will be ignored" );
1162 if ( mCrs.hasVerticalAxis() &&
crs != oldVerticalCrs )
1165 *errorMessage = QObject::tr(
"Project CRS is a Projected 3D CRS, specified Vertical CRS will be ignored" );
1183 res = rebuildCrs3D( errorMessage );
1184 mProjectScope.reset();
1191 if ( mCrs3D != oldCrs3D )
1202 return mTransformContext;
1209 if ( context == mTransformContext )
1212 mTransformContext = context;
1213 mProjectScope.reset();
1215 mMainAnnotationLayer->setTransformContext( context );
1216 for (
auto &layer : mLayerStore.get()->mapLayers() )
1218 layer->setTransformContext( context );
1227 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
1231 if ( !mIsBeingDeleted )
1240 mProjectScope.reset();
1241 mFile.setFileName( QString() );
1242 mProperties.clearKeys();
1244 mSaveUserFull.clear();
1245 mSaveDateTime = QDateTime();
1248 mCachedHomePath.clear();
1252 mCustomVariables.clear();
1258 if ( !mSettings.value( u
"projects/anonymize_new_projects"_s,
false,
QgsSettings::Core ).toBool() )
1260 mMetadata.setCreationDateTime( QDateTime::currentDateTime() );
1279 mEmbeddedLayers.clear();
1280 mRelationManager->clear();
1281 mAnnotationManager->clear();
1282 mLayoutManager->clear();
1283 mElevationProfileManager->clear();
1284 mSelectiveMaskingSourceSetManager->clear();
1285 m3DViewsManager->clear();
1286 mBookmarkManager->clear();
1287 mSensorManager->clear();
1288 mViewSettings->reset();
1289 mTimeSettings->reset();
1290 mElevationProperties->reset();
1291 mDisplaySettings->reset();
1292 mGpsSettings->reset();
1293 mSnappingConfig.reset();
1298 mMapThemeCollection = std::make_unique< QgsMapThemeCollection >(
this );
1301 mLabelingEngineSettings->clear();
1305 releaseHandlesToProjectArchive();
1307 mAuxiliaryStorage = std::make_unique< QgsAuxiliaryStorage >();
1308 mArchive = std::make_unique< QgsArchive >();
1311 mStyleSettings->reset();
1315 if ( !mIsBeingDeleted )
1323 writeEntry( u
"PositionPrecision"_s, u
"/Automatic"_s,
true );
1324 writeEntry( u
"PositionPrecision"_s, u
"/DecimalPlaces"_s, 2 );
1326 const bool defaultRelativePaths = mSettings.value( u
"/qgis/defaultProjectPathsRelative"_s,
true ).toBool();
1329 int red = mSettings.value( u
"qgis/default_canvas_color_red"_s, 255 ).toInt();
1330 int green = mSettings.value( u
"qgis/default_canvas_color_green"_s, 255 ).toInt();
1331 int blue = mSettings.value( u
"qgis/default_canvas_color_blue"_s, 255 ).toInt();
1334 red = mSettings.value( u
"qgis/default_selection_color_red"_s, 255 ).toInt();
1335 green = mSettings.value( u
"qgis/default_selection_color_green"_s, 255 ).toInt();
1336 blue = mSettings.value( u
"qgis/default_selection_color_blue"_s, 0 ).toInt();
1337 const int alpha = mSettings.value( u
"qgis/default_selection_color_alpha"_s, 255 ).toInt();
1340 mSnappingConfig.clearIndividualLayerSettings();
1343 mRootGroup->clear();
1344 if ( mMainAnnotationLayer )
1345 mMainAnnotationLayer->reset();
1347 snapSingleBlocker.release();
1349 if ( !mBlockSnappingUpdates )
1355 if ( !mBlockChangeSignalsDuringClear )
1367 topQgsPropertyKey.
dump();
1400 const QDomElement propertiesElem = doc.documentElement().firstChildElement( u
"properties"_s );
1402 if ( propertiesElem.isNull() )
1407 const QDomNodeList scopes = propertiesElem.childNodes();
1409 if ( propertiesElem.firstChild().isNull() )
1411 QgsDebugError( u
"empty ``properties'' XML tag ... bailing"_s );
1415 if ( !project_properties.
readXml( propertiesElem ) )
1431 const QDomElement ddElem = doc.documentElement().firstChildElement( u
"dataDefinedServerProperties"_s );
1432 if ( !ddElem.isNull() )
1434 if ( !ddServerProperties.
readXml( ddElem, dataDefinedServerPropertyDefinitions ) )
1436 QgsDebugError( u
"dataDefinedServerProperties.readXml() failed"_s );
1439 return ddServerProperties;
1446static void _getTitle(
const QDomDocument &doc, QString &title )
1448 const QDomElement titleNode = doc.documentElement().firstChildElement( u
"title"_s );
1452 if ( titleNode.isNull() )
1458 if ( !titleNode.hasChildNodes() )
1464 const QDomNode titleTextNode = titleNode.firstChild();
1466 if ( !titleTextNode.isText() )
1472 const QDomText titleText = titleTextNode.toText();
1474 title = titleText.data();
1477static void readProjectFileMetadata(
const QDomDocument &doc, QString &lastUser, QString &lastUserFull, QDateTime &lastSaveDateTime )
1479 const QDomNodeList nl = doc.elementsByTagName( u
"qgis"_s );
1487 const QDomNode qgisNode = nl.item( 0 );
1489 const QDomElement qgisElement = qgisNode.toElement();
1490 lastUser = qgisElement.attribute( u
"saveUser"_s, QString() );
1491 lastUserFull = qgisElement.attribute( u
"saveUserFull"_s, QString() );
1492 lastSaveDateTime = QDateTime::fromString( qgisElement.attribute( u
"saveDateTime"_s, QString() ), Qt::ISODate );
1497 const QDomNodeList nl = doc.elementsByTagName( u
"qgis"_s );
1501 QgsDebugError( u
" unable to find qgis element in project file"_s );
1505 const QDomNode qgisNode = nl.item( 0 );
1507 const QDomElement qgisElement = qgisNode.toElement();
1509 return projectVersion;
1516 return mSnappingConfig;
1535 if ( mAvoidIntersectionsMode == mode )
1538 mAvoidIntersectionsMode = mode;
1572void QgsProject::preloadProviders(
1579 QMap<QString, LayerToLoad> layersToLoad;
1581 for (
const QDomNode &node : parallelLayerNodes )
1585 const QDomElement layerElement = node.toElement();
1587 layerToLoad.
layerId = layerElement.namedItem( u
"id"_s ).toElement().text();
1588 layerToLoad.
provider = layerElement.namedItem( u
"provider"_s ).toElement().text();
1589 layerToLoad.
dataSource = layerElement.namedItem( u
"datasource"_s ).toElement().text();
1600 layersToLoad.insert( layerToLoad.
layerId, layerToLoad );
1603 while ( !layersToLoad.isEmpty() )
1605 const QList<LayerToLoad> layersToAttemptInParallel = layersToLoad.values();
1606 QString layerToAttemptInMainThread;
1608 QHash<QString, QgsRunnableProviderCreator *> runnables;
1609 QThreadPool threadPool;
1612 for (
const LayerToLoad &lay : layersToAttemptInParallel )
1614 QgsRunnableProviderCreator *run =
new QgsRunnableProviderCreator( lay.layerId, lay.provider, lay.dataSource, lay.options, lay.flags );
1615 runnables.insert( lay.layerId, run );
1620 layersToLoad.remove( layId );
1622 QgsRunnableProviderCreator *finishedRun = runnables.value( layId,
nullptr );
1623 Q_ASSERT( finishedRun );
1625 std::unique_ptr<QgsDataProvider> provider( finishedRun->
dataProvider() );
1626 Q_ASSERT( provider && provider->isValid() );
1628 loadedProviders.insert( layId, provider.release() );
1633 if ( layerToAttemptInMainThread.isEmpty() )
1634 layerToAttemptInMainThread = layId;
1638 if ( i == parallelLayerNodes.count() || !isValid )
1641 threadPool.start( run );
1645 threadPool.waitForDone();
1647 qDeleteAll( runnables );
1650 auto it = layersToLoad.find( layerToAttemptInMainThread );
1651 if ( it != layersToLoad.end() )
1653 std::unique_ptr<QgsDataProvider> provider;
1656 const LayerToLoad &lay = it.value();
1660 QgsScopedRuntimeProfile profile(
"Create data providers/" + lay.
layerId, u
"projectload"_s );
1663 if ( provider && provider->isValid() )
1668 layersToLoad.erase( it );
1671 loadedProviders.insert( layerId, provider.release() );
1678void QgsProject::releaseHandlesToProjectArchive()
1680 mStyleSettings->removeProjectStyle();
1683bool QgsProject::rebuildCrs3D( QString *error )
1686 if ( !mCrs.isValid() )
1688 mCrs3D = QgsCoordinateReferenceSystem();
1690 else if ( !mVerticalCrs.isValid() )
1696 switch ( mCrs.type() )
1708 res = mCrs3D.isValid();
1714 mCrs3D = QgsCoordinateReferenceSystem();
1729 res = mCrs3D.isValid();
1737bool QgsProject::_getMapLayers(
const QDomDocument &doc, QList<QDomNode> &brokenNodes,
Qgis::ProjectReadFlags flags )
1744 QDomElement layerElement = doc.documentElement().firstChildElement( u
"projectlayers"_s ).firstChildElement( u
"maplayer"_s );
1748 if ( layerElement.isNull() )
1758 bool returnStatus =
true;
1761 while ( !layerElement.isNull() )
1764 layerElement = layerElement.nextSiblingElement( u
"maplayer"_s );
1768 QgsScopedRuntimeProfile profile( tr(
"Sorting layers" ), u
"projectload"_s );
1769 const QgsLayerDefinition::DependencySorter depSorter( doc );
1770 if ( depSorter.hasCycle() )
1774 if ( depSorter.hasMissingDependency() )
1775 returnStatus =
false;
1779 const QVector<QDomNode> sortedLayerNodes = depSorter.sortedLayerNodes();
1780 const int totalLayerCount = sortedLayerNodes.count();
1782 QVector<QDomNode> parallelLoading;
1783 QMap<QString, QgsDataProvider *> loadedProviders;
1787 profile.switchTask( tr(
"Load providers in parallel" ) );
1788 for (
const QDomNode &node : sortedLayerNodes )
1790 const QDomElement element = node.toElement();
1791 if ( element.attribute( u
"embedded"_s ) !=
"1"_L1 )
1793 const QString layerId = node.namedItem( u
"id"_s ).toElement().text();
1794 if ( !depSorter.isLayerDependent( layerId ) )
1796 const QDomNode mnl = element.namedItem( u
"provider"_s );
1797 const QDomElement mne = mnl.toElement();
1798 const QString provider = mne.text();
1802 parallelLoading.append( node );
1809 QgsReadWriteContext context;
1811 if ( !parallelLoading.isEmpty() )
1812 preloadProviders( parallelLoading, context, loadedProviders, projectFlagsToLayerReadFlags(
flags, mFlags ), sortedLayerNodes.count() );
1815 int i = loadedProviders.count();
1816 for (
const QDomNode &node : std::as_const( sortedLayerNodes ) )
1818 const QDomElement element = node.toElement();
1819 const QString name =
translate( u
"project:layers:%1"_s.arg( node.namedItem( u
"id"_s ).toElement().text() ), node.namedItem( u
"layername"_s ).toElement().text() );
1820 if ( !name.isNull() )
1821 emit
loadingLayer( tr(
"Loading layer %1" ).arg( name ) );
1823 profile.switchTask( name );
1824 if ( element.attribute( u
"embedded"_s ) ==
"1"_L1 )
1830 QgsReadWriteContext context;
1834 QString layerId = element.namedItem( u
"id"_s ).toElement().text();
1836 if ( !addLayer( element, brokenNodes, context,
flags, loadedProviders.take( layerId ) ) )
1838 returnStatus =
false;
1841 if ( !messages.isEmpty() )
1850 return returnStatus;
1857 const QString type = layerElem.attribute( u
"type"_s );
1859 std::unique_ptr<QgsMapLayer>
mapLayer;
1861 QgsScopedRuntimeProfile profile( tr(
"Create layer" ), u
"projectload"_s );
1867 QgsDebugError( u
"Unknown layer type \"%1\""_s.arg( type ) );
1871 switch ( layerType )
1874 mapLayer = std::make_unique<QgsVectorLayer>();
1878 mapLayer = std::make_unique<QgsRasterLayer>();
1882 mapLayer = std::make_unique<QgsMeshLayer>();
1886 mapLayer = std::make_unique<QgsVectorTileLayer>();
1890 mapLayer = std::make_unique<QgsPointCloudLayer>();
1894 mapLayer = std::make_unique<QgsTiledSceneLayer>();
1899 const QString typeName = layerElem.attribute( u
"name"_s );
1906 const QgsAnnotationLayer::LayerOptions options( mTransformContext );
1907 mapLayer = std::make_unique<QgsAnnotationLayer>( QString(), options );
1913 const QgsGroupLayer::LayerOptions options( mTransformContext );
1914 mapLayer = std::make_unique<QgsGroupLayer>( QString(), options );
1929 const QString layerId { layerElem.namedItem( u
"id"_s ).toElement().text() };
1930 Q_ASSERT( !layerId.isEmpty() );
1936 profile.switchTask( tr(
"Load layer source" ) );
1937 const bool layerIsValid =
mapLayer->readLayerXml( layerElem, context, layerFlags, provider ) &&
mapLayer->isValid();
1940 if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>(
mapLayer.get() ) )
1943 if ( vl->dataProvider() )
1950 profile.switchTask( tr(
"Add layer to project" ) );
1951 QList<QgsMapLayer *> newLayers;
1961 if ( QgsVectorLayer *vLayer = qobject_cast<QgsVectorLayer *>(
mapLayer.get() ) )
1963 vLayer->joinBuffer()->resolveReferences(
this );
1972 brokenNodes.push_back( layerElem );
1975 const bool wasEditable = layerElem.attribute( u
"editable"_s, u
"0"_s ).toInt();
1978 mapLayer->setCustomProperty( u
"_layer_was_editable"_s,
true );
1982 mapLayer->removeCustomProperty( u
"_layer_was_editable"_s );
1987 if ( !layerWasStored )
1992 return layerIsValid;
1999 mFile.setFileName( filename );
2000 mCachedHomePath.clear();
2001 mProjectScope.reset();
2010 const QString filename = mFile.fileName();
2015 QTemporaryFile inDevice;
2016 if ( !inDevice.open() )
2018 setError( tr(
"Unable to open %1" ).arg( inDevice.fileName() ) );
2024 if ( !storage->readProject( filename, &inDevice, context ) )
2026 QString err = tr(
"Unable to open %1" ).arg( filename );
2027 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
2028 if ( !messages.isEmpty() )
2029 err += u
"\n\n"_s + messages.last().message();
2033 returnValue = unzip( inDevice.fileName(),
flags );
2039 returnValue = unzip( mFile.fileName(),
flags );
2043 mAuxiliaryStorage = std::make_unique< QgsAuxiliaryStorage >( *
this );
2044 const QFileInfo finfo( mFile.fileName() );
2045 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( u
"%1_attachments.zip"_s.arg( finfo.completeBaseName() ) );
2046 if ( QFile( attachmentsZip ).exists() )
2048 auto archive = std::make_unique<QgsArchive>();
2049 if ( archive->unzip( attachmentsZip ) )
2051 releaseHandlesToProjectArchive();
2052 mArchive = std::move( archive );
2055 returnValue = readProjectFile( mFile.fileName(),
flags );
2061 mFile.setFileName( filename );
2062 mCachedHomePath.clear();
2063 mProjectScope.reset();
2068 mTranslator.reset(
nullptr );
2081 ScopedIntIncrementor snapSignalBlock( &mBlockSnappingUpdates );
2083 QFile projectFile( filename );
2091 if ( QFile( u
"%1/%2.qm"_s.arg( QFileInfo( mFile ).
absolutePath(), localeFileName ) ).exists() )
2093 mTranslator = std::make_unique< QTranslator >();
2094 ( void ) mTranslator->load( localeFileName, QFileInfo( mFile ).
absolutePath() );
2097 profile.switchTask( tr(
"Reading project file" ) );
2098 auto doc = std::make_unique<QDomDocument>( u
"qgis"_s );
2100 if ( !projectFile.open( QIODevice::ReadOnly | QIODevice::Text ) )
2102 projectFile.close();
2104 setError( tr(
"Unable to open %1" ).arg( projectFile.fileName() ) );
2109 QTextStream textStream( &projectFile );
2110 QString projectString = textStream.readAll();
2111 projectFile.close();
2113 for (
int i = 0; i < 32; i++ )
2115 if ( i == 9 || i == 10 || i == 13 )
2119 projectString.replace( QChar( i ), u
"%1%2%1"_s.arg(
FONTMARKER_CHR_FIX, QString::number( i ) ) );
2125 if ( !doc->setContent( projectString, &errorMsg, &line, &column ) )
2127 const QString errorString = tr(
"Project file read error in file %1: %2 at line %3 column %4" ).arg( projectFile.fileName(), errorMsg ).arg( line ).arg( column );
2129 setError( errorString );
2134 projectFile.close();
2139 const QgsProjectVersion fileVersion =
getVersion( *doc );
2142 profile.switchTask( tr(
"Updating project file" ) );
2143 if ( thisVersion > fileVersion )
2145 const bool isOlderMajorVersion = fileVersion.
majorVersion() < thisVersion.majorVersion();
2147 if ( isOlderMajorVersion )
2150 "Loading a file that was saved with an older "
2151 "version of qgis (saved in "
2152 + fileVersion.
text()
2155 +
"). Problems may occur."
2159 QgsProjectFileTransform projectFile( *doc, fileVersion );
2167 projectFile.updateRevision( thisVersion );
2169 else if ( fileVersion > thisVersion )
2172 "Loading a file that was saved with a newer "
2173 "version of qgis (saved in "
2174 + fileVersion.
text()
2177 +
"). Problems may occur."
2184 profile.switchTask( tr(
"Creating auxiliary storage" ) );
2185 const QString
fileName = mFile.fileName();
2187 const QgsCoordinateReferenceSystem oldVerticalCrs =
verticalCrs();
2188 const QgsCoordinateReferenceSystem oldCrs3D = mCrs3D;
2192 std::unique_ptr<QgsAuxiliaryStorage> aStorage = std::move( mAuxiliaryStorage );
2193 std::unique_ptr<QgsArchive> archive = std::move( mArchive );
2197 mBlockChangeSignalsDuringClear =
true;
2199 mBlockChangeSignalsDuringClear =
false;
2204 releaseHandlesToProjectArchive();
2206 mAuxiliaryStorage = std::move( aStorage );
2207 mArchive = std::move( archive );
2210 mCachedHomePath.clear();
2211 mProjectScope.reset();
2212 mSaveVersion = fileVersion;
2215 profile.switchTask( tr(
"Reading properties" ) );
2221 QgsDebugMsgLevel( QString::number( mProperties.count() ) +
" properties read", 2 );
2224 dump_( mProperties );
2229 _getTitle( *doc, oldTitle );
2231 readProjectFileMetadata( *doc, mSaveUser, mSaveUserFull, mSaveDateTime );
2233 const QDomNodeList homePathNl = doc->elementsByTagName( u
"homePath"_s );
2234 if ( homePathNl.count() > 0 )
2236 const QDomElement homePathElement = homePathNl.at( 0 ).toElement();
2237 const QString
homePath = homePathElement.attribute( u
"path"_s );
2249 selectionColor(
readNumEntry( u
"Gui"_s, u
"/SelectionColorRedPart"_s, 255 ),
readNumEntry( u
"Gui"_s, u
"/SelectionColorGreenPart"_s, 255 ),
readNumEntry( u
"Gui"_s, u
"/SelectionColorBluePart"_s, 255 ),
readNumEntry( u
"Gui"_s, u
"/SelectionColorAlphaPart"_s, 255 ) );
2253 const QString distanceUnitString =
readEntry( u
"Measurement"_s, u
"/DistanceUnits"_s, QString() );
2254 if ( !distanceUnitString.isEmpty() )
2257 const QString areaUnitString =
readEntry( u
"Measurement"_s, u
"/AreaUnits"_s, QString() );
2258 if ( !areaUnitString.isEmpty() )
2263 QgsReadWriteContext context;
2268 QgsCoordinateReferenceSystem projectCrs;
2269 if (
readNumEntry( u
"SpatialRefSys"_s, u
"/ProjectionsEnabled"_s, 0 ) )
2272 const QDomNode srsNode = doc->documentElement().namedItem( u
"projectCrs"_s );
2273 if ( !srsNode.isNull() )
2275 projectCrs.
readXml( srsNode );
2280 const QString projCrsString =
readEntry( u
"SpatialRefSys"_s, u
"/ProjectCRSProj4String"_s );
2281 const long currentCRS =
readNumEntry( u
"SpatialRefSys"_s, u
"/ProjectCRSID"_s, -1 );
2282 const QString authid =
readEntry( u
"SpatialRefSys"_s, u
"/ProjectCrs"_s );
2285 const bool isUserAuthId = authid.startsWith(
"USER:"_L1, Qt::CaseInsensitive );
2286 if ( !authid.isEmpty() && !isUserAuthId )
2287 projectCrs = QgsCoordinateReferenceSystem( authid );
2290 if ( !projectCrs.
isValid() && currentCRS >= 0 )
2296 if ( !projCrsString.isEmpty() && ( authid.isEmpty() || isUserAuthId ) && ( !projectCrs.
isValid() || projectCrs.
toProj() != projCrsString ) )
2313 const QDomNode verticalCrsNode = doc->documentElement().namedItem( u
"verticalCrs"_s );
2314 if ( !verticalCrsNode.isNull() )
2322 QStringList datumErrors;
2323 if ( !mTransformContext.readXml( doc->documentElement(), context, datumErrors ) && !datumErrors.empty() )
2330 const QDomNode elevationShadingNode = doc->documentElement().namedItem( u
"elevation-shading-renderer"_s );
2331 if ( !elevationShadingNode.isNull() )
2333 mElevationShadingRenderer.readXml( elevationShadingNode.toElement(), context );
2340 const QStringList variableNames =
readListEntry( u
"Variables"_s, u
"/variableNames"_s );
2341 const QStringList variableValues =
readListEntry( u
"Variables"_s, u
"/variableValues"_s );
2343 mCustomVariables.clear();
2344 if ( variableNames.length() == variableValues.length() )
2346 for (
int i = 0; i < variableNames.length(); ++i )
2348 mCustomVariables.insert( variableNames.at( i ), variableValues.at( i ) );
2353 QgsMessageLog::logMessage( tr(
"Project Variables Invalid" ), tr(
"The project contains invalid variable settings." ) );
2361 QDomElement element = doc->documentElement().firstChildElement( u
"projectMetadata"_s );
2363 if ( !element.isNull() )
2365 mMetadata.readMetadataXml( element, context );
2370 mMetadata = QgsProjectMetadata();
2372 if ( mMetadata.title().isEmpty() && !oldTitle.isEmpty() )
2375 mMetadata.setTitle( oldTitle );
2381 element = doc->documentElement().firstChildElement( u
"transaction"_s );
2382 if ( !element.isNull() )
2389 element = doc->documentElement().firstChildElement( u
"autotransaction"_s );
2390 if ( !element.isNull() )
2392 mTransactionMode =
static_cast<Qgis::TransactionMode>( element.attribute( u
"active"_s, u
"0"_s ).toInt() );
2397 profile.switchTask( tr(
"Loading layer tree" ) );
2398 mRootGroup->setCustomProperty( u
"loading"_s, 1 );
2400 QDomElement layerTreeElem = doc->documentElement().firstChildElement( u
"layer-tree-group"_s );
2401 if ( !layerTreeElem.isNull() )
2404 QgsLayerTree tempTree;
2413 mLayerTreeRegistryBridge->setEnabled(
false );
2416 profile.switchTask( tr(
"Reading map layers" ) );
2418 loadProjectFlags( doc.get() );
2420 QList<QDomNode> brokenNodes;
2421 const bool clean = _getMapLayers( *doc, brokenNodes,
flags );
2426 QgsDebugError( u
"Unable to get map layers from project file."_s );
2428 if ( !brokenNodes.isEmpty() )
2430 QgsDebugError(
"there are " + QString::number( brokenNodes.size() ) +
" broken layers" );
2435 mBadLayerHandler->handleBadLayers( brokenNodes );
2438 mMainAnnotationLayer->readLayerXml( doc->documentElement().firstChildElement( u
"main-annotation-layer"_s ), context );
2439 mMainAnnotationLayer->setTransformContext( mTransformContext );
2442 profile.switchTask( tr(
"Loading embedded layers" ) );
2443 loadEmbeddedNodes( mRootGroup.get(),
flags );
2447 profile.switchTask( tr(
"Resolving layer references" ) );
2448 QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
2449 for ( QMap<QString, QgsMapLayer *>::iterator it =
layers.begin(); it !=
layers.end(); ++it )
2451 it.value()->resolveReferences(
this );
2453 mMainAnnotationLayer->resolveReferences(
this );
2455 mLayerTreeRegistryBridge->setEnabled(
true );
2458 profile.switchTask( tr(
"Resolving references" ) );
2459 mRootGroup->resolveReferences(
this );
2462 if ( QgsProjectVersion( 3, 28, 0 ) > mSaveVersion )
2469 if ( !layerTreeElem.isNull() )
2471 mRootGroup->readLayerOrderFromXml( layerTreeElem );
2475 const QDomElement layerTreeCanvasElem = doc->documentElement().firstChildElement( u
"layer-tree-canvas"_s );
2476 if ( !layerTreeCanvasElem.isNull() )
2478 mRootGroup->readLayerOrderFromXml( layerTreeCanvasElem );
2482 if ( QgsProjectVersion( 3, 4, 0 ) > mSaveVersion )
2484 const QStringList requiredLayerIds =
readListEntry( u
"RequiredLayers"_s, u
"Layers"_s );
2485 for (
const QString &layerId : requiredLayerIds )
2487 if ( QgsMapLayer *layer =
mapLayer( layerId ) )
2492 const QStringList disabledLayerIds =
readListEntry( u
"Identify"_s, u
"/disabledLayers"_s );
2493 for (
const QString &layerId : disabledLayerIds )
2495 if ( QgsMapLayer *layer =
mapLayer( layerId ) )
2503 if ( QgsProjectVersion( 3, 26, 0 ) > mSaveVersion )
2506 QString styleName =
readEntry( u
"DefaultStyles"_s, u
"/Marker"_s );
2507 if ( !styleName.isEmpty() )
2512 styleName =
readEntry( u
"DefaultStyles"_s, u
"/Line"_s );
2513 if ( !styleName.isEmpty() )
2518 styleName =
readEntry( u
"DefaultStyles"_s, u
"/Fill"_s );
2519 if ( !styleName.isEmpty() )
2524 styleName =
readEntry( u
"DefaultStyles"_s, u
"/ColorRamp"_s );
2525 if ( !styleName.isEmpty() )
2535 double opacity = 1.0;
2538 double alpha =
readDoubleEntry( u
"DefaultStyles"_s, u
"/AlphaInt"_s, 255, &ok );
2540 opacity = alpha / 255.0;
2541 double newOpacity =
readDoubleEntry( u
"DefaultStyles"_s, u
"/Opacity"_s, 1.0, &ok );
2543 opacity = newOpacity;
2550 removeEntry( u
"DefaultStyles"_s, u
"/ColorRamp"_s );
2551 removeEntry( u
"DefaultStyles"_s, u
"/RandomColors"_s );
2552 removeEntry( u
"DefaultStyles"_s, u
"/AlphaInt"_s );
2561 profile.switchTask( tr(
"Storing original layer properties" ) );
2565 mRootGroup->removeCustomProperty( u
"loading"_s );
2567 profile.switchTask( tr(
"Loading map themes" ) );
2568 mMapThemeCollection = std::make_unique< QgsMapThemeCollection >(
this );
2570 mMapThemeCollection->readXml( *doc );
2572 profile.switchTask( tr(
"Loading label settings" ) );
2573 mLabelingEngineSettings->readSettingsFromProject(
this );
2575 const QDomElement labelEngineSettingsElement = doc->documentElement().firstChildElement( u
"labelEngineSettings"_s );
2576 mLabelingEngineSettings->readXml( labelEngineSettingsElement, context );
2578 mLabelingEngineSettings->resolveReferences(
this );
2582 profile.switchTask( tr(
"Loading annotations" ) );
2585 mAnnotationManager->readXml( doc->documentElement(), context );
2589 mAnnotationManager->readXmlAndUpgradeToAnnotationLayerItems( doc->documentElement(), context, mMainAnnotationLayer, mTransformContext );
2593 profile.switchTask( tr(
"Loading layouts" ) );
2594 mLayoutManager->readXml( doc->documentElement(), *doc );
2598 profile.switchTask( tr(
"Loading elevation profiles" ) );
2599 mElevationProfileManager->readXml( doc->documentElement(), *doc, context );
2600 mElevationProfileManager->resolveReferences(
this );
2604 profile.switchTask( tr(
"Loading selective masking source sets" ) );
2605 mSelectiveMaskingSourceSetManager->readXml( doc->documentElement(), *doc, context );
2610 profile.switchTask( tr(
"Loading 3D Views" ) );
2611 m3DViewsManager->readXml( doc->documentElement(), *doc );
2614 profile.switchTask( tr(
"Loading bookmarks" ) );
2615 mBookmarkManager->readXml( doc->documentElement(), *doc );
2617 profile.switchTask( tr(
"Loading sensors" ) );
2618 mSensorManager->readXml( doc->documentElement(), *doc );
2621 QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
2622 for ( QMap<QString, QgsMapLayer *>::iterator it = existingMaps.begin(); it != existingMaps.end(); ++it )
2624 it.value()->setDependencies( it.value()->dependencies() );
2627 profile.switchTask( tr(
"Loading snapping settings" ) );
2628 mSnappingConfig.readProject( *doc );
2633 profile.switchTask( tr(
"Loading view settings" ) );
2635 mViewSettings->setUseProjectScales(
readBoolEntry( u
"Scales"_s, u
"/useProjectScales"_s ) );
2636 const QStringList scales =
readListEntry( u
"Scales"_s, u
"/ScalesList"_s );
2637 QVector<double> res;
2638 for (
const QString &scale : scales )
2640 const QStringList parts = scale.split(
':' );
2641 if ( parts.size() != 2 )
2645 const double denominator = QLocale().toDouble( parts[1], &ok );
2651 mViewSettings->setMapScales( res );
2652 const QDomElement viewSettingsElement = doc->documentElement().firstChildElement( u
"ProjectViewSettings"_s );
2653 if ( !viewSettingsElement.isNull() )
2654 mViewSettings->readXml( viewSettingsElement, context );
2657 profile.switchTask( tr(
"Loading style properties" ) );
2658 const QDomElement styleSettingsElement = doc->documentElement().firstChildElement( u
"ProjectStyleSettings"_s );
2659 if ( !styleSettingsElement.isNull() )
2661 mStyleSettings->removeProjectStyle();
2662 mStyleSettings->readXml( styleSettingsElement, context,
flags );
2666 profile.switchTask( tr(
"Loading temporal settings" ) );
2667 const QDomElement timeSettingsElement = doc->documentElement().firstChildElement( u
"ProjectTimeSettings"_s );
2668 if ( !timeSettingsElement.isNull() )
2669 mTimeSettings->readXml( timeSettingsElement, context );
2672 profile.switchTask( tr(
"Loading elevation properties" ) );
2673 const QDomElement elevationPropertiesElement = doc->documentElement().firstChildElement( u
"ElevationProperties"_s );
2674 if ( !elevationPropertiesElement.isNull() )
2675 mElevationProperties->readXml( elevationPropertiesElement, context );
2676 mElevationProperties->resolveReferences(
this );
2678 profile.switchTask( tr(
"Loading display settings" ) );
2680 const QDomElement displaySettingsElement = doc->documentElement().firstChildElement( u
"ProjectDisplaySettings"_s );
2681 if ( !displaySettingsElement.isNull() )
2682 mDisplaySettings->readXml( displaySettingsElement, context );
2685 profile.switchTask( tr(
"Loading GPS settings" ) );
2687 const QDomElement gpsSettingsElement = doc->documentElement().firstChildElement( u
"ProjectGpsSettings"_s );
2688 if ( !gpsSettingsElement.isNull() )
2689 mGpsSettings->readXml( gpsSettingsElement, context );
2690 mGpsSettings->resolveReferences(
this );
2693 profile.switchTask( tr(
"Updating variables" ) );
2695 profile.switchTask( tr(
"Updating CRS" ) );
2699 if ( mCrs3D != oldCrs3D )
2704 profile.switchTask( tr(
"Reading external settings" ) );
2708 profile.switchTask( tr(
"Updating interface" ) );
2710 snapSignalBlock.release();
2711 if ( !mBlockSnappingUpdates )
2732 const QString newFileName( u
"%1/%2.qgs"_s.arg( QFileInfo( mFile ).
absolutePath(), localeFileName ) );
2746 const QMap<QString, QgsMapLayer *> loadedLayers =
mapLayers();
2747 for (
auto it = loadedLayers.constBegin(); it != loadedLayers.constEnd(); ++it )
2749 if ( it.value()->isValid() && it.value()->customProperty( u
"_layer_was_editable"_s ).toBool() )
2751 if ( QgsVectorLayer *vl = qobject_cast< QgsVectorLayer * >( it.value() ) )
2753 it.value()->removeCustomProperty( u
"_layer_was_editable"_s );
2765 const auto constChildren = group->
children();
2766 for ( QgsLayerTreeNode *child : constChildren )
2779 QList<QgsLayerTreeNode *> clonedChildren;
2780 const QList<QgsLayerTreeNode *> constChildren = newGroup->children();
2781 clonedChildren.reserve( constChildren.size() );
2782 for ( QgsLayerTreeNode *newGroupChild : constChildren )
2783 clonedChildren << newGroupChild->clone();
2790 loadEmbeddedNodes( childGroup,
flags );
2795 if ( child->customProperty( u
"embedded"_s ).toInt() )
2797 QList<QDomNode> brokenNodes;
2800 valid = valid &&
false;
2814 return mCustomVariables;
2821 if ( variables == mCustomVariables )
2825 QStringList variableNames;
2826 QStringList variableValues;
2828 QVariantMap::const_iterator it = variables.constBegin();
2829 for ( ; it != variables.constEnd(); ++it )
2831 variableNames << it.key();
2832 variableValues << it.value().toString();
2835 writeEntry( u
"Variables"_s, u
"/variableNames"_s, variableNames );
2836 writeEntry( u
"Variables"_s, u
"/variableValues"_s, variableValues );
2838 mCustomVariables = variables;
2839 mProjectScope.reset();
2848 *mLabelingEngineSettings = settings;
2856 return *mLabelingEngineSettings;
2863 mProjectScope.reset();
2864 return mLayerStore.get();
2871 return mLayerStore.get();
2878 QList<QgsVectorLayer *>
layers;
2879 const QStringList layerIds =
readListEntry( u
"Digitizing"_s, u
"/AvoidIntersectionsList"_s, QStringList() );
2880 const auto constLayerIds = layerIds;
2881 for (
const QString &layerId : constLayerIds )
2894 list.reserve(
layers.size() );
2899 list << layer->id();
2902 writeEntry( u
"Digitizing"_s, u
"/AvoidIntersectionsList"_s, list );
2923 if ( mProjectScope )
2925 auto projectScope = std::make_unique< QgsExpressionContextScope >( *mProjectScope );
2932 projectScope->addFunction( u
"sensor_data"_s,
new GetSensorData(
sensorManager()->sensorsData() ) );
2934 return projectScope.release();
2937 mProjectScope = std::make_unique< QgsExpressionContextScope >( QObject::tr(
"Project" ) );
2941 QVariantMap::const_iterator it = vars.constBegin();
2943 for ( ; it != vars.constEnd(); ++it )
2945 mProjectScope->setVariable( it.key(), it.value(),
true );
2949 if ( projectPath.isEmpty() )
2950 projectPath = mOriginalPath;
2951 const QString projectFolder = QFileInfo( projectPath ).path();
2952 const QString projectFilename = QFileInfo( projectPath ).fileName();
2953 const QString projectBasename =
baseName();
2990 QVariantMap keywords;
2992 for (
auto it = metadataKeywords.constBegin(); it != metadataKeywords.constEnd(); ++it )
2994 keywords.insert( it.key(), it.value() );
2999 QVariantList layersIds;
3001 const QMap<QString, QgsMapLayer *> layersInProject = mLayerStore->mapLayers();
3002 layersIds.reserve( layersInProject.count() );
3003 layers.reserve( layersInProject.count() );
3004 for (
auto it = layersInProject.constBegin(); it != layersInProject.constEnd(); ++it )
3006 layersIds << it.value()->id();
3012 mProjectScope->addFunction( u
"project_color"_s,
new GetNamedProjectColor(
this ) );
3013 mProjectScope->addFunction( u
"project_color_object"_s,
new GetNamedProjectColorObject(
this ) );
3018void QgsProject::onMapLayersAdded(
const QList<QgsMapLayer *> &layers )
3022 const QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
3024 const auto constLayers =
layers;
3027 if ( !layer->isValid() )
3030 if (
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer ) )
3033 if ( vlayer->dataProvider() )
3040 for ( QMap<QString, QgsMapLayer *>::const_iterator it = existingMaps.cbegin(); it != existingMaps.cend(); ++it )
3042 const QSet<QgsMapLayerDependency> deps = it.value()->dependencies();
3043 if ( deps.contains( layer->id() ) )
3046 it.value()->setDependencies( deps );
3051 updateTransactionGroups();
3053 if ( !mBlockSnappingUpdates && mSnappingConfig.addLayers(
layers ) )
3057void QgsProject::onMapLayersRemoved(
const QList<QgsMapLayer *> &layers )
3061 if ( !mBlockSnappingUpdates && mSnappingConfig.removeLayers(
layers ) )
3064 for ( QgsMapLayer *layer :
layers )
3066 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
3070 mEditBufferGroup.removeLayer( vlayer );
3074void QgsProject::cleanTransactionGroups(
bool force )
3078 bool changed =
false;
3079 for ( QMap< QPair< QString, QString>, QgsTransactionGroup *>::Iterator tg = mTransactionGroups.begin(); tg != mTransactionGroups.end(); )
3081 if ( tg.value()->isEmpty() || force )
3084 tg = mTransactionGroups.erase( tg );
3096void QgsProject::updateTransactionGroups()
3100 mEditBufferGroup.clear();
3102 switch ( mTransactionMode )
3106 cleanTransactionGroups(
true );
3111 cleanTransactionGroups(
true );
3114 cleanTransactionGroups(
false );
3118 bool tgChanged =
false;
3119 const auto constLayers =
mapLayers().values();
3120 for ( QgsMapLayer *layer : constLayers )
3122 if ( !layer->isValid() )
3125 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
3129 switch ( mTransactionMode )
3141 QgsTransactionGroup *tg = mTransactionGroups.value( qMakePair( key, connString ) );
3145 tg =
new QgsTransactionGroup();
3146 mTransactionGroups.insert( qMakePair( key, connString ), tg );
3156 mEditBufferGroup.addLayer( vlayer );
3172 context.setProjectTranslator(
this );
3174 context.setCurrentLayerId( layerNode.toElement().firstChildElement( u
"id"_s ).text() );
3175 QList<QDomNode> brokenNodes;
3176 if ( addLayer( layerNode.toElement(), brokenNodes, context ) )
3184 layer->resolveReferences(
this );
3186 if ( layer->isValid() && layer->customProperty( u
"_layer_was_editable"_s ).toBool() )
3188 layer->startEditing();
3189 layer->removeCustomProperty( u
"_layer_was_editable"_s );
3201 mFile.setFileName( filename );
3203 mCachedHomePath.clear();
3211 mProjectScope.reset();
3217 const QString storageFilePath { storage->filePath( mFile.fileName() ) };
3218 if ( storageFilePath.isEmpty() )
3224 const QString tempPath = QStandardPaths::standardLocations( QStandardPaths::TempLocation ).at( 0 );
3225 const QString tmpZipFilename( tempPath + QDir::separator() + QUuid::createUuid().toString() );
3227 if ( !zip( tmpZipFilename ) )
3230 QFile tmpZipFile( tmpZipFilename );
3231 if ( !tmpZipFile.open( QIODevice::ReadOnly ) )
3233 setError( tr(
"Unable to read file %1" ).arg( tmpZipFilename ) );
3238 if ( !storage->writeProject( mFile.fileName(), &tmpZipFile, context ) )
3240 QString err = tr(
"Unable to save project to storage %1" ).arg( mFile.fileName() );
3241 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
3242 if ( !messages.isEmpty() )
3243 err += u
"\n\n"_s + messages.last().message();
3249 QFile::remove( tmpZipFilename );
3256 return zip( mFile.fileName() );
3262 const bool asOk = saveAuxiliaryStorage();
3263 const bool writeOk = writeProjectFile( mFile.fileName() );
3264 bool attachmentsOk =
true;
3265 if ( !mArchive->files().isEmpty() )
3267 const QFileInfo finfo( mFile.fileName() );
3268 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( u
"%1_attachments.zip"_s.arg( finfo.completeBaseName() ) );
3269 attachmentsOk = mArchive->zip( attachmentsZip );
3273 if ( ( !asOk || !attachmentsOk ) && writeOk )
3275 QStringList errorMessage;
3278 const QString err = mAuxiliaryStorage->errorString();
3279 errorMessage.append( tr(
"Unable to save auxiliary storage ('%1')" ).arg( err ) );
3281 if ( !attachmentsOk )
3283 errorMessage.append( tr(
"Unable to save attachments archive" ) );
3285 setError( errorMessage.join(
'\n' ) );
3288 return asOk && writeOk && attachmentsOk;
3292bool QgsProject::writeProjectFile(
const QString &filename )
3296 QFile projectFile( filename );
3302 const QFileInfo myFileInfo( projectFile );
3303 if ( myFileInfo.exists() && !myFileInfo.isWritable() )
3305 setError( tr(
"%1 is not writable. Please adjust permissions (if possible) and try again." ).arg( projectFile.fileName() ) );
3309 QgsReadWriteContext context;
3313 QDomImplementation::setInvalidDataPolicy( QDomImplementation::DropInvalidChars );
3315 const QDomDocumentType documentType = QDomImplementation().createDocumentType( u
"qgis"_s, u
"http://mrcc.com/qgis.dtd"_s, u
"SYSTEM"_s );
3316 auto doc = std::make_unique<QDomDocument>( documentType );
3318 QDomElement qgisNode = doc->createElement( u
"qgis"_s );
3319 qgisNode.setAttribute( u
"projectname"_s,
title() );
3322 if ( !mSettings.value( u
"projects/anonymize_saved_projects"_s,
false,
QgsSettings::Core ).toBool() )
3326 qgisNode.setAttribute( u
"saveUser"_s, newSaveUser );
3327 qgisNode.setAttribute( u
"saveUserFull"_s, newSaveUserFull );
3328 mSaveUser = newSaveUser;
3329 mSaveUserFull = newSaveUserFull;
3330 if ( mMetadata.author().isEmpty() )
3334 if ( !mMetadata.creationDateTime().isValid() )
3336 mMetadata.setCreationDateTime( QDateTime( QDateTime::currentDateTime() ) );
3338 mSaveDateTime = QDateTime::currentDateTime();
3339 qgisNode.setAttribute( u
"saveDateTime"_s, mSaveDateTime.toString( Qt::ISODate ) );
3344 mSaveUserFull.clear();
3345 mMetadata.setAuthor( QString() );
3346 mMetadata.setCreationDateTime( QDateTime() );
3347 mSaveDateTime = QDateTime();
3349 doc->appendChild( qgisNode );
3352 QDomElement homePathNode = doc->createElement( u
"homePath"_s );
3353 homePathNode.setAttribute( u
"path"_s, mHomePath );
3354 qgisNode.appendChild( homePathNode );
3357 QDomElement titleNode = doc->createElement( u
"title"_s );
3358 qgisNode.appendChild( titleNode );
3360 QDomElement transactionNode = doc->createElement( u
"transaction"_s );
3361 transactionNode.setAttribute( u
"mode"_s,
qgsEnumValueToKey( mTransactionMode ) );
3362 qgisNode.appendChild( transactionNode );
3364 QDomElement flagsNode = doc->createElement( u
"projectFlags"_s );
3366 qgisNode.appendChild( flagsNode );
3368 const QDomText titleText = doc->createTextNode(
title() );
3369 titleNode.appendChild( titleText );
3373 QDomElement srsNode = doc->createElement( u
"projectCrs"_s );
3374 mCrs.writeXml( srsNode, *doc );
3375 qgisNode.appendChild( srsNode );
3378 QDomElement verticalSrsNode = doc->createElement( u
"verticalCrs"_s );
3379 mVerticalCrs.writeXml( verticalSrsNode, *doc );
3380 qgisNode.appendChild( verticalSrsNode );
3383 QDomElement elevationShadingNode = doc->createElement( u
"elevation-shading-renderer"_s );
3384 mElevationShadingRenderer.writeXml( elevationShadingNode, context );
3385 qgisNode.appendChild( elevationShadingNode );
3388 std::unique_ptr< QgsLayerTreeNode > clonedRoot( mRootGroup->clone() );
3392 clonedRoot->writeXml( qgisNode, context );
3395 mSnappingConfig.writeProject( *doc );
3396 writeEntry( u
"Digitizing"_s, u
"/AvoidIntersectionsMode"_s,
static_cast<int>( mAvoidIntersectionsMode ) );
3404 QDomElement annotationLayerNode = doc->createElement( u
"main-annotation-layer"_s );
3405 mMainAnnotationLayer->writeLayerXml( annotationLayerNode, *doc, context );
3406 qgisNode.appendChild( annotationLayerNode );
3410 QDomElement projectLayersNode = doc->createElement( u
"projectlayers"_s );
3412 QMap<QString, QgsMapLayer *>::ConstIterator li =
layers.constBegin();
3413 while ( li !=
layers.end() )
3415 QgsMapLayer *ml = li.value();
3419 const QHash< QString, QPair< QString, bool> >::const_iterator emIt = mEmbeddedLayers.constFind( ml->
id() );
3420 if ( emIt == mEmbeddedLayers.constEnd() )
3422 QDomElement maplayerElem;
3428 maplayerElem = doc->createElement( u
"maplayer"_s );
3432 maplayerElem.setAttribute( u
"editable"_s, u
"1"_s );
3436 QDomDocument document;
3439 maplayerElem = document.firstChildElement();
3443 QgsDebugError( u
"Could not restore layer properties for layer %1"_s.arg( ml->
id() ) );
3449 projectLayersNode.appendChild( maplayerElem );
3455 if ( emIt.value().second )
3457 QDomElement mapLayerElem = doc->createElement( u
"maplayer"_s );
3458 mapLayerElem.setAttribute( u
"embedded"_s, 1 );
3459 mapLayerElem.setAttribute( u
"project"_s,
writePath( emIt.value().first ) );
3460 mapLayerElem.setAttribute( u
"id"_s, ml->
id() );
3461 projectLayersNode.appendChild( mapLayerElem );
3468 qgisNode.appendChild( projectLayersNode );
3470 QDomElement layerOrderNode = doc->createElement( u
"layerorder"_s );
3471 const auto constCustomLayerOrder = mRootGroup->customLayerOrder();
3472 for ( QgsMapLayer *layer : constCustomLayerOrder )
3474 QDomElement mapLayerElem = doc->createElement( u
"layer"_s );
3475 mapLayerElem.setAttribute( u
"id"_s, layer->id() );
3476 layerOrderNode.appendChild( mapLayerElem );
3478 qgisNode.appendChild( layerOrderNode );
3480 mLabelingEngineSettings->writeSettingsToProject(
this );
3482 QDomElement labelEngineSettingsElement = doc->createElement( u
"labelEngineSettings"_s );
3483 mLabelingEngineSettings->writeXml( *doc, labelEngineSettingsElement, context );
3484 qgisNode.appendChild( labelEngineSettingsElement );
3487 writeEntry( u
"Gui"_s, u
"/CanvasColorRedPart"_s, mBackgroundColor.red() );
3488 writeEntry( u
"Gui"_s, u
"/CanvasColorGreenPart"_s, mBackgroundColor.green() );
3489 writeEntry( u
"Gui"_s, u
"/CanvasColorBluePart"_s, mBackgroundColor.blue() );
3491 writeEntry( u
"Gui"_s, u
"/SelectionColorRedPart"_s, mSelectionColor.red() );
3492 writeEntry( u
"Gui"_s, u
"/SelectionColorGreenPart"_s, mSelectionColor.green() );
3493 writeEntry( u
"Gui"_s, u
"/SelectionColorBluePart"_s, mSelectionColor.blue() );
3494 writeEntry( u
"Gui"_s, u
"/SelectionColorAlphaPart"_s, mSelectionColor.alpha() );
3502 dump_( mProperties );
3505 QgsDebugMsgLevel( u
"there are %1 property scopes"_s.arg(
static_cast<int>( mProperties.count() ) ), 2 );
3507 if ( !mProperties.isEmpty() )
3510 mProperties.writeXml( u
"properties"_s, qgisNode, *doc );
3513 QDomElement ddElem = doc->createElement( u
"dataDefinedServerProperties"_s );
3514 mDataDefinedServerProperties.writeXml( ddElem, dataDefinedServerPropertyDefinitions() );
3515 qgisNode.appendChild( ddElem );
3517 mMapThemeCollection->writeXml( *doc );
3519 mTransformContext.writeXml( qgisNode, context );
3521 QDomElement metadataElem = doc->createElement( u
"projectMetadata"_s );
3522 mMetadata.writeMetadataXml( metadataElem, *doc );
3523 qgisNode.appendChild( metadataElem );
3526 const QDomElement annotationsElem = mAnnotationManager->writeXml( *doc, context );
3527 qgisNode.appendChild( annotationsElem );
3531 const QDomElement layoutElem = mLayoutManager->writeXml( *doc );
3532 qgisNode.appendChild( layoutElem );
3536 const QDomElement elevationProfileElem = mElevationProfileManager->writeXml( *doc, context );
3537 qgisNode.appendChild( elevationProfileElem );
3541 const QDomElement selectiveMaskingSourceSetElem = mSelectiveMaskingSourceSetManager->writeXml( *doc, context );
3542 qgisNode.appendChild( selectiveMaskingSourceSetElem );
3546 const QDomElement views3DElem = m3DViewsManager->writeXml( *doc );
3547 qgisNode.appendChild( views3DElem );
3551 const QDomElement bookmarkElem = mBookmarkManager->writeXml( *doc );
3552 qgisNode.appendChild( bookmarkElem );
3556 const QDomElement sensorElem = mSensorManager->writeXml( *doc );
3557 qgisNode.appendChild( sensorElem );
3561 const QDomElement viewSettingsElem = mViewSettings->writeXml( *doc, context );
3562 qgisNode.appendChild( viewSettingsElem );
3566 const QDomElement styleSettingsElem = mStyleSettings->writeXml( *doc, context );
3567 qgisNode.appendChild( styleSettingsElem );
3571 const QDomElement timeSettingsElement = mTimeSettings->writeXml( *doc, context );
3572 qgisNode.appendChild( timeSettingsElement );
3576 const QDomElement elevationPropertiesElement = mElevationProperties->writeXml( *doc, context );
3577 qgisNode.appendChild( elevationPropertiesElement );
3581 const QDomElement displaySettingsElem = mDisplaySettings->writeXml( *doc, context );
3582 qgisNode.appendChild( displaySettingsElem );
3586 const QDomElement gpsSettingsElem = mGpsSettings->writeXml( *doc, context );
3587 qgisNode.appendChild( gpsSettingsElem );
3596 QFile backupFile( u
"%1~"_s.arg( filename ) );
3598 ok &= backupFile.open( QIODevice::WriteOnly | QIODevice::Truncate );
3599 ok &= projectFile.open( QIODevice::ReadOnly );
3602 while ( ok && !projectFile.atEnd() )
3604 ba = projectFile.read( 10240 );
3605 ok &= backupFile.write( ba ) == ba.size();
3608 projectFile.close();
3613 setError( tr(
"Unable to create backup file %1" ).arg( backupFile.fileName() ) );
3618 struct utimbuf tb = {
static_cast<time_t
>( fi.lastRead().toSecsSinceEpoch() ),
static_cast<time_t
>( fi.lastModified().toSecsSinceEpoch() ) };
3619 utime( backupFile.fileName().toUtf8().constData(), &tb );
3622 if ( !projectFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
3624 projectFile.close();
3627 setError( tr(
"Unable to save to file %1" ).arg( projectFile.fileName() ) );
3631 QTemporaryFile tempFile;
3632 bool ok = tempFile.open();
3635 QTextStream projectFileStream( &tempFile );
3636 doc->save( projectFileStream, 2 );
3637 ok &= projectFileStream.pos() > -1;
3639 ok &= tempFile.seek( 0 );
3642 while ( ok && !tempFile.atEnd() )
3644 ba = tempFile.read( 10240 );
3645 ok &= projectFile.write( ba ) == ba.size();
3648 ok &= projectFile.error() == QFile::NoError;
3650 projectFile.close();
3658 "Unable to save to file %1. Your project "
3659 "may be corrupted on disk. Try clearing some space on the volume and "
3660 "check file permissions before pressing save again."
3662 .arg( projectFile.fileName() ) );
3676 bool propertiesModified;
3677 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3679 if ( propertiesModified )
3689 bool propertiesModified;
3690 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3692 if ( propertiesModified )
3702 bool propertiesModified;
3703 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3705 if ( propertiesModified )
3715 bool propertiesModified;
3716 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3718 if ( propertiesModified )
3728 bool propertiesModified;
3729 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3731 if ( propertiesModified )
3748 value =
property->value();
3750 const bool valid = QMetaType::Type::QStringList == value.userType();
3756 return value.toStringList();
3776 value =
property->value();
3778 const bool valid = value.canConvert( QMetaType::Type::QString );
3783 return value.toString();
3801 value =
property->value();
3804 const bool valid = value.canConvert( QMetaType::Type::Int );
3813 return value.toInt();
3826 const QVariant value =
property->value();
3828 const bool valid = value.canConvert( QMetaType::Type::Double );
3833 return value.toDouble();
3849 const QVariant value =
property->value();
3851 const bool valid = value.canConvert( QMetaType::Type::Bool );
3856 return value.toBool();
3868 if (
findKey_( scope, key, mProperties ) )
3874 return !
findKey_( scope, key, mProperties );
3883 QStringList entries;
3885 if ( foundProperty )
3904 QStringList entries;
3906 if ( foundProperty )
3923 dump_( mProperties );
3943 filePath = storage->filePath( mFile.fileName() );
3970void QgsProject::setError(
const QString &errorMessage )
3974 mErrorMessage = errorMessage;
3981 return mErrorMessage;
3984void QgsProject::clearError()
3988 setError( QString() );
3995 mBadLayerHandler.reset( handler );
4002 const QHash< QString, QPair< QString, bool > >::const_iterator it = mEmbeddedLayers.find(
id );
4003 if ( it == mEmbeddedLayers.constEnd() )
4007 return it.value().first;
4016 static QString sPrevProjectFilePath;
4017 static QDateTime sPrevProjectFileTimestamp;
4018 static QDomDocument sProjectDocument;
4020 QString qgsProjectFile = projectFilePath;
4022 if ( projectFilePath.endsWith(
".qgz"_L1, Qt::CaseInsensitive ) )
4024 archive.
unzip( projectFilePath );
4028 const QDateTime projectFileTimestamp = QFileInfo( projectFilePath ).lastModified();
4030 if ( projectFilePath != sPrevProjectFilePath || projectFileTimestamp != sPrevProjectFileTimestamp )
4032 sPrevProjectFilePath.clear();
4034 QFile projectFile( qgsProjectFile );
4035 if ( !projectFile.open( QIODevice::ReadOnly ) )
4040 if ( !sProjectDocument.setContent( &projectFile ) )
4045 sPrevProjectFilePath = projectFilePath;
4046 sPrevProjectFileTimestamp = projectFileTimestamp;
4050 bool useAbsolutePaths =
true;
4052 const QDomElement propertiesElem = sProjectDocument.documentElement().firstChildElement( u
"properties"_s );
4053 if ( !propertiesElem.isNull() )
4055 QDomElement e = propertiesElem.firstChildElement( u
"Paths"_s );
4058 e = propertiesElem.firstChildElement( u
"properties"_s );
4059 while ( !e.isNull() && e.attribute( u
"name"_s ) !=
"Paths"_L1 )
4060 e = e.nextSiblingElement( u
"properties"_s );
4062 e = e.firstChildElement( u
"properties"_s );
4063 while ( !e.isNull() && e.attribute( u
"name"_s ) !=
"Absolute"_L1 )
4064 e = e.nextSiblingElement( u
"properties"_s );
4068 e = e.firstChildElement( u
"Absolute"_s );
4073 useAbsolutePaths = e.text().compare(
"true"_L1, Qt::CaseInsensitive ) == 0;
4078 if ( !useAbsolutePaths )
4084 const QDomElement projectLayersElem = sProjectDocument.documentElement().firstChildElement( u
"projectlayers"_s );
4085 if ( projectLayersElem.isNull() )
4090 QDomElement mapLayerElem = projectLayersElem.firstChildElement( u
"maplayer"_s );
4091 while ( !mapLayerElem.isNull() )
4094 const QString
id = mapLayerElem.firstChildElement( u
"id"_s ).text();
4095 if (
id == layerId )
4098 if ( mapLayerElem.attribute( u
"embedded"_s ) ==
"1"_L1 )
4103 mEmbeddedLayers.insert( layerId, qMakePair( projectFilePath, saveFlag ) );
4105 if ( addLayer( mapLayerElem, brokenNodes, embeddedContext,
flags ) )
4111 mEmbeddedLayers.remove( layerId );
4115 mapLayerElem = mapLayerElem.nextSiblingElement( u
"maplayer"_s );
4125 QString qgsProjectFile = projectFilePath;
4127 if ( projectFilePath.endsWith(
".qgz"_L1, Qt::CaseInsensitive ) )
4129 archive.
unzip( projectFilePath );
4134 QFile projectFile( qgsProjectFile );
4135 if ( !projectFile.open( QIODevice::ReadOnly ) )
4140 QDomDocument projectDocument;
4141 if ( !projectDocument.setContent( &projectFile ) )
4151 auto root = std::make_unique< QgsLayerTreeGroup >();
4153 QDomElement layerTreeElem = projectDocument.documentElement().firstChildElement( u
"layer-tree-group"_s );
4154 if ( !layerTreeElem.isNull() )
4156 root->readChildrenFromXml( layerTreeElem, context );
4174 newGroup->setCustomProperty( u
"embedded"_s, 1 );
4175 newGroup->setCustomProperty( u
"embedded_project"_s, projectFilePath );
4178 mLayerTreeRegistryBridge->setEnabled(
false );
4179 initializeEmbeddedSubtree( projectFilePath, newGroup.get(),
flags );
4180 mLayerTreeRegistryBridge->setEnabled(
true );
4183 const QStringList constFindLayerIds = newGroup->findLayerIds();
4184 for (
const QString &layerId : constFindLayerIds )
4201 const auto constChildren = group->
children();
4205 child->setCustomProperty( u
"embedded"_s, 1 );
4214 QList<QDomNode> brokenNodes;
4238 writeEntry( u
"Digitizing"_s, u
"/TopologicalEditing"_s, ( enabled ? 1 : 0 ) );
4246 return readNumEntry( u
"Digitizing"_s, u
"/TopologicalEditing"_s, 0 );
4253 if ( mDistanceUnits == unit )
4256 mDistanceUnits = unit;
4265 if ( mAreaUnits == unit )
4277 if ( mScaleMethod == method )
4280 mScaleMethod = method;
4290 if ( !mCachedHomePath.isEmpty() )
4291 return mCachedHomePath;
4295 if ( !mHomePath.isEmpty() )
4297 const QFileInfo homeInfo( mHomePath );
4298 if ( !homeInfo.isRelative() )
4300 mCachedHomePath = mHomePath;
4309 const QString storagePath { storage->filePath(
fileName() ) };
4310 if ( !storagePath.isEmpty() && QFileInfo::exists( storagePath ) )
4312 mCachedHomePath = QFileInfo( storagePath ).path();
4313 return mCachedHomePath;
4317 mCachedHomePath = pfi.path();
4318 return mCachedHomePath;
4321 if ( !pfi.exists() )
4323 mCachedHomePath = mHomePath;
4327 if ( !mHomePath.isEmpty() )
4330 mCachedHomePath = QDir::cleanPath( pfi.path() +
'/' + mHomePath );
4334 mCachedHomePath = pfi.canonicalPath();
4336 return mCachedHomePath;
4351 return mRelationManager.get();
4358 return mLayoutManager.get();
4365 return mLayoutManager.get();
4372 return mElevationProfileManager.get();
4379 return mElevationProfileManager.get();
4386 return mSelectiveMaskingSourceSetManager.get();
4393 return mSelectiveMaskingSourceSetManager.get();
4400 return m3DViewsManager.get();
4407 return m3DViewsManager.get();
4414 return mBookmarkManager;
4421 return mBookmarkManager;
4428 return mSensorManager;
4435 return mSensorManager;
4442 return mViewSettings;
4449 return mViewSettings;
4456 return mStyleSettings;
4464 return mStyleSettings;
4471 return mTimeSettings;
4478 return mTimeSettings;
4485 return mElevationProperties;
4492 return mElevationProperties;
4499 return mDisplaySettings;
4506 return mDisplaySettings;
4513 return mGpsSettings;
4520 return mGpsSettings;
4527 return mRootGroup.get();
4534 return mMapThemeCollection.get();
4541 return mAnnotationManager.get();
4548 return mAnnotationManager.get();
4555 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
4556 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
4561 if (
layers.contains( it.value() ) )
4578 for (
const QString &layerId : layerIds )
4596 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
4628 updateTransactionGroups();
4635 return mTransactionMode;
4646 const auto constLayers =
mapLayers().values();
4649 if ( layer->isEditable() )
4651 QgsLogger::warning( tr(
"Transaction mode can be changed only if all layers are not editable." ) );
4657 updateTransactionGroups();
4666 return mTransactionGroups;
4679 return mLayerStore->count();
4686 return mLayerStore->validCount();
4694 if ( mMainAnnotationLayer && layerId == mMainAnnotationLayer->id() )
4695 return mMainAnnotationLayer;
4697 return mLayerStore->mapLayer( layerId );
4704 return mLayerStore->mapLayersByName( layerName );
4711 QList<QgsMapLayer *>
layers;
4712 const auto constMapLayers { mLayerStore->mapLayers() };
4713 for (
const auto &l : constMapLayers )
4715 if ( !l->serverProperties()->shortName().isEmpty() )
4717 if ( l->serverProperties()->shortName() == shortName )
4720 else if ( l->name() == shortName )
4733 auto archive = std::make_unique<QgsProjectArchive>();
4736 if ( !archive->unzip( filename ) )
4738 setError( tr(
"Unable to unzip file '%1'" ).arg( filename ) );
4743 if ( archive->projectFile().isEmpty() )
4745 setError( tr(
"Zip archive does not provide a project file" ) );
4750 releaseHandlesToProjectArchive();
4751 mArchive = std::move( archive );
4754 if ( !
static_cast<QgsProjectArchive *
>( mArchive.get() )->auxiliaryStorageFile().isEmpty() )
4758 mAuxiliaryStorage = std::make_unique< QgsAuxiliaryStorage >(
static_cast<QgsProjectArchive *
>( mArchive.get() )->auxiliaryStorageFile(),
false );
4762 mAuxiliaryStorage = std::make_unique< QgsAuxiliaryStorage >( *
this );
4766 if ( !readProjectFile(
static_cast<QgsProjectArchive *
>( mArchive.get() )->projectFile(),
flags ) )
4768 setError( tr(
"Cannot read unzipped qgs project file" ) + u
": "_s +
error() );
4773 static_cast<QgsProjectArchive *
>( mArchive.get() )->clearProjectFile();
4778bool QgsProject::zip(
const QString &filename )
4785 auto archive = std::make_unique<QgsProjectArchive>();
4786 const QString
baseName = QFileInfo( filename ).baseName();
4787 const QString qgsFileName = u
"%1.qgs"_s.arg(
baseName );
4788 QFile qgsFile( QDir( archive->dir() ).filePath( qgsFileName ) );
4790 bool writeOk =
false;
4791 if ( qgsFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
4793 writeOk = writeProjectFile( qgsFile.fileName() );
4800 setError( tr(
"Unable to write temporary qgs file" ) );
4805 const QFileInfo info( qgsFile );
4807 const QString asFileName = info.path() + QDir::separator() + info.completeBaseName() + asExt;
4809 bool auxiliaryStorageSavedOk =
true;
4810 if ( !saveAuxiliaryStorage( asFileName ) )
4812 const QString err = mAuxiliaryStorage->errorString();
4814 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 )
4816 auxiliaryStorageSavedOk =
false;
4819 if ( !mArchive->exists() )
4821 releaseHandlesToProjectArchive();
4822 mArchive = std::make_unique< QgsProjectArchive >();
4823 mArchive->unzip( mFile.fileName() );
4824 static_cast<QgsProjectArchive *
>( mArchive.get() )->clearProjectFile();
4826 const QString auxiliaryStorageFile =
static_cast<QgsProjectArchive *
>( mArchive.get() )->auxiliaryStorageFile();
4827 if ( !auxiliaryStorageFile.isEmpty() )
4829 archive->addFile( auxiliaryStorageFile );
4830 mAuxiliaryStorage = std::make_unique< QgsAuxiliaryStorage >( auxiliaryStorageFile,
false );
4838 if ( QFile::exists( asFileName ) )
4840 archive->addFile( asFileName );
4845 archive->addFile( qgsFile.fileName() );
4848 const QStringList &files = mArchive->files();
4849 for (
const QString &file : files )
4851 if ( !file.endsWith(
".qgs"_L1, Qt::CaseInsensitive ) && !file.endsWith( asExt, Qt::CaseInsensitive ) )
4853 archive->addFile( file );
4859 if ( !archive->zip( filename ) )
4861 setError( tr(
"Unable to perform zip" ) );
4865 return auxiliaryStorageSavedOk && zipOk;
4879 const QList<QgsMapLayer *> myResultList { mLayerStore->addMapLayers(
layers, takeOwnership ) };
4880 if ( !myResultList.isEmpty() )
4883 for (
auto &l : myResultList )
4897 if ( mAuxiliaryStorage )
4912 mProjectScope.reset();
4914 return myResultList;
4921 QList<QgsMapLayer *> addedLayers;
4922 addedLayers =
addMapLayers( QList<QgsMapLayer *>() << layer, addToLegend, takeOwnership );
4923 return addedLayers.isEmpty() ? nullptr : addedLayers[0];
4926void QgsProject::removeAuxiliaryLayer(
const QgsMapLayer *ml )
4933 const QgsVectorLayer *vl = qobject_cast<const QgsVectorLayer *>( ml );
4945 for (
const auto &layerId : layerIds )
4946 removeAuxiliaryLayer( mLayerStore->mapLayer( layerId ) );
4948 mProjectScope.reset();
4949 mLayerStore->removeMapLayers( layerIds );
4956 for (
const auto &layer :
layers )
4957 removeAuxiliaryLayer( layer );
4959 mProjectScope.reset();
4960 mLayerStore->removeMapLayers(
layers );
4967 removeAuxiliaryLayer( mLayerStore->mapLayer( layerId ) );
4968 mProjectScope.reset();
4969 mLayerStore->removeMapLayer( layerId );
4976 removeAuxiliaryLayer( layer );
4977 mProjectScope.reset();
4978 mLayerStore->removeMapLayer( layer );
4985 mProjectScope.reset();
4986 return mLayerStore->takeMapLayer( layer );
4993 return mMainAnnotationLayer;
5000 if ( mLayerStore->count() == 0 )
5003 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
5004 mProjectScope.reset();
5005 mLayerStore->removeAllMapLayers();
5007 snapSingleBlocker.release();
5008 mSnappingConfig.clearIndividualLayerSettings();
5009 if ( !mBlockSnappingUpdates )
5017 const QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
5018 QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin();
5019 for ( ; it !=
layers.constEnd(); ++it )
5021 it.value()->reload();
5030 return validOnly ? mLayerStore->validMapLayers() : mLayerStore->mapLayers();
5037 return mTransactionGroups.value( qMakePair( providerKey, connString ) );
5044 return &mEditBufferGroup;
5055 if ( mSettings.value( u
"/projections/unknownCrsBehavior"_s, u
"NoAction"_s,
QgsSettings::App ).toString() == u
"UseProjectCrs"_s
5056 || mSettings.value( u
"/projections/unknownCrsBehavior"_s, 0,
QgsSettings::App ).toString() ==
"2"_L1 )
5064 const QString layerDefaultCrs = mSettings.value( u
"/Projections/layerDefaultCrs"_s, u
"EPSG:4326"_s ).toString();
5085bool QgsProject::saveAuxiliaryStorage(
const QString &filename )
5091 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5096 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() );
5104 if ( !mAuxiliaryStorage->exists( *
this ) && empty )
5108 else if ( !filename.isEmpty() )
5110 return mAuxiliaryStorage->saveAs( filename );
5114 return mAuxiliaryStorage->saveAs( *
this );
5123 return sPropertyDefinitions;
5136 return mAuxiliaryStorage.get();
5143 return mAuxiliaryStorage.get();
5150 const QDir archiveDir( mArchive->dir() );
5151 QTemporaryFile tmpFile( archiveDir.filePath(
"XXXXXX_" + nameTemplate ),
this );
5152 tmpFile.setAutoRemove(
false );
5153 if ( !tmpFile.open() )
5155 setError( tr(
"Unable to open %1" ).arg( tmpFile.fileName() ) );
5158 mArchive->addFile( tmpFile.fileName() );
5159 return tmpFile.fileName();
5166 QStringList attachments;
5168 const QStringList files = mArchive->files();
5169 attachments.reserve( files.size() );
5170 for (
const QString &file : files )
5174 attachments.append( file );
5184 return mArchive->removeFile( path );
5191 return u
"attachment:///%1"_s.arg( QFileInfo( attachedFile ).
fileName() );
5198 if ( identifier.startsWith(
"attachment:///"_L1 ) )
5200 return QDir( mArchive->dir() ).absoluteFilePath( identifier.mid( 14 ) );
5221 mProjectScope.reset();
5236 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5250 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
5251 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
5256 if (
layers.contains( it.value() ) )
5268 QStringList customColors;
5269 QStringList customColorLabels;
5271 QgsNamedColorList::const_iterator colorIt = colors.constBegin();
5272 for ( ; colorIt != colors.constEnd(); ++colorIt )
5275 const QString label = ( *colorIt ).second;
5276 customColors.append( color );
5277 customColorLabels.append( label );
5279 writeEntry( u
"Palette"_s, u
"/Colors"_s, customColors );
5280 writeEntry( u
"Palette"_s, u
"/Labels"_s, customColorLabels );
5281 mProjectScope.reset();
5289 if ( mBackgroundColor == color )
5292 mBackgroundColor = color;
5300 return mBackgroundColor;
5307 if ( mSelectionColor == color )
5310 mSelectionColor = color;
5318 return mSelectionColor;
5325 mViewSettings->setMapScales( scales );
5332 return mViewSettings->mapScales();
5339 mViewSettings->setUseProjectScales( enabled );
5346 return mViewSettings->useProjectScales();
5359 translationContext.writeTsFile( locale );
5362QString
QgsProject::translate(
const QString &context,
const QString &sourceText,
const char *disambiguation,
int n )
const
5371 QString result = mTranslator->translate( context.toUtf8(), sourceText.toUtf8(), disambiguation, n );
5373 if ( result.isEmpty() )
5387 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5392 if ( !( ( *it )->accept( visitor ) ) )
5401 if ( !mLayoutManager->accept( visitor ) )
5404 if ( !mAnnotationManager->accept( visitor ) )
5414 const QString macros =
readEntry( u
"Macros"_s, u
"/pythonCode"_s, QString() );
5415 if ( !macros.isEmpty() )
5424 const QString expressionFunctions =
readEntry( u
"ExpressionFunctions"_s, u
"/pythonCode"_s );
5425 if ( !expressionFunctions.isEmpty() )
5437 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5439 if ( !( ( *it )->accept( visitor, context ) ) )
5451 return mElevationShadingRenderer;
5454void QgsProject::loadProjectFlags(
const QDomDocument *doc )
5458 QDomElement element = doc->documentElement().firstChildElement( u
"projectFlags"_s );
5460 if ( !element.isNull() )
5467 element = doc->documentElement().firstChildElement( u
"evaluateDefaultValues"_s );
5468 if ( !element.isNull() )
5470 if ( element.attribute( u
"active"_s, u
"0"_s ).toInt() == 1 )
5475 element = doc->documentElement().firstChildElement( u
"trust"_s );
5476 if ( !element.isNull() )
5478 if ( element.attribute( u
"active"_s, u
"0"_s ).toInt() == 1 )
5492 const QString projectFunctions =
readEntry( u
"ExpressionFunctions"_s, u
"/pythonCode"_s, QString() );
5493 if ( !projectFunctions.isEmpty() )
5513QHash< QString, QColor > loadColorsFromProject(
const QgsProject *project )
5515 QHash< QString, QColor > colors;
5518 QStringList colorStrings = project->
readListEntry( u
"Palette"_s, u
"/Colors"_s );
5519 const QStringList colorLabels = project->
readListEntry( u
"Palette"_s, u
"/Labels"_s );
5523 for ( QStringList::iterator it = colorStrings.begin(); it != colorStrings.end(); ++it )
5527 if ( colorLabels.length() > colorIndex )
5529 label = colorLabels.at( colorIndex );
5532 colors.insert( label.toLower(), color );
5540GetNamedProjectColor::GetNamedProjectColor(
const QgsProject *project )
5546 mColors = loadColorsFromProject( project );
5549GetNamedProjectColor::GetNamedProjectColor(
const QHash<QString, QColor> &colors )
5556 const QString colorName = values.at( 0 ).toString().toLower();
5557 if ( mColors.contains( colorName ) )
5559 return u
"%1,%2,%3"_s.arg( mColors.value( colorName ).red() ).arg( mColors.value( colorName ).green() ).arg( mColors.value( colorName ).blue() );
5567 return new GetNamedProjectColor( mColors );
5570GetNamedProjectColorObject::GetNamedProjectColorObject(
const QgsProject *project )
5576 mColors = loadColorsFromProject( project );
5579GetNamedProjectColorObject::GetNamedProjectColorObject(
const QHash<QString, QColor> &colors )
5586 const QString colorName = values.at( 0 ).toString().toLower();
5587 if ( mColors.contains( colorName ) )
5589 return mColors.value( colorName );
5597 return new GetNamedProjectColorObject( mColors );
5602GetSensorData::GetSensorData(
const QMap<QString, QgsAbstractSensor::SensorData> &sensorData )
5604 , mSensorData( sensorData )
5609 const QString sensorName = values.at( 0 ).toString();
5610 const int expiration = values.at( 1 ).toInt();
5611 const qint64 timestamp = QDateTime::currentMSecsSinceEpoch();
5612 if ( mSensorData.contains( sensorName ) )
5614 if ( expiration <= 0 || ( timestamp - mSensorData[sensorName].lastTimestamp.toMSecsSinceEpoch() ) < expiration )
5616 return mSensorData[sensorName].lastValue;
5625 return new GetSensorData( mSensorData );
@ ExpressionFunction
Project macros.
@ DontLoad3DViews
Skip loading 3D views.
@ 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.
@ TrustLayerMetadata
Trust layer metadata. Improves project read time. Do not use it if layers' extent is not fixed during...
@ DontUpgradeAnnotations
Don't upgrade old annotation items to QgsAnnotationItem.
@ 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.
@ Trusted
The project trust has not yet been determined by the user.
QFlags< ProjectCapability > ProjectCapabilities
Flags which control project capabilities.
QFlags< ProjectReadFlag > ProjectReadFlags
Project load flags.
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.
@ Compound
Compound (horizontal + vertical) CRS.
@ Projected
Projected CRS.
@ DerivedProjected
Derived projected CRS.
@ Engineering
Engineering CRS.
@ Geographic3d
3D geopraphic CRS
@ Geographic2d
2D geographic CRS
@ Geocentric
Geocentric CRS.
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...
QFlags< DataProviderReadFlag > DataProviderReadFlags
Flags which control data provider construction.
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.
ScaleCalculationMethod
Scale calculation logic.
@ HorizontalMiddle
Calculate horizontally, across midle of map.
@ SkipCredentialsRequest
Skip credentials if the provided one are not valid, let the provider be invalid, avoiding to block th...
@ ParallelThreadLoading
Provider is created in a parallel thread than the one where it will live.
QFlags< ProjectFlag > ProjectFlags
static QString geoNone()
Constant that holds the string representation for "No ellipse/No CRS".
@ Preferred
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
virtual bool readXml(const QDomElement &collectionElem, const QgsPropertiesDefinition &definitions)
Reads property collection state from an XML element.
QList< QgsAction > actions(const QString &actionScope=QString()) const
Returns a list of actions that are available in the given action scope.
Utility class that encapsulates an action based on vector attributes.
Represents a map layer containing a set of georeferenced annotations, e.g.
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.
Manages zip/unzip operations for an archive.
A container for attribute editors, used to group them visually in the attribute form if it is set to ...
QList< QgsAttributeEditorElement * > children() const
Gets a list of the children elements of this container.
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.
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.
static QColor colorFromString(const QString &string)
Decodes a string into a color value.
static QString colorToString(const QColor &color)
Encodes a color into a string value.
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.
static QgsCoordinateReferenceSystem createCompoundCrs(const QgsCoordinateReferenceSystem &horizontalCrs, const QgsCoordinateReferenceSystem &verticalCrs, QString &error)
Given a horizontal and vertical CRS, attempts to create a compound CRS from them.
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.
QString toWkt(Qgis::CrsWktVariant variant=Qgis::CrsWktVariant::Wkt1Gdal, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
static QgsCoordinateReferenceSystem fromSrsId(long srsId)
Creates a CRS from a specified QGIS SRS ID.
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.
Abstract base class for spatial data provider implementations.
@ EvaluateDefaultValues
Evaluate default values on provider side when calling QgsVectorDataProvider::defaultValue( int index ...
Stores the component parts of a data source URI (e.g.
Manages storage of a set of elevation profiles.
Renders elevation shading on an image with different methods (eye dome lighting, hillshading,...
A embedded script entity for QgsObjectEntityVisitorInterface.
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...
An abstract base class for defining QgsExpression functions.
An expression node for expression functions.
Handles parsing and evaluation of expressions (formerly called "search strings").
virtual QgsLegendSymbolList legendSymbolItems() const
Returns a list of symbology items for the legend.
Encapsulate a field in an attribute table or data source.
Container of fields for a vector layer.
Stores global configuration for labeling engine.
Layer tree group node serves as a container for layers and further groups.
QgsLayerTreeGroup * findGroup(const QString &name)
Find group node with specified name.
void readChildrenFromXml(const QDomElement &element, const QgsReadWriteContext &context)
Read children from XML and append them to the group.
QString name() const override
Returns the group's name.
void insertChildNodes(int index, const QList< QgsLayerTreeNode * > &nodes)
Insert existing nodes at specified position.
QgsLayerTreeGroup * clone() const override
Returns a clone of the group.
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).
Base class for nodes in a layer tree.
QList< QgsLayerTreeNode * > abandonChildren()
Removes the children, disconnect all the forwarded and external signals and sets their parent to null...
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.
QList< QgsLayerTreeNode * > children()
Gets list of children of the node. Children are owned by the parent.
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).
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.
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
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.
Manages storage of a set of layouts.
Stores information about one class/rule of a vector layer renderer in a unified way that can be used ...
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.
QFlags< ReadFlag > ReadFlags
QString source() const
Returns the source for the layer.
QString providerType() const
Returns the provider type (provider key) for this layer.
void configChanged()
Emitted whenever the configuration is changed.
static Qgis::DataProviderReadFlags providerReadFlags(const QDomNode &layerNode, QgsMapLayer::ReadFlags layerReadFlags)
Returns provider read flag deduced from layer read flags layerReadFlags and a dom node layerNode that...
QString originalXmlProperties() const
Returns the XML properties of the original layer as they were when the layer was first read from the ...
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...
@ FlagReadExtentFromXml
Read extent from xml and skip get extent from provider.
@ 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.
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, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
Adds a message to the log instance (and creates it if necessary).
An interface for classes which can visit various object entity (e.g.
virtual bool visitEmbeddedScript(const QgsEmbeddedScriptEntity &entity, const QgsObjectVisitorContext &context)
Called when the visitor will visit an embedded script entity.
A QgsObjectEntityVisitorInterface context object.
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.
Allows managing the zip/unzip actions on project files.
QString projectFile() const
Returns the current .qgs project 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 files.
Contains settings and properties relating to how a QgsProject should display values such as map coord...
Contains elevation properties for a QgsProject.
Contains settings and properties relating to how a QgsProject should interact with a GPS device.
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.
void subkeyList(QStringList &entries) const
Returns any sub-keys contained by this property which themselves contain other keys.
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.
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.
void setDefaultSymbol(Qgis::SymbolType symbolType, QgsSymbol *symbol)
Sets the project default symbol for a given type.
void setRandomizeDefaultSymbolColor(bool randomized)
Sets whether the default symbol fill color is randomized.
void setDefaultColorRamp(QgsColorRamp *colorRamp)
Sets the project default color ramp.
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...
static Qgis::ProjectTrustStatus checkUserTrust(QgsProject *project)
Returns the current trust status of the specified project.
Describes 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,...
void mapScalesChanged()
Emitted when the list of custom project map scales changes.
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 void oldProjectVersionWarning(const QString &warning)
Emitted when an old project file is read.
Q_DECL_DEPRECATED bool evaluateDefaultValues() const
Should default values be evaluated on provider side when requested and not when committed.
Qgis::DistanceUnit distanceUnits
void layersAddedWithoutLegend(const QList< QgsMapLayer * > &layers)
Emitted when layers were added to the registry without adding to the legend.
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.
void readProjectWithContext(const QDomDocument &document, QgsReadWriteContext &context)
Emitted when a project is being read.
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.
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.
void titleChanged()
Emitted when the title 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...
void setScaleMethod(Qgis::ScaleCalculationMethod method)
Sets the method to use for map scale calculations for the project.
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 a string using the Qt QTranslator mechanism.
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.
std::unique_ptr< 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.
Q_DECL_DEPRECATED void setAutoTransaction(bool autoTransaction)
Transactional editing means that on supported datasources (postgres databases) the edit state of all ...
@ WMSOnlineResource
Alias.
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...
bool setVerticalCrs(const QgsCoordinateReferenceSystem &crs, QString *errorMessage=nullptr)
Sets the project's vertical coordinate reference system.
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 crs3DChanged()
Emitted when the crs3D() of the project has changed.
void scaleMethodChanged()
Emitted when the project's scale method is changed.
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 specified scope and key.
Qgis::TransactionMode transactionMode
QgsAnnotationManager * annotationManager()
Returns pointer to the project's annotation manager.
QgsProjectDisplaySettings * displaySettings
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 transactionModeChanged()
Emitted when the transaction mode has changed.
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.
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.
Q_INVOKABLE QList< QgsMapLayer * > mapLayersByName(const QString &layerName) const
Retrieve a list of matching registered layers by layer name.
QgsCoordinateReferenceSystem crs3D() const
Returns the CRS to use for the project when transforming 3D data, or when z/elevation value handling ...
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
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 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...
Qgis::ProjectCapabilities capabilities() const
Returns the project's capabilities, which dictate optional functionality which can be selectively ena...
bool loadFunctionsFromProject(bool force=false)
Loads python expression functions stored in the current project.
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...
const QgsElevationProfileManager * elevationProfileManager() const
Returns the project's elevation profile manager, which manages elevation profiles within the project.
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 readProject(const QDomDocument &document)
Emitted when a project is being read.
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 specified scope and key.
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.
const QgsProjectViewSettings * viewSettings() const
Returns the project's view settings, which contains settings and properties relating to how a QgsProj...
void cleanFunctionsFromProject()
Unloads python expression functions stored in the current project and reloads local functions from th...
QgsCoordinateReferenceSystem verticalCrs() const
Returns the project's vertical coordinate reference system.
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.
const QgsSelectiveMaskingSourceSetManager * selectiveMaskingSourceSetManager() const
Returns the project's selective masking set manager, which manages storage of a set of selective mask...
void legendLayersAdded(const QList< QgsMapLayer * > &layers)
Emitted when layers were 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.
void writeProject(QDomDocument &document)
Emitted when the project is being written.
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 verticalCrsChanged()
Emitted when the verticalCrs() of the project has changed.
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 an integer key value.
void clear() final
Removes all properties from the collection.
@ 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.
static bool run(const QString &command, const QString &messageOnError=QString())
Execute a Python statement.
static bool isValid()
Returns true if the runner has an instance (and thus is able to run commands).
A container for the context for various read/write operations on objects.
void setCurrentLayerId(const QString &layerId)
Sets the current layer id.
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.
Manages a set of relations between layers.
Represents a relationship between two vector layers.
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.
Manages storage of a set of selective masking source sets.
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.
Stores configuration of snapping settings for the project.
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.
void triggerIconRebuild()
Triggers emission of the rebuildIconPreviews() signal.
static QgsStyle * defaultStyle(bool initialize=true)
Returns the default application-wide style.
Represents a transaction group.
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.
Represents a vector layer which manages a vector based dataset.
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.
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...
QgsFeatureRenderer * renderer()
Returns the feature renderer used for rendering the features in the layer in 2D map views.
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...
QgsActionManager * actions()
Returns all layer actions defined on this layer.
QgsEditFormConfig editFormConfig
static bool isZipFile(const QString &filename)
Returns true if the file name is a zipped file ( i.e with a '.qgz' extension, false otherwise.
QList< QPair< QColor, QString > > QgsNamedColorList
List of colors paired with a friendly display name identifying the color.
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
#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.
void dump_(const QgsProjectPropertyKey &topQgsPropertyKey)
QgsProjectProperty * findKey_(const QString &scope, const QString &key, QgsProjectPropertyKey &rootProperty)
Takes the given scope and key and convert them to a string list of key tokens that will be used to na...
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 FONTMARKER_CHR_FIX
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS_NON_FATAL
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS
Qgis::DataProviderReadFlags 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.
Contains information relating to a node (i.e.