86#include <QApplication>
91#include <QRegularExpression>
92#include <QStandardPaths>
94#include <QTemporaryFile>
100#include "moc_qgsproject.cpp"
102using namespace Qt::StringLiterals;
105#include <sys/utime.h>
121QStringList makeKeyTokens_(
const QString &scope,
const QString &key )
123 QStringList keyTokens = QStringList( scope );
124 keyTokens += key.split(
'/', Qt::SkipEmptyParts );
127 keyTokens.push_front( u
"properties"_s );
150 QStringList keySequence = makeKeyTokens_( scope, key );
152 while ( !keySequence.isEmpty() )
156 if ( keySequence.first() == currentProperty->
name() )
159 keySequence.pop_front();
161 if ( 1 == keySequence.count() )
164 return currentProperty->
find( keySequence.front() );
166 else if ( keySequence.isEmpty() )
171 return currentProperty;
173 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
175 if ( nextProperty->
isKey() )
179 else if ( nextProperty->
isValue() && 1 == keySequence.count() )
185 return currentProperty;
223 const QVariant &value,
224 bool &propertiesModified )
226 QStringList keySequence = makeKeyTokens_( scope, key );
233 propertiesModified =
false;
234 while ( ! keySequence.isEmpty() )
238 if ( keySequence.first() == currentProperty->
name() )
241 keySequence.pop_front();
245 if ( 1 == keySequence.count() )
248 if ( !property || property->value() != value )
250 currentProperty->
setValue( keySequence.front(), value );
251 propertiesModified =
true;
254 return currentProperty;
258 else if ( keySequence.isEmpty() )
260 if ( currentProperty->
value() != value )
263 propertiesModified =
true;
266 return currentProperty;
268 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
272 if ( currentProperty )
283 if ( ( newPropertyKey = currentProperty->
addKey( keySequence.first() ) ) )
285 currentProperty = newPropertyKey;
315 QStringList keySequence = makeKeyTokens_( scope, key );
317 while ( ! keySequence.isEmpty() )
321 if ( keySequence.first() == currentProperty->
name() )
324 keySequence.pop_front();
328 if ( 1 == keySequence.count() )
330 currentProperty->
removeKey( keySequence.front() );
335 else if ( keySequence.isEmpty() )
337 previousQgsPropertyKey->
removeKey( currentProperty->
name() );
339 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
341 previousQgsPropertyKey = currentProperty;
344 if ( currentProperty )
371 , mSnappingConfig( this )
390 mProperties.setName( u
"properties"_s );
393 mMainAnnotationLayer->setParent(
this );
400 mLayerTreeRegistryBridge = std::make_unique<QgsLayerTreeRegistryBridge>( mRootGroup.get(),
this,
this );
407 this, [
this](
const QStringList &
layers ) { mProjectScope.reset(); emit layersWillBeRemoved( layers ); } );
409 this, [
this](
const QList<QgsMapLayer *> &
layers ) { mProjectScope.reset(); emit layersWillBeRemoved( layers ); } );
411 this, [
this](
const QString & layer ) { mProjectScope.reset(); emit layerWillBeRemoved( layer ); } );
413 this, [
this](
QgsMapLayer * layer ) { mProjectScope.reset(); emit layerWillBeRemoved( layer ); } );
415 [
this](
const QStringList &
layers ) { mProjectScope.reset(); emit layersRemoved( layers ); } );
417 [
this](
const QString & layer ) { mProjectScope.reset(); emit layerRemoved( layer ); } );
419 [
this]() { mProjectScope.reset(); emit removeAll(); } );
421 [
this](
const QList< QgsMapLayer * > &
layers ) { mProjectScope.reset(); emit layersAdded( layers ); } );
423 [
this](
QgsMapLayer * layer ) { mProjectScope.reset(); emit layerWasAdded( layer ); } );
431 [
this](
const QList<QgsMapLayer *> &
layers )
433 for ( const auto &layer : layers )
435 disconnect( layer, &QgsMapLayer::dataSourceChanged, mRelationManager.get(), &QgsRelationManager::updateRelationsStatus );
440 [
this](
const QList<QgsMapLayer *> &layers )
442 for ( const auto &layer : layers )
444 connect( layer, &QgsMapLayer::dataSourceChanged, mRelationManager.get(), &QgsRelationManager::updateRelationsStatus );
453 mStyleSettings->combinedStyleModel()->addDefaultStyle();
459 mIsBeingDeleted =
true;
462 releaseHandlesToProjectArchive();
464 if (
this == sProject )
491 if (
title == mMetadata.title() )
494 mMetadata.setTitle(
title );
495 mProjectScope.reset();
507 return mMetadata.title();
516 if ( oldEvaluateDefaultValues != newEvaluateDefaultValues )
519 for (
auto layerIt =
layers.constBegin(); layerIt !=
layers.constEnd(); ++layerIt )
521 if (
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layerIt.value() ) )
522 if ( vl->dataProvider() )
529 if ( oldTrustLayerMetadata != newTrustLayerMetadata )
532 for (
auto layerIt =
layers.constBegin(); layerIt !=
layers.constEnd(); ++layerIt )
534 if (
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layerIt.value() ) )
536 vl->setReadExtentFromXml( newTrustLayerMetadata );
541 if ( mFlags !=
flags )
556 newFlags &= ~(
static_cast< int >( flag ) );
571 return mSaveUserFull;
578 return mSaveDateTime;
599 if ( dirty && mDirtyBlockCount > 0 )
605 if ( mDirty == dirty )
616 if ( path == mHomePath )
620 mCachedHomePath.clear();
621 mProjectScope.reset();
632 const QList<QgsAttributeEditorElement *> elements = parent->
children();
640 translationContext->
registerTranslation( u
"project:layers:%1:formcontainers"_s.arg( layerId ), container->
name() );
642 if ( !container->
children().empty() )
653 const QList<QgsLayerTreeLayer *>
layers = mRootGroup->findLayers();
657 translationContext->
registerTranslation( u
"project:layers:%1"_s.arg( layer->layerId() ), layer->name() );
669 for (
const QgsField &field : fields )
674 if ( field.alias().isEmpty() )
675 fieldName = field.name();
677 fieldName = field.alias();
679 translationContext->
registerTranslation( u
"project:layers:%1:fieldaliases"_s.arg( vlayer->
id() ), fieldName );
682 if ( !field.constraints().constraintDescription().isEmpty() )
683 translationContext->
registerTranslation( u
"project:layers:%1:constraintdescriptions"_s.arg( vlayer->
id() ), field.constraints().constraintDescription() );
687 if ( field.editorWidgetSetup().type() ==
"ValueRelation"_L1 )
689 translationContext->
registerTranslation( u
"project:layers:%1:fields:%2:valuerelationvalue"_s.arg( vlayer->
id(), field.name() ), field.editorWidgetSetup().config().value( u
"Value"_s ).toString() );
690 translationContext->
registerTranslation( u
"project:layers:%1:fields:%2:valuerelationdescription"_s.arg( vlayer->
id(), field.name() ), field.editorWidgetSetup().config().value( u
"Description"_s ).toString() );
694 if ( field.editorWidgetSetup().type() ==
"ValueMap"_L1 )
696 if ( field.editorWidgetSetup().config().value( u
"map"_s ).canConvert<QList<QVariant>>() )
698 const QList<QVariant> valueList = field.editorWidgetSetup().config().value( u
"map"_s ).toList();
700 for (
int i = 0, row = 0; i < valueList.count(); i++, row++ )
702 translationContext->
registerTranslation( u
"project:layers:%1:fields:%2:valuemapdescriptions"_s.arg( vlayer->
id(), field.name() ), valueList[i].toMap().constBegin().key() );
714 translationContext->
registerTranslation( u
"project:layers:%1:actiondescriptions"_s.arg( vlayer->
id() ), action.name() );
715 translationContext->
registerTranslation( u
"project:layers:%1:actionshorttitles"_s.arg( vlayer->
id() ), action.shortTitle() );
723 translationContext->
registerTranslation( u
"project:layers:%1:legendsymbollabels"_s.arg( vlayer->
id() ), item.label() );
741 mapLayer->metadata().registerTranslations( translationContext );
746 const QList<QgsLayerTreeGroup *> groupLayers = mRootGroup->findGroups(
true );
753 const QList<QgsRelation> &relations = mRelationManager->relations().values();
760 mMetadata.registerTranslations( translationContext );
767 mDataDefinedServerProperties = properties;
774 return mDataDefinedServerProperties;
781 switch ( mTransactionMode )
792 return mEditBufferGroup.startEditing();
802 switch ( mTransactionMode )
809 commitErrors.append( tr(
"Trying to commit changes without a layer specified. This only works if the transaction mode is buffered" ) );
818 return mEditBufferGroup.commitChanges( commitErrors, stopEditing );
828 switch ( mTransactionMode )
835 rollbackErrors.append( tr(
"Trying to roll back changes without a layer specified. This only works if the transaction mode is buffered" ) );
838 bool success = vectorLayer->
rollBack( stopEditing );
844 return mEditBufferGroup.rollBack( rollbackErrors, stopEditing );
854 if ( name == mFile.fileName() )
857 const QString oldHomePath =
homePath();
859 mFile.setFileName( name );
860 mCachedHomePath.clear();
861 mProjectScope.reset();
865 const QString newHomePath =
homePath();
866 if ( newHomePath != oldHomePath )
877 return mFile.fileName();
884 mOriginalPath = path;
891 return mOriginalPath;
898 return QFileInfo( mFile );
916 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
921 return QFileInfo( mFile.fileName() ).lastModified();
932 if ( mFile.fileName().isEmpty() )
935 return QFileInfo( mFile.fileName() ).absolutePath();
946 if ( mFile.fileName().isEmpty() )
949 return QFileInfo( mFile.fileName() ).absoluteFilePath();
960 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
965 return QFileInfo( mFile.fileName() ).completeBaseName();
973 const bool absolutePaths =
readBoolEntry( u
"Paths"_s, u
"/Absolute"_s,
false );
984 writeEntry( u
"Paths"_s, u
"/Absolute"_s,
true );
987 writeEntry( u
"Paths"_s, u
"/Absolute"_s,
false );
1004 return mCrs3D.isValid() ? mCrs3D : mCrs;
1016 writeEntry( u
"SpatialRefSys"_s, u
"/ProjectionsEnabled"_s,
crs.isValid() ? 1 : 0 );
1017 mProjectScope.reset();
1021 if ( !mMainAnnotationLayer->crs().isValid() || mMainAnnotationLayer->isEmpty() )
1022 mMainAnnotationLayer->setCrs(
crs );
1031 if ( oldCrs3D != mCrs3D )
1035 if ( adjustEllipsoid )
1044 if ( !
crs().isValid() )
1057 mProjectScope.reset();
1067 switch ( mCrs.type() )
1070 QgsDebugError( u
"Project has a vertical CRS set as the horizontal CRS!"_s );
1074 return mCrs.verticalCrs();
1089 return mVerticalCrs;
1096 if (
crs.isValid() )
1099 switch (
crs.type() )
1117 *errorMessage = QObject::tr(
"Specified CRS is a %1 CRS, not a Vertical CRS" ).arg(
qgsEnumValueToKey(
crs.type() ) );
1122 if (
crs != mVerticalCrs )
1127 switch ( mCrs.type() )
1130 if (
crs != oldVerticalCrs )
1133 *errorMessage = QObject::tr(
"Project CRS is a Compound CRS, specified Vertical CRS will be ignored" );
1139 if (
crs != oldVerticalCrs )
1142 *errorMessage = QObject::tr(
"Project CRS is a Geographic 3D CRS, specified Vertical CRS will be ignored" );
1148 if (
crs != oldVerticalCrs )
1151 *errorMessage = QObject::tr(
"Project CRS is a Geocentric CRS, specified Vertical CRS will be ignored" );
1157 if ( mCrs.hasVerticalAxis() &&
crs != oldVerticalCrs )
1160 *errorMessage = QObject::tr(
"Project CRS is a Projected 3D CRS, specified Vertical CRS will be ignored" );
1178 res = rebuildCrs3D( errorMessage );
1179 mProjectScope.reset();
1186 if ( mCrs3D != oldCrs3D )
1197 return mTransformContext;
1204 if ( context == mTransformContext )
1207 mTransformContext = context;
1208 mProjectScope.reset();
1210 mMainAnnotationLayer->setTransformContext( context );
1211 for (
auto &layer : mLayerStore.get()->mapLayers() )
1213 layer->setTransformContext( context );
1222 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
1226 if ( !mIsBeingDeleted )
1235 mProjectScope.reset();
1236 mFile.setFileName( QString() );
1237 mProperties.clearKeys();
1239 mSaveUserFull.clear();
1240 mSaveDateTime = QDateTime();
1243 mCachedHomePath.clear();
1247 mCustomVariables.clear();
1253 if ( !mSettings.value( u
"projects/anonymize_new_projects"_s,
false,
QgsSettings::Core ).toBool() )
1255 mMetadata.setCreationDateTime( QDateTime::currentDateTime() );
1274 mEmbeddedLayers.clear();
1275 mRelationManager->clear();
1276 mAnnotationManager->clear();
1277 mLayoutManager->clear();
1278 mElevationProfileManager->clear();
1279 m3DViewsManager->clear();
1280 mBookmarkManager->clear();
1281 mSensorManager->clear();
1282 mViewSettings->reset();
1283 mTimeSettings->reset();
1284 mElevationProperties->reset();
1285 mDisplaySettings->reset();
1286 mGpsSettings->reset();
1287 mSnappingConfig.reset();
1292 mMapThemeCollection = std::make_unique< QgsMapThemeCollection >(
this );
1295 mLabelingEngineSettings->clear();
1299 releaseHandlesToProjectArchive();
1301 mAuxiliaryStorage = std::make_unique< QgsAuxiliaryStorage >();
1302 mArchive = std::make_unique< QgsArchive >();
1305 mStyleSettings->reset();
1309 if ( !mIsBeingDeleted )
1317 writeEntry( u
"PositionPrecision"_s, u
"/Automatic"_s,
true );
1318 writeEntry( u
"PositionPrecision"_s, u
"/DecimalPlaces"_s, 2 );
1320 const bool defaultRelativePaths = mSettings.value( u
"/qgis/defaultProjectPathsRelative"_s,
true ).toBool();
1323 int red = mSettings.value( u
"qgis/default_canvas_color_red"_s, 255 ).toInt();
1324 int green = mSettings.value( u
"qgis/default_canvas_color_green"_s, 255 ).toInt();
1325 int blue = mSettings.value( u
"qgis/default_canvas_color_blue"_s, 255 ).toInt();
1328 red = mSettings.value( u
"qgis/default_selection_color_red"_s, 255 ).toInt();
1329 green = mSettings.value( u
"qgis/default_selection_color_green"_s, 255 ).toInt();
1330 blue = mSettings.value( u
"qgis/default_selection_color_blue"_s, 0 ).toInt();
1331 const int alpha = mSettings.value( u
"qgis/default_selection_color_alpha"_s, 255 ).toInt();
1334 mSnappingConfig.clearIndividualLayerSettings();
1337 mRootGroup->clear();
1338 if ( mMainAnnotationLayer )
1339 mMainAnnotationLayer->reset();
1341 snapSingleBlocker.release();
1343 if ( !mBlockSnappingUpdates )
1349 if ( !mBlockChangeSignalsDuringClear )
1361 topQgsPropertyKey.
dump();
1394 const QDomElement propertiesElem = doc.documentElement().firstChildElement( u
"properties"_s );
1396 if ( propertiesElem.isNull() )
1401 const QDomNodeList scopes = propertiesElem.childNodes();
1403 if ( propertiesElem.firstChild().isNull() )
1405 QgsDebugError( u
"empty ``properties'' XML tag ... bailing"_s );
1409 if ( ! project_properties.
readXml( propertiesElem ) )
1425 const QDomElement ddElem = doc.documentElement().firstChildElement( u
"dataDefinedServerProperties"_s );
1426 if ( !ddElem.isNull() )
1428 if ( !ddServerProperties.
readXml( ddElem, dataDefinedServerPropertyDefinitions ) )
1430 QgsDebugError( u
"dataDefinedServerProperties.readXml() failed"_s );
1433 return ddServerProperties;
1440static void _getTitle(
const QDomDocument &doc, QString &title )
1442 const QDomElement titleNode = doc.documentElement().firstChildElement( u
"title"_s );
1446 if ( titleNode.isNull() )
1452 if ( !titleNode.hasChildNodes() )
1458 const QDomNode titleTextNode = titleNode.firstChild();
1460 if ( !titleTextNode.isText() )
1466 const QDomText titleText = titleTextNode.toText();
1468 title = titleText.data();
1472static void readProjectFileMetadata(
const QDomDocument &doc, QString &lastUser, QString &lastUserFull, QDateTime &lastSaveDateTime )
1474 const QDomNodeList nl = doc.elementsByTagName( u
"qgis"_s );
1482 const QDomNode qgisNode = nl.item( 0 );
1484 const QDomElement qgisElement = qgisNode.toElement();
1485 lastUser = qgisElement.attribute( u
"saveUser"_s, QString() );
1486 lastUserFull = qgisElement.attribute( u
"saveUserFull"_s, QString() );
1487 lastSaveDateTime = QDateTime::fromString( qgisElement.attribute( u
"saveDateTime"_s, QString() ), Qt::ISODate );
1492 const QDomNodeList nl = doc.elementsByTagName( u
"qgis"_s );
1496 QgsDebugError( u
" unable to find qgis element in project file"_s );
1500 const QDomNode qgisNode = nl.item( 0 );
1502 const QDomElement qgisElement = qgisNode.toElement();
1504 return projectVersion;
1511 return mSnappingConfig;
1530 if ( mAvoidIntersectionsMode == mode )
1533 mAvoidIntersectionsMode = mode;
1567void QgsProject::preloadProviders(
const QVector<QDomNode> ¶llelLayerNodes,
1569 QMap<QString, QgsDataProvider *> &loadedProviders,
1571 int totalProviderCount )
1576 QMap<QString, LayerToLoad> layersToLoad;
1578 for (
const QDomNode &node : parallelLayerNodes )
1582 const QDomElement layerElement = node.toElement();
1584 layerToLoad.
layerId = layerElement.namedItem( u
"id"_s ).toElement().text();
1585 layerToLoad.
provider = layerElement.namedItem( u
"provider"_s ).toElement().text();
1586 layerToLoad.
dataSource = layerElement.namedItem( u
"datasource"_s ).toElement().text();
1597 layersToLoad.insert( layerToLoad.
layerId, layerToLoad );
1600 while ( !layersToLoad.isEmpty() )
1602 const QList<LayerToLoad> layersToAttemptInParallel = layersToLoad.values();
1603 QString layerToAttemptInMainThread;
1605 QHash<QString, QgsRunnableProviderCreator *> runnables;
1606 QThreadPool threadPool;
1609 for (
const LayerToLoad &lay : layersToAttemptInParallel )
1611 QgsRunnableProviderCreator *run =
new QgsRunnableProviderCreator( lay.layerId, lay.provider, lay.dataSource, lay.options, lay.flags );
1612 runnables.insert( lay.layerId, run );
1618 layersToLoad.remove( layId );
1620 QgsRunnableProviderCreator *finishedRun = runnables.value( layId,
nullptr );
1621 Q_ASSERT( finishedRun );
1623 std::unique_ptr<QgsDataProvider> provider( finishedRun->
dataProvider() );
1624 Q_ASSERT( provider && provider->isValid() );
1626 loadedProviders.insert( layId, provider.release() );
1631 if ( layerToAttemptInMainThread.isEmpty() )
1632 layerToAttemptInMainThread = layId;
1636 if ( i == parallelLayerNodes.count() || !isValid )
1639 threadPool.start( run );
1643 threadPool.waitForDone();
1645 qDeleteAll( runnables );
1648 auto it = layersToLoad.find( layerToAttemptInMainThread );
1649 if ( it != layersToLoad.end() )
1651 std::unique_ptr<QgsDataProvider> provider;
1654 const LayerToLoad &lay = it.value();
1658 QgsScopedRuntimeProfile profile(
"Create data providers/" + lay.
layerId, u
"projectload"_s );
1661 if ( provider && provider->isValid() )
1666 layersToLoad.erase( it );
1669 loadedProviders.insert( layerId, provider.release() );
1677void QgsProject::releaseHandlesToProjectArchive()
1679 mStyleSettings->removeProjectStyle();
1682bool QgsProject::rebuildCrs3D( QString *error )
1685 if ( !mCrs.isValid() )
1687 mCrs3D = QgsCoordinateReferenceSystem();
1689 else if ( !mVerticalCrs.isValid() )
1695 switch ( mCrs.type() )
1707 res = mCrs3D.isValid();
1713 mCrs3D = QgsCoordinateReferenceSystem();
1728 res = mCrs3D.isValid();
1736bool QgsProject::_getMapLayers(
const QDomDocument &doc, QList<QDomNode> &brokenNodes,
Qgis::ProjectReadFlags flags )
1743 QDomElement layerElement = doc.documentElement().firstChildElement( u
"projectlayers"_s ).firstChildElement( u
"maplayer"_s );
1747 if ( layerElement.isNull() )
1757 bool returnStatus =
true;
1760 while ( ! layerElement.isNull() )
1763 layerElement = layerElement.nextSiblingElement( u
"maplayer"_s );
1767 QgsScopedRuntimeProfile profile( tr(
"Sorting layers" ), u
"projectload"_s );
1768 const QgsLayerDefinition::DependencySorter depSorter( doc );
1769 if ( depSorter.hasCycle() )
1773 if ( depSorter.hasMissingDependency() )
1774 returnStatus =
false;
1778 const QVector<QDomNode> sortedLayerNodes = depSorter.sortedLayerNodes();
1779 const int totalLayerCount = sortedLayerNodes.count();
1781 QVector<QDomNode> parallelLoading;
1782 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;
1853bool QgsProject::addLayer(
const QDomElement &layerElem,
1854 QList<QDomNode> &brokenNodes,
1861 const QString type = layerElem.attribute( u
"type"_s );
1863 std::unique_ptr<QgsMapLayer>
mapLayer;
1865 QgsScopedRuntimeProfile profile( tr(
"Create layer" ), u
"projectload"_s );
1871 QgsDebugError( u
"Unknown layer type \"%1\""_s.arg( type ) );
1875 switch ( layerType )
1878 mapLayer = std::make_unique<QgsVectorLayer>();
1882 mapLayer = std::make_unique<QgsRasterLayer>();
1886 mapLayer = std::make_unique<QgsMeshLayer>();
1890 mapLayer = std::make_unique<QgsVectorTileLayer>();
1894 mapLayer = std::make_unique<QgsPointCloudLayer>();
1898 mapLayer = std::make_unique<QgsTiledSceneLayer>();
1903 const QString typeName = layerElem.attribute( u
"name"_s );
1910 const QgsAnnotationLayer::LayerOptions options( mTransformContext );
1911 mapLayer = std::make_unique<QgsAnnotationLayer>( QString(), options );
1917 const QgsGroupLayer::LayerOptions options( mTransformContext );
1918 mapLayer = std::make_unique<QgsGroupLayer>( QString(), options );
1933 const QString layerId { layerElem.namedItem( u
"id"_s ).toElement().text() };
1934 Q_ASSERT( ! layerId.isEmpty() );
1940 profile.switchTask( tr(
"Load layer source" ) );
1941 const bool layerIsValid =
mapLayer->readLayerXml( layerElem, context, layerFlags, provider ) &&
mapLayer->isValid();
1944 if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>(
mapLayer.get() ) )
1947 if ( vl->dataProvider() )
1954 profile.switchTask( tr(
"Add layer to project" ) );
1955 QList<QgsMapLayer *> newLayers;
1965 if ( QgsVectorLayer *vLayer = qobject_cast<QgsVectorLayer *>(
mapLayer.get() ) )
1967 vLayer->joinBuffer()->resolveReferences(
this );
1976 brokenNodes.push_back( layerElem );
1979 const bool wasEditable = layerElem.attribute( u
"editable"_s, u
"0"_s ).toInt();
1982 mapLayer->setCustomProperty( u
"_layer_was_editable"_s,
true );
1986 mapLayer->removeCustomProperty( u
"_layer_was_editable"_s );
1991 if ( ! layerWasStored )
1996 return layerIsValid;
2003 mFile.setFileName( filename );
2004 mCachedHomePath.clear();
2005 mProjectScope.reset();
2014 const QString filename = mFile.fileName();
2019 QTemporaryFile inDevice;
2020 if ( !inDevice.open() )
2022 setError( tr(
"Unable to open %1" ).arg( inDevice.fileName() ) );
2028 if ( !storage->readProject( filename, &inDevice, context ) )
2030 QString err = tr(
"Unable to open %1" ).arg( filename );
2031 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
2032 if ( !messages.isEmpty() )
2033 err += u
"\n\n"_s + messages.last().message();
2037 returnValue = unzip( inDevice.fileName(),
flags );
2043 returnValue = unzip( mFile.fileName(),
flags );
2047 mAuxiliaryStorage = std::make_unique< QgsAuxiliaryStorage >( *
this );
2048 const QFileInfo finfo( mFile.fileName() );
2049 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( u
"%1_attachments.zip"_s.arg( finfo.completeBaseName() ) );
2050 if ( QFile( attachmentsZip ).exists() )
2052 auto archive = std::make_unique<QgsArchive>();
2053 if ( archive->unzip( attachmentsZip ) )
2055 releaseHandlesToProjectArchive();
2056 mArchive = std::move( archive );
2059 returnValue = readProjectFile( mFile.fileName(),
flags );
2065 mFile.setFileName( filename );
2066 mCachedHomePath.clear();
2067 mProjectScope.reset();
2072 mTranslator.reset(
nullptr );
2085 ScopedIntIncrementor snapSignalBlock( &mBlockSnappingUpdates );
2087 QFile projectFile( filename );
2095 if ( QFile( u
"%1/%2.qm"_s.arg( QFileInfo( mFile ).
absolutePath(), localeFileName ) ).exists() )
2097 mTranslator = std::make_unique< QTranslator >();
2098 ( void )mTranslator->load( localeFileName, QFileInfo( mFile ).
absolutePath() );
2101 profile.switchTask( tr(
"Reading project file" ) );
2102 auto doc = std::make_unique<QDomDocument>( u
"qgis"_s );
2104 if ( !projectFile.open( QIODevice::ReadOnly | QIODevice::Text ) )
2106 projectFile.close();
2108 setError( tr(
"Unable to open %1" ).arg( projectFile.fileName() ) );
2113 QTextStream textStream( &projectFile );
2114 QString projectString = textStream.readAll();
2115 projectFile.close();
2117 for (
int i = 0; i < 32; i++ )
2119 if ( i == 9 || i == 10 || i == 13 )
2123 projectString.replace( QChar( i ), u
"%1%2%1"_s.arg(
FONTMARKER_CHR_FIX, QString::number( i ) ) );
2129 if ( !doc->setContent( projectString, &errorMsg, &line, &column ) )
2131 const QString errorString = tr(
"Project file read error in file %1: %2 at line %3 column %4" )
2132 .arg( projectFile.fileName(), errorMsg ).arg( line ).arg( column );
2134 setError( errorString );
2139 projectFile.close();
2144 const QgsProjectVersion fileVersion =
getVersion( *doc );
2147 profile.switchTask( tr(
"Updating project file" ) );
2148 if ( thisVersion > fileVersion )
2150 const bool isOlderMajorVersion = fileVersion.
majorVersion() < thisVersion.majorVersion();
2152 if ( isOlderMajorVersion )
2155 "version of qgis (saved in " + fileVersion.
text() +
2157 "). Problems may occur." );
2160 QgsProjectFileTransform projectFile( *doc, fileVersion );
2168 projectFile.updateRevision( thisVersion );
2170 else if ( fileVersion > thisVersion )
2173 "version of qgis (saved in " + fileVersion.
text() +
2175 "). Problems may occur." );
2181 profile.switchTask( tr(
"Creating auxiliary storage" ) );
2182 const QString
fileName = mFile.fileName();
2184 const QgsCoordinateReferenceSystem oldVerticalCrs =
verticalCrs();
2185 const QgsCoordinateReferenceSystem oldCrs3D = mCrs3D;
2189 std::unique_ptr<QgsAuxiliaryStorage> aStorage = std::move( mAuxiliaryStorage );
2190 std::unique_ptr<QgsArchive> archive = std::move( mArchive );
2194 mBlockChangeSignalsDuringClear =
true;
2196 mBlockChangeSignalsDuringClear =
false;
2201 releaseHandlesToProjectArchive();
2203 mAuxiliaryStorage = std::move( aStorage );
2204 mArchive = std::move( archive );
2207 mCachedHomePath.clear();
2208 mProjectScope.reset();
2209 mSaveVersion = fileVersion;
2212 profile.switchTask( tr(
"Reading properties" ) );
2218 QgsDebugMsgLevel( QString::number( mProperties.count() ) +
" properties read", 2 );
2221 dump_( mProperties );
2226 _getTitle( *doc, oldTitle );
2228 readProjectFileMetadata( *doc, mSaveUser, mSaveUserFull, mSaveDateTime );
2230 const QDomNodeList homePathNl = doc->elementsByTagName( u
"homePath"_s );
2231 if ( homePathNl.count() > 0 )
2233 const QDomElement homePathElement = homePathNl.at( 0 ).toElement();
2234 const QString
homePath = homePathElement.attribute( u
"path"_s );
2244 readNumEntry( u
"Gui"_s, u
"/CanvasColorGreenPart"_s, 255 ),
2245 readNumEntry( u
"Gui"_s, u
"/CanvasColorBluePart"_s, 255 ) );
2248 readNumEntry( u
"Gui"_s, u
"/SelectionColorGreenPart"_s, 255 ),
2249 readNumEntry( u
"Gui"_s, u
"/SelectionColorBluePart"_s, 255 ),
2250 readNumEntry( u
"Gui"_s, u
"/SelectionColorAlphaPart"_s, 255 ) );
2254 const QString distanceUnitString =
readEntry( u
"Measurement"_s, u
"/DistanceUnits"_s, QString() );
2255 if ( !distanceUnitString.isEmpty() )
2258 const QString areaUnitString =
readEntry( u
"Measurement"_s, u
"/AreaUnits"_s, QString() );
2259 if ( !areaUnitString.isEmpty() )
2264 QgsReadWriteContext context;
2269 QgsCoordinateReferenceSystem projectCrs;
2270 if (
readNumEntry( u
"SpatialRefSys"_s, u
"/ProjectionsEnabled"_s, 0 ) )
2273 const QDomNode srsNode = doc->documentElement().namedItem( u
"projectCrs"_s );
2274 if ( !srsNode.isNull() )
2276 projectCrs.
readXml( srsNode );
2281 const QString projCrsString =
readEntry( u
"SpatialRefSys"_s, u
"/ProjectCRSProj4String"_s );
2282 const long currentCRS =
readNumEntry( u
"SpatialRefSys"_s, u
"/ProjectCRSID"_s, -1 );
2283 const QString authid =
readEntry( u
"SpatialRefSys"_s, u
"/ProjectCrs"_s );
2286 const bool isUserAuthId = authid.startsWith(
"USER:"_L1, Qt::CaseInsensitive );
2287 if ( !authid.isEmpty() && !isUserAuthId )
2288 projectCrs = QgsCoordinateReferenceSystem( authid );
2291 if ( !projectCrs.
isValid() && currentCRS >= 0 )
2297 if ( !projCrsString.isEmpty() && ( authid.isEmpty() || isUserAuthId ) && ( !projectCrs.
isValid() || projectCrs.
toProj() != projCrsString ) )
2314 const QDomNode verticalCrsNode = doc->documentElement().namedItem( u
"verticalCrs"_s );
2315 if ( !verticalCrsNode.isNull() )
2323 QStringList datumErrors;
2324 if ( !mTransformContext.readXml( doc->documentElement(), context, datumErrors ) && !datumErrors.empty() )
2331 const QDomNode elevationShadingNode = doc->documentElement().namedItem( u
"elevation-shading-renderer"_s );
2332 if ( !elevationShadingNode.isNull() )
2334 mElevationShadingRenderer.readXml( elevationShadingNode.toElement(), context );
2341 const QStringList variableNames =
readListEntry( u
"Variables"_s, u
"/variableNames"_s );
2342 const QStringList variableValues =
readListEntry( u
"Variables"_s, u
"/variableValues"_s );
2344 mCustomVariables.clear();
2345 if ( variableNames.length() == variableValues.length() )
2347 for (
int i = 0; i < variableNames.length(); ++i )
2349 mCustomVariables.insert( variableNames.at( i ), variableValues.at( i ) );
2354 QgsMessageLog::logMessage( tr(
"Project Variables Invalid" ), tr(
"The project contains invalid variable settings." ) );
2362 QDomElement element = doc->documentElement().firstChildElement( u
"projectMetadata"_s );
2364 if ( !element.isNull() )
2366 mMetadata.readMetadataXml( element, context );
2371 mMetadata = QgsProjectMetadata();
2373 if ( mMetadata.title().isEmpty() && !oldTitle.isEmpty() )
2376 mMetadata.setTitle( oldTitle );
2382 element = doc->documentElement().firstChildElement( u
"transaction"_s );
2383 if ( !element.isNull() )
2390 element = doc->documentElement().firstChildElement( u
"autotransaction"_s );
2391 if ( ! element.isNull() )
2393 mTransactionMode =
static_cast<Qgis::TransactionMode>( element.attribute( u
"active"_s, u
"0"_s ).toInt() );
2398 profile.switchTask( tr(
"Loading layer tree" ) );
2399 mRootGroup->setCustomProperty( u
"loading"_s, 1 );
2401 QDomElement layerTreeElem = doc->documentElement().firstChildElement( u
"layer-tree-group"_s );
2402 if ( !layerTreeElem.isNull() )
2405 QgsLayerTree tempTree;
2414 mLayerTreeRegistryBridge->setEnabled(
false );
2417 profile.switchTask( tr(
"Reading map layers" ) );
2419 loadProjectFlags( doc.get() );
2421 QList<QDomNode> brokenNodes;
2422 const bool clean = _getMapLayers( *doc, brokenNodes,
flags );
2427 QgsDebugError( u
"Unable to get map layers from project file."_s );
2429 if ( !brokenNodes.isEmpty() )
2431 QgsDebugError(
"there are " + QString::number( brokenNodes.size() ) +
" broken layers" );
2436 mBadLayerHandler->handleBadLayers( brokenNodes );
2439 mMainAnnotationLayer->readLayerXml( doc->documentElement().firstChildElement( u
"main-annotation-layer"_s ), context );
2440 mMainAnnotationLayer->setTransformContext( mTransformContext );
2443 profile.switchTask( tr(
"Loading embedded layers" ) );
2444 loadEmbeddedNodes( mRootGroup.get(),
flags );
2448 profile.switchTask( tr(
"Resolving layer references" ) );
2449 QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
2450 for ( QMap<QString, QgsMapLayer *>::iterator it =
layers.begin(); it !=
layers.end(); ++it )
2452 it.value()->resolveReferences(
this );
2454 mMainAnnotationLayer->resolveReferences(
this );
2456 mLayerTreeRegistryBridge->setEnabled(
true );
2459 profile.switchTask( tr(
"Resolving references" ) );
2460 mRootGroup->resolveReferences(
this );
2463 if ( QgsProjectVersion( 3, 28, 0 ) > mSaveVersion )
2470 if ( !layerTreeElem.isNull() )
2472 mRootGroup->readLayerOrderFromXml( layerTreeElem );
2476 const QDomElement layerTreeCanvasElem = doc->documentElement().firstChildElement( u
"layer-tree-canvas"_s );
2477 if ( !layerTreeCanvasElem.isNull( ) )
2479 mRootGroup->readLayerOrderFromXml( layerTreeCanvasElem );
2483 if ( QgsProjectVersion( 3, 4, 0 ) > mSaveVersion )
2485 const QStringList requiredLayerIds =
readListEntry( u
"RequiredLayers"_s, u
"Layers"_s );
2486 for (
const QString &layerId : requiredLayerIds )
2488 if ( QgsMapLayer *layer =
mapLayer( layerId ) )
2493 const QStringList disabledLayerIds =
readListEntry( u
"Identify"_s, u
"/disabledLayers"_s );
2494 for (
const QString &layerId : disabledLayerIds )
2496 if ( QgsMapLayer *layer =
mapLayer( layerId ) )
2504 if ( QgsProjectVersion( 3, 26, 0 ) > mSaveVersion )
2507 QString styleName =
readEntry( u
"DefaultStyles"_s, u
"/Marker"_s );
2508 if ( !styleName.isEmpty() )
2513 styleName =
readEntry( u
"DefaultStyles"_s, u
"/Line"_s );
2514 if ( !styleName.isEmpty() )
2519 styleName =
readEntry( u
"DefaultStyles"_s, u
"/Fill"_s );
2520 if ( !styleName.isEmpty() )
2525 styleName =
readEntry( u
"DefaultStyles"_s, u
"/ColorRamp"_s );
2526 if ( !styleName.isEmpty() )
2536 double opacity = 1.0;
2539 double alpha =
readDoubleEntry( u
"DefaultStyles"_s, u
"/AlphaInt"_s, 255, &ok );
2541 opacity = alpha / 255.0;
2542 double newOpacity =
readDoubleEntry( u
"DefaultStyles"_s, u
"/Opacity"_s, 1.0, &ok );
2544 opacity = newOpacity;
2551 removeEntry( u
"DefaultStyles"_s, u
"/ColorRamp"_s );
2552 removeEntry( u
"DefaultStyles"_s, u
"/RandomColors"_s );
2553 removeEntry( u
"DefaultStyles"_s, u
"/AlphaInt"_s );
2562 profile.switchTask( tr(
"Storing original layer properties" ) );
2566 mRootGroup->removeCustomProperty( u
"loading"_s );
2568 profile.switchTask( tr(
"Loading map themes" ) );
2569 mMapThemeCollection = std::make_unique< QgsMapThemeCollection >(
this );
2571 mMapThemeCollection->readXml( *doc );
2573 profile.switchTask( tr(
"Loading label settings" ) );
2574 mLabelingEngineSettings->readSettingsFromProject(
this );
2576 const QDomElement labelEngineSettingsElement = doc->documentElement().firstChildElement( u
"labelEngineSettings"_s );
2577 mLabelingEngineSettings->readXml( labelEngineSettingsElement, context );
2579 mLabelingEngineSettings->resolveReferences(
this );
2583 profile.switchTask( tr(
"Loading annotations" ) );
2586 mAnnotationManager->readXml( doc->documentElement(), context );
2590 mAnnotationManager->readXmlAndUpgradeToAnnotationLayerItems( doc->documentElement(), context, mMainAnnotationLayer, mTransformContext );
2594 profile.switchTask( tr(
"Loading layouts" ) );
2595 mLayoutManager->readXml( doc->documentElement(), *doc );
2599 profile.switchTask( tr(
"Loading elevation profiles" ) );
2600 mElevationProfileManager->readXml( doc->documentElement(), *doc, context );
2601 mElevationProfileManager->resolveReferences(
this );
2606 profile.switchTask( tr(
"Loading 3D Views" ) );
2607 m3DViewsManager->readXml( doc->documentElement(), *doc );
2610 profile.switchTask( tr(
"Loading bookmarks" ) );
2611 mBookmarkManager->readXml( doc->documentElement(), *doc );
2613 profile.switchTask( tr(
"Loading sensors" ) );
2614 mSensorManager->readXml( doc->documentElement(), *doc );
2617 QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
2618 for ( QMap<QString, QgsMapLayer *>::iterator it = existingMaps.begin(); it != existingMaps.end(); ++it )
2620 it.value()->setDependencies( it.value()->dependencies() );
2623 profile.switchTask( tr(
"Loading snapping settings" ) );
2624 mSnappingConfig.readProject( *doc );
2627 profile.switchTask( tr(
"Loading view settings" ) );
2629 mViewSettings->setUseProjectScales(
readBoolEntry( u
"Scales"_s, u
"/useProjectScales"_s ) );
2630 const QStringList scales =
readListEntry( u
"Scales"_s, u
"/ScalesList"_s );
2631 QVector<double> res;
2632 for (
const QString &scale : scales )
2634 const QStringList parts = scale.split(
':' );
2635 if ( parts.size() != 2 )
2639 const double denominator = QLocale().toDouble( parts[1], &ok );
2645 mViewSettings->setMapScales( res );
2646 const QDomElement viewSettingsElement = doc->documentElement().firstChildElement( u
"ProjectViewSettings"_s );
2647 if ( !viewSettingsElement.isNull() )
2648 mViewSettings->readXml( viewSettingsElement, context );
2651 profile.switchTask( tr(
"Loading style properties" ) );
2652 const QDomElement styleSettingsElement = doc->documentElement().firstChildElement( u
"ProjectStyleSettings"_s );
2653 if ( !styleSettingsElement.isNull() )
2655 mStyleSettings->removeProjectStyle();
2656 mStyleSettings->readXml( styleSettingsElement, context,
flags );
2660 profile.switchTask( tr(
"Loading temporal settings" ) );
2661 const QDomElement timeSettingsElement = doc->documentElement().firstChildElement( u
"ProjectTimeSettings"_s );
2662 if ( !timeSettingsElement.isNull() )
2663 mTimeSettings->readXml( timeSettingsElement, context );
2666 profile.switchTask( tr(
"Loading elevation properties" ) );
2667 const QDomElement elevationPropertiesElement = doc->documentElement().firstChildElement( u
"ElevationProperties"_s );
2668 if ( !elevationPropertiesElement.isNull() )
2669 mElevationProperties->readXml( elevationPropertiesElement, context );
2670 mElevationProperties->resolveReferences(
this );
2672 profile.switchTask( tr(
"Loading display settings" ) );
2674 const QDomElement displaySettingsElement = doc->documentElement().firstChildElement( u
"ProjectDisplaySettings"_s );
2675 if ( !displaySettingsElement.isNull() )
2676 mDisplaySettings->readXml( displaySettingsElement, context );
2679 profile.switchTask( tr(
"Loading GPS settings" ) );
2681 const QDomElement gpsSettingsElement = doc->documentElement().firstChildElement( u
"ProjectGpsSettings"_s );
2682 if ( !gpsSettingsElement.isNull() )
2683 mGpsSettings->readXml( gpsSettingsElement, context );
2684 mGpsSettings->resolveReferences(
this );
2687 profile.switchTask( tr(
"Updating variables" ) );
2689 profile.switchTask( tr(
"Updating CRS" ) );
2693 if ( mCrs3D != oldCrs3D )
2698 profile.switchTask( tr(
"Reading external settings" ) );
2702 profile.switchTask( tr(
"Updating interface" ) );
2704 snapSignalBlock.release();
2705 if ( !mBlockSnappingUpdates )
2726 const QString newFileName( u
"%1/%2.qgs"_s.arg( QFileInfo( mFile ).
absolutePath(), localeFileName ) );
2740 const QMap<QString, QgsMapLayer *> loadedLayers =
mapLayers();
2741 for (
auto it = loadedLayers.constBegin(); it != loadedLayers.constEnd(); ++it )
2743 if ( it.value()->isValid() && it.value()->customProperty( u
"_layer_was_editable"_s ).toBool() )
2745 if ( QgsVectorLayer *vl = qobject_cast< QgsVectorLayer * >( it.value() ) )
2747 it.value()->removeCustomProperty( u
"_layer_was_editable"_s );
2759 const auto constChildren = group->
children();
2760 for ( QgsLayerTreeNode *child : constChildren )
2773 QList<QgsLayerTreeNode *> clonedChildren;
2774 const QList<QgsLayerTreeNode *> constChildren = newGroup->children();
2775 clonedChildren.reserve( constChildren.size() );
2776 for ( QgsLayerTreeNode *newGroupChild : constChildren )
2777 clonedChildren << newGroupChild->clone();
2784 loadEmbeddedNodes( childGroup,
flags );
2789 if ( child->customProperty( u
"embedded"_s ).toInt() )
2791 QList<QDomNode> brokenNodes;
2794 valid = valid &&
false;
2809 return mCustomVariables;
2816 if ( variables == mCustomVariables )
2820 QStringList variableNames;
2821 QStringList variableValues;
2823 QVariantMap::const_iterator it = variables.constBegin();
2824 for ( ; it != variables.constEnd(); ++it )
2826 variableNames << it.key();
2827 variableValues << it.value().toString();
2830 writeEntry( u
"Variables"_s, u
"/variableNames"_s, variableNames );
2831 writeEntry( u
"Variables"_s, u
"/variableValues"_s, variableValues );
2833 mCustomVariables = variables;
2834 mProjectScope.reset();
2843 *mLabelingEngineSettings = settings;
2851 return *mLabelingEngineSettings;
2858 mProjectScope.reset();
2859 return mLayerStore.get();
2866 return mLayerStore.get();
2873 QList<QgsVectorLayer *>
layers;
2874 const QStringList layerIds =
readListEntry( u
"Digitizing"_s, u
"/AvoidIntersectionsList"_s, QStringList() );
2875 const auto constLayerIds = layerIds;
2876 for (
const QString &layerId : constLayerIds )
2889 list.reserve(
layers.size() );
2894 list << layer->id();
2897 writeEntry( u
"Digitizing"_s, u
"/AvoidIntersectionsList"_s, list );
2919 if ( mProjectScope )
2921 auto projectScope = std::make_unique< QgsExpressionContextScope >( *mProjectScope );
2928 projectScope->addFunction( u
"sensor_data"_s,
new GetSensorData(
sensorManager()->sensorsData() ) );
2930 return projectScope.release();
2933 mProjectScope = std::make_unique< QgsExpressionContextScope >( QObject::tr(
"Project" ) );
2937 QVariantMap::const_iterator it = vars.constBegin();
2939 for ( ; it != vars.constEnd(); ++it )
2941 mProjectScope->setVariable( it.key(), it.value(),
true );
2945 if ( projectPath.isEmpty() )
2946 projectPath = mOriginalPath;
2947 const QString projectFolder = QFileInfo( projectPath ).path();
2948 const QString projectFilename = QFileInfo( projectPath ).fileName();
2949 const QString projectBasename =
baseName();
2986 QVariantMap keywords;
2988 for (
auto it = metadataKeywords.constBegin(); it != metadataKeywords.constEnd(); ++it )
2990 keywords.insert( it.key(), it.value() );
2995 QVariantList layersIds;
2997 const QMap<QString, QgsMapLayer *> layersInProject = mLayerStore->mapLayers();
2998 layersIds.reserve( layersInProject.count() );
2999 layers.reserve( layersInProject.count() );
3000 for (
auto it = layersInProject.constBegin(); it != layersInProject.constEnd(); ++it )
3002 layersIds << it.value()->id();
3008 mProjectScope->addFunction( u
"project_color"_s,
new GetNamedProjectColor(
this ) );
3009 mProjectScope->addFunction( u
"project_color_object"_s,
new GetNamedProjectColorObject(
this ) );
3014void QgsProject::onMapLayersAdded(
const QList<QgsMapLayer *> &layers )
3018 const QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
3020 const auto constLayers =
layers;
3023 if ( ! layer->isValid() )
3026 if (
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer ) )
3029 if ( vlayer->dataProvider() )
3037 for ( QMap<QString, QgsMapLayer *>::const_iterator it = existingMaps.cbegin(); it != existingMaps.cend(); ++it )
3039 const QSet<QgsMapLayerDependency> deps = it.value()->dependencies();
3040 if ( deps.contains( layer->id() ) )
3043 it.value()->setDependencies( deps );
3048 updateTransactionGroups();
3050 if ( !mBlockSnappingUpdates && mSnappingConfig.addLayers(
layers ) )
3054void QgsProject::onMapLayersRemoved(
const QList<QgsMapLayer *> &layers )
3058 if ( !mBlockSnappingUpdates && mSnappingConfig.removeLayers(
layers ) )
3061 for ( QgsMapLayer *layer :
layers )
3063 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
3067 mEditBufferGroup.removeLayer( vlayer );
3071void QgsProject::cleanTransactionGroups(
bool force )
3075 bool changed =
false;
3076 for ( QMap< QPair< QString, QString>, QgsTransactionGroup *>::Iterator tg = mTransactionGroups.begin(); tg != mTransactionGroups.end(); )
3078 if ( tg.value()->isEmpty() || force )
3081 tg = mTransactionGroups.erase( tg );
3093void QgsProject::updateTransactionGroups()
3097 mEditBufferGroup.clear();
3099 switch ( mTransactionMode )
3103 cleanTransactionGroups(
true );
3108 cleanTransactionGroups(
true );
3111 cleanTransactionGroups(
false );
3115 bool tgChanged =
false;
3116 const auto constLayers =
mapLayers().values();
3117 for ( QgsMapLayer *layer : constLayers )
3119 if ( ! layer->isValid() )
3122 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
3126 switch ( mTransactionMode )
3138 QgsTransactionGroup *tg = mTransactionGroups.value( qMakePair( key, connString ) );
3142 tg =
new QgsTransactionGroup();
3143 mTransactionGroups.insert( qMakePair( key, connString ), tg );
3153 mEditBufferGroup.addLayer( vlayer );
3169 context.setProjectTranslator(
this );
3171 context.setCurrentLayerId( layerNode.toElement().firstChildElement( u
"id"_s ).text() );
3172 QList<QDomNode> brokenNodes;
3173 if ( addLayer( layerNode.toElement(), brokenNodes, context ) )
3181 layer->resolveReferences(
this );
3183 if ( layer->isValid() && layer->customProperty( u
"_layer_was_editable"_s ).toBool() )
3185 layer->startEditing();
3186 layer->removeCustomProperty( u
"_layer_was_editable"_s );
3198 mFile.setFileName( filename );
3200 mCachedHomePath.clear();
3208 mProjectScope.reset();
3214 const QString storageFilePath { storage->filePath( mFile.fileName() ) };
3215 if ( storageFilePath.isEmpty() )
3221 const QString tempPath = QStandardPaths::standardLocations( QStandardPaths::TempLocation ).at( 0 );
3222 const QString tmpZipFilename( tempPath + QDir::separator() + QUuid::createUuid().toString() );
3224 if ( !zip( tmpZipFilename ) )
3227 QFile tmpZipFile( tmpZipFilename );
3228 if ( !tmpZipFile.open( QIODevice::ReadOnly ) )
3230 setError( tr(
"Unable to read file %1" ).arg( tmpZipFilename ) );
3235 if ( !storage->writeProject( mFile.fileName(), &tmpZipFile, context ) )
3237 QString err = tr(
"Unable to save project to storage %1" ).arg( mFile.fileName() );
3238 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
3239 if ( !messages.isEmpty() )
3240 err += u
"\n\n"_s + messages.last().message();
3246 QFile::remove( tmpZipFilename );
3253 return zip( mFile.fileName() );
3259 const bool asOk = saveAuxiliaryStorage();
3260 const bool writeOk = writeProjectFile( mFile.fileName() );
3261 bool attachmentsOk =
true;
3262 if ( !mArchive->files().isEmpty() )
3264 const QFileInfo finfo( mFile.fileName() );
3265 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( u
"%1_attachments.zip"_s.arg( finfo.completeBaseName() ) );
3266 attachmentsOk = mArchive->zip( attachmentsZip );
3270 if ( ( !asOk || !attachmentsOk ) && writeOk )
3272 QStringList errorMessage;
3275 const QString err = mAuxiliaryStorage->errorString();
3276 errorMessage.append( tr(
"Unable to save auxiliary storage ('%1')" ).arg( err ) );
3278 if ( !attachmentsOk )
3280 errorMessage.append( tr(
"Unable to save attachments archive" ) );
3282 setError( errorMessage.join(
'\n' ) );
3285 return asOk && writeOk && attachmentsOk;
3289bool QgsProject::writeProjectFile(
const QString &filename )
3293 QFile projectFile( filename );
3299 const QFileInfo myFileInfo( projectFile );
3300 if ( myFileInfo.exists() && !myFileInfo.isWritable() )
3302 setError( tr(
"%1 is not writable. Please adjust permissions (if possible) and try again." )
3303 .arg( projectFile.fileName() ) );
3307 QgsReadWriteContext context;
3311 QDomImplementation::setInvalidDataPolicy( QDomImplementation::DropInvalidChars );
3313 const QDomDocumentType documentType =
3314 QDomImplementation().createDocumentType( u
"qgis"_s, u
"http://mrcc.com/qgis.dtd"_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 views3DElem = m3DViewsManager->writeXml( *doc );
3542 qgisNode.appendChild( views3DElem );
3546 const QDomElement bookmarkElem = mBookmarkManager->writeXml( *doc );
3547 qgisNode.appendChild( bookmarkElem );
3551 const QDomElement sensorElem = mSensorManager->writeXml( *doc );
3552 qgisNode.appendChild( sensorElem );
3556 const QDomElement viewSettingsElem = mViewSettings->writeXml( *doc, context );
3557 qgisNode.appendChild( viewSettingsElem );
3561 const QDomElement styleSettingsElem = mStyleSettings->writeXml( *doc, context );
3562 qgisNode.appendChild( styleSettingsElem );
3566 const QDomElement timeSettingsElement = mTimeSettings->writeXml( *doc, context );
3567 qgisNode.appendChild( timeSettingsElement );
3571 const QDomElement elevationPropertiesElement = mElevationProperties->writeXml( *doc, context );
3572 qgisNode.appendChild( elevationPropertiesElement );
3576 const QDomElement displaySettingsElem = mDisplaySettings->writeXml( *doc, context );
3577 qgisNode.appendChild( displaySettingsElem );
3581 const QDomElement gpsSettingsElem = mGpsSettings->writeXml( *doc, context );
3582 qgisNode.appendChild( gpsSettingsElem );
3591 QFile backupFile( u
"%1~"_s.arg( filename ) );
3593 ok &= backupFile.open( QIODevice::WriteOnly | QIODevice::Truncate );
3594 ok &= projectFile.open( QIODevice::ReadOnly );
3597 while ( ok && !projectFile.atEnd() )
3599 ba = projectFile.read( 10240 );
3600 ok &= backupFile.write( ba ) == ba.size();
3603 projectFile.close();
3608 setError( tr(
"Unable to create backup file %1" ).arg( backupFile.fileName() ) );
3613 struct utimbuf tb = {
static_cast<time_t
>( fi.lastRead().toSecsSinceEpoch() ),
static_cast<time_t
>( fi.lastModified().toSecsSinceEpoch() ) };
3614 utime( backupFile.fileName().toUtf8().constData(), &tb );
3617 if ( !projectFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
3619 projectFile.close();
3622 setError( tr(
"Unable to save to file %1" ).arg( projectFile.fileName() ) );
3626 QTemporaryFile tempFile;
3627 bool ok = tempFile.open();
3630 QTextStream projectFileStream( &tempFile );
3631 doc->save( projectFileStream, 2 );
3632 ok &= projectFileStream.pos() > -1;
3634 ok &= tempFile.seek( 0 );
3637 while ( ok && !tempFile.atEnd() )
3639 ba = tempFile.read( 10240 );
3640 ok &= projectFile.write( ba ) == ba.size();
3643 ok &= projectFile.error() == QFile::NoError;
3645 projectFile.close();
3652 setError( tr(
"Unable to save to file %1. Your project "
3653 "may be corrupted on disk. Try clearing some space on the volume and "
3654 "check file permissions before pressing save again." )
3655 .arg( projectFile.fileName() ) );
3669 bool propertiesModified;
3670 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3672 if ( propertiesModified )
3682 bool propertiesModified;
3683 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3685 if ( propertiesModified )
3695 bool propertiesModified;
3696 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3698 if ( propertiesModified )
3708 bool propertiesModified;
3709 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3711 if ( propertiesModified )
3721 bool propertiesModified;
3722 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3724 if ( propertiesModified )
3732 const QStringList &def,
3744 value =
property->value();
3746 const bool valid = QMetaType::Type::QStringList == value.userType();
3752 return value.toStringList();
3775 value =
property->value();
3777 const bool valid = value.canConvert( QMetaType::Type::QString );
3782 return value.toString();
3801 value =
property->value();
3804 const bool valid = value.canConvert( QMetaType::Type::Int );
3813 return value.toInt();
3828 const QVariant value =
property->value();
3830 const bool valid = value.canConvert( QMetaType::Type::Double );
3835 return value.toDouble();
3852 const QVariant value =
property->value();
3854 const bool valid = value.canConvert( QMetaType::Type::Bool );
3859 return value.toBool();
3871 if (
findKey_( scope, key, mProperties ) )
3877 return !
findKey_( scope, key, mProperties );
3886 QStringList entries;
3888 if ( foundProperty )
3905 QStringList entries;
3907 if ( foundProperty )
3922 dump_( mProperties );
3942 filePath = storage->filePath( mFile.fileName() );
3969void QgsProject::setError(
const QString &errorMessage )
3973 mErrorMessage = errorMessage;
3980 return mErrorMessage;
3983void QgsProject::clearError()
3987 setError( QString() );
3994 mBadLayerHandler.reset( handler );
4001 const QHash< QString, QPair< QString, bool > >::const_iterator it = mEmbeddedLayers.find(
id );
4002 if ( it == mEmbeddedLayers.constEnd() )
4006 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;
4310 const QString storagePath { storage->filePath(
fileName() ) };
4311 if ( ! storagePath.isEmpty() && QFileInfo::exists( storagePath ) )
4313 mCachedHomePath = QFileInfo( storagePath ).path();
4314 return mCachedHomePath;
4318 mCachedHomePath = pfi.path();
4319 return mCachedHomePath;
4322 if ( !pfi.exists() )
4324 mCachedHomePath = mHomePath;
4328 if ( !mHomePath.isEmpty() )
4331 mCachedHomePath = QDir::cleanPath( pfi.path() +
'/' + mHomePath );
4335 mCachedHomePath = pfi.canonicalPath();
4337 return mCachedHomePath;
4352 return mRelationManager.get();
4359 return mLayoutManager.get();
4366 return mLayoutManager.get();
4373 return mElevationProfileManager.get();
4380 return mElevationProfileManager.get();
4387 return m3DViewsManager.get();
4394 return m3DViewsManager.get();
4401 return mBookmarkManager;
4408 return mBookmarkManager;
4415 return mSensorManager;
4422 return mSensorManager;
4429 return mViewSettings;
4436 return mViewSettings;
4443 return mStyleSettings;
4451 return mStyleSettings;
4458 return mTimeSettings;
4465 return mTimeSettings;
4472 return mElevationProperties;
4479 return mElevationProperties;
4486 return mDisplaySettings;
4493 return mDisplaySettings;
4500 return mGpsSettings;
4507 return mGpsSettings;
4514 return mRootGroup.get();
4521 return mMapThemeCollection.get();
4528 return mAnnotationManager.get();
4535 return mAnnotationManager.get();
4542 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
4543 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
4548 if (
layers.contains( it.value() ) )
4565 for (
const QString &layerId : layerIds )
4583 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
4617 updateTransactionGroups();
4624 return mTransactionMode;
4635 const auto constLayers =
mapLayers().values();
4638 if ( layer->isEditable() )
4640 QgsLogger::warning( tr(
"Transaction mode can be changed only if all layers are not editable." ) );
4646 updateTransactionGroups();
4655 return mTransactionGroups;
4668 return mLayerStore->count();
4675 return mLayerStore->validCount();
4683 if ( mMainAnnotationLayer && layerId == mMainAnnotationLayer->id() )
4684 return mMainAnnotationLayer;
4686 return mLayerStore->mapLayer( layerId );
4693 return mLayerStore->mapLayersByName( layerName );
4700 QList<QgsMapLayer *>
layers;
4701 const auto constMapLayers { mLayerStore->mapLayers() };
4702 for (
const auto &l : constMapLayers )
4704 if ( ! l->serverProperties()->shortName().isEmpty() )
4706 if ( l->serverProperties()->shortName() == shortName )
4709 else if ( l->name() == shortName )
4722 auto archive = std::make_unique<QgsProjectArchive>();
4725 if ( !archive->unzip( filename ) )
4727 setError( tr(
"Unable to unzip file '%1'" ).arg( filename ) );
4732 if ( archive->projectFile().isEmpty() )
4734 setError( tr(
"Zip archive does not provide a project file" ) );
4739 releaseHandlesToProjectArchive();
4740 mArchive = std::move( archive );
4743 if ( !
static_cast<QgsProjectArchive *
>( mArchive.get() )->auxiliaryStorageFile().isEmpty() )
4747 mAuxiliaryStorage = std::make_unique< QgsAuxiliaryStorage >(
static_cast<QgsProjectArchive *
>( mArchive.get() )->auxiliaryStorageFile(),
false );
4751 mAuxiliaryStorage = std::make_unique< QgsAuxiliaryStorage >( *
this );
4755 if ( ! readProjectFile(
static_cast<QgsProjectArchive *
>( mArchive.get() )->projectFile(),
flags ) )
4757 setError( tr(
"Cannot read unzipped qgs project file" ) + u
": "_s +
error() );
4762 static_cast<QgsProjectArchive *
>( mArchive.get() )->clearProjectFile();
4767bool QgsProject::zip(
const QString &filename )
4774 auto archive = std::make_unique<QgsProjectArchive>();
4775 const QString
baseName = QFileInfo( filename ).baseName();
4776 const QString qgsFileName = u
"%1.qgs"_s.arg(
baseName );
4777 QFile qgsFile( QDir( archive->dir() ).filePath( qgsFileName ) );
4779 bool writeOk =
false;
4780 if ( qgsFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
4782 writeOk = writeProjectFile( qgsFile.fileName() );
4789 setError( tr(
"Unable to write temporary qgs file" ) );
4794 const QFileInfo info( qgsFile );
4796 const QString asFileName = info.path() + QDir::separator() + info.completeBaseName() + asExt;
4798 bool auxiliaryStorageSavedOk =
true;
4799 if ( ! saveAuxiliaryStorage( asFileName ) )
4801 const QString err = mAuxiliaryStorage->errorString();
4802 setError( tr(
"Unable to save auxiliary storage file ('%1'). The project has been saved but the latest changes to auxiliary data cannot be recovered. It is recommended to reload the project." ).arg( err ) );
4803 auxiliaryStorageSavedOk =
false;
4806 if ( !mArchive->exists() )
4808 releaseHandlesToProjectArchive();
4809 mArchive = std::make_unique< QgsProjectArchive >();
4810 mArchive->unzip( mFile.fileName() );
4811 static_cast<QgsProjectArchive *
>( mArchive.get() )->clearProjectFile();
4813 const QString auxiliaryStorageFile =
static_cast<QgsProjectArchive *
>( mArchive.get() )->auxiliaryStorageFile();
4814 if ( ! auxiliaryStorageFile.isEmpty() )
4816 archive->addFile( auxiliaryStorageFile );
4817 mAuxiliaryStorage = std::make_unique< QgsAuxiliaryStorage >( auxiliaryStorageFile,
false );
4825 if ( QFile::exists( asFileName ) )
4827 archive->addFile( asFileName );
4832 archive->addFile( qgsFile.fileName() );
4835 const QStringList &files = mArchive->files();
4836 for (
const QString &file : files )
4838 if ( !file.endsWith(
".qgs"_L1, Qt::CaseInsensitive ) && !file.endsWith( asExt, Qt::CaseInsensitive ) )
4840 archive->addFile( file );
4846 if ( !archive->zip( filename ) )
4848 setError( tr(
"Unable to perform zip" ) );
4852 return auxiliaryStorageSavedOk && zipOk;
4863 const QList<QgsMapLayer *> &
layers,
4865 bool takeOwnership )
4869 const QList<QgsMapLayer *> myResultList { mLayerStore->addMapLayers(
layers, takeOwnership ) };
4870 if ( !myResultList.isEmpty() )
4873 for (
auto &l : myResultList )
4887 if ( mAuxiliaryStorage )
4902 mProjectScope.reset();
4904 return myResultList;
4910 bool takeOwnership )
4914 QList<QgsMapLayer *> addedLayers;
4915 addedLayers =
addMapLayers( QList<QgsMapLayer *>() << layer, addToLegend, takeOwnership );
4916 return addedLayers.isEmpty() ? nullptr : addedLayers[0];
4919void QgsProject::removeAuxiliaryLayer(
const QgsMapLayer *ml )
4926 const QgsVectorLayer *vl = qobject_cast<const QgsVectorLayer *>( ml );
4938 for (
const auto &layerId : layerIds )
4939 removeAuxiliaryLayer( mLayerStore->mapLayer( layerId ) );
4941 mProjectScope.reset();
4942 mLayerStore->removeMapLayers( layerIds );
4949 for (
const auto &layer :
layers )
4950 removeAuxiliaryLayer( layer );
4952 mProjectScope.reset();
4953 mLayerStore->removeMapLayers(
layers );
4960 removeAuxiliaryLayer( mLayerStore->mapLayer( layerId ) );
4961 mProjectScope.reset();
4962 mLayerStore->removeMapLayer( layerId );
4969 removeAuxiliaryLayer( layer );
4970 mProjectScope.reset();
4971 mLayerStore->removeMapLayer( layer );
4978 mProjectScope.reset();
4979 return mLayerStore->takeMapLayer( layer );
4986 return mMainAnnotationLayer;
4993 if ( mLayerStore->count() == 0 )
4996 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
4997 mProjectScope.reset();
4998 mLayerStore->removeAllMapLayers();
5000 snapSingleBlocker.release();
5001 mSnappingConfig.clearIndividualLayerSettings();
5002 if ( !mBlockSnappingUpdates )
5010 const QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
5011 QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin();
5012 for ( ; it !=
layers.constEnd(); ++it )
5014 it.value()->reload();
5023 return validOnly ? mLayerStore->validMapLayers() : mLayerStore->mapLayers();
5030 return mTransactionGroups.value( qMakePair( providerKey, connString ) );
5037 return &mEditBufferGroup;
5048 if ( mSettings.value( u
"/projections/unknownCrsBehavior"_s, u
"NoAction"_s,
QgsSettings::App ).toString() == u
"UseProjectCrs"_s
5049 || mSettings.value( u
"/projections/unknownCrsBehavior"_s, 0,
QgsSettings::App ).toString() ==
"2"_L1 )
5057 const QString layerDefaultCrs = mSettings.value( u
"/Projections/layerDefaultCrs"_s, u
"EPSG:4326"_s ).toString();
5078bool QgsProject::saveAuxiliaryStorage(
const QString &filename )
5084 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5089 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() );
5097 if ( !mAuxiliaryStorage->exists( *
this ) && empty )
5101 else if ( !filename.isEmpty() )
5103 return mAuxiliaryStorage->saveAs( filename );
5107 return mAuxiliaryStorage->saveAs( *
this );
5120 return sPropertyDefinitions;
5133 return mAuxiliaryStorage.get();
5140 return mAuxiliaryStorage.get();
5147 const QDir archiveDir( mArchive->dir() );
5148 QTemporaryFile tmpFile( archiveDir.filePath(
"XXXXXX_" + nameTemplate ),
this );
5149 tmpFile.setAutoRemove(
false );
5150 if ( !tmpFile.open() )
5152 setError( tr(
"Unable to open %1" ).arg( tmpFile.fileName() ) );
5155 mArchive->addFile( tmpFile.fileName() );
5156 return tmpFile.fileName();
5163 QStringList attachments;
5165 const QStringList files = mArchive->files();
5166 attachments.reserve( files.size() );
5167 for (
const QString &file : files )
5171 attachments.append( file );
5181 return mArchive->removeFile( path );
5188 return u
"attachment:///%1"_s.arg( QFileInfo( attachedFile ).
fileName() );
5195 if ( identifier.startsWith(
"attachment:///"_L1 ) )
5197 return QDir( mArchive->dir() ).absoluteFilePath( identifier.mid( 14 ) );
5218 mProjectScope.reset();
5233 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5247 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
5248 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
5253 if (
layers.contains( it.value() ) )
5265 QStringList customColors;
5266 QStringList customColorLabels;
5268 QgsNamedColorList::const_iterator colorIt = colors.constBegin();
5269 for ( ; colorIt != colors.constEnd(); ++colorIt )
5272 const QString label = ( *colorIt ).second;
5273 customColors.append( color );
5274 customColorLabels.append( label );
5276 writeEntry( u
"Palette"_s, u
"/Colors"_s, customColors );
5277 writeEntry( u
"Palette"_s, u
"/Labels"_s, customColorLabels );
5278 mProjectScope.reset();
5286 if ( mBackgroundColor == color )
5289 mBackgroundColor = color;
5297 return mBackgroundColor;
5304 if ( mSelectionColor == color )
5307 mSelectionColor = color;
5315 return mSelectionColor;
5322 mViewSettings->setMapScales( scales );
5329 return mViewSettings->mapScales();
5336 mViewSettings->setUseProjectScales( enabled );
5343 return mViewSettings->useProjectScales();
5356 translationContext.writeTsFile( locale );
5359QString
QgsProject::translate(
const QString &context,
const QString &sourceText,
const char *disambiguation,
int n )
const
5368 QString result = mTranslator->translate( context.toUtf8(), sourceText.toUtf8(), disambiguation, n );
5370 if ( result.isEmpty() )
5384 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5389 if ( !( ( *it )->accept( visitor ) ) )
5398 if ( !mLayoutManager->accept( visitor ) )
5401 if ( !mAnnotationManager->accept( visitor ) )
5411 const QString macros =
readEntry( u
"Macros"_s, u
"/pythonCode"_s, QString() );
5412 if ( !macros.isEmpty() )
5421 const QString expressionFunctions =
readEntry( u
"ExpressionFunctions"_s, u
"/pythonCode"_s );
5422 if ( !expressionFunctions.isEmpty() )
5434 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5436 if ( !( ( *it )->accept( visitor, context ) ) )
5448 return mElevationShadingRenderer;
5451void QgsProject::loadProjectFlags(
const QDomDocument *doc )
5455 QDomElement element = doc->documentElement().firstChildElement( u
"projectFlags"_s );
5457 if ( !element.isNull() )
5464 element = doc->documentElement().firstChildElement( u
"evaluateDefaultValues"_s );
5465 if ( !element.isNull() )
5467 if ( element.attribute( u
"active"_s, u
"0"_s ).toInt() == 1 )
5472 element = doc->documentElement().firstChildElement( u
"trust"_s );
5473 if ( !element.isNull() )
5475 if ( element.attribute( u
"active"_s, u
"0"_s ).toInt() == 1 )
5489 const QString projectFunctions =
readEntry( u
"ExpressionFunctions"_s, u
"/pythonCode"_s, QString() );
5490 if ( !projectFunctions.isEmpty() )
5510QHash< QString, QColor > loadColorsFromProject(
const QgsProject *project )
5512 QHash< QString, QColor > colors;
5515 QStringList colorStrings = project->
readListEntry( u
"Palette"_s, u
"/Colors"_s );
5516 const QStringList colorLabels = project->
readListEntry( u
"Palette"_s, u
"/Labels"_s );
5520 for ( QStringList::iterator it = colorStrings.begin();
5521 it != colorStrings.end(); ++it )
5525 if ( colorLabels.length() > colorIndex )
5527 label = colorLabels.at( colorIndex );
5530 colors.insert( label.toLower(), color );
5538GetNamedProjectColor::GetNamedProjectColor(
const QgsProject *project )
5544 mColors = loadColorsFromProject( project );
5547GetNamedProjectColor::GetNamedProjectColor(
const QHash<QString, QColor> &colors )
5555 const QString colorName = values.at( 0 ).toString().toLower();
5556 if ( mColors.contains( colorName ) )
5558 return u
"%1,%2,%3"_s.arg( mColors.value( colorName ).red() ).arg( mColors.value( colorName ).green() ).arg( mColors.value( colorName ).blue() );
5566 return new GetNamedProjectColor( mColors );
5569GetNamedProjectColorObject::GetNamedProjectColorObject(
const QgsProject *project )
5575 mColors = loadColorsFromProject( project );
5578GetNamedProjectColorObject::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 )
5606 , mSensorData( sensorData )
5612 const QString sensorName = values.at( 0 ).toString();
5613 const int expiration = values.at( 1 ).toInt();
5614 const qint64 timestamp = QDateTime::currentMSecsSinceEpoch();
5615 if ( mSensorData.contains( sensorName ) )
5617 if ( expiration <= 0 || ( timestamp - mSensorData[sensorName].lastTimestamp.toMSecsSinceEpoch() ) < expiration )
5619 return mSensorData[sensorName].lastValue;
5628 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())
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.
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.
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.