87#include <QApplication>
92#include <QRegularExpression>
93#include <QStandardPaths>
95#include <QTemporaryFile>
101#include "moc_qgsproject.cpp"
103using namespace Qt::StringLiterals;
106#include <sys/utime.h>
122QStringList makeKeyTokens_(
const QString &scope,
const QString &key )
124 QStringList keyTokens = QStringList( scope );
125 keyTokens += key.split(
'/', Qt::SkipEmptyParts );
128 keyTokens.push_front( u
"properties"_s );
151 QStringList keySequence = makeKeyTokens_( scope, key );
153 while ( !keySequence.isEmpty() )
157 if ( keySequence.first() == currentProperty->
name() )
160 keySequence.pop_front();
162 if ( 1 == keySequence.count() )
165 return currentProperty->
find( keySequence.front() );
167 else if ( keySequence.isEmpty() )
172 return currentProperty;
174 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
176 if ( nextProperty->
isKey() )
180 else if ( nextProperty->
isValue() && 1 == keySequence.count() )
186 return currentProperty;
224 const QVariant &value,
225 bool &propertiesModified )
227 QStringList keySequence = makeKeyTokens_( scope, key );
234 propertiesModified =
false;
235 while ( ! keySequence.isEmpty() )
239 if ( keySequence.first() == currentProperty->
name() )
242 keySequence.pop_front();
246 if ( 1 == keySequence.count() )
249 if ( !property || property->value() != value )
251 currentProperty->
setValue( keySequence.front(), value );
252 propertiesModified =
true;
255 return currentProperty;
259 else if ( keySequence.isEmpty() )
261 if ( currentProperty->
value() != value )
264 propertiesModified =
true;
267 return currentProperty;
269 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
273 if ( currentProperty )
284 if ( ( newPropertyKey = currentProperty->
addKey( keySequence.first() ) ) )
286 currentProperty = newPropertyKey;
316 QStringList keySequence = makeKeyTokens_( scope, key );
318 while ( ! keySequence.isEmpty() )
322 if ( keySequence.first() == currentProperty->
name() )
325 keySequence.pop_front();
329 if ( 1 == keySequence.count() )
331 currentProperty->
removeKey( keySequence.front() );
336 else if ( keySequence.isEmpty() )
338 previousQgsPropertyKey->
removeKey( currentProperty->
name() );
340 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
342 previousQgsPropertyKey = currentProperty;
345 if ( currentProperty )
372 , mSnappingConfig( this )
392 mProperties.setName( u
"properties"_s );
395 mMainAnnotationLayer->setParent(
this );
402 mLayerTreeRegistryBridge = std::make_unique<QgsLayerTreeRegistryBridge>( mRootGroup.get(),
this,
this );
409 this, [
this](
const QStringList &
layers ) { mProjectScope.reset(); emit layersWillBeRemoved( layers ); } );
411 this, [
this](
const QList<QgsMapLayer *> &
layers ) { mProjectScope.reset(); emit layersWillBeRemoved( layers ); } );
413 this, [
this](
const QString & layer ) { mProjectScope.reset(); emit layerWillBeRemoved( layer ); } );
415 this, [
this](
QgsMapLayer * layer ) { mProjectScope.reset(); emit layerWillBeRemoved( layer ); } );
417 [
this](
const QStringList &
layers ) { mProjectScope.reset(); emit layersRemoved( layers ); } );
419 [
this](
const QString & layer ) { mProjectScope.reset(); emit layerRemoved( layer ); } );
421 [
this]() { mProjectScope.reset(); emit removeAll(); } );
423 [
this](
const QList< QgsMapLayer * > &
layers ) { mProjectScope.reset(); emit layersAdded( layers ); } );
425 [
this](
QgsMapLayer * layer ) { mProjectScope.reset(); emit layerWasAdded( layer ); } );
433 [
this](
const QList<QgsMapLayer *> &
layers )
435 for ( const auto &layer : layers )
437 disconnect( layer, &QgsMapLayer::dataSourceChanged, mRelationManager.get(), &QgsRelationManager::updateRelationsStatus );
442 [
this](
const QList<QgsMapLayer *> &layers )
444 for ( const auto &layer : layers )
446 connect( layer, &QgsMapLayer::dataSourceChanged, mRelationManager.get(), &QgsRelationManager::updateRelationsStatus );
455 mStyleSettings->combinedStyleModel()->addDefaultStyle();
461 mIsBeingDeleted =
true;
464 releaseHandlesToProjectArchive();
466 if (
this == sProject )
493 if (
title == mMetadata.title() )
496 mMetadata.setTitle(
title );
497 mProjectScope.reset();
509 return mMetadata.title();
518 if ( oldEvaluateDefaultValues != newEvaluateDefaultValues )
521 for (
auto layerIt =
layers.constBegin(); layerIt !=
layers.constEnd(); ++layerIt )
523 if (
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layerIt.value() ) )
524 if ( vl->dataProvider() )
531 if ( oldTrustLayerMetadata != newTrustLayerMetadata )
534 for (
auto layerIt =
layers.constBegin(); layerIt !=
layers.constEnd(); ++layerIt )
536 if (
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layerIt.value() ) )
538 vl->setReadExtentFromXml( newTrustLayerMetadata );
543 if ( mFlags !=
flags )
558 newFlags &= ~(
static_cast< int >( flag ) );
573 return mSaveUserFull;
580 return mSaveDateTime;
601 if ( dirty && mDirtyBlockCount > 0 )
607 if ( mDirty == dirty )
618 if ( path == mHomePath )
622 mCachedHomePath.clear();
623 mProjectScope.reset();
634 const QList<QgsAttributeEditorElement *> elements = parent->
children();
642 translationContext->
registerTranslation( u
"project:layers:%1:formcontainers"_s.arg( layerId ), container->
name() );
644 if ( !container->
children().empty() )
655 const QList<QgsLayerTreeLayer *>
layers = mRootGroup->findLayers();
659 translationContext->
registerTranslation( u
"project:layers:%1"_s.arg( layer->layerId() ), layer->name() );
671 for (
const QgsField &field : fields )
676 if ( field.alias().isEmpty() )
677 fieldName = field.name();
679 fieldName = field.alias();
681 translationContext->
registerTranslation( u
"project:layers:%1:fieldaliases"_s.arg( vlayer->
id() ), fieldName );
684 if ( !field.constraints().constraintDescription().isEmpty() )
685 translationContext->
registerTranslation( u
"project:layers:%1:constraintdescriptions"_s.arg( vlayer->
id() ), field.constraints().constraintDescription() );
689 if ( field.editorWidgetSetup().type() ==
"ValueRelation"_L1 )
691 translationContext->
registerTranslation( u
"project:layers:%1:fields:%2:valuerelationvalue"_s.arg( vlayer->
id(), field.name() ), field.editorWidgetSetup().config().value( u
"Value"_s ).toString() );
692 translationContext->
registerTranslation( u
"project:layers:%1:fields:%2:valuerelationdescription"_s.arg( vlayer->
id(), field.name() ), field.editorWidgetSetup().config().value( u
"Description"_s ).toString() );
696 if ( field.editorWidgetSetup().type() ==
"ValueMap"_L1 )
698 if ( field.editorWidgetSetup().config().value( u
"map"_s ).canConvert<QList<QVariant>>() )
700 const QList<QVariant> valueList = field.editorWidgetSetup().config().value( u
"map"_s ).toList();
702 for (
int i = 0, row = 0; i < valueList.count(); i++, row++ )
704 translationContext->
registerTranslation( u
"project:layers:%1:fields:%2:valuemapdescriptions"_s.arg( vlayer->
id(), field.name() ), valueList[i].toMap().constBegin().key() );
716 translationContext->
registerTranslation( u
"project:layers:%1:actiondescriptions"_s.arg( vlayer->
id() ), action.name() );
717 translationContext->
registerTranslation( u
"project:layers:%1:actionshorttitles"_s.arg( vlayer->
id() ), action.shortTitle() );
725 translationContext->
registerTranslation( u
"project:layers:%1:legendsymbollabels"_s.arg( vlayer->
id() ), item.label() );
743 mapLayer->metadata().registerTranslations( translationContext );
748 const QList<QgsLayerTreeGroup *> groupLayers = mRootGroup->findGroups(
true );
755 const QList<QgsRelation> &relations = mRelationManager->relations().values();
762 mMetadata.registerTranslations( translationContext );
769 mDataDefinedServerProperties = properties;
776 return mDataDefinedServerProperties;
783 switch ( mTransactionMode )
794 return mEditBufferGroup.startEditing();
804 switch ( mTransactionMode )
811 commitErrors.append( tr(
"Trying to commit changes without a layer specified. This only works if the transaction mode is buffered" ) );
820 return mEditBufferGroup.commitChanges( commitErrors, stopEditing );
830 switch ( mTransactionMode )
837 rollbackErrors.append( tr(
"Trying to roll back changes without a layer specified. This only works if the transaction mode is buffered" ) );
840 bool success = vectorLayer->
rollBack( stopEditing );
846 return mEditBufferGroup.rollBack( rollbackErrors, stopEditing );
856 if ( name == mFile.fileName() )
859 const QString oldHomePath =
homePath();
861 mFile.setFileName( name );
862 mCachedHomePath.clear();
863 mProjectScope.reset();
867 const QString newHomePath =
homePath();
868 if ( newHomePath != oldHomePath )
879 return mFile.fileName();
886 mOriginalPath = path;
893 return mOriginalPath;
900 return QFileInfo( mFile );
918 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
923 return QFileInfo( mFile.fileName() ).lastModified();
934 if ( mFile.fileName().isEmpty() )
937 return QFileInfo( mFile.fileName() ).absolutePath();
948 if ( mFile.fileName().isEmpty() )
951 return QFileInfo( mFile.fileName() ).absoluteFilePath();
962 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
967 return QFileInfo( mFile.fileName() ).completeBaseName();
975 const bool absolutePaths =
readBoolEntry( u
"Paths"_s, u
"/Absolute"_s,
false );
986 writeEntry( u
"Paths"_s, u
"/Absolute"_s,
true );
989 writeEntry( u
"Paths"_s, u
"/Absolute"_s,
false );
1006 return mCrs3D.isValid() ? mCrs3D : mCrs;
1018 writeEntry( u
"SpatialRefSys"_s, u
"/ProjectionsEnabled"_s,
crs.isValid() ? 1 : 0 );
1019 mProjectScope.reset();
1023 if ( !mMainAnnotationLayer->crs().isValid() || mMainAnnotationLayer->isEmpty() )
1024 mMainAnnotationLayer->setCrs(
crs );
1033 if ( oldCrs3D != mCrs3D )
1037 if ( adjustEllipsoid )
1046 if ( !
crs().isValid() )
1059 mProjectScope.reset();
1069 switch ( mCrs.type() )
1072 QgsDebugError( u
"Project has a vertical CRS set as the horizontal CRS!"_s );
1076 return mCrs.verticalCrs();
1091 return mVerticalCrs;
1098 if (
crs.isValid() )
1101 switch (
crs.type() )
1119 *errorMessage = QObject::tr(
"Specified CRS is a %1 CRS, not a Vertical CRS" ).arg(
qgsEnumValueToKey(
crs.type() ) );
1124 if (
crs != mVerticalCrs )
1129 switch ( mCrs.type() )
1132 if (
crs != oldVerticalCrs )
1135 *errorMessage = QObject::tr(
"Project CRS is a Compound CRS, specified Vertical CRS will be ignored" );
1141 if (
crs != oldVerticalCrs )
1144 *errorMessage = QObject::tr(
"Project CRS is a Geographic 3D CRS, specified Vertical CRS will be ignored" );
1150 if (
crs != oldVerticalCrs )
1153 *errorMessage = QObject::tr(
"Project CRS is a Geocentric CRS, specified Vertical CRS will be ignored" );
1159 if ( mCrs.hasVerticalAxis() &&
crs != oldVerticalCrs )
1162 *errorMessage = QObject::tr(
"Project CRS is a Projected 3D CRS, specified Vertical CRS will be ignored" );
1180 res = rebuildCrs3D( errorMessage );
1181 mProjectScope.reset();
1188 if ( mCrs3D != oldCrs3D )
1199 return mTransformContext;
1206 if ( context == mTransformContext )
1209 mTransformContext = context;
1210 mProjectScope.reset();
1212 mMainAnnotationLayer->setTransformContext( context );
1213 for (
auto &layer : mLayerStore.get()->mapLayers() )
1215 layer->setTransformContext( context );
1224 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
1228 if ( !mIsBeingDeleted )
1237 mProjectScope.reset();
1238 mFile.setFileName( QString() );
1239 mProperties.clearKeys();
1241 mSaveUserFull.clear();
1242 mSaveDateTime = QDateTime();
1245 mCachedHomePath.clear();
1249 mCustomVariables.clear();
1255 if ( !mSettings.value( u
"projects/anonymize_new_projects"_s,
false,
QgsSettings::Core ).toBool() )
1257 mMetadata.setCreationDateTime( QDateTime::currentDateTime() );
1276 mEmbeddedLayers.clear();
1277 mRelationManager->clear();
1278 mAnnotationManager->clear();
1279 mLayoutManager->clear();
1280 mElevationProfileManager->clear();
1281 mSelectiveMaskingSourceSetManager->clear();
1282 m3DViewsManager->clear();
1283 mBookmarkManager->clear();
1284 mSensorManager->clear();
1285 mViewSettings->reset();
1286 mTimeSettings->reset();
1287 mElevationProperties->reset();
1288 mDisplaySettings->reset();
1289 mGpsSettings->reset();
1290 mSnappingConfig.reset();
1295 mMapThemeCollection = std::make_unique< QgsMapThemeCollection >(
this );
1298 mLabelingEngineSettings->clear();
1302 releaseHandlesToProjectArchive();
1304 mAuxiliaryStorage = std::make_unique< QgsAuxiliaryStorage >();
1305 mArchive = std::make_unique< QgsArchive >();
1308 mStyleSettings->reset();
1312 if ( !mIsBeingDeleted )
1320 writeEntry( u
"PositionPrecision"_s, u
"/Automatic"_s,
true );
1321 writeEntry( u
"PositionPrecision"_s, u
"/DecimalPlaces"_s, 2 );
1323 const bool defaultRelativePaths = mSettings.value( u
"/qgis/defaultProjectPathsRelative"_s,
true ).toBool();
1326 int red = mSettings.value( u
"qgis/default_canvas_color_red"_s, 255 ).toInt();
1327 int green = mSettings.value( u
"qgis/default_canvas_color_green"_s, 255 ).toInt();
1328 int blue = mSettings.value( u
"qgis/default_canvas_color_blue"_s, 255 ).toInt();
1331 red = mSettings.value( u
"qgis/default_selection_color_red"_s, 255 ).toInt();
1332 green = mSettings.value( u
"qgis/default_selection_color_green"_s, 255 ).toInt();
1333 blue = mSettings.value( u
"qgis/default_selection_color_blue"_s, 0 ).toInt();
1334 const int alpha = mSettings.value( u
"qgis/default_selection_color_alpha"_s, 255 ).toInt();
1337 mSnappingConfig.clearIndividualLayerSettings();
1340 mRootGroup->clear();
1341 if ( mMainAnnotationLayer )
1342 mMainAnnotationLayer->reset();
1344 snapSingleBlocker.release();
1346 if ( !mBlockSnappingUpdates )
1352 if ( !mBlockChangeSignalsDuringClear )
1364 topQgsPropertyKey.
dump();
1397 const QDomElement propertiesElem = doc.documentElement().firstChildElement( u
"properties"_s );
1399 if ( propertiesElem.isNull() )
1404 const QDomNodeList scopes = propertiesElem.childNodes();
1406 if ( propertiesElem.firstChild().isNull() )
1408 QgsDebugError( u
"empty ``properties'' XML tag ... bailing"_s );
1412 if ( ! project_properties.
readXml( propertiesElem ) )
1428 const QDomElement ddElem = doc.documentElement().firstChildElement( u
"dataDefinedServerProperties"_s );
1429 if ( !ddElem.isNull() )
1431 if ( !ddServerProperties.
readXml( ddElem, dataDefinedServerPropertyDefinitions ) )
1433 QgsDebugError( u
"dataDefinedServerProperties.readXml() failed"_s );
1436 return ddServerProperties;
1443static void _getTitle(
const QDomDocument &doc, QString &title )
1445 const QDomElement titleNode = doc.documentElement().firstChildElement( u
"title"_s );
1449 if ( titleNode.isNull() )
1455 if ( !titleNode.hasChildNodes() )
1461 const QDomNode titleTextNode = titleNode.firstChild();
1463 if ( !titleTextNode.isText() )
1469 const QDomText titleText = titleTextNode.toText();
1471 title = titleText.data();
1475static void readProjectFileMetadata(
const QDomDocument &doc, QString &lastUser, QString &lastUserFull, QDateTime &lastSaveDateTime )
1477 const QDomNodeList nl = doc.elementsByTagName( u
"qgis"_s );
1485 const QDomNode qgisNode = nl.item( 0 );
1487 const QDomElement qgisElement = qgisNode.toElement();
1488 lastUser = qgisElement.attribute( u
"saveUser"_s, QString() );
1489 lastUserFull = qgisElement.attribute( u
"saveUserFull"_s, QString() );
1490 lastSaveDateTime = QDateTime::fromString( qgisElement.attribute( u
"saveDateTime"_s, QString() ), Qt::ISODate );
1495 const QDomNodeList nl = doc.elementsByTagName( u
"qgis"_s );
1499 QgsDebugError( u
" unable to find qgis element in project file"_s );
1503 const QDomNode qgisNode = nl.item( 0 );
1505 const QDomElement qgisElement = qgisNode.toElement();
1507 return projectVersion;
1514 return mSnappingConfig;
1533 if ( mAvoidIntersectionsMode == mode )
1536 mAvoidIntersectionsMode = mode;
1570void QgsProject::preloadProviders(
const QVector<QDomNode> ¶llelLayerNodes,
1572 QMap<QString, QgsDataProvider *> &loadedProviders,
1574 int totalProviderCount )
1579 QMap<QString, LayerToLoad> layersToLoad;
1581 for (
const QDomNode &node : parallelLayerNodes )
1585 const QDomElement layerElement = node.toElement();
1587 layerToLoad.
layerId = layerElement.namedItem( u
"id"_s ).toElement().text();
1588 layerToLoad.
provider = layerElement.namedItem( u
"provider"_s ).toElement().text();
1589 layerToLoad.
dataSource = layerElement.namedItem( u
"datasource"_s ).toElement().text();
1600 layersToLoad.insert( layerToLoad.
layerId, layerToLoad );
1603 while ( !layersToLoad.isEmpty() )
1605 const QList<LayerToLoad> layersToAttemptInParallel = layersToLoad.values();
1606 QString layerToAttemptInMainThread;
1608 QHash<QString, QgsRunnableProviderCreator *> runnables;
1609 QThreadPool threadPool;
1612 for (
const LayerToLoad &lay : layersToAttemptInParallel )
1614 QgsRunnableProviderCreator *run =
new QgsRunnableProviderCreator( lay.layerId, lay.provider, lay.dataSource, lay.options, lay.flags );
1615 runnables.insert( lay.layerId, run );
1621 layersToLoad.remove( layId );
1623 QgsRunnableProviderCreator *finishedRun = runnables.value( layId,
nullptr );
1624 Q_ASSERT( finishedRun );
1626 std::unique_ptr<QgsDataProvider> provider( finishedRun->
dataProvider() );
1627 Q_ASSERT( provider && provider->isValid() );
1629 loadedProviders.insert( layId, provider.release() );
1634 if ( layerToAttemptInMainThread.isEmpty() )
1635 layerToAttemptInMainThread = layId;
1639 if ( i == parallelLayerNodes.count() || !isValid )
1642 threadPool.start( run );
1646 threadPool.waitForDone();
1648 qDeleteAll( runnables );
1651 auto it = layersToLoad.find( layerToAttemptInMainThread );
1652 if ( it != layersToLoad.end() )
1654 std::unique_ptr<QgsDataProvider> provider;
1657 const LayerToLoad &lay = it.value();
1661 QgsScopedRuntimeProfile profile(
"Create data providers/" + lay.
layerId, u
"projectload"_s );
1664 if ( provider && provider->isValid() )
1669 layersToLoad.erase( it );
1672 loadedProviders.insert( layerId, provider.release() );
1680void QgsProject::releaseHandlesToProjectArchive()
1682 mStyleSettings->removeProjectStyle();
1685bool QgsProject::rebuildCrs3D( QString *error )
1688 if ( !mCrs.isValid() )
1690 mCrs3D = QgsCoordinateReferenceSystem();
1692 else if ( !mVerticalCrs.isValid() )
1698 switch ( mCrs.type() )
1710 res = mCrs3D.isValid();
1716 mCrs3D = QgsCoordinateReferenceSystem();
1731 res = mCrs3D.isValid();
1739bool QgsProject::_getMapLayers(
const QDomDocument &doc, QList<QDomNode> &brokenNodes,
Qgis::ProjectReadFlags flags )
1746 QDomElement layerElement = doc.documentElement().firstChildElement( u
"projectlayers"_s ).firstChildElement( u
"maplayer"_s );
1750 if ( layerElement.isNull() )
1760 bool returnStatus =
true;
1763 while ( ! layerElement.isNull() )
1766 layerElement = layerElement.nextSiblingElement( u
"maplayer"_s );
1770 QgsScopedRuntimeProfile profile( tr(
"Sorting layers" ), u
"projectload"_s );
1771 const QgsLayerDefinition::DependencySorter depSorter( doc );
1772 if ( depSorter.hasCycle() )
1776 if ( depSorter.hasMissingDependency() )
1777 returnStatus =
false;
1781 const QVector<QDomNode> sortedLayerNodes = depSorter.sortedLayerNodes();
1782 const int totalLayerCount = sortedLayerNodes.count();
1784 QVector<QDomNode> parallelLoading;
1785 QMap<QString, QgsDataProvider *> loadedProviders;
1790 profile.switchTask( tr(
"Load providers in parallel" ) );
1791 for (
const QDomNode &node : sortedLayerNodes )
1793 const QDomElement element = node.toElement();
1794 if ( element.attribute( u
"embedded"_s ) !=
"1"_L1 )
1796 const QString layerId = node.namedItem( u
"id"_s ).toElement().text();
1797 if ( !depSorter.isLayerDependent( layerId ) )
1799 const QDomNode mnl = element.namedItem( u
"provider"_s );
1800 const QDomElement mne = mnl.toElement();
1801 const QString provider = mne.text();
1805 parallelLoading.append( node );
1812 QgsReadWriteContext context;
1814 if ( !parallelLoading.isEmpty() )
1815 preloadProviders( parallelLoading, context, loadedProviders, projectFlagsToLayerReadFlags(
flags, mFlags ), sortedLayerNodes.count() );
1818 int i = loadedProviders.count();
1819 for (
const QDomNode &node : std::as_const( sortedLayerNodes ) )
1821 const QDomElement element = node.toElement();
1822 const QString name =
translate( u
"project:layers:%1"_s.arg( node.namedItem( u
"id"_s ).toElement().text() ), node.namedItem( u
"layername"_s ).toElement().text() );
1823 if ( !name.isNull() )
1824 emit
loadingLayer( tr(
"Loading layer %1" ).arg( name ) );
1826 profile.switchTask( name );
1827 if ( element.attribute( u
"embedded"_s ) ==
"1"_L1 )
1833 QgsReadWriteContext context;
1837 QString layerId = element.namedItem( u
"id"_s ).toElement().text();
1839 if ( !addLayer( element, brokenNodes, context,
flags, loadedProviders.take( layerId ) ) )
1841 returnStatus =
false;
1844 if ( !messages.isEmpty() )
1853 return returnStatus;
1856bool QgsProject::addLayer(
const QDomElement &layerElem,
1857 QList<QDomNode> &brokenNodes,
1864 const QString type = layerElem.attribute( u
"type"_s );
1866 std::unique_ptr<QgsMapLayer>
mapLayer;
1868 QgsScopedRuntimeProfile profile( tr(
"Create layer" ), u
"projectload"_s );
1874 QgsDebugError( u
"Unknown layer type \"%1\""_s.arg( type ) );
1878 switch ( layerType )
1881 mapLayer = std::make_unique<QgsVectorLayer>();
1885 mapLayer = std::make_unique<QgsRasterLayer>();
1889 mapLayer = std::make_unique<QgsMeshLayer>();
1893 mapLayer = std::make_unique<QgsVectorTileLayer>();
1897 mapLayer = std::make_unique<QgsPointCloudLayer>();
1901 mapLayer = std::make_unique<QgsTiledSceneLayer>();
1906 const QString typeName = layerElem.attribute( u
"name"_s );
1913 const QgsAnnotationLayer::LayerOptions options( mTransformContext );
1914 mapLayer = std::make_unique<QgsAnnotationLayer>( QString(), options );
1920 const QgsGroupLayer::LayerOptions options( mTransformContext );
1921 mapLayer = std::make_unique<QgsGroupLayer>( QString(), options );
1936 const QString layerId { layerElem.namedItem( u
"id"_s ).toElement().text() };
1937 Q_ASSERT( ! layerId.isEmpty() );
1943 profile.switchTask( tr(
"Load layer source" ) );
1944 const bool layerIsValid =
mapLayer->readLayerXml( layerElem, context, layerFlags, provider ) &&
mapLayer->isValid();
1947 if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>(
mapLayer.get() ) )
1950 if ( vl->dataProvider() )
1957 profile.switchTask( tr(
"Add layer to project" ) );
1958 QList<QgsMapLayer *> newLayers;
1968 if ( QgsVectorLayer *vLayer = qobject_cast<QgsVectorLayer *>(
mapLayer.get() ) )
1970 vLayer->joinBuffer()->resolveReferences(
this );
1979 brokenNodes.push_back( layerElem );
1982 const bool wasEditable = layerElem.attribute( u
"editable"_s, u
"0"_s ).toInt();
1985 mapLayer->setCustomProperty( u
"_layer_was_editable"_s,
true );
1989 mapLayer->removeCustomProperty( u
"_layer_was_editable"_s );
1994 if ( ! layerWasStored )
1999 return layerIsValid;
2006 mFile.setFileName( filename );
2007 mCachedHomePath.clear();
2008 mProjectScope.reset();
2017 const QString filename = mFile.fileName();
2022 QTemporaryFile inDevice;
2023 if ( !inDevice.open() )
2025 setError( tr(
"Unable to open %1" ).arg( inDevice.fileName() ) );
2031 if ( !storage->readProject( filename, &inDevice, context ) )
2033 QString err = tr(
"Unable to open %1" ).arg( filename );
2034 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
2035 if ( !messages.isEmpty() )
2036 err += u
"\n\n"_s + messages.last().message();
2040 returnValue = unzip( inDevice.fileName(),
flags );
2046 returnValue = unzip( mFile.fileName(),
flags );
2050 mAuxiliaryStorage = std::make_unique< QgsAuxiliaryStorage >( *
this );
2051 const QFileInfo finfo( mFile.fileName() );
2052 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( u
"%1_attachments.zip"_s.arg( finfo.completeBaseName() ) );
2053 if ( QFile( attachmentsZip ).exists() )
2055 auto archive = std::make_unique<QgsArchive>();
2056 if ( archive->unzip( attachmentsZip ) )
2058 releaseHandlesToProjectArchive();
2059 mArchive = std::move( archive );
2062 returnValue = readProjectFile( mFile.fileName(),
flags );
2068 mFile.setFileName( filename );
2069 mCachedHomePath.clear();
2070 mProjectScope.reset();
2075 mTranslator.reset(
nullptr );
2088 ScopedIntIncrementor snapSignalBlock( &mBlockSnappingUpdates );
2090 QFile projectFile( filename );
2098 if ( QFile( u
"%1/%2.qm"_s.arg( QFileInfo( mFile ).
absolutePath(), localeFileName ) ).exists() )
2100 mTranslator = std::make_unique< QTranslator >();
2101 ( void )mTranslator->load( localeFileName, QFileInfo( mFile ).
absolutePath() );
2104 profile.switchTask( tr(
"Reading project file" ) );
2105 auto doc = std::make_unique<QDomDocument>( u
"qgis"_s );
2107 if ( !projectFile.open( QIODevice::ReadOnly | QIODevice::Text ) )
2109 projectFile.close();
2111 setError( tr(
"Unable to open %1" ).arg( projectFile.fileName() ) );
2116 QTextStream textStream( &projectFile );
2117 QString projectString = textStream.readAll();
2118 projectFile.close();
2120 for (
int i = 0; i < 32; i++ )
2122 if ( i == 9 || i == 10 || i == 13 )
2126 projectString.replace( QChar( i ), u
"%1%2%1"_s.arg(
FONTMARKER_CHR_FIX, QString::number( i ) ) );
2132 if ( !doc->setContent( projectString, &errorMsg, &line, &column ) )
2134 const QString errorString = tr(
"Project file read error in file %1: %2 at line %3 column %4" )
2135 .arg( projectFile.fileName(), errorMsg ).arg( line ).arg( column );
2137 setError( errorString );
2142 projectFile.close();
2147 const QgsProjectVersion fileVersion =
getVersion( *doc );
2150 profile.switchTask( tr(
"Updating project file" ) );
2151 if ( thisVersion > fileVersion )
2153 const bool isOlderMajorVersion = fileVersion.
majorVersion() < thisVersion.majorVersion();
2155 if ( isOlderMajorVersion )
2158 "version of qgis (saved in " + fileVersion.
text() +
2160 "). Problems may occur." );
2163 QgsProjectFileTransform projectFile( *doc, fileVersion );
2171 projectFile.updateRevision( thisVersion );
2173 else if ( fileVersion > thisVersion )
2176 "version of qgis (saved in " + fileVersion.
text() +
2178 "). Problems may occur." );
2184 profile.switchTask( tr(
"Creating auxiliary storage" ) );
2185 const QString
fileName = mFile.fileName();
2187 const QgsCoordinateReferenceSystem oldVerticalCrs =
verticalCrs();
2188 const QgsCoordinateReferenceSystem oldCrs3D = mCrs3D;
2192 std::unique_ptr<QgsAuxiliaryStorage> aStorage = std::move( mAuxiliaryStorage );
2193 std::unique_ptr<QgsArchive> archive = std::move( mArchive );
2197 mBlockChangeSignalsDuringClear =
true;
2199 mBlockChangeSignalsDuringClear =
false;
2204 releaseHandlesToProjectArchive();
2206 mAuxiliaryStorage = std::move( aStorage );
2207 mArchive = std::move( archive );
2210 mCachedHomePath.clear();
2211 mProjectScope.reset();
2212 mSaveVersion = fileVersion;
2215 profile.switchTask( tr(
"Reading properties" ) );
2221 QgsDebugMsgLevel( QString::number( mProperties.count() ) +
" properties read", 2 );
2224 dump_( mProperties );
2229 _getTitle( *doc, oldTitle );
2231 readProjectFileMetadata( *doc, mSaveUser, mSaveUserFull, mSaveDateTime );
2233 const QDomNodeList homePathNl = doc->elementsByTagName( u
"homePath"_s );
2234 if ( homePathNl.count() > 0 )
2236 const QDomElement homePathElement = homePathNl.at( 0 ).toElement();
2237 const QString
homePath = homePathElement.attribute( u
"path"_s );
2247 readNumEntry( u
"Gui"_s, u
"/CanvasColorGreenPart"_s, 255 ),
2248 readNumEntry( u
"Gui"_s, u
"/CanvasColorBluePart"_s, 255 ) );
2251 readNumEntry( u
"Gui"_s, u
"/SelectionColorGreenPart"_s, 255 ),
2252 readNumEntry( u
"Gui"_s, u
"/SelectionColorBluePart"_s, 255 ),
2253 readNumEntry( u
"Gui"_s, u
"/SelectionColorAlphaPart"_s, 255 ) );
2257 const QString distanceUnitString =
readEntry( u
"Measurement"_s, u
"/DistanceUnits"_s, QString() );
2258 if ( !distanceUnitString.isEmpty() )
2261 const QString areaUnitString =
readEntry( u
"Measurement"_s, u
"/AreaUnits"_s, QString() );
2262 if ( !areaUnitString.isEmpty() )
2267 QgsReadWriteContext context;
2272 QgsCoordinateReferenceSystem projectCrs;
2273 if (
readNumEntry( u
"SpatialRefSys"_s, u
"/ProjectionsEnabled"_s, 0 ) )
2276 const QDomNode srsNode = doc->documentElement().namedItem( u
"projectCrs"_s );
2277 if ( !srsNode.isNull() )
2279 projectCrs.
readXml( srsNode );
2284 const QString projCrsString =
readEntry( u
"SpatialRefSys"_s, u
"/ProjectCRSProj4String"_s );
2285 const long currentCRS =
readNumEntry( u
"SpatialRefSys"_s, u
"/ProjectCRSID"_s, -1 );
2286 const QString authid =
readEntry( u
"SpatialRefSys"_s, u
"/ProjectCrs"_s );
2289 const bool isUserAuthId = authid.startsWith(
"USER:"_L1, Qt::CaseInsensitive );
2290 if ( !authid.isEmpty() && !isUserAuthId )
2291 projectCrs = QgsCoordinateReferenceSystem( authid );
2294 if ( !projectCrs.
isValid() && currentCRS >= 0 )
2300 if ( !projCrsString.isEmpty() && ( authid.isEmpty() || isUserAuthId ) && ( !projectCrs.
isValid() || projectCrs.
toProj() != projCrsString ) )
2317 const QDomNode verticalCrsNode = doc->documentElement().namedItem( u
"verticalCrs"_s );
2318 if ( !verticalCrsNode.isNull() )
2326 QStringList datumErrors;
2327 if ( !mTransformContext.readXml( doc->documentElement(), context, datumErrors ) && !datumErrors.empty() )
2334 const QDomNode elevationShadingNode = doc->documentElement().namedItem( u
"elevation-shading-renderer"_s );
2335 if ( !elevationShadingNode.isNull() )
2337 mElevationShadingRenderer.readXml( elevationShadingNode.toElement(), context );
2344 const QStringList variableNames =
readListEntry( u
"Variables"_s, u
"/variableNames"_s );
2345 const QStringList variableValues =
readListEntry( u
"Variables"_s, u
"/variableValues"_s );
2347 mCustomVariables.clear();
2348 if ( variableNames.length() == variableValues.length() )
2350 for (
int i = 0; i < variableNames.length(); ++i )
2352 mCustomVariables.insert( variableNames.at( i ), variableValues.at( i ) );
2357 QgsMessageLog::logMessage( tr(
"Project Variables Invalid" ), tr(
"The project contains invalid variable settings." ) );
2365 QDomElement element = doc->documentElement().firstChildElement( u
"projectMetadata"_s );
2367 if ( !element.isNull() )
2369 mMetadata.readMetadataXml( element, context );
2374 mMetadata = QgsProjectMetadata();
2376 if ( mMetadata.title().isEmpty() && !oldTitle.isEmpty() )
2379 mMetadata.setTitle( oldTitle );
2385 element = doc->documentElement().firstChildElement( u
"transaction"_s );
2386 if ( !element.isNull() )
2393 element = doc->documentElement().firstChildElement( u
"autotransaction"_s );
2394 if ( ! element.isNull() )
2396 mTransactionMode =
static_cast<Qgis::TransactionMode>( element.attribute( u
"active"_s, u
"0"_s ).toInt() );
2401 profile.switchTask( tr(
"Loading layer tree" ) );
2402 mRootGroup->setCustomProperty( u
"loading"_s, 1 );
2404 QDomElement layerTreeElem = doc->documentElement().firstChildElement( u
"layer-tree-group"_s );
2405 if ( !layerTreeElem.isNull() )
2408 QgsLayerTree tempTree;
2417 mLayerTreeRegistryBridge->setEnabled(
false );
2420 profile.switchTask( tr(
"Reading map layers" ) );
2422 loadProjectFlags( doc.get() );
2424 QList<QDomNode> brokenNodes;
2425 const bool clean = _getMapLayers( *doc, brokenNodes,
flags );
2430 QgsDebugError( u
"Unable to get map layers from project file."_s );
2432 if ( !brokenNodes.isEmpty() )
2434 QgsDebugError(
"there are " + QString::number( brokenNodes.size() ) +
" broken layers" );
2439 mBadLayerHandler->handleBadLayers( brokenNodes );
2442 mMainAnnotationLayer->readLayerXml( doc->documentElement().firstChildElement( u
"main-annotation-layer"_s ), context );
2443 mMainAnnotationLayer->setTransformContext( mTransformContext );
2446 profile.switchTask( tr(
"Loading embedded layers" ) );
2447 loadEmbeddedNodes( mRootGroup.get(),
flags );
2451 profile.switchTask( tr(
"Resolving layer references" ) );
2452 QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
2453 for ( QMap<QString, QgsMapLayer *>::iterator it =
layers.begin(); it !=
layers.end(); ++it )
2455 it.value()->resolveReferences(
this );
2457 mMainAnnotationLayer->resolveReferences(
this );
2459 mLayerTreeRegistryBridge->setEnabled(
true );
2462 profile.switchTask( tr(
"Resolving references" ) );
2463 mRootGroup->resolveReferences(
this );
2466 if ( QgsProjectVersion( 3, 28, 0 ) > mSaveVersion )
2473 if ( !layerTreeElem.isNull() )
2475 mRootGroup->readLayerOrderFromXml( layerTreeElem );
2479 const QDomElement layerTreeCanvasElem = doc->documentElement().firstChildElement( u
"layer-tree-canvas"_s );
2480 if ( !layerTreeCanvasElem.isNull( ) )
2482 mRootGroup->readLayerOrderFromXml( layerTreeCanvasElem );
2486 if ( QgsProjectVersion( 3, 4, 0 ) > mSaveVersion )
2488 const QStringList requiredLayerIds =
readListEntry( u
"RequiredLayers"_s, u
"Layers"_s );
2489 for (
const QString &layerId : requiredLayerIds )
2491 if ( QgsMapLayer *layer =
mapLayer( layerId ) )
2496 const QStringList disabledLayerIds =
readListEntry( u
"Identify"_s, u
"/disabledLayers"_s );
2497 for (
const QString &layerId : disabledLayerIds )
2499 if ( QgsMapLayer *layer =
mapLayer( layerId ) )
2507 if ( QgsProjectVersion( 3, 26, 0 ) > mSaveVersion )
2510 QString styleName =
readEntry( u
"DefaultStyles"_s, u
"/Marker"_s );
2511 if ( !styleName.isEmpty() )
2516 styleName =
readEntry( u
"DefaultStyles"_s, u
"/Line"_s );
2517 if ( !styleName.isEmpty() )
2522 styleName =
readEntry( u
"DefaultStyles"_s, u
"/Fill"_s );
2523 if ( !styleName.isEmpty() )
2528 styleName =
readEntry( u
"DefaultStyles"_s, u
"/ColorRamp"_s );
2529 if ( !styleName.isEmpty() )
2539 double opacity = 1.0;
2542 double alpha =
readDoubleEntry( u
"DefaultStyles"_s, u
"/AlphaInt"_s, 255, &ok );
2544 opacity = alpha / 255.0;
2545 double newOpacity =
readDoubleEntry( u
"DefaultStyles"_s, u
"/Opacity"_s, 1.0, &ok );
2547 opacity = newOpacity;
2554 removeEntry( u
"DefaultStyles"_s, u
"/ColorRamp"_s );
2555 removeEntry( u
"DefaultStyles"_s, u
"/RandomColors"_s );
2556 removeEntry( u
"DefaultStyles"_s, u
"/AlphaInt"_s );
2565 profile.switchTask( tr(
"Storing original layer properties" ) );
2569 mRootGroup->removeCustomProperty( u
"loading"_s );
2571 profile.switchTask( tr(
"Loading map themes" ) );
2572 mMapThemeCollection = std::make_unique< QgsMapThemeCollection >(
this );
2574 mMapThemeCollection->readXml( *doc );
2576 profile.switchTask( tr(
"Loading label settings" ) );
2577 mLabelingEngineSettings->readSettingsFromProject(
this );
2579 const QDomElement labelEngineSettingsElement = doc->documentElement().firstChildElement( u
"labelEngineSettings"_s );
2580 mLabelingEngineSettings->readXml( labelEngineSettingsElement, context );
2582 mLabelingEngineSettings->resolveReferences(
this );
2586 profile.switchTask( tr(
"Loading annotations" ) );
2589 mAnnotationManager->readXml( doc->documentElement(), context );
2593 mAnnotationManager->readXmlAndUpgradeToAnnotationLayerItems( doc->documentElement(), context, mMainAnnotationLayer, mTransformContext );
2597 profile.switchTask( tr(
"Loading layouts" ) );
2598 mLayoutManager->readXml( doc->documentElement(), *doc );
2602 profile.switchTask( tr(
"Loading elevation profiles" ) );
2603 mElevationProfileManager->readXml( doc->documentElement(), *doc, context );
2604 mElevationProfileManager->resolveReferences(
this );
2608 profile.switchTask( tr(
"Loading selective masking source sets" ) );
2609 mSelectiveMaskingSourceSetManager->readXml( doc->documentElement(), *doc, context );
2614 profile.switchTask( tr(
"Loading 3D Views" ) );
2615 m3DViewsManager->readXml( doc->documentElement(), *doc );
2618 profile.switchTask( tr(
"Loading bookmarks" ) );
2619 mBookmarkManager->readXml( doc->documentElement(), *doc );
2621 profile.switchTask( tr(
"Loading sensors" ) );
2622 mSensorManager->readXml( doc->documentElement(), *doc );
2625 QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
2626 for ( QMap<QString, QgsMapLayer *>::iterator it = existingMaps.begin(); it != existingMaps.end(); ++it )
2628 it.value()->setDependencies( it.value()->dependencies() );
2631 profile.switchTask( tr(
"Loading snapping settings" ) );
2632 mSnappingConfig.readProject( *doc );
2635 profile.switchTask( tr(
"Loading view settings" ) );
2637 mViewSettings->setUseProjectScales(
readBoolEntry( u
"Scales"_s, u
"/useProjectScales"_s ) );
2638 const QStringList scales =
readListEntry( u
"Scales"_s, u
"/ScalesList"_s );
2639 QVector<double> res;
2640 for (
const QString &scale : scales )
2642 const QStringList parts = scale.split(
':' );
2643 if ( parts.size() != 2 )
2647 const double denominator = QLocale().toDouble( parts[1], &ok );
2653 mViewSettings->setMapScales( res );
2654 const QDomElement viewSettingsElement = doc->documentElement().firstChildElement( u
"ProjectViewSettings"_s );
2655 if ( !viewSettingsElement.isNull() )
2656 mViewSettings->readXml( viewSettingsElement, context );
2659 profile.switchTask( tr(
"Loading style properties" ) );
2660 const QDomElement styleSettingsElement = doc->documentElement().firstChildElement( u
"ProjectStyleSettings"_s );
2661 if ( !styleSettingsElement.isNull() )
2663 mStyleSettings->removeProjectStyle();
2664 mStyleSettings->readXml( styleSettingsElement, context,
flags );
2668 profile.switchTask( tr(
"Loading temporal settings" ) );
2669 const QDomElement timeSettingsElement = doc->documentElement().firstChildElement( u
"ProjectTimeSettings"_s );
2670 if ( !timeSettingsElement.isNull() )
2671 mTimeSettings->readXml( timeSettingsElement, context );
2674 profile.switchTask( tr(
"Loading elevation properties" ) );
2675 const QDomElement elevationPropertiesElement = doc->documentElement().firstChildElement( u
"ElevationProperties"_s );
2676 if ( !elevationPropertiesElement.isNull() )
2677 mElevationProperties->readXml( elevationPropertiesElement, context );
2678 mElevationProperties->resolveReferences(
this );
2680 profile.switchTask( tr(
"Loading display settings" ) );
2682 const QDomElement displaySettingsElement = doc->documentElement().firstChildElement( u
"ProjectDisplaySettings"_s );
2683 if ( !displaySettingsElement.isNull() )
2684 mDisplaySettings->readXml( displaySettingsElement, context );
2687 profile.switchTask( tr(
"Loading GPS settings" ) );
2689 const QDomElement gpsSettingsElement = doc->documentElement().firstChildElement( u
"ProjectGpsSettings"_s );
2690 if ( !gpsSettingsElement.isNull() )
2691 mGpsSettings->readXml( gpsSettingsElement, context );
2692 mGpsSettings->resolveReferences(
this );
2695 profile.switchTask( tr(
"Updating variables" ) );
2697 profile.switchTask( tr(
"Updating CRS" ) );
2701 if ( mCrs3D != oldCrs3D )
2706 profile.switchTask( tr(
"Reading external settings" ) );
2710 profile.switchTask( tr(
"Updating interface" ) );
2712 snapSignalBlock.release();
2713 if ( !mBlockSnappingUpdates )
2734 const QString newFileName( u
"%1/%2.qgs"_s.arg( QFileInfo( mFile ).
absolutePath(), localeFileName ) );
2748 const QMap<QString, QgsMapLayer *> loadedLayers =
mapLayers();
2749 for (
auto it = loadedLayers.constBegin(); it != loadedLayers.constEnd(); ++it )
2751 if ( it.value()->isValid() && it.value()->customProperty( u
"_layer_was_editable"_s ).toBool() )
2753 if ( QgsVectorLayer *vl = qobject_cast< QgsVectorLayer * >( it.value() ) )
2755 it.value()->removeCustomProperty( u
"_layer_was_editable"_s );
2767 const auto constChildren = group->
children();
2768 for ( QgsLayerTreeNode *child : constChildren )
2781 QList<QgsLayerTreeNode *> clonedChildren;
2782 const QList<QgsLayerTreeNode *> constChildren = newGroup->children();
2783 clonedChildren.reserve( constChildren.size() );
2784 for ( QgsLayerTreeNode *newGroupChild : constChildren )
2785 clonedChildren << newGroupChild->clone();
2792 loadEmbeddedNodes( childGroup,
flags );
2797 if ( child->customProperty( u
"embedded"_s ).toInt() )
2799 QList<QDomNode> brokenNodes;
2802 valid = valid &&
false;
2817 return mCustomVariables;
2824 if ( variables == mCustomVariables )
2828 QStringList variableNames;
2829 QStringList variableValues;
2831 QVariantMap::const_iterator it = variables.constBegin();
2832 for ( ; it != variables.constEnd(); ++it )
2834 variableNames << it.key();
2835 variableValues << it.value().toString();
2838 writeEntry( u
"Variables"_s, u
"/variableNames"_s, variableNames );
2839 writeEntry( u
"Variables"_s, u
"/variableValues"_s, variableValues );
2841 mCustomVariables = variables;
2842 mProjectScope.reset();
2851 *mLabelingEngineSettings = settings;
2859 return *mLabelingEngineSettings;
2866 mProjectScope.reset();
2867 return mLayerStore.get();
2874 return mLayerStore.get();
2881 QList<QgsVectorLayer *>
layers;
2882 const QStringList layerIds =
readListEntry( u
"Digitizing"_s, u
"/AvoidIntersectionsList"_s, QStringList() );
2883 const auto constLayerIds = layerIds;
2884 for (
const QString &layerId : constLayerIds )
2897 list.reserve(
layers.size() );
2902 list << layer->id();
2905 writeEntry( u
"Digitizing"_s, u
"/AvoidIntersectionsList"_s, list );
2927 if ( mProjectScope )
2929 auto projectScope = std::make_unique< QgsExpressionContextScope >( *mProjectScope );
2936 projectScope->addFunction( u
"sensor_data"_s,
new GetSensorData(
sensorManager()->sensorsData() ) );
2938 return projectScope.release();
2941 mProjectScope = std::make_unique< QgsExpressionContextScope >( QObject::tr(
"Project" ) );
2945 QVariantMap::const_iterator it = vars.constBegin();
2947 for ( ; it != vars.constEnd(); ++it )
2949 mProjectScope->setVariable( it.key(), it.value(),
true );
2953 if ( projectPath.isEmpty() )
2954 projectPath = mOriginalPath;
2955 const QString projectFolder = QFileInfo( projectPath ).path();
2956 const QString projectFilename = QFileInfo( projectPath ).fileName();
2957 const QString projectBasename =
baseName();
2994 QVariantMap keywords;
2996 for (
auto it = metadataKeywords.constBegin(); it != metadataKeywords.constEnd(); ++it )
2998 keywords.insert( it.key(), it.value() );
3003 QVariantList layersIds;
3005 const QMap<QString, QgsMapLayer *> layersInProject = mLayerStore->mapLayers();
3006 layersIds.reserve( layersInProject.count() );
3007 layers.reserve( layersInProject.count() );
3008 for (
auto it = layersInProject.constBegin(); it != layersInProject.constEnd(); ++it )
3010 layersIds << it.value()->id();
3016 mProjectScope->addFunction( u
"project_color"_s,
new GetNamedProjectColor(
this ) );
3017 mProjectScope->addFunction( u
"project_color_object"_s,
new GetNamedProjectColorObject(
this ) );
3022void QgsProject::onMapLayersAdded(
const QList<QgsMapLayer *> &layers )
3026 const QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
3028 const auto constLayers =
layers;
3031 if ( ! layer->isValid() )
3034 if (
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer ) )
3037 if ( vlayer->dataProvider() )
3045 for ( QMap<QString, QgsMapLayer *>::const_iterator it = existingMaps.cbegin(); it != existingMaps.cend(); ++it )
3047 const QSet<QgsMapLayerDependency> deps = it.value()->dependencies();
3048 if ( deps.contains( layer->id() ) )
3051 it.value()->setDependencies( deps );
3056 updateTransactionGroups();
3058 if ( !mBlockSnappingUpdates && mSnappingConfig.addLayers(
layers ) )
3062void QgsProject::onMapLayersRemoved(
const QList<QgsMapLayer *> &layers )
3066 if ( !mBlockSnappingUpdates && mSnappingConfig.removeLayers(
layers ) )
3069 for ( QgsMapLayer *layer :
layers )
3071 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
3075 mEditBufferGroup.removeLayer( vlayer );
3079void QgsProject::cleanTransactionGroups(
bool force )
3083 bool changed =
false;
3084 for ( QMap< QPair< QString, QString>, QgsTransactionGroup *>::Iterator tg = mTransactionGroups.begin(); tg != mTransactionGroups.end(); )
3086 if ( tg.value()->isEmpty() || force )
3089 tg = mTransactionGroups.erase( tg );
3101void QgsProject::updateTransactionGroups()
3105 mEditBufferGroup.clear();
3107 switch ( mTransactionMode )
3111 cleanTransactionGroups(
true );
3116 cleanTransactionGroups(
true );
3119 cleanTransactionGroups(
false );
3123 bool tgChanged =
false;
3124 const auto constLayers =
mapLayers().values();
3125 for ( QgsMapLayer *layer : constLayers )
3127 if ( ! layer->isValid() )
3130 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
3134 switch ( mTransactionMode )
3146 QgsTransactionGroup *tg = mTransactionGroups.value( qMakePair( key, connString ) );
3150 tg =
new QgsTransactionGroup();
3151 mTransactionGroups.insert( qMakePair( key, connString ), tg );
3161 mEditBufferGroup.addLayer( vlayer );
3177 context.setProjectTranslator(
this );
3179 context.setCurrentLayerId( layerNode.toElement().firstChildElement( u
"id"_s ).text() );
3180 QList<QDomNode> brokenNodes;
3181 if ( addLayer( layerNode.toElement(), brokenNodes, context ) )
3189 layer->resolveReferences(
this );
3191 if ( layer->isValid() && layer->customProperty( u
"_layer_was_editable"_s ).toBool() )
3193 layer->startEditing();
3194 layer->removeCustomProperty( u
"_layer_was_editable"_s );
3206 mFile.setFileName( filename );
3208 mCachedHomePath.clear();
3216 mProjectScope.reset();
3222 const QString storageFilePath { storage->filePath( mFile.fileName() ) };
3223 if ( storageFilePath.isEmpty() )
3229 const QString tempPath = QStandardPaths::standardLocations( QStandardPaths::TempLocation ).at( 0 );
3230 const QString tmpZipFilename( tempPath + QDir::separator() + QUuid::createUuid().toString() );
3232 if ( !zip( tmpZipFilename ) )
3235 QFile tmpZipFile( tmpZipFilename );
3236 if ( !tmpZipFile.open( QIODevice::ReadOnly ) )
3238 setError( tr(
"Unable to read file %1" ).arg( tmpZipFilename ) );
3243 if ( !storage->writeProject( mFile.fileName(), &tmpZipFile, context ) )
3245 QString err = tr(
"Unable to save project to storage %1" ).arg( mFile.fileName() );
3246 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
3247 if ( !messages.isEmpty() )
3248 err += u
"\n\n"_s + messages.last().message();
3254 QFile::remove( tmpZipFilename );
3261 return zip( mFile.fileName() );
3267 const bool asOk = saveAuxiliaryStorage();
3268 const bool writeOk = writeProjectFile( mFile.fileName() );
3269 bool attachmentsOk =
true;
3270 if ( !mArchive->files().isEmpty() )
3272 const QFileInfo finfo( mFile.fileName() );
3273 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( u
"%1_attachments.zip"_s.arg( finfo.completeBaseName() ) );
3274 attachmentsOk = mArchive->zip( attachmentsZip );
3278 if ( ( !asOk || !attachmentsOk ) && writeOk )
3280 QStringList errorMessage;
3283 const QString err = mAuxiliaryStorage->errorString();
3284 errorMessage.append( tr(
"Unable to save auxiliary storage ('%1')" ).arg( err ) );
3286 if ( !attachmentsOk )
3288 errorMessage.append( tr(
"Unable to save attachments archive" ) );
3290 setError( errorMessage.join(
'\n' ) );
3293 return asOk && writeOk && attachmentsOk;
3297bool QgsProject::writeProjectFile(
const QString &filename )
3301 QFile projectFile( filename );
3307 const QFileInfo myFileInfo( projectFile );
3308 if ( myFileInfo.exists() && !myFileInfo.isWritable() )
3310 setError( tr(
"%1 is not writable. Please adjust permissions (if possible) and try again." )
3311 .arg( projectFile.fileName() ) );
3315 QgsReadWriteContext context;
3319 QDomImplementation::setInvalidDataPolicy( QDomImplementation::DropInvalidChars );
3321 const QDomDocumentType documentType =
3322 QDomImplementation().createDocumentType( u
"qgis"_s, u
"http://mrcc.com/qgis.dtd"_s,
3324 auto doc = std::make_unique<QDomDocument>( documentType );
3326 QDomElement qgisNode = doc->createElement( u
"qgis"_s );
3327 qgisNode.setAttribute( u
"projectname"_s,
title() );
3330 if ( !mSettings.value( u
"projects/anonymize_saved_projects"_s,
false,
QgsSettings::Core ).toBool() )
3334 qgisNode.setAttribute( u
"saveUser"_s, newSaveUser );
3335 qgisNode.setAttribute( u
"saveUserFull"_s, newSaveUserFull );
3336 mSaveUser = newSaveUser;
3337 mSaveUserFull = newSaveUserFull;
3338 if ( mMetadata.author().isEmpty() )
3342 if ( !mMetadata.creationDateTime().isValid() )
3344 mMetadata.setCreationDateTime( QDateTime( QDateTime::currentDateTime() ) );
3346 mSaveDateTime = QDateTime::currentDateTime();
3347 qgisNode.setAttribute( u
"saveDateTime"_s, mSaveDateTime.toString( Qt::ISODate ) );
3352 mSaveUserFull.clear();
3353 mMetadata.setAuthor( QString() );
3354 mMetadata.setCreationDateTime( QDateTime() );
3355 mSaveDateTime = QDateTime();
3357 doc->appendChild( qgisNode );
3360 QDomElement homePathNode = doc->createElement( u
"homePath"_s );
3361 homePathNode.setAttribute( u
"path"_s, mHomePath );
3362 qgisNode.appendChild( homePathNode );
3365 QDomElement titleNode = doc->createElement( u
"title"_s );
3366 qgisNode.appendChild( titleNode );
3368 QDomElement transactionNode = doc->createElement( u
"transaction"_s );
3369 transactionNode.setAttribute( u
"mode"_s,
qgsEnumValueToKey( mTransactionMode ) );
3370 qgisNode.appendChild( transactionNode );
3372 QDomElement flagsNode = doc->createElement( u
"projectFlags"_s );
3374 qgisNode.appendChild( flagsNode );
3376 const QDomText titleText = doc->createTextNode(
title() );
3377 titleNode.appendChild( titleText );
3381 QDomElement srsNode = doc->createElement( u
"projectCrs"_s );
3382 mCrs.writeXml( srsNode, *doc );
3383 qgisNode.appendChild( srsNode );
3386 QDomElement verticalSrsNode = doc->createElement( u
"verticalCrs"_s );
3387 mVerticalCrs.writeXml( verticalSrsNode, *doc );
3388 qgisNode.appendChild( verticalSrsNode );
3391 QDomElement elevationShadingNode = doc->createElement( u
"elevation-shading-renderer"_s );
3392 mElevationShadingRenderer.writeXml( elevationShadingNode, context );
3393 qgisNode.appendChild( elevationShadingNode );
3396 std::unique_ptr< QgsLayerTreeNode > clonedRoot( mRootGroup->clone() );
3400 clonedRoot->writeXml( qgisNode, context );
3403 mSnappingConfig.writeProject( *doc );
3404 writeEntry( u
"Digitizing"_s, u
"/AvoidIntersectionsMode"_s,
static_cast<int>( mAvoidIntersectionsMode ) );
3412 QDomElement annotationLayerNode = doc->createElement( u
"main-annotation-layer"_s );
3413 mMainAnnotationLayer->writeLayerXml( annotationLayerNode, *doc, context );
3414 qgisNode.appendChild( annotationLayerNode );
3418 QDomElement projectLayersNode = doc->createElement( u
"projectlayers"_s );
3420 QMap<QString, QgsMapLayer *>::ConstIterator li =
layers.constBegin();
3421 while ( li !=
layers.end() )
3423 QgsMapLayer *ml = li.value();
3427 const QHash< QString, QPair< QString, bool> >::const_iterator emIt = mEmbeddedLayers.constFind( ml->
id() );
3428 if ( emIt == mEmbeddedLayers.constEnd() )
3430 QDomElement maplayerElem;
3436 maplayerElem = doc->createElement( u
"maplayer"_s );
3440 maplayerElem.setAttribute( u
"editable"_s, u
"1"_s );
3444 QDomDocument document;
3447 maplayerElem = document.firstChildElement();
3451 QgsDebugError( u
"Could not restore layer properties for layer %1"_s.arg( ml->
id() ) );
3457 projectLayersNode.appendChild( maplayerElem );
3463 if ( emIt.value().second )
3465 QDomElement mapLayerElem = doc->createElement( u
"maplayer"_s );
3466 mapLayerElem.setAttribute( u
"embedded"_s, 1 );
3467 mapLayerElem.setAttribute( u
"project"_s,
writePath( emIt.value().first ) );
3468 mapLayerElem.setAttribute( u
"id"_s, ml->
id() );
3469 projectLayersNode.appendChild( mapLayerElem );
3476 qgisNode.appendChild( projectLayersNode );
3478 QDomElement layerOrderNode = doc->createElement( u
"layerorder"_s );
3479 const auto constCustomLayerOrder = mRootGroup->customLayerOrder();
3480 for ( QgsMapLayer *layer : constCustomLayerOrder )
3482 QDomElement mapLayerElem = doc->createElement( u
"layer"_s );
3483 mapLayerElem.setAttribute( u
"id"_s, layer->id() );
3484 layerOrderNode.appendChild( mapLayerElem );
3486 qgisNode.appendChild( layerOrderNode );
3488 mLabelingEngineSettings->writeSettingsToProject(
this );
3490 QDomElement labelEngineSettingsElement = doc->createElement( u
"labelEngineSettings"_s );
3491 mLabelingEngineSettings->writeXml( *doc, labelEngineSettingsElement, context );
3492 qgisNode.appendChild( labelEngineSettingsElement );
3495 writeEntry( u
"Gui"_s, u
"/CanvasColorRedPart"_s, mBackgroundColor.red() );
3496 writeEntry( u
"Gui"_s, u
"/CanvasColorGreenPart"_s, mBackgroundColor.green() );
3497 writeEntry( u
"Gui"_s, u
"/CanvasColorBluePart"_s, mBackgroundColor.blue() );
3499 writeEntry( u
"Gui"_s, u
"/SelectionColorRedPart"_s, mSelectionColor.red() );
3500 writeEntry( u
"Gui"_s, u
"/SelectionColorGreenPart"_s, mSelectionColor.green() );
3501 writeEntry( u
"Gui"_s, u
"/SelectionColorBluePart"_s, mSelectionColor.blue() );
3502 writeEntry( u
"Gui"_s, u
"/SelectionColorAlphaPart"_s, mSelectionColor.alpha() );
3510 dump_( mProperties );
3513 QgsDebugMsgLevel( u
"there are %1 property scopes"_s.arg(
static_cast<int>( mProperties.count() ) ), 2 );
3515 if ( !mProperties.isEmpty() )
3518 mProperties.writeXml( u
"properties"_s, qgisNode, *doc );
3521 QDomElement ddElem = doc->createElement( u
"dataDefinedServerProperties"_s );
3522 mDataDefinedServerProperties.writeXml( ddElem, dataDefinedServerPropertyDefinitions() );
3523 qgisNode.appendChild( ddElem );
3525 mMapThemeCollection->writeXml( *doc );
3527 mTransformContext.writeXml( qgisNode, context );
3529 QDomElement metadataElem = doc->createElement( u
"projectMetadata"_s );
3530 mMetadata.writeMetadataXml( metadataElem, *doc );
3531 qgisNode.appendChild( metadataElem );
3534 const QDomElement annotationsElem = mAnnotationManager->writeXml( *doc, context );
3535 qgisNode.appendChild( annotationsElem );
3539 const QDomElement layoutElem = mLayoutManager->writeXml( *doc );
3540 qgisNode.appendChild( layoutElem );
3544 const QDomElement elevationProfileElem = mElevationProfileManager->writeXml( *doc, context );
3545 qgisNode.appendChild( elevationProfileElem );
3549 const QDomElement selectiveMaskingSourceSetElem = mSelectiveMaskingSourceSetManager->writeXml( *doc, context );
3550 qgisNode.appendChild( selectiveMaskingSourceSetElem );
3554 const QDomElement views3DElem = m3DViewsManager->writeXml( *doc );
3555 qgisNode.appendChild( views3DElem );
3559 const QDomElement bookmarkElem = mBookmarkManager->writeXml( *doc );
3560 qgisNode.appendChild( bookmarkElem );
3564 const QDomElement sensorElem = mSensorManager->writeXml( *doc );
3565 qgisNode.appendChild( sensorElem );
3569 const QDomElement viewSettingsElem = mViewSettings->writeXml( *doc, context );
3570 qgisNode.appendChild( viewSettingsElem );
3574 const QDomElement styleSettingsElem = mStyleSettings->writeXml( *doc, context );
3575 qgisNode.appendChild( styleSettingsElem );
3579 const QDomElement timeSettingsElement = mTimeSettings->writeXml( *doc, context );
3580 qgisNode.appendChild( timeSettingsElement );
3584 const QDomElement elevationPropertiesElement = mElevationProperties->writeXml( *doc, context );
3585 qgisNode.appendChild( elevationPropertiesElement );
3589 const QDomElement displaySettingsElem = mDisplaySettings->writeXml( *doc, context );
3590 qgisNode.appendChild( displaySettingsElem );
3594 const QDomElement gpsSettingsElem = mGpsSettings->writeXml( *doc, context );
3595 qgisNode.appendChild( gpsSettingsElem );
3604 QFile backupFile( u
"%1~"_s.arg( filename ) );
3606 ok &= backupFile.open( QIODevice::WriteOnly | QIODevice::Truncate );
3607 ok &= projectFile.open( QIODevice::ReadOnly );
3610 while ( ok && !projectFile.atEnd() )
3612 ba = projectFile.read( 10240 );
3613 ok &= backupFile.write( ba ) == ba.size();
3616 projectFile.close();
3621 setError( tr(
"Unable to create backup file %1" ).arg( backupFile.fileName() ) );
3626 struct utimbuf tb = {
static_cast<time_t
>( fi.lastRead().toSecsSinceEpoch() ),
static_cast<time_t
>( fi.lastModified().toSecsSinceEpoch() ) };
3627 utime( backupFile.fileName().toUtf8().constData(), &tb );
3630 if ( !projectFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
3632 projectFile.close();
3635 setError( tr(
"Unable to save to file %1" ).arg( projectFile.fileName() ) );
3639 QTemporaryFile tempFile;
3640 bool ok = tempFile.open();
3643 QTextStream projectFileStream( &tempFile );
3644 doc->save( projectFileStream, 2 );
3645 ok &= projectFileStream.pos() > -1;
3647 ok &= tempFile.seek( 0 );
3650 while ( ok && !tempFile.atEnd() )
3652 ba = tempFile.read( 10240 );
3653 ok &= projectFile.write( ba ) == ba.size();
3656 ok &= projectFile.error() == QFile::NoError;
3658 projectFile.close();
3665 setError( tr(
"Unable to save to file %1. Your project "
3666 "may be corrupted on disk. Try clearing some space on the volume and "
3667 "check file permissions before pressing save again." )
3668 .arg( projectFile.fileName() ) );
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 )
3734 bool propertiesModified;
3735 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3737 if ( propertiesModified )
3745 const QStringList &def,
3757 value =
property->value();
3759 const bool valid = QMetaType::Type::QStringList == value.userType();
3765 return value.toStringList();
3788 value =
property->value();
3790 const bool valid = value.canConvert( QMetaType::Type::QString );
3795 return value.toString();
3814 value =
property->value();
3817 const bool valid = value.canConvert( QMetaType::Type::Int );
3826 return value.toInt();
3841 const QVariant value =
property->value();
3843 const bool valid = value.canConvert( QMetaType::Type::Double );
3848 return value.toDouble();
3865 const QVariant value =
property->value();
3867 const bool valid = value.canConvert( QMetaType::Type::Bool );
3872 return value.toBool();
3884 if (
findKey_( scope, key, mProperties ) )
3890 return !
findKey_( scope, key, mProperties );
3899 QStringList entries;
3901 if ( foundProperty )
3918 QStringList entries;
3920 if ( foundProperty )
3935 dump_( mProperties );
3955 filePath = storage->filePath( mFile.fileName() );
3982void QgsProject::setError(
const QString &errorMessage )
3986 mErrorMessage = errorMessage;
3993 return mErrorMessage;
3996void QgsProject::clearError()
4000 setError( QString() );
4007 mBadLayerHandler.reset( handler );
4014 const QHash< QString, QPair< QString, bool > >::const_iterator it = mEmbeddedLayers.find(
id );
4015 if ( it == mEmbeddedLayers.constEnd() )
4019 return it.value().first;
4029 static QString sPrevProjectFilePath;
4030 static QDateTime sPrevProjectFileTimestamp;
4031 static QDomDocument sProjectDocument;
4033 QString qgsProjectFile = projectFilePath;
4035 if ( projectFilePath.endsWith(
".qgz"_L1, Qt::CaseInsensitive ) )
4037 archive.
unzip( projectFilePath );
4041 const QDateTime projectFileTimestamp = QFileInfo( projectFilePath ).lastModified();
4043 if ( projectFilePath != sPrevProjectFilePath || projectFileTimestamp != sPrevProjectFileTimestamp )
4045 sPrevProjectFilePath.clear();
4047 QFile projectFile( qgsProjectFile );
4048 if ( !projectFile.open( QIODevice::ReadOnly ) )
4053 if ( !sProjectDocument.setContent( &projectFile ) )
4058 sPrevProjectFilePath = projectFilePath;
4059 sPrevProjectFileTimestamp = projectFileTimestamp;
4063 bool useAbsolutePaths =
true;
4065 const QDomElement propertiesElem = sProjectDocument.documentElement().firstChildElement( u
"properties"_s );
4066 if ( !propertiesElem.isNull() )
4068 QDomElement e = propertiesElem.firstChildElement( u
"Paths"_s );
4071 e = propertiesElem.firstChildElement( u
"properties"_s );
4072 while ( !e.isNull() && e.attribute( u
"name"_s ) !=
"Paths"_L1 )
4073 e = e.nextSiblingElement( u
"properties"_s );
4075 e = e.firstChildElement( u
"properties"_s );
4076 while ( !e.isNull() && e.attribute( u
"name"_s ) !=
"Absolute"_L1 )
4077 e = e.nextSiblingElement( u
"properties"_s );
4081 e = e.firstChildElement( u
"Absolute"_s );
4086 useAbsolutePaths = e.text().compare(
"true"_L1, Qt::CaseInsensitive ) == 0;
4091 if ( !useAbsolutePaths )
4097 const QDomElement projectLayersElem = sProjectDocument.documentElement().firstChildElement( u
"projectlayers"_s );
4098 if ( projectLayersElem.isNull() )
4103 QDomElement mapLayerElem = projectLayersElem.firstChildElement( u
"maplayer"_s );
4104 while ( ! mapLayerElem.isNull() )
4107 const QString
id = mapLayerElem.firstChildElement( u
"id"_s ).text();
4108 if (
id == layerId )
4111 if ( mapLayerElem.attribute( u
"embedded"_s ) ==
"1"_L1 )
4116 mEmbeddedLayers.insert( layerId, qMakePair( projectFilePath, saveFlag ) );
4118 if ( addLayer( mapLayerElem, brokenNodes, embeddedContext,
flags ) )
4124 mEmbeddedLayers.remove( layerId );
4128 mapLayerElem = mapLayerElem.nextSiblingElement( u
"maplayer"_s );
4138 QString qgsProjectFile = projectFilePath;
4140 if ( projectFilePath.endsWith(
".qgz"_L1, Qt::CaseInsensitive ) )
4142 archive.
unzip( projectFilePath );
4147 QFile projectFile( qgsProjectFile );
4148 if ( !projectFile.open( QIODevice::ReadOnly ) )
4153 QDomDocument projectDocument;
4154 if ( !projectDocument.setContent( &projectFile ) )
4164 auto root = std::make_unique< QgsLayerTreeGroup >();
4166 QDomElement layerTreeElem = projectDocument.documentElement().firstChildElement( u
"layer-tree-group"_s );
4167 if ( !layerTreeElem.isNull() )
4169 root->readChildrenFromXml( layerTreeElem, context );
4187 newGroup->setCustomProperty( u
"embedded"_s, 1 );
4188 newGroup->setCustomProperty( u
"embedded_project"_s, projectFilePath );
4191 mLayerTreeRegistryBridge->setEnabled(
false );
4192 initializeEmbeddedSubtree( projectFilePath, newGroup.get(),
flags );
4193 mLayerTreeRegistryBridge->setEnabled(
true );
4196 const QStringList constFindLayerIds = newGroup->findLayerIds();
4197 for (
const QString &layerId : constFindLayerIds )
4214 const auto constChildren = group->
children();
4218 child->setCustomProperty( u
"embedded"_s, 1 );
4227 QList<QDomNode> brokenNodes;
4251 writeEntry( u
"Digitizing"_s, u
"/TopologicalEditing"_s, ( enabled ? 1 : 0 ) );
4259 return readNumEntry( u
"Digitizing"_s, u
"/TopologicalEditing"_s, 0 );
4266 if ( mDistanceUnits == unit )
4269 mDistanceUnits = unit;
4278 if ( mAreaUnits == unit )
4290 if ( mScaleMethod == method )
4293 mScaleMethod = method;
4303 if ( !mCachedHomePath.isEmpty() )
4304 return mCachedHomePath;
4308 if ( !mHomePath.isEmpty() )
4310 const QFileInfo homeInfo( mHomePath );
4311 if ( !homeInfo.isRelative() )
4313 mCachedHomePath = mHomePath;
4323 const QString storagePath { storage->filePath(
fileName() ) };
4324 if ( ! storagePath.isEmpty() && QFileInfo::exists( storagePath ) )
4326 mCachedHomePath = QFileInfo( storagePath ).path();
4327 return mCachedHomePath;
4331 mCachedHomePath = pfi.path();
4332 return mCachedHomePath;
4335 if ( !pfi.exists() )
4337 mCachedHomePath = mHomePath;
4341 if ( !mHomePath.isEmpty() )
4344 mCachedHomePath = QDir::cleanPath( pfi.path() +
'/' + mHomePath );
4348 mCachedHomePath = pfi.canonicalPath();
4350 return mCachedHomePath;
4365 return mRelationManager.get();
4372 return mLayoutManager.get();
4379 return mLayoutManager.get();
4386 return mElevationProfileManager.get();
4393 return mElevationProfileManager.get();
4400 return mSelectiveMaskingSourceSetManager.get();
4407 return mSelectiveMaskingSourceSetManager.get();
4414 return m3DViewsManager.get();
4421 return m3DViewsManager.get();
4428 return mBookmarkManager;
4435 return mBookmarkManager;
4442 return mSensorManager;
4449 return mSensorManager;
4456 return mViewSettings;
4463 return mViewSettings;
4470 return mStyleSettings;
4478 return mStyleSettings;
4485 return mTimeSettings;
4492 return mTimeSettings;
4499 return mElevationProperties;
4506 return mElevationProperties;
4513 return mDisplaySettings;
4520 return mDisplaySettings;
4527 return mGpsSettings;
4534 return mGpsSettings;
4541 return mRootGroup.get();
4548 return mMapThemeCollection.get();
4555 return mAnnotationManager.get();
4562 return mAnnotationManager.get();
4569 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
4570 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
4575 if (
layers.contains( it.value() ) )
4592 for (
const QString &layerId : layerIds )
4610 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
4644 updateTransactionGroups();
4651 return mTransactionMode;
4662 const auto constLayers =
mapLayers().values();
4665 if ( layer->isEditable() )
4667 QgsLogger::warning( tr(
"Transaction mode can be changed only if all layers are not editable." ) );
4673 updateTransactionGroups();
4682 return mTransactionGroups;
4695 return mLayerStore->count();
4702 return mLayerStore->validCount();
4710 if ( mMainAnnotationLayer && layerId == mMainAnnotationLayer->id() )
4711 return mMainAnnotationLayer;
4713 return mLayerStore->mapLayer( layerId );
4720 return mLayerStore->mapLayersByName( layerName );
4727 QList<QgsMapLayer *>
layers;
4728 const auto constMapLayers { mLayerStore->mapLayers() };
4729 for (
const auto &l : constMapLayers )
4731 if ( ! l->serverProperties()->shortName().isEmpty() )
4733 if ( l->serverProperties()->shortName() == shortName )
4736 else if ( l->name() == shortName )
4749 auto archive = std::make_unique<QgsProjectArchive>();
4752 if ( !archive->unzip( filename ) )
4754 setError( tr(
"Unable to unzip file '%1'" ).arg( filename ) );
4759 if ( archive->projectFile().isEmpty() )
4761 setError( tr(
"Zip archive does not provide a project file" ) );
4766 releaseHandlesToProjectArchive();
4767 mArchive = std::move( archive );
4770 if ( !
static_cast<QgsProjectArchive *
>( mArchive.get() )->auxiliaryStorageFile().isEmpty() )
4774 mAuxiliaryStorage = std::make_unique< QgsAuxiliaryStorage >(
static_cast<QgsProjectArchive *
>( mArchive.get() )->auxiliaryStorageFile(),
false );
4778 mAuxiliaryStorage = std::make_unique< QgsAuxiliaryStorage >( *
this );
4782 if ( ! readProjectFile(
static_cast<QgsProjectArchive *
>( mArchive.get() )->projectFile(),
flags ) )
4784 setError( tr(
"Cannot read unzipped qgs project file" ) + u
": "_s +
error() );
4789 static_cast<QgsProjectArchive *
>( mArchive.get() )->clearProjectFile();
4794bool QgsProject::zip(
const QString &filename )
4801 auto archive = std::make_unique<QgsProjectArchive>();
4802 const QString
baseName = QFileInfo( filename ).baseName();
4803 const QString qgsFileName = u
"%1.qgs"_s.arg(
baseName );
4804 QFile qgsFile( QDir( archive->dir() ).filePath( qgsFileName ) );
4806 bool writeOk =
false;
4807 if ( qgsFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
4809 writeOk = writeProjectFile( qgsFile.fileName() );
4816 setError( tr(
"Unable to write temporary qgs file" ) );
4821 const QFileInfo info( qgsFile );
4823 const QString asFileName = info.path() + QDir::separator() + info.completeBaseName() + asExt;
4825 bool auxiliaryStorageSavedOk =
true;
4826 if ( ! saveAuxiliaryStorage( asFileName ) )
4828 const QString err = mAuxiliaryStorage->errorString();
4829 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 ) );
4830 auxiliaryStorageSavedOk =
false;
4833 if ( !mArchive->exists() )
4835 releaseHandlesToProjectArchive();
4836 mArchive = std::make_unique< QgsProjectArchive >();
4837 mArchive->unzip( mFile.fileName() );
4838 static_cast<QgsProjectArchive *
>( mArchive.get() )->clearProjectFile();
4840 const QString auxiliaryStorageFile =
static_cast<QgsProjectArchive *
>( mArchive.get() )->auxiliaryStorageFile();
4841 if ( ! auxiliaryStorageFile.isEmpty() )
4843 archive->addFile( auxiliaryStorageFile );
4844 mAuxiliaryStorage = std::make_unique< QgsAuxiliaryStorage >( auxiliaryStorageFile,
false );
4852 if ( QFile::exists( asFileName ) )
4854 archive->addFile( asFileName );
4859 archive->addFile( qgsFile.fileName() );
4862 const QStringList &files = mArchive->files();
4863 for (
const QString &file : files )
4865 if ( !file.endsWith(
".qgs"_L1, Qt::CaseInsensitive ) && !file.endsWith( asExt, Qt::CaseInsensitive ) )
4867 archive->addFile( file );
4873 if ( !archive->zip( filename ) )
4875 setError( tr(
"Unable to perform zip" ) );
4879 return auxiliaryStorageSavedOk && zipOk;
4890 const QList<QgsMapLayer *> &
layers,
4892 bool takeOwnership )
4896 const QList<QgsMapLayer *> myResultList { mLayerStore->addMapLayers(
layers, takeOwnership ) };
4897 if ( !myResultList.isEmpty() )
4900 for (
auto &l : myResultList )
4914 if ( mAuxiliaryStorage )
4929 mProjectScope.reset();
4931 return myResultList;
4937 bool takeOwnership )
4941 QList<QgsMapLayer *> addedLayers;
4942 addedLayers =
addMapLayers( QList<QgsMapLayer *>() << layer, addToLegend, takeOwnership );
4943 return addedLayers.isEmpty() ? nullptr : addedLayers[0];
4946void QgsProject::removeAuxiliaryLayer(
const QgsMapLayer *ml )
4953 const QgsVectorLayer *vl = qobject_cast<const QgsVectorLayer *>( ml );
4965 for (
const auto &layerId : layerIds )
4966 removeAuxiliaryLayer( mLayerStore->mapLayer( layerId ) );
4968 mProjectScope.reset();
4969 mLayerStore->removeMapLayers( layerIds );
4976 for (
const auto &layer :
layers )
4977 removeAuxiliaryLayer( layer );
4979 mProjectScope.reset();
4980 mLayerStore->removeMapLayers(
layers );
4987 removeAuxiliaryLayer( mLayerStore->mapLayer( layerId ) );
4988 mProjectScope.reset();
4989 mLayerStore->removeMapLayer( layerId );
4996 removeAuxiliaryLayer( layer );
4997 mProjectScope.reset();
4998 mLayerStore->removeMapLayer( layer );
5005 mProjectScope.reset();
5006 return mLayerStore->takeMapLayer( layer );
5013 return mMainAnnotationLayer;
5020 if ( mLayerStore->count() == 0 )
5023 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
5024 mProjectScope.reset();
5025 mLayerStore->removeAllMapLayers();
5027 snapSingleBlocker.release();
5028 mSnappingConfig.clearIndividualLayerSettings();
5029 if ( !mBlockSnappingUpdates )
5037 const QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
5038 QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin();
5039 for ( ; it !=
layers.constEnd(); ++it )
5041 it.value()->reload();
5050 return validOnly ? mLayerStore->validMapLayers() : mLayerStore->mapLayers();
5057 return mTransactionGroups.value( qMakePair( providerKey, connString ) );
5064 return &mEditBufferGroup;
5075 if ( mSettings.value( u
"/projections/unknownCrsBehavior"_s, u
"NoAction"_s,
QgsSettings::App ).toString() == u
"UseProjectCrs"_s
5076 || mSettings.value( u
"/projections/unknownCrsBehavior"_s, 0,
QgsSettings::App ).toString() ==
"2"_L1 )
5084 const QString layerDefaultCrs = mSettings.value( u
"/Projections/layerDefaultCrs"_s, u
"EPSG:4326"_s ).toString();
5105bool QgsProject::saveAuxiliaryStorage(
const QString &filename )
5111 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5116 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() );
5124 if ( !mAuxiliaryStorage->exists( *
this ) && empty )
5128 else if ( !filename.isEmpty() )
5130 return mAuxiliaryStorage->saveAs( filename );
5134 return mAuxiliaryStorage->saveAs( *
this );
5147 return sPropertyDefinitions;
5160 return mAuxiliaryStorage.get();
5167 return mAuxiliaryStorage.get();
5174 const QDir archiveDir( mArchive->dir() );
5175 QTemporaryFile tmpFile( archiveDir.filePath(
"XXXXXX_" + nameTemplate ),
this );
5176 tmpFile.setAutoRemove(
false );
5177 if ( !tmpFile.open() )
5179 setError( tr(
"Unable to open %1" ).arg( tmpFile.fileName() ) );
5182 mArchive->addFile( tmpFile.fileName() );
5183 return tmpFile.fileName();
5190 QStringList attachments;
5192 const QStringList files = mArchive->files();
5193 attachments.reserve( files.size() );
5194 for (
const QString &file : files )
5198 attachments.append( file );
5208 return mArchive->removeFile( path );
5215 return u
"attachment:///%1"_s.arg( QFileInfo( attachedFile ).
fileName() );
5222 if ( identifier.startsWith(
"attachment:///"_L1 ) )
5224 return QDir( mArchive->dir() ).absoluteFilePath( identifier.mid( 14 ) );
5245 mProjectScope.reset();
5260 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5274 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
5275 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
5280 if (
layers.contains( it.value() ) )
5292 QStringList customColors;
5293 QStringList customColorLabels;
5295 QgsNamedColorList::const_iterator colorIt = colors.constBegin();
5296 for ( ; colorIt != colors.constEnd(); ++colorIt )
5299 const QString label = ( *colorIt ).second;
5300 customColors.append( color );
5301 customColorLabels.append( label );
5303 writeEntry( u
"Palette"_s, u
"/Colors"_s, customColors );
5304 writeEntry( u
"Palette"_s, u
"/Labels"_s, customColorLabels );
5305 mProjectScope.reset();
5313 if ( mBackgroundColor == color )
5316 mBackgroundColor = color;
5324 return mBackgroundColor;
5331 if ( mSelectionColor == color )
5334 mSelectionColor = color;
5342 return mSelectionColor;
5349 mViewSettings->setMapScales( scales );
5356 return mViewSettings->mapScales();
5363 mViewSettings->setUseProjectScales( enabled );
5370 return mViewSettings->useProjectScales();
5383 translationContext.writeTsFile( locale );
5386QString
QgsProject::translate(
const QString &context,
const QString &sourceText,
const char *disambiguation,
int n )
const
5395 QString result = mTranslator->translate( context.toUtf8(), sourceText.toUtf8(), disambiguation, n );
5397 if ( result.isEmpty() )
5411 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5416 if ( !( ( *it )->accept( visitor ) ) )
5425 if ( !mLayoutManager->accept( visitor ) )
5428 if ( !mAnnotationManager->accept( visitor ) )
5438 const QString macros =
readEntry( u
"Macros"_s, u
"/pythonCode"_s, QString() );
5439 if ( !macros.isEmpty() )
5448 const QString expressionFunctions =
readEntry( u
"ExpressionFunctions"_s, u
"/pythonCode"_s );
5449 if ( !expressionFunctions.isEmpty() )
5461 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5463 if ( !( ( *it )->accept( visitor, context ) ) )
5475 return mElevationShadingRenderer;
5478void QgsProject::loadProjectFlags(
const QDomDocument *doc )
5482 QDomElement element = doc->documentElement().firstChildElement( u
"projectFlags"_s );
5484 if ( !element.isNull() )
5491 element = doc->documentElement().firstChildElement( u
"evaluateDefaultValues"_s );
5492 if ( !element.isNull() )
5494 if ( element.attribute( u
"active"_s, u
"0"_s ).toInt() == 1 )
5499 element = doc->documentElement().firstChildElement( u
"trust"_s );
5500 if ( !element.isNull() )
5502 if ( element.attribute( u
"active"_s, u
"0"_s ).toInt() == 1 )
5516 const QString projectFunctions =
readEntry( u
"ExpressionFunctions"_s, u
"/pythonCode"_s, QString() );
5517 if ( !projectFunctions.isEmpty() )
5537QHash< QString, QColor > loadColorsFromProject(
const QgsProject *project )
5539 QHash< QString, QColor > colors;
5542 QStringList colorStrings = project->
readListEntry( u
"Palette"_s, u
"/Colors"_s );
5543 const QStringList colorLabels = project->
readListEntry( u
"Palette"_s, u
"/Labels"_s );
5547 for ( QStringList::iterator it = colorStrings.begin();
5548 it != colorStrings.end(); ++it )
5552 if ( colorLabels.length() > colorIndex )
5554 label = colorLabels.at( colorIndex );
5557 colors.insert( label.toLower(), color );
5565GetNamedProjectColor::GetNamedProjectColor(
const QgsProject *project )
5571 mColors = loadColorsFromProject( project );
5574GetNamedProjectColor::GetNamedProjectColor(
const QHash<QString, QColor> &colors )
5582 const QString colorName = values.at( 0 ).toString().toLower();
5583 if ( mColors.contains( colorName ) )
5585 return u
"%1,%2,%3"_s.arg( mColors.value( colorName ).red() ).arg( mColors.value( colorName ).green() ).arg( mColors.value( colorName ).blue() );
5593 return new GetNamedProjectColor( mColors );
5596GetNamedProjectColorObject::GetNamedProjectColorObject(
const QgsProject *project )
5602 mColors = loadColorsFromProject( project );
5605GetNamedProjectColorObject::GetNamedProjectColorObject(
const QHash<QString, QColor> &colors )
5613 const QString colorName = values.at( 0 ).toString().toLower();
5614 if ( mColors.contains( colorName ) )
5616 return mColors.value( colorName );
5624 return new GetNamedProjectColorObject( mColors );
5629GetSensorData::GetSensorData(
const QMap<QString, QgsAbstractSensor::SensorData> &sensorData )
5633 , mSensorData( sensorData )
5639 const QString sensorName = values.at( 0 ).toString();
5640 const int expiration = values.at( 1 ).toInt();
5641 const qint64 timestamp = QDateTime::currentMSecsSinceEpoch();
5642 if ( mSensorData.contains( sensorName ) )
5644 if ( expiration <= 0 || ( timestamp - mSensorData[sensorName].lastTimestamp.toMSecsSinceEpoch() ) < expiration )
5646 return mSensorData[sensorName].lastValue;
5655 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.
const QgsSelectiveMaskingSourceSetManager * selectiveMaskingSourceSetManager() const
Returns the project's selective masking set manager, which manages storage of a set of selective mask...
void legendLayersAdded(const QList< QgsMapLayer * > &layers)
Emitted when layers were added to the registry and the legend.
QVariantMap customVariables() const
A map of custom project variables.
void setAvoidIntersectionsLayers(const QList< QgsVectorLayer * > &layers)
Sets the list of layers with which intersections should be avoided.
void homePathChanged()
Emitted when the home path of the project changes.
void dirtySet()
Emitted when setDirty(true) is called.
void setCustomVariables(const QVariantMap &customVariables)
A map of custom project variables.
void writeProject(QDomDocument &document)
Emitted when the project is being written.
QgsCoordinateReferenceSystem defaultCrsForNewLayers() const
Returns the default CRS for new layers based on the settings and the current project CRS.
QString saveUserFullName() const
Returns the full user name that did the last save.
void layersAdded(const QList< QgsMapLayer * > &layers)
Emitted when one or more layers were added to the registry.
QMap< QString, QgsMapLayer * > mapLayers(const bool validOnly=false) const
Returns a map of all registered layers by layer ID.
bool isDirty() const
Returns true if the project has been modified since the last write().
QgsMapLayer * takeMapLayer(QgsMapLayer *layer)
Takes a layer from the registry.
void isDirtyChanged(bool dirty)
Emitted when the project dirty status changes.
void setDistanceUnits(Qgis::DistanceUnit unit)
Sets the default distance measurement units for the project.
Q_DECL_DEPRECATED bool useProjectScales() const
Returns true if project mapScales() are enabled.
Q_DECL_DEPRECATED void setMapScales(const QVector< double > &scales)
Sets the list of custom project map scales.
void setPresetHomePath(const QString &path)
Sets the project's home path.
void setFlags(Qgis::ProjectFlags flags)
Sets the project's flags, which dictate the behavior of the project.
QList< QgsMapLayer * > mapLayersByShortName(const QString &shortName) const
Retrieves a list of matching registered layers by layer shortName.
QgsProjectStorage * projectStorage() const
Returns pointer to project storage implementation that handles read/write of the project file.
QString layerIsEmbedded(const QString &id) const
Returns the source project file path if the layer with matching id is embedded from other project fil...
const QgsProjectTimeSettings * timeSettings() const
Returns the project's time settings, which contains the project's temporal range and other time based...
void verticalCrsChanged()
Emitted when the verticalCrs() of the project has changed.
void topologicalEditingChanged()
Emitted when the topological editing flag has changed.
bool removeEntry(const QString &scope, const QString &key)
Remove the given key from the specified scope.
QgsProjectVersion lastSaveVersion() const
Returns the QGIS version which the project was last saved using.
void avoidIntersectionsModeChanged()
Emitted whenever the avoid intersections mode has changed.
void loadingLayer(const QString &layerName)
Emitted when a layer is loaded.
A grouped map of multiple QgsProperty objects, each referenced by an integer key value.
void clear() final
Removes all properties from the collection.
@ String
Any string value.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
QString relativeToAbsoluteUri(const QString &providerKey, const QString &uri, const QgsReadWriteContext &context) const
Converts relative path(s) to absolute path(s) in the given provider-specific URI.
QgsProviderMetadata * providerMetadata(const QString &providerKey) const
Returns metadata of the provider or nullptr if not found.
static bool run(const QString &command, const QString &messageOnError=QString())
Execute a Python statement.
static bool isValid()
Returns true if the runner has an instance (and thus is able to run commands).
A container for the context for various read/write operations on objects.
void setCurrentLayerId(const QString &layerId)
Sets the current layer id.
void setTransformContext(const QgsCoordinateTransformContext &transformContext)
Sets data coordinate transform context to transformContext.
QgsCoordinateTransformContext transformContext() const
Returns data provider coordinate transform context.
QList< QgsReadWriteContext::ReadWriteMessage > takeMessages()
Returns the stored messages and remove them.
void setProjectTranslator(QgsProjectTranslator *projectTranslator)
Sets the project translator.
void setPathResolver(const QgsPathResolver &resolver)
Sets up path resolver for conversion between relative and absolute paths.
Manages a set of relations between layers.
Represents a relationship between two vector layers.
void providerCreated(bool isValid, const QString &layerId)
Emitted when a provider is created with isValid set to True when the provider is valid.
QgsDataProvider * dataProvider()
Returns the created data provider.
void clear(const QString &group="startup")
clear Clear all profile data.
Expression function for use within a QgsExpressionContextScope.
Scoped object for logging of the runtime for a single operation or group of operations.
Manages storage of a set of selective masking source sets.
static const QgsSettingsEntryInteger * settingsLayerParallelLoadingMaxCount
Settings entry maximum thread count used to load layer in parallel.
static const QgsSettingsEntryBool * settingsLayerParallelLoading
Settings entry whether layer are loading in parallel.
Stores configuration of snapping settings for the project.
An interface for classes which can visit style entity (e.g.
virtual bool visitExit(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor stops visiting a node.
virtual bool visitEnter(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor starts visiting a node.
void triggerIconRebuild()
Triggers emission of the rebuildIconPreviews() signal.
static QgsStyle * defaultStyle(bool initialize=true)
Returns the default application-wide style.
Represents a transaction group.
bool addLayer(QgsVectorLayer *layer)
Add a layer to this transaction group.
static bool supportsTransaction(const QgsVectorLayer *layer)
Checks if the provider of a given layer supports transactions.
QString connectionString() const
Returns the connection string of the transaction.
Used for the collecting of strings from projects for translation and creation of ts files.
void registerTranslation(const QString &context, const QString &source)
Registers the source to be translated.
void setProject(QgsProject *project)
Sets the project being translated.
static Q_INVOKABLE QString toString(Qgis::DistanceUnit unit)
Returns a translated string representing a distance unit.
static Q_INVOKABLE Qgis::AreaUnit decodeAreaUnit(const QString &string, bool *ok=nullptr)
Decodes an areal unit from a string.
static Q_INVOKABLE QString encodeUnit(Qgis::DistanceUnit unit)
Encodes a distance unit to a string.
static Q_INVOKABLE Qgis::DistanceUnit decodeDistanceUnit(const QString &string, bool *ok=nullptr)
Decodes a distance unit from a string.
The edit buffer group manages a group of edit buffers.
Represents a vector layer which manages a vector based dataset.
Q_INVOKABLE bool startEditing()
Makes the layer editable.
bool loadAuxiliaryLayer(const QgsAuxiliaryStorage &storage, const QString &key=QString())
Loads the auxiliary layer for this vector layer.
QgsAuxiliaryLayer * auxiliaryLayer()
Returns the current auxiliary layer.
QStringList commitErrors() const
Returns a list containing any error messages generated when attempting to commit changes to the layer...
QgsFeatureRenderer * renderer()
Returns the feature renderer used for rendering the features in the layer in 2D map views.
Q_INVOKABLE bool rollBack(bool deleteBuffer=true)
Stops a current editing operation and discards any uncommitted edits.
Q_INVOKABLE bool commitChanges(bool stopEditing=true)
Attempts to commit to the underlying data provider any buffered changes made since the last to call t...
QgsActionManager * actions()
Returns all layer actions defined on this layer.
QgsEditFormConfig editFormConfig
static bool isZipFile(const QString &filename)
Returns true if the file name is a zipped file ( i.e with a '.qgz' extension, false otherwise.
QList< QPair< QColor, QString > > QgsNamedColorList
List of colors paired with a friendly display name identifying the color.
T qgsEnumKeyToValue(const QString &key, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given key of an enum.
#define Q_NOWARN_DEPRECATED_POP
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
QString qgsFlagValueToKeys(const T &value, bool *returnOk=nullptr)
Returns the value for the given keys of a flag.
T qgsFlagKeysToValue(const QString &keys, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given keys of a flag.
#define Q_NOWARN_DEPRECATED_PUSH
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)
QPointer< QgsMapLayer > QgsWeakMapLayerPointer
Weak pointer for QgsMapLayer.
void _getProperties(const QDomDocument &doc, QgsProjectPropertyKey &project_properties)
Restores any optional properties found in "doc" to "properties".
QgsPropertyCollection getDataDefinedServerProperties(const QDomDocument &doc, const QgsPropertiesDefinition &dataDefinedServerPropertyDefinitions)
Returns the data defined server properties collection found in "doc" to "dataDefinedServerProperties"...
void removeKey_(const QString &scope, const QString &key, QgsProjectPropertyKey &rootProperty)
Removes a given key.
QgsProjectVersion getVersion(const QDomDocument &doc)
Returns the version string found in the given DOM document.
void dump_(const QgsProjectPropertyKey &topQgsPropertyKey)
QgsProjectProperty * findKey_(const QString &scope, const QString &key, QgsProjectPropertyKey &rootProperty)
Takes the given scope and key and convert them to a string list of key tokens that will be used to na...
QgsProjectProperty * addKey_(const QString &scope, const QString &key, QgsProjectPropertyKey *rootProperty, const QVariant &value, bool &propertiesModified)
Adds the given key and value.
CORE_EXPORT QgsProjectVersion getVersion(QDomDocument const &doc)
Returns the version string found in the given DOM document.
QMap< int, QgsPropertyDefinition > QgsPropertiesDefinition
Definition of available properties.
#define FONTMARKER_CHR_FIX
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS_NON_FATAL
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS
Qgis::DataProviderReadFlags flags
QgsDataProvider::ProviderOptions options
Setting options for loading annotation layers.
Setting options for creating vector data providers.
Single variable definition for use within a QgsExpressionContextScope.
Contains information relating to a node (i.e.