90#include <QApplication>
95#include <QRegularExpression>
96#include <QStandardPaths>
98#include <QTemporaryFile>
100#include <QThreadPool>
104#include "moc_qgsproject.cpp"
106using namespace Qt::StringLiterals;
109#include <sys/utime.h>
132QStringList makeKeyTokens_(
const QString &scope,
const QString &key )
134 QStringList keyTokens = QStringList( scope );
135 keyTokens += key.split(
'/', Qt::SkipEmptyParts );
138 keyTokens.push_front( u
"properties"_s );
158 QStringList keySequence = makeKeyTokens_( scope, key );
160 while ( !keySequence.isEmpty() )
164 if ( keySequence.first() == currentProperty->
name() )
167 keySequence.pop_front();
169 if ( 1 == keySequence.count() )
172 return currentProperty->
find( keySequence.front() );
174 else if ( keySequence.isEmpty() )
179 return currentProperty;
181 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
183 if ( nextProperty->
isKey() )
187 else if ( nextProperty->
isValue() && 1 == keySequence.count() )
193 return currentProperty;
229 QStringList keySequence = makeKeyTokens_( scope, key );
236 propertiesModified =
false;
237 while ( !keySequence.isEmpty() )
241 if ( keySequence.first() == currentProperty->
name() )
244 keySequence.pop_front();
248 if ( 1 == keySequence.count() )
251 if ( !property || property->value() != value )
253 currentProperty->
setValue( keySequence.front(), value );
254 propertiesModified =
true;
257 return currentProperty;
261 else if ( keySequence.isEmpty() )
263 if ( currentProperty->
value() != value )
266 propertiesModified =
true;
269 return currentProperty;
271 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
275 if ( currentProperty )
286 if ( ( newPropertyKey = currentProperty->
addKey( keySequence.first() ) ) )
288 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 mProjectScope.reset();
410 emit layersWillBeRemoved( layers );
413 mProjectScope.reset();
414 emit layersWillBeRemoved( layers );
417 mProjectScope.reset();
418 emit layerWillBeRemoved( layer );
421 mProjectScope.reset();
422 emit layerWillBeRemoved( layer );
425 mProjectScope.reset();
426 emit layersRemoved( layers );
429 mProjectScope.reset();
430 emit layerRemoved( layer );
433 mProjectScope.reset();
437 mProjectScope.reset();
438 emit layersAdded( layers );
441 mProjectScope.reset();
442 emit layerWasAdded( layer );
451 for ( const auto &layer : layers )
453 disconnect( layer, &QgsMapLayer::dataSourceChanged, mRelationManager.get(), &QgsRelationManager::updateRelationsStatus );
456 connect( mLayerStore.get(), qOverload<
const QList<QgsMapLayer *> & >( &
QgsMapLayerStore::layersAdded ),
this, [
this](
const QList<QgsMapLayer *> &layers ) {
457 for ( const auto &layer : layers )
459 connect( layer, &QgsMapLayer::dataSourceChanged, mRelationManager.get(), &QgsRelationManager::updateRelationsStatus );
467 mStyleSettings->combinedStyleModel()->addDefaultStyle();
473 mIsBeingDeleted =
true;
476 releaseHandlesToProjectArchive();
478 if (
this == sProject )
505 if (
title == mMetadata.title() )
508 mMetadata.setTitle(
title );
509 mProjectScope.reset();
521 return mMetadata.title();
530 if ( oldEvaluateDefaultValues != newEvaluateDefaultValues )
533 for (
auto layerIt =
layers.constBegin(); layerIt !=
layers.constEnd(); ++layerIt )
535 if (
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layerIt.value() ) )
536 if ( vl->dataProvider() )
543 if ( oldTrustLayerMetadata != newTrustLayerMetadata )
546 for (
auto layerIt =
layers.constBegin(); layerIt !=
layers.constEnd(); ++layerIt )
548 if (
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layerIt.value() ) )
550 vl->setReadExtentFromXml( newTrustLayerMetadata );
555 if ( mFlags !=
flags )
570 newFlags &= ~(
static_cast< int >( flag ) );
585 return mSaveUserFull;
592 return mSaveDateTime;
613 if ( dirty && mDirtyBlockCount > 0 )
619 if ( mDirty == dirty )
630 if ( path == mHomePath )
634 mCachedHomePath.clear();
635 mProjectScope.reset();
646 const QList<QgsAttributeEditorElement *> elements = parent->
children();
654 translationContext->
registerTranslation( u
"project:layers:%1:formcontainers"_s.arg( layerId ), container->
name() );
656 if ( !container->
children().empty() )
667 const QList<QgsLayerTreeLayer *>
layers = mRootGroup->findLayers();
671 translationContext->
registerTranslation( u
"project:layers:%1"_s.arg( layer->layerId() ), layer->name() );
683 for (
const QgsField &field : fields )
688 if ( field.alias().isEmpty() )
689 fieldName = field.name();
691 fieldName = field.alias();
693 translationContext->
registerTranslation( u
"project:layers:%1:fieldaliases"_s.arg( vlayer->
id() ), fieldName );
696 if ( !field.constraints().constraintDescription().isEmpty() )
697 translationContext->
registerTranslation( u
"project:layers:%1:constraintdescriptions"_s.arg( vlayer->
id() ), field.constraints().constraintDescription() );
701 if ( field.editorWidgetSetup().type() ==
"ValueRelation"_L1 )
703 translationContext->
registerTranslation( u
"project:layers:%1:fields:%2:valuerelationvalue"_s.arg( vlayer->
id(), field.name() ), field.editorWidgetSetup().config().value( u
"Value"_s ).toString() );
705 ->
registerTranslation( u
"project:layers:%1:fields:%2:valuerelationdescription"_s.arg( vlayer->
id(), field.name() ), field.editorWidgetSetup().config().value( u
"Description"_s ).toString() );
709 if ( field.editorWidgetSetup().type() ==
"ValueMap"_L1 )
711 if ( field.editorWidgetSetup().config().value( u
"map"_s ).canConvert<QList<QVariant>>() )
713 const QList<QVariant> valueList = field.editorWidgetSetup().config().value( u
"map"_s ).toList();
715 for (
int i = 0; i < valueList.count(); i++ )
717 translationContext->
registerTranslation( u
"project:layers:%1:fields:%2:valuemapdescriptions"_s.arg( vlayer->
id(), field.name() ), valueList[i].toMap().constBegin().key() );
729 translationContext->
registerTranslation( u
"project:layers:%1:actiondescriptions"_s.arg( vlayer->
id() ), action.name() );
730 translationContext->
registerTranslation( u
"project:layers:%1:actionshorttitles"_s.arg( vlayer->
id() ), action.shortTitle() );
738 translationContext->
registerTranslation( u
"project:layers:%1:legendsymbollabels"_s.arg( vlayer->
id() ), item.label() );
756 mapLayer->metadata().registerTranslations( translationContext );
761 const QList<QgsLayerTreeGroup *> groupLayers = mRootGroup->findGroups(
true );
768 const QList<QgsRelation> &relations = mRelationManager->relations().values();
775 mMetadata.registerTranslations( translationContext );
782 mDataDefinedServerProperties = properties;
789 return mDataDefinedServerProperties;
796 switch ( mTransactionMode )
807 return mEditBufferGroup.startEditing();
817 switch ( mTransactionMode )
824 commitErrors.append( tr(
"Trying to commit changes without a layer specified. This only works if the transaction mode is buffered" ) );
833 return mEditBufferGroup.commitChanges( commitErrors, stopEditing );
843 switch ( mTransactionMode )
850 rollbackErrors.append( tr(
"Trying to roll back changes without a layer specified. This only works if the transaction mode is buffered" ) );
853 bool success = vectorLayer->
rollBack( stopEditing );
859 return mEditBufferGroup.rollBack( rollbackErrors, stopEditing );
869 if ( name == mFile.fileName() )
872 const QString oldHomePath =
homePath();
874 mFile.setFileName( name );
875 mCachedHomePath.clear();
876 mProjectScope.reset();
880 const QString newHomePath =
homePath();
881 if ( newHomePath != oldHomePath )
892 return mFile.fileName();
899 mOriginalPath = path;
906 return mOriginalPath;
913 return QFileInfo( mFile );
931 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
936 return QFileInfo( mFile.fileName() ).lastModified();
947 if ( mFile.fileName().isEmpty() )
950 return QFileInfo( mFile.fileName() ).absolutePath();
961 if ( mFile.fileName().isEmpty() )
964 return QFileInfo( mFile.fileName() ).absoluteFilePath();
975 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
980 return QFileInfo( mFile.fileName() ).completeBaseName();
988 const bool absolutePaths =
readBoolEntry( u
"Paths"_s, u
"/Absolute"_s,
false );
999 writeEntry( u
"Paths"_s, u
"/Absolute"_s,
true );
1002 writeEntry( u
"Paths"_s, u
"/Absolute"_s,
false );
1019 return mCrs3D.isValid() ? mCrs3D : mCrs;
1033 if ( adjustEllipsoid && !mCrs.isSameCelestialBody(
crs ) )
1035 mBlockEllipsoidChangedSignal =
true;
1037 mBlockEllipsoidChangedSignal =
false;
1043 writeEntry( u
"SpatialRefSys"_s, u
"/ProjectionsEnabled"_s,
crs.isValid() ? 1 : 0 );
1044 mProjectScope.reset();
1048 if ( !mMainAnnotationLayer->crs().isValid() || mMainAnnotationLayer->isEmpty() )
1049 mMainAnnotationLayer->setCrs(
crs );
1058 if ( oldCrs3D != mCrs3D )
1062 if ( adjustEllipsoid )
1071 if ( !
crs().isValid() )
1084 mProjectScope.reset();
1087 if ( !mBlockEllipsoidChangedSignal )
1096 switch ( mCrs.type() )
1099 QgsDebugError( u
"Project has a vertical CRS set as the horizontal CRS!"_s );
1103 return mCrs.verticalCrs();
1118 return mVerticalCrs;
1125 if (
crs.isValid() )
1128 switch (
crs.type() )
1146 *errorMessage = QObject::tr(
"Specified CRS is a %1 CRS, not a Vertical CRS" ).arg(
qgsEnumValueToKey(
crs.type() ) );
1151 if (
crs != mVerticalCrs )
1156 switch ( mCrs.type() )
1159 if (
crs != oldVerticalCrs )
1162 *errorMessage = QObject::tr(
"Project CRS is a Compound CRS, specified Vertical CRS will be ignored" );
1168 if (
crs != oldVerticalCrs )
1171 *errorMessage = QObject::tr(
"Project CRS is a Geographic 3D CRS, specified Vertical CRS will be ignored" );
1177 if (
crs != oldVerticalCrs )
1180 *errorMessage = QObject::tr(
"Project CRS is a Geocentric CRS, specified Vertical CRS will be ignored" );
1186 if ( mCrs.hasVerticalAxis() &&
crs != oldVerticalCrs )
1189 *errorMessage = QObject::tr(
"Project CRS is a Projected 3D CRS, specified Vertical CRS will be ignored" );
1207 res = rebuildCrs3D( errorMessage );
1208 mProjectScope.reset();
1215 if ( mCrs3D != oldCrs3D )
1226 return mTransformContext;
1233 if ( context == mTransformContext )
1236 mTransformContext = context;
1237 mProjectScope.reset();
1239 mMainAnnotationLayer->setTransformContext( context );
1240 for (
auto &layer : mLayerStore.get()->mapLayers() )
1242 layer->setTransformContext( context );
1251 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
1255 if ( !mIsBeingDeleted )
1264 mProjectScope.reset();
1265 mFile.setFileName( QString() );
1266 mProperties.clearKeys();
1268 mSaveUserFull.clear();
1269 mSaveDateTime = QDateTime();
1272 mCachedHomePath.clear();
1276 mCustomVariables.clear();
1284 mMetadata.setCreationDateTime( QDateTime::currentDateTime() );
1303 mEmbeddedLayers.clear();
1304 mRelationManager->clear();
1305 mAnnotationManager->clear();
1306 mLayoutManager->clear();
1307 mElevationProfileManager->clear();
1308 mSelectiveMaskingSourceSetManager->clear();
1309 m3DViewsManager->clear();
1310 mBookmarkManager->clear();
1311 mSensorManager->clear();
1312 mViewSettings->reset();
1313 mTimeSettings->reset();
1314 mElevationProperties->reset();
1315 mDisplaySettings->reset();
1316 mGpsSettings->reset();
1317 mSnappingConfig.reset();
1322 mMapThemeCollection = std::make_unique< QgsMapThemeCollection >(
this );
1325 mLabelingEngineSettings->clear();
1329 releaseHandlesToProjectArchive();
1331 mAuxiliaryStorage = std::make_unique< QgsAuxiliaryStorage >();
1332 mArchive = std::make_unique< QgsArchive >();
1335 mStyleSettings->reset();
1339 if ( !mIsBeingDeleted )
1347 writeEntry( u
"PositionPrecision"_s, u
"/Automatic"_s,
true );
1348 writeEntry( u
"PositionPrecision"_s, u
"/DecimalPlaces"_s, 2 );
1357 mSnappingConfig.clearIndividualLayerSettings();
1360 mRootGroup->clear();
1361 if ( mMainAnnotationLayer )
1362 mMainAnnotationLayer->reset();
1364 snapSingleBlocker.release();
1366 if ( !mBlockSnappingUpdates )
1372 if ( !mBlockChangeSignalsDuringClear )
1384 topQgsPropertyKey.
dump();
1417 const QDomElement propertiesElem = doc.documentElement().firstChildElement( u
"properties"_s );
1419 if ( propertiesElem.isNull() )
1424 const QDomNodeList scopes = propertiesElem.childNodes();
1426 if ( propertiesElem.firstChild().isNull() )
1428 QgsDebugError( u
"empty ``properties'' XML tag ... bailing"_s );
1432 if ( !project_properties.
readXml( propertiesElem ) )
1448 const QDomElement ddElem = doc.documentElement().firstChildElement( u
"dataDefinedServerProperties"_s );
1449 if ( !ddElem.isNull() )
1451 if ( !ddServerProperties.
readXml( ddElem, dataDefinedServerPropertyDefinitions ) )
1453 QgsDebugError( u
"dataDefinedServerProperties.readXml() failed"_s );
1456 return ddServerProperties;
1463static void _getTitle(
const QDomDocument &doc, QString &title )
1465 const QDomElement titleNode = doc.documentElement().firstChildElement( u
"title"_s );
1469 if ( titleNode.isNull() )
1475 if ( !titleNode.hasChildNodes() )
1481 const QDomNode titleTextNode = titleNode.firstChild();
1483 if ( !titleTextNode.isText() )
1489 const QDomText titleText = titleTextNode.toText();
1491 title = titleText.data();
1494static void readProjectFileMetadata(
const QDomDocument &doc, QString &lastUser, QString &lastUserFull, QDateTime &lastSaveDateTime )
1496 const QDomNodeList nl = doc.elementsByTagName( u
"qgis"_s );
1504 const QDomNode qgisNode = nl.item( 0 );
1506 const QDomElement qgisElement = qgisNode.toElement();
1507 lastUser = qgisElement.attribute( u
"saveUser"_s, QString() );
1508 lastUserFull = qgisElement.attribute( u
"saveUserFull"_s, QString() );
1509 lastSaveDateTime = QDateTime::fromString( qgisElement.attribute( u
"saveDateTime"_s, QString() ), Qt::ISODate );
1514 const QDomNodeList nl = doc.elementsByTagName( u
"qgis"_s );
1518 QgsDebugError( u
" unable to find qgis element in project file"_s );
1522 const QDomNode qgisNode = nl.item( 0 );
1524 const QDomElement qgisElement = qgisNode.toElement();
1526 return projectVersion;
1533 return mSnappingConfig;
1552 if ( mAvoidIntersectionsMode == mode )
1555 mAvoidIntersectionsMode = mode;
1589void QgsProject::preloadProviders(
1596 QMap<QString, LayerToLoad> layersToLoad;
1598 for (
const QDomNode &node : parallelLayerNodes )
1602 const QDomElement layerElement = node.toElement();
1604 layerToLoad.
layerId = layerElement.namedItem( u
"id"_s ).toElement().text();
1605 layerToLoad.
provider = layerElement.namedItem( u
"provider"_s ).toElement().text();
1606 layerToLoad.
dataSource = layerElement.namedItem( u
"datasource"_s ).toElement().text();
1617 layersToLoad.insert( layerToLoad.
layerId, layerToLoad );
1620 while ( !layersToLoad.isEmpty() )
1622 const QList<LayerToLoad> layersToAttemptInParallel = layersToLoad.values();
1623 QString layerToAttemptInMainThread;
1625 QHash<QString, QgsRunnableProviderCreator *> runnables;
1626 QThreadPool threadPool;
1629 for (
const LayerToLoad &lay : layersToAttemptInParallel )
1631 QgsRunnableProviderCreator *run =
new QgsRunnableProviderCreator( lay.layerId, lay.provider, lay.dataSource, lay.options, lay.flags );
1632 runnables.insert( lay.layerId, run );
1637 layersToLoad.remove( layId );
1639 QgsRunnableProviderCreator *finishedRun = runnables.value( layId,
nullptr );
1640 Q_ASSERT( finishedRun );
1642 std::unique_ptr<QgsDataProvider> provider( finishedRun->
dataProvider() );
1643 Q_ASSERT( provider && provider->isValid() );
1645 provider->moveToThread( QThread::currentThread() );
1648 loadedProviders.insert( layId, provider.release() );
1653 if ( layerToAttemptInMainThread.isEmpty() )
1654 layerToAttemptInMainThread = layId;
1658 if ( i == parallelLayerNodes.count() || !isValid )
1661 threadPool.start( run );
1665 threadPool.waitForDone();
1667 qDeleteAll( runnables );
1670 auto it = layersToLoad.find( layerToAttemptInMainThread );
1671 if ( it != layersToLoad.end() )
1673 std::unique_ptr<QgsDataProvider> provider;
1676 const LayerToLoad &lay = it.value();
1680 QgsScopedRuntimeProfile profile(
"Create data providers/" + lay.
layerId, u
"projectload"_s );
1683 if ( provider && provider->isValid() )
1688 layersToLoad.erase( it );
1691 loadedProviders.insert( layerId, provider.release() );
1698void QgsProject::releaseHandlesToProjectArchive()
1700 mStyleSettings->removeProjectStyle();
1703bool QgsProject::rebuildCrs3D( QString *error )
1706 if ( !mCrs.isValid() )
1708 mCrs3D = QgsCoordinateReferenceSystem();
1710 else if ( !mVerticalCrs.isValid() )
1716 switch ( mCrs.type() )
1728 res = mCrs3D.isValid();
1734 mCrs3D = QgsCoordinateReferenceSystem();
1749 res = mCrs3D.isValid();
1757bool QgsProject::_getMapLayers(
const QDomDocument &doc, QList<QDomNode> &brokenNodes,
Qgis::ProjectReadFlags flags )
1764 QDomElement layerElement = doc.documentElement().firstChildElement( u
"projectlayers"_s ).firstChildElement( u
"maplayer"_s );
1768 if ( layerElement.isNull() )
1778 bool returnStatus =
true;
1781 while ( !layerElement.isNull() )
1784 layerElement = layerElement.nextSiblingElement( u
"maplayer"_s );
1788 QgsScopedRuntimeProfile profile( tr(
"Sorting layers" ), u
"projectload"_s );
1789 const QgsLayerDefinition::DependencySorter depSorter( doc );
1790 if ( depSorter.hasCycle() )
1794 if ( depSorter.hasMissingDependency() )
1795 returnStatus =
false;
1799 const QVector<QDomNode> sortedLayerNodes = depSorter.sortedLayerNodes();
1800 const int totalLayerCount = sortedLayerNodes.count();
1802 QVector<QDomNode> parallelLoading;
1803 QMap<QString, QgsDataProvider *> loadedProviders;
1807 profile.switchTask( tr(
"Load providers in parallel" ) );
1808 for (
const QDomNode &node : sortedLayerNodes )
1810 const QDomElement element = node.toElement();
1811 if ( element.attribute( u
"embedded"_s ) !=
"1"_L1 )
1813 const QString layerId = node.namedItem( u
"id"_s ).toElement().text();
1814 if ( !depSorter.isLayerDependent( layerId ) )
1816 const QDomNode mnl = element.namedItem( u
"provider"_s );
1817 const QDomElement mne = mnl.toElement();
1818 const QString provider = mne.text();
1822 parallelLoading.append( node );
1829 QgsReadWriteContext context;
1831 if ( !parallelLoading.isEmpty() )
1832 preloadProviders( parallelLoading, context, loadedProviders, projectFlagsToLayerReadFlags(
flags, mFlags ), sortedLayerNodes.count() );
1835 int i = loadedProviders.count();
1836 for (
const QDomNode &node : std::as_const( sortedLayerNodes ) )
1838 const QDomElement element = node.toElement();
1839 const QString name =
translate( u
"project:layers:%1"_s.arg( node.namedItem( u
"id"_s ).toElement().text() ), node.namedItem( u
"layername"_s ).toElement().text() );
1840 if ( !name.isNull() )
1841 emit
loadingLayer( tr(
"Loading layer %1" ).arg( name ) );
1843 profile.switchTask( name );
1844 if ( element.attribute( u
"embedded"_s ) ==
"1"_L1 )
1850 QgsReadWriteContext context;
1854 QString layerId = element.namedItem( u
"id"_s ).toElement().text();
1856 if ( !addLayer( element, brokenNodes, context,
flags, loadedProviders.take( layerId ) ) )
1858 returnStatus =
false;
1861 if ( !messages.isEmpty() )
1870 return returnStatus;
1877 const QString type = layerElem.attribute( u
"type"_s );
1879 std::unique_ptr<QgsMapLayer>
mapLayer;
1881 QgsScopedRuntimeProfile profile( tr(
"Create layer" ), u
"projectload"_s );
1887 QgsDebugError( u
"Unknown layer type \"%1\""_s.arg( type ) );
1891 switch ( layerType )
1894 mapLayer = std::make_unique<QgsVectorLayer>();
1898 mapLayer = std::make_unique<QgsRasterLayer>();
1902 mapLayer = std::make_unique<QgsMeshLayer>();
1906 mapLayer = std::make_unique<QgsVectorTileLayer>();
1910 mapLayer = std::make_unique<QgsPointCloudLayer>();
1914 mapLayer = std::make_unique<QgsTiledSceneLayer>();
1919 const QString typeName = layerElem.attribute( u
"name"_s );
1926 const QgsAnnotationLayer::LayerOptions options( mTransformContext );
1927 mapLayer = std::make_unique<QgsAnnotationLayer>( QString(), options );
1933 const QgsGroupLayer::LayerOptions options( mTransformContext );
1934 mapLayer = std::make_unique<QgsGroupLayer>( QString(), options );
1949 const QString layerId { layerElem.namedItem( u
"id"_s ).toElement().text() };
1950 Q_ASSERT( !layerId.isEmpty() );
1956 profile.switchTask( tr(
"Load layer source" ) );
1957 const bool layerIsValid =
mapLayer->readLayerXml( layerElem, context, layerFlags, provider ) &&
mapLayer->isValid();
1960 if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>(
mapLayer.get() ) )
1963 if ( vl->dataProvider() )
1970 profile.switchTask( tr(
"Add layer to project" ) );
1971 QList<QgsMapLayer *> newLayers;
1981 if ( QgsVectorLayer *vLayer = qobject_cast<QgsVectorLayer *>(
mapLayer.get() ) )
1983 vLayer->joinBuffer()->resolveReferences(
this );
1992 brokenNodes.push_back( layerElem );
1995 const bool wasEditable = layerElem.attribute( u
"editable"_s, u
"0"_s ).toInt();
1998 mapLayer->setCustomProperty( u
"_layer_was_editable"_s,
true );
2002 mapLayer->removeCustomProperty( u
"_layer_was_editable"_s );
2007 if ( !layerWasStored )
2012 return layerIsValid;
2019 mFile.setFileName( filename );
2020 mCachedHomePath.clear();
2021 mProjectScope.reset();
2030 const QString filename = mFile.fileName();
2035 QTemporaryFile inDevice;
2036 if ( !inDevice.open() )
2038 setError( tr(
"Unable to open %1" ).arg( inDevice.fileName() ) );
2044 if ( !storage->readProject( filename, &inDevice, context ) )
2046 QString err = tr(
"Unable to open %1" ).arg( filename );
2047 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
2048 if ( !messages.isEmpty() )
2049 err += u
"\n\n"_s + messages.last().message();
2053 returnValue = unzip( inDevice.fileName(),
flags );
2059 returnValue = unzip( mFile.fileName(),
flags );
2063 mAuxiliaryStorage = std::make_unique< QgsAuxiliaryStorage >( *
this );
2064 const QFileInfo finfo( mFile.fileName() );
2065 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( u
"%1_attachments.zip"_s.arg( finfo.completeBaseName() ) );
2066 if ( QFile( attachmentsZip ).exists() )
2068 auto archive = std::make_unique<QgsArchive>();
2069 if ( archive->unzip( attachmentsZip ) )
2071 releaseHandlesToProjectArchive();
2072 mArchive = std::move( archive );
2075 returnValue = readProjectFile( mFile.fileName(),
flags );
2081 mFile.setFileName( filename );
2082 mCachedHomePath.clear();
2083 mProjectScope.reset();
2088 mTranslator.reset(
nullptr );
2101 ScopedIntIncrementor snapSignalBlock( &mBlockSnappingUpdates );
2103 QFile projectFile( filename );
2110 const QString projectBaseName = QFileInfo( mFile ).baseName();
2111 const QString projectDir = QFileInfo( mFile ).absolutePath();
2112 QString localeFileName = u
"%1_%2"_s.arg( projectBaseName, locale );
2114 if ( !QFile( u
"%1/%2.qm"_s.arg( projectDir, localeFileName ) ).exists() && locale.contains(
'_' ) )
2117 localeFileName = u
"%1_%2"_s.arg( projectBaseName, locale.left( locale.indexOf(
'_' ) ) );
2120 if ( QFile( u
"%1/%2.qm"_s.arg( projectDir, localeFileName ) ).exists() )
2122 mTranslator = std::make_unique< QTranslator >();
2123 ( void ) mTranslator->load( localeFileName, projectDir );
2126 profile.switchTask( tr(
"Reading project file" ) );
2127 auto doc = std::make_unique<QDomDocument>( u
"qgis"_s );
2129 if ( !projectFile.open( QIODevice::ReadOnly | QIODevice::Text ) )
2131 projectFile.close();
2133 setError( tr(
"Unable to open %1" ).arg( projectFile.fileName() ) );
2138 QTextStream textStream( &projectFile );
2139 QString projectString = textStream.readAll();
2140 projectFile.close();
2142 for (
int i = 0; i < 32; i++ )
2144 if ( i == 9 || i == 10 || i == 13 )
2148 projectString.replace( QChar( i ), u
"%1%2%1"_s.arg(
FONTMARKER_CHR_FIX, QString::number( i ) ) );
2154 if ( !doc->setContent( projectString, &errorMsg, &line, &column ) )
2156 const QString errorString = tr(
"Project file read error in file %1: %2 at line %3 column %4" ).arg( projectFile.fileName(), errorMsg ).arg( line ).arg( column );
2158 setError( errorString );
2163 projectFile.close();
2168 const QgsProjectVersion fileVersion =
getVersion( *doc );
2171 profile.switchTask( tr(
"Updating project file" ) );
2172 if ( thisVersion > fileVersion )
2174 const bool isOlderMajorVersion = fileVersion.
majorVersion() < thisVersion.majorVersion();
2176 if ( isOlderMajorVersion )
2179 "Loading a file that was saved with an older "
2180 "version of qgis (saved in "
2181 + fileVersion.
text()
2184 +
"). Problems may occur."
2188 QgsProjectFileTransform projectFile( *doc, fileVersion );
2196 projectFile.updateRevision( thisVersion );
2198 else if ( fileVersion > thisVersion )
2201 "Loading a file that was saved with a newer "
2202 "version of qgis (saved in "
2203 + fileVersion.
text()
2206 +
"). Problems may occur."
2213 profile.switchTask( tr(
"Creating auxiliary storage" ) );
2214 const QString
fileName = mFile.fileName();
2216 const QgsCoordinateReferenceSystem oldVerticalCrs =
verticalCrs();
2217 const QgsCoordinateReferenceSystem oldCrs3D = mCrs3D;
2221 std::unique_ptr<QgsAuxiliaryStorage> aStorage = std::move( mAuxiliaryStorage );
2222 std::unique_ptr<QgsArchive> archive = std::move( mArchive );
2226 mBlockChangeSignalsDuringClear =
true;
2228 mBlockChangeSignalsDuringClear =
false;
2233 releaseHandlesToProjectArchive();
2235 mAuxiliaryStorage = std::move( aStorage );
2236 mArchive = std::move( archive );
2239 mCachedHomePath.clear();
2240 mProjectScope.reset();
2241 mSaveVersion = fileVersion;
2244 profile.switchTask( tr(
"Reading properties" ) );
2250 QgsDebugMsgLevel( QString::number( mProperties.count() ) +
" properties read", 2 );
2253 dump_( mProperties );
2258 _getTitle( *doc, oldTitle );
2260 readProjectFileMetadata( *doc, mSaveUser, mSaveUserFull, mSaveDateTime );
2262 const QDomNodeList homePathNl = doc->elementsByTagName( u
"homePath"_s );
2263 if ( homePathNl.count() > 0 )
2265 const QDomElement homePathElement = homePathNl.at( 0 ).toElement();
2266 const QString
homePath = homePathElement.attribute( u
"path"_s );
2278 selectionColor(
readNumEntry( u
"Gui"_s, u
"/SelectionColorRedPart"_s, 255 ),
readNumEntry( u
"Gui"_s, u
"/SelectionColorGreenPart"_s, 255 ),
readNumEntry( u
"Gui"_s, u
"/SelectionColorBluePart"_s, 255 ),
readNumEntry( u
"Gui"_s, u
"/SelectionColorAlphaPart"_s, 255 ) );
2282 const QString distanceUnitString =
readEntry( u
"Measurement"_s, u
"/DistanceUnits"_s, QString() );
2283 if ( !distanceUnitString.isEmpty() )
2286 const QString areaUnitString =
readEntry( u
"Measurement"_s, u
"/AreaUnits"_s, QString() );
2287 if ( !areaUnitString.isEmpty() )
2292 QgsReadWriteContext context;
2297 QgsCoordinateReferenceSystem projectCrs;
2298 if (
readNumEntry( u
"SpatialRefSys"_s, u
"/ProjectionsEnabled"_s, 0 ) )
2301 const QDomNode srsNode = doc->documentElement().namedItem( u
"projectCrs"_s );
2302 if ( !srsNode.isNull() )
2304 projectCrs.
readXml( srsNode );
2309 const QString projCrsString =
readEntry( u
"SpatialRefSys"_s, u
"/ProjectCRSProj4String"_s );
2310 const long currentCRS =
readNumEntry( u
"SpatialRefSys"_s, u
"/ProjectCRSID"_s, -1 );
2311 const QString authid =
readEntry( u
"SpatialRefSys"_s, u
"/ProjectCrs"_s );
2314 const bool isUserAuthId = authid.startsWith(
"USER:"_L1, Qt::CaseInsensitive );
2315 if ( !authid.isEmpty() && !isUserAuthId )
2316 projectCrs = QgsCoordinateReferenceSystem( authid );
2319 if ( !projectCrs.
isValid() && currentCRS >= 0 )
2325 if ( !projCrsString.isEmpty() && ( authid.isEmpty() || isUserAuthId ) && ( !projectCrs.
isValid() || projectCrs.
toProj() != projCrsString ) )
2342 const QDomNode verticalCrsNode = doc->documentElement().namedItem( u
"verticalCrs"_s );
2343 if ( !verticalCrsNode.isNull() )
2351 QStringList datumErrors;
2352 if ( !mTransformContext.readXml( doc->documentElement(), context, datumErrors ) && !datumErrors.empty() )
2359 const QDomNode elevationShadingNode = doc->documentElement().namedItem( u
"elevation-shading-renderer"_s );
2360 if ( !elevationShadingNode.isNull() )
2362 mElevationShadingRenderer.readXml( elevationShadingNode.toElement(), context );
2369 const QStringList variableNames =
readListEntry( u
"Variables"_s, u
"/variableNames"_s );
2370 const QStringList variableValues =
readListEntry( u
"Variables"_s, u
"/variableValues"_s );
2372 mCustomVariables.clear();
2373 if ( variableNames.length() == variableValues.length() )
2375 for (
int i = 0; i < variableNames.length(); ++i )
2377 mCustomVariables.insert( variableNames.at( i ), variableValues.at( i ) );
2382 QgsMessageLog::logMessage( tr(
"Project Variables Invalid" ), tr(
"The project contains invalid variable settings." ) );
2390 QDomElement element = doc->documentElement().firstChildElement( u
"projectMetadata"_s );
2392 if ( !element.isNull() )
2394 mMetadata.readMetadataXml( element, context );
2399 mMetadata = QgsProjectMetadata();
2401 if ( mMetadata.title().isEmpty() && !oldTitle.isEmpty() )
2404 mMetadata.setTitle( oldTitle );
2410 element = doc->documentElement().firstChildElement( u
"transaction"_s );
2411 if ( !element.isNull() )
2418 element = doc->documentElement().firstChildElement( u
"autotransaction"_s );
2419 if ( !element.isNull() )
2421 mTransactionMode =
static_cast<Qgis::TransactionMode>( element.attribute( u
"active"_s, u
"0"_s ).toInt() );
2426 profile.switchTask( tr(
"Loading layer tree" ) );
2427 mRootGroup->setCustomProperty( u
"loading"_s, 1 );
2429 QDomElement layerTreeElem = doc->documentElement().firstChildElement( u
"layer-tree-group"_s );
2430 if ( !layerTreeElem.isNull() )
2433 QgsLayerTree tempTree;
2442 mLayerTreeRegistryBridge->setEnabled(
false );
2445 profile.switchTask( tr(
"Reading map layers" ) );
2447 loadProjectFlags( doc.get() );
2449 QList<QDomNode> brokenNodes;
2450 const bool clean = _getMapLayers( *doc, brokenNodes,
flags );
2455 QgsDebugError( u
"Unable to get map layers from project file."_s );
2457 if ( !brokenNodes.isEmpty() )
2459 QgsDebugError(
"there are " + QString::number( brokenNodes.size() ) +
" broken layers" );
2464 mBadLayerHandler->handleBadLayers( brokenNodes );
2467 mMainAnnotationLayer->readLayerXml( doc->documentElement().firstChildElement( u
"main-annotation-layer"_s ), context );
2468 mMainAnnotationLayer->setTransformContext( mTransformContext );
2471 profile.switchTask( tr(
"Loading embedded layers" ) );
2472 loadEmbeddedNodes( mRootGroup.get(),
flags );
2476 profile.switchTask( tr(
"Resolving layer references" ) );
2477 QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
2478 for ( QMap<QString, QgsMapLayer *>::iterator it =
layers.begin(); it !=
layers.end(); ++it )
2480 it.value()->resolveReferences(
this );
2482 mMainAnnotationLayer->resolveReferences(
this );
2484 mLayerTreeRegistryBridge->setEnabled(
true );
2487 profile.switchTask( tr(
"Resolving references" ) );
2488 mRootGroup->resolveReferences(
this );
2491 if ( QgsProjectVersion( 3, 28, 0 ) > mSaveVersion )
2498 if ( !layerTreeElem.isNull() )
2500 mRootGroup->readLayerOrderFromXml( layerTreeElem );
2504 const QDomElement layerTreeCanvasElem = doc->documentElement().firstChildElement( u
"layer-tree-canvas"_s );
2505 if ( !layerTreeCanvasElem.isNull() )
2507 mRootGroup->readLayerOrderFromXml( layerTreeCanvasElem );
2511 if ( QgsProjectVersion( 3, 4, 0 ) > mSaveVersion )
2513 const QStringList requiredLayerIds =
readListEntry( u
"RequiredLayers"_s, u
"Layers"_s );
2514 for (
const QString &layerId : requiredLayerIds )
2516 if ( QgsMapLayer *layer =
mapLayer( layerId ) )
2521 const QStringList disabledLayerIds =
readListEntry( u
"Identify"_s, u
"/disabledLayers"_s );
2522 for (
const QString &layerId : disabledLayerIds )
2524 if ( QgsMapLayer *layer =
mapLayer( layerId ) )
2532 if ( QgsProjectVersion( 3, 26, 0 ) > mSaveVersion )
2535 QString styleName =
readEntry( u
"DefaultStyles"_s, u
"/Marker"_s );
2536 if ( !styleName.isEmpty() )
2541 styleName =
readEntry( u
"DefaultStyles"_s, u
"/Line"_s );
2542 if ( !styleName.isEmpty() )
2547 styleName =
readEntry( u
"DefaultStyles"_s, u
"/Fill"_s );
2548 if ( !styleName.isEmpty() )
2553 styleName =
readEntry( u
"DefaultStyles"_s, u
"/ColorRamp"_s );
2554 if ( !styleName.isEmpty() )
2564 double opacity = 1.0;
2567 double alpha =
readDoubleEntry( u
"DefaultStyles"_s, u
"/AlphaInt"_s, 255, &ok );
2569 opacity = alpha / 255.0;
2570 double newOpacity =
readDoubleEntry( u
"DefaultStyles"_s, u
"/Opacity"_s, 1.0, &ok );
2572 opacity = newOpacity;
2579 removeEntry( u
"DefaultStyles"_s, u
"/ColorRamp"_s );
2580 removeEntry( u
"DefaultStyles"_s, u
"/RandomColors"_s );
2581 removeEntry( u
"DefaultStyles"_s, u
"/AlphaInt"_s );
2590 profile.switchTask( tr(
"Storing original layer properties" ) );
2594 mRootGroup->removeCustomProperty( u
"loading"_s );
2596 profile.switchTask( tr(
"Loading map themes" ) );
2597 mMapThemeCollection = std::make_unique< QgsMapThemeCollection >(
this );
2599 mMapThemeCollection->readXml( *doc );
2601 profile.switchTask( tr(
"Loading label settings" ) );
2602 mLabelingEngineSettings->readSettingsFromProject(
this );
2604 const QDomElement labelEngineSettingsElement = doc->documentElement().firstChildElement( u
"labelEngineSettings"_s );
2605 mLabelingEngineSettings->readXml( labelEngineSettingsElement, context );
2607 mLabelingEngineSettings->resolveReferences(
this );
2611 profile.switchTask( tr(
"Loading annotations" ) );
2614 mAnnotationManager->readXml( doc->documentElement(), context );
2618 mAnnotationManager->readXmlAndUpgradeToAnnotationLayerItems( doc->documentElement(), context, mMainAnnotationLayer, mTransformContext );
2622 profile.switchTask( tr(
"Loading layouts" ) );
2623 mLayoutManager->readXml( doc->documentElement(), *doc );
2627 profile.switchTask( tr(
"Loading elevation profiles" ) );
2628 mElevationProfileManager->readXml( doc->documentElement(), *doc, context );
2629 mElevationProfileManager->resolveReferences(
this );
2633 profile.switchTask( tr(
"Loading selective masking source sets" ) );
2634 mSelectiveMaskingSourceSetManager->readXml( doc->documentElement(), *doc, context );
2639 profile.switchTask( tr(
"Loading 3D Views" ) );
2640 m3DViewsManager->readXml( doc->documentElement(), *doc );
2643 profile.switchTask( tr(
"Loading bookmarks" ) );
2644 mBookmarkManager->readXml( doc->documentElement(), *doc );
2646 profile.switchTask( tr(
"Loading sensors" ) );
2647 mSensorManager->readXml( doc->documentElement(), *doc );
2650 QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
2651 for ( QMap<QString, QgsMapLayer *>::iterator it = existingMaps.begin(); it != existingMaps.end(); ++it )
2653 it.value()->setDependencies( it.value()->dependencies() );
2656 profile.switchTask( tr(
"Loading snapping settings" ) );
2657 mSnappingConfig.readProject( *doc );
2662 profile.switchTask( tr(
"Loading view settings" ) );
2664 mViewSettings->setUseProjectScales(
readBoolEntry( u
"Scales"_s, u
"/useProjectScales"_s ) );
2665 const QStringList scales =
readListEntry( u
"Scales"_s, u
"/ScalesList"_s );
2666 QVector<double> res;
2667 for (
const QString &scale : scales )
2669 const QStringList parts = scale.split(
':' );
2670 if ( parts.size() != 2 )
2674 const double denominator = QLocale().toDouble( parts[1], &ok );
2680 mViewSettings->setMapScales( res );
2681 const QDomElement viewSettingsElement = doc->documentElement().firstChildElement( u
"ProjectViewSettings"_s );
2682 if ( !viewSettingsElement.isNull() )
2683 mViewSettings->readXml( viewSettingsElement, context );
2686 profile.switchTask( tr(
"Loading style properties" ) );
2687 const QDomElement styleSettingsElement = doc->documentElement().firstChildElement( u
"ProjectStyleSettings"_s );
2688 if ( !styleSettingsElement.isNull() )
2690 mStyleSettings->removeProjectStyle();
2691 mStyleSettings->readXml( styleSettingsElement, context,
flags );
2695 profile.switchTask( tr(
"Loading temporal settings" ) );
2696 const QDomElement timeSettingsElement = doc->documentElement().firstChildElement( u
"ProjectTimeSettings"_s );
2697 if ( !timeSettingsElement.isNull() )
2698 mTimeSettings->readXml( timeSettingsElement, context );
2701 profile.switchTask( tr(
"Loading elevation properties" ) );
2702 const QDomElement elevationPropertiesElement = doc->documentElement().firstChildElement( u
"ElevationProperties"_s );
2703 if ( !elevationPropertiesElement.isNull() )
2704 mElevationProperties->readXml( elevationPropertiesElement, context );
2705 mElevationProperties->resolveReferences(
this );
2707 profile.switchTask( tr(
"Loading display settings" ) );
2709 const QDomElement displaySettingsElement = doc->documentElement().firstChildElement( u
"ProjectDisplaySettings"_s );
2710 if ( !displaySettingsElement.isNull() )
2711 mDisplaySettings->readXml( displaySettingsElement, context );
2714 profile.switchTask( tr(
"Loading GPS settings" ) );
2716 const QDomElement gpsSettingsElement = doc->documentElement().firstChildElement( u
"ProjectGpsSettings"_s );
2717 if ( !gpsSettingsElement.isNull() )
2718 mGpsSettings->readXml( gpsSettingsElement, context );
2719 mGpsSettings->resolveReferences(
this );
2722 profile.switchTask( tr(
"Updating variables" ) );
2724 profile.switchTask( tr(
"Updating CRS" ) );
2728 if ( mCrs3D != oldCrs3D )
2733 profile.switchTask( tr(
"Reading external settings" ) );
2737 profile.switchTask( tr(
"Updating interface" ) );
2739 snapSignalBlock.release();
2740 if ( !mBlockSnappingUpdates )
2761 const QString newFileName( u
"%1/%2.qgs"_s.arg( QFileInfo( mFile ).
absolutePath(), localeFileName ) );
2775 const QMap<QString, QgsMapLayer *> loadedLayers =
mapLayers();
2776 for (
auto it = loadedLayers.constBegin(); it != loadedLayers.constEnd(); ++it )
2778 if ( it.value()->isValid() && it.value()->customProperty( u
"_layer_was_editable"_s ).toBool() )
2780 if ( QgsVectorLayer *vl = qobject_cast< QgsVectorLayer * >( it.value() ) )
2782 it.value()->removeCustomProperty( u
"_layer_was_editable"_s );
2794 const auto constChildren = group->
children();
2795 for ( QgsLayerTreeNode *child : constChildren )
2808 QList<QgsLayerTreeNode *> clonedChildren;
2809 const QList<QgsLayerTreeNode *> constChildren = newGroup->children();
2810 clonedChildren.reserve( constChildren.size() );
2811 for ( QgsLayerTreeNode *newGroupChild : constChildren )
2812 clonedChildren << newGroupChild->clone();
2819 loadEmbeddedNodes( childGroup,
flags );
2824 if ( child->customProperty( u
"embedded"_s ).toInt() )
2826 QList<QDomNode> brokenNodes;
2829 valid = valid &&
false;
2843 return mCustomVariables;
2850 if ( variables == mCustomVariables )
2854 QStringList variableNames;
2855 QStringList variableValues;
2857 QVariantMap::const_iterator it = variables.constBegin();
2858 for ( ; it != variables.constEnd(); ++it )
2860 variableNames << it.key();
2861 variableValues << it.value().toString();
2864 writeEntry( u
"Variables"_s, u
"/variableNames"_s, variableNames );
2865 writeEntry( u
"Variables"_s, u
"/variableValues"_s, variableValues );
2867 mCustomVariables = variables;
2868 mProjectScope.reset();
2877 *mLabelingEngineSettings = settings;
2885 return *mLabelingEngineSettings;
2892 mProjectScope.reset();
2893 return mLayerStore.get();
2900 return mLayerStore.get();
2907 QList<QgsVectorLayer *>
layers;
2908 const QStringList layerIds =
readListEntry( u
"Digitizing"_s, u
"/AvoidIntersectionsList"_s, QStringList() );
2909 const auto constLayerIds = layerIds;
2910 for (
const QString &layerId : constLayerIds )
2923 list.reserve(
layers.size() );
2928 list << layer->id();
2931 writeEntry( u
"Digitizing"_s, u
"/AvoidIntersectionsList"_s, list );
2952 if ( mProjectScope )
2954 auto projectScope = std::make_unique< QgsExpressionContextScope >( *mProjectScope );
2961 projectScope->addFunction( u
"sensor_data"_s,
new GetSensorData(
sensorManager()->sensorsData() ) );
2963 return projectScope.release();
2966 mProjectScope = std::make_unique< QgsExpressionContextScope >( QObject::tr(
"Project" ) );
2970 QVariantMap::const_iterator it = vars.constBegin();
2972 for ( ; it != vars.constEnd(); ++it )
2974 mProjectScope->setVariable( it.key(), it.value(),
true );
2978 if ( projectPath.isEmpty() )
2979 projectPath = mOriginalPath;
2980 const QString projectFolder = QFileInfo( projectPath ).path();
2981 const QString projectFilename = QFileInfo( projectPath ).fileName();
2982 const QString projectBasename =
baseName();
3019 QVariantMap keywords;
3021 for (
auto it = metadataKeywords.constBegin(); it != metadataKeywords.constEnd(); ++it )
3023 keywords.insert( it.key(), it.value() );
3028 QVariantList layersIds;
3030 const QMap<QString, QgsMapLayer *> layersInProject = mLayerStore->mapLayers();
3031 layersIds.reserve( layersInProject.count() );
3032 layers.reserve( layersInProject.count() );
3033 for (
auto it = layersInProject.constBegin(); it != layersInProject.constEnd(); ++it )
3035 layersIds << it.value()->id();
3041 mProjectScope->addFunction( u
"project_color"_s,
new GetNamedProjectColor(
this ) );
3042 mProjectScope->addFunction( u
"project_color_object"_s,
new GetNamedProjectColorObject(
this ) );
3047void QgsProject::onMapLayersAdded(
const QList<QgsMapLayer *> &layers )
3051 const QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
3053 const auto constLayers =
layers;
3056 if ( !layer->isValid() )
3059 if (
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer ) )
3062 if ( vlayer->dataProvider() )
3069 for ( QMap<QString, QgsMapLayer *>::const_iterator it = existingMaps.cbegin(); it != existingMaps.cend(); ++it )
3071 const QSet<QgsMapLayerDependency> deps = it.value()->dependencies();
3072 if ( deps.contains( layer->id() ) )
3075 it.value()->setDependencies( deps );
3080 updateTransactionGroups();
3082 if ( !mBlockSnappingUpdates && mSnappingConfig.addLayers(
layers ) )
3086void QgsProject::onMapLayersRemoved(
const QList<QgsMapLayer *> &layers )
3090 if ( !mBlockSnappingUpdates && mSnappingConfig.removeLayers(
layers ) )
3093 for ( QgsMapLayer *layer :
layers )
3095 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
3099 mEditBufferGroup.removeLayer( vlayer );
3103void QgsProject::cleanTransactionGroups(
bool force )
3107 bool changed =
false;
3108 for ( QMap< QPair< QString, QString>, QgsTransactionGroup *>::Iterator tg = mTransactionGroups.begin(); tg != mTransactionGroups.end(); )
3110 if ( tg.value()->isEmpty() || force )
3113 tg = mTransactionGroups.erase( tg );
3125void QgsProject::updateTransactionGroups()
3129 mEditBufferGroup.clear();
3131 switch ( mTransactionMode )
3135 cleanTransactionGroups(
true );
3140 cleanTransactionGroups(
true );
3143 cleanTransactionGroups(
false );
3147 bool tgChanged =
false;
3148 const auto constLayers =
mapLayers().values();
3149 for ( QgsMapLayer *layer : constLayers )
3151 if ( !layer->isValid() )
3154 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
3158 switch ( mTransactionMode )
3170 QgsTransactionGroup *tg = mTransactionGroups.value( qMakePair( key, connString ) );
3174 tg =
new QgsTransactionGroup();
3175 mTransactionGroups.insert( qMakePair( key, connString ), tg );
3185 mEditBufferGroup.addLayer( vlayer );
3201 context.setProjectTranslator(
this );
3203 context.setCurrentLayerId( layerNode.toElement().firstChildElement( u
"id"_s ).text() );
3204 QList<QDomNode> brokenNodes;
3205 if ( addLayer( layerNode.toElement(), brokenNodes, context ) )
3213 layer->resolveReferences(
this );
3215 if ( layer->isValid() && layer->customProperty( u
"_layer_was_editable"_s ).toBool() )
3217 layer->startEditing();
3218 layer->removeCustomProperty( u
"_layer_was_editable"_s );
3230 mFile.setFileName( filename );
3232 mCachedHomePath.clear();
3240 mProjectScope.reset();
3246 const QString storageFilePath { storage->filePath( mFile.fileName() ) };
3247 if ( storageFilePath.isEmpty() )
3253 const QString tempPath = QStandardPaths::standardLocations( QStandardPaths::TempLocation ).at( 0 );
3254 const QString tmpZipFilename( tempPath + QDir::separator() + QUuid::createUuid().toString() );
3256 if ( !zip( tmpZipFilename ) )
3259 QFile tmpZipFile( tmpZipFilename );
3260 if ( !tmpZipFile.open( QIODevice::ReadOnly ) )
3262 setError( tr(
"Unable to read file %1" ).arg( tmpZipFilename ) );
3267 if ( !storage->writeProject( mFile.fileName(), &tmpZipFile, context ) )
3269 QString err = tr(
"Unable to save project to storage %1" ).arg( mFile.fileName() );
3270 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
3271 if ( !messages.isEmpty() )
3272 err += u
"\n\n"_s + messages.last().message();
3278 QFile::remove( tmpZipFilename );
3285 return zip( mFile.fileName() );
3291 const bool asOk = saveAuxiliaryStorage();
3292 const bool writeOk = writeProjectFile( mFile.fileName() );
3293 bool attachmentsOk =
true;
3294 if ( !mArchive->files().isEmpty() )
3296 const QFileInfo finfo( mFile.fileName() );
3297 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( u
"%1_attachments.zip"_s.arg( finfo.completeBaseName() ) );
3298 attachmentsOk = mArchive->zip( attachmentsZip );
3302 if ( ( !asOk || !attachmentsOk ) && writeOk )
3304 QStringList errorMessage;
3307 const QString err = mAuxiliaryStorage->errorString();
3308 errorMessage.append( tr(
"Unable to save auxiliary storage ('%1')" ).arg( err ) );
3310 if ( !attachmentsOk )
3312 errorMessage.append( tr(
"Unable to save attachments archive" ) );
3314 setError( errorMessage.join(
'\n' ) );
3317 return asOk && writeOk && attachmentsOk;
3321bool QgsProject::writeProjectFile(
const QString &filename )
3325 QFile projectFile( filename );
3331 const QFileInfo myFileInfo( projectFile );
3332 if ( myFileInfo.exists() && !myFileInfo.isWritable() )
3334 setError( tr(
"%1 is not writable. Please adjust permissions (if possible) and try again." ).arg( projectFile.fileName() ) );
3338 QgsReadWriteContext context;
3342 QDomImplementation::setInvalidDataPolicy( QDomImplementation::DropInvalidChars );
3344 const QDomDocumentType documentType = QDomImplementation().createDocumentType( u
"qgis"_s, u
"http://mrcc.com/qgis.dtd"_s, u
"SYSTEM"_s );
3345 auto doc = std::make_unique<QDomDocument>( documentType );
3347 QDomElement qgisNode = doc->createElement( u
"qgis"_s );
3348 qgisNode.setAttribute( u
"projectname"_s,
title() );
3355 qgisNode.setAttribute( u
"saveUser"_s, newSaveUser );
3356 qgisNode.setAttribute( u
"saveUserFull"_s, newSaveUserFull );
3357 mSaveUser = newSaveUser;
3358 mSaveUserFull = newSaveUserFull;
3359 if ( mMetadata.author().isEmpty() )
3363 if ( !mMetadata.creationDateTime().isValid() )
3365 mMetadata.setCreationDateTime( QDateTime( QDateTime::currentDateTime() ) );
3367 mSaveDateTime = QDateTime::currentDateTime();
3368 qgisNode.setAttribute( u
"saveDateTime"_s, mSaveDateTime.toString( Qt::ISODate ) );
3373 mSaveUserFull.clear();
3374 mMetadata.setAuthor( QString() );
3375 mMetadata.setCreationDateTime( QDateTime() );
3376 mSaveDateTime = QDateTime();
3378 doc->appendChild( qgisNode );
3381 QDomElement homePathNode = doc->createElement( u
"homePath"_s );
3382 homePathNode.setAttribute( u
"path"_s, mHomePath );
3383 qgisNode.appendChild( homePathNode );
3386 QDomElement titleNode = doc->createElement( u
"title"_s );
3387 qgisNode.appendChild( titleNode );
3389 QDomElement transactionNode = doc->createElement( u
"transaction"_s );
3390 transactionNode.setAttribute( u
"mode"_s,
qgsEnumValueToKey( mTransactionMode ) );
3391 qgisNode.appendChild( transactionNode );
3393 QDomElement flagsNode = doc->createElement( u
"projectFlags"_s );
3395 qgisNode.appendChild( flagsNode );
3397 const QDomText titleText = doc->createTextNode(
title() );
3398 titleNode.appendChild( titleText );
3402 QDomElement srsNode = doc->createElement( u
"projectCrs"_s );
3403 mCrs.writeXml( srsNode, *doc );
3404 qgisNode.appendChild( srsNode );
3407 QDomElement verticalSrsNode = doc->createElement( u
"verticalCrs"_s );
3408 mVerticalCrs.writeXml( verticalSrsNode, *doc );
3409 qgisNode.appendChild( verticalSrsNode );
3412 QDomElement elevationShadingNode = doc->createElement( u
"elevation-shading-renderer"_s );
3413 mElevationShadingRenderer.writeXml( elevationShadingNode, context );
3414 qgisNode.appendChild( elevationShadingNode );
3417 std::unique_ptr< QgsLayerTreeNode > clonedRoot( mRootGroup->clone() );
3421 clonedRoot->writeXml( qgisNode, context );
3424 mSnappingConfig.writeProject( *doc );
3425 writeEntry( u
"Digitizing"_s, u
"/AvoidIntersectionsMode"_s,
static_cast<int>( mAvoidIntersectionsMode ) );
3433 QDomElement annotationLayerNode = doc->createElement( u
"main-annotation-layer"_s );
3434 mMainAnnotationLayer->writeLayerXml( annotationLayerNode, *doc, context );
3435 qgisNode.appendChild( annotationLayerNode );
3439 QDomElement projectLayersNode = doc->createElement( u
"projectlayers"_s );
3441 QMap<QString, QgsMapLayer *>::ConstIterator li =
layers.constBegin();
3442 while ( li !=
layers.end() )
3444 QgsMapLayer *ml = li.value();
3448 const QHash< QString, QPair< QString, bool> >::const_iterator emIt = mEmbeddedLayers.constFind( ml->
id() );
3449 if ( emIt == mEmbeddedLayers.constEnd() )
3451 QDomElement maplayerElem;
3457 maplayerElem = doc->createElement( u
"maplayer"_s );
3461 maplayerElem.setAttribute( u
"editable"_s, u
"1"_s );
3465 QDomDocument document;
3468 maplayerElem = document.firstChildElement();
3472 QgsDebugError( u
"Could not restore layer properties for layer %1"_s.arg( ml->
id() ) );
3478 projectLayersNode.appendChild( maplayerElem );
3484 if ( emIt.value().second )
3486 QDomElement mapLayerElem = doc->createElement( u
"maplayer"_s );
3487 mapLayerElem.setAttribute( u
"embedded"_s, 1 );
3488 mapLayerElem.setAttribute( u
"project"_s,
writePath( emIt.value().first ) );
3489 mapLayerElem.setAttribute( u
"id"_s, ml->
id() );
3490 projectLayersNode.appendChild( mapLayerElem );
3497 qgisNode.appendChild( projectLayersNode );
3499 QDomElement layerOrderNode = doc->createElement( u
"layerorder"_s );
3500 const auto constCustomLayerOrder = mRootGroup->customLayerOrder();
3501 for ( QgsMapLayer *layer : constCustomLayerOrder )
3503 QDomElement mapLayerElem = doc->createElement( u
"layer"_s );
3504 mapLayerElem.setAttribute( u
"id"_s, layer->id() );
3505 layerOrderNode.appendChild( mapLayerElem );
3507 qgisNode.appendChild( layerOrderNode );
3509 mLabelingEngineSettings->writeSettingsToProject(
this );
3511 QDomElement labelEngineSettingsElement = doc->createElement( u
"labelEngineSettings"_s );
3512 mLabelingEngineSettings->writeXml( *doc, labelEngineSettingsElement, context );
3513 qgisNode.appendChild( labelEngineSettingsElement );
3516 writeEntry( u
"Gui"_s, u
"/CanvasColorRedPart"_s, mBackgroundColor.red() );
3517 writeEntry( u
"Gui"_s, u
"/CanvasColorGreenPart"_s, mBackgroundColor.green() );
3518 writeEntry( u
"Gui"_s, u
"/CanvasColorBluePart"_s, mBackgroundColor.blue() );
3520 writeEntry( u
"Gui"_s, u
"/SelectionColorRedPart"_s, mSelectionColor.red() );
3521 writeEntry( u
"Gui"_s, u
"/SelectionColorGreenPart"_s, mSelectionColor.green() );
3522 writeEntry( u
"Gui"_s, u
"/SelectionColorBluePart"_s, mSelectionColor.blue() );
3523 writeEntry( u
"Gui"_s, u
"/SelectionColorAlphaPart"_s, mSelectionColor.alpha() );
3531 dump_( mProperties );
3534 QgsDebugMsgLevel( u
"there are %1 property scopes"_s.arg(
static_cast<int>( mProperties.count() ) ), 2 );
3536 if ( !mProperties.isEmpty() )
3539 mProperties.writeXml( u
"properties"_s, qgisNode, *doc );
3542 QDomElement ddElem = doc->createElement( u
"dataDefinedServerProperties"_s );
3543 mDataDefinedServerProperties.writeXml( ddElem, dataDefinedServerPropertyDefinitions() );
3544 qgisNode.appendChild( ddElem );
3546 mMapThemeCollection->writeXml( *doc );
3548 mTransformContext.writeXml( qgisNode, context );
3550 QDomElement metadataElem = doc->createElement( u
"projectMetadata"_s );
3551 mMetadata.writeMetadataXml( metadataElem, *doc );
3552 qgisNode.appendChild( metadataElem );
3555 const QDomElement annotationsElem = mAnnotationManager->writeXml( *doc, context );
3556 qgisNode.appendChild( annotationsElem );
3560 const QDomElement layoutElem = mLayoutManager->writeXml( *doc );
3561 qgisNode.appendChild( layoutElem );
3565 const QDomElement elevationProfileElem = mElevationProfileManager->writeXml( *doc, context );
3566 qgisNode.appendChild( elevationProfileElem );
3570 const QDomElement selectiveMaskingSourceSetElem = mSelectiveMaskingSourceSetManager->writeXml( *doc, context );
3571 qgisNode.appendChild( selectiveMaskingSourceSetElem );
3575 const QDomElement views3DElem = m3DViewsManager->writeXml( *doc );
3576 qgisNode.appendChild( views3DElem );
3580 const QDomElement bookmarkElem = mBookmarkManager->writeXml( *doc );
3581 qgisNode.appendChild( bookmarkElem );
3585 const QDomElement sensorElem = mSensorManager->writeXml( *doc );
3586 qgisNode.appendChild( sensorElem );
3590 const QDomElement viewSettingsElem = mViewSettings->writeXml( *doc, context );
3591 qgisNode.appendChild( viewSettingsElem );
3595 const QDomElement styleSettingsElem = mStyleSettings->writeXml( *doc, context );
3596 qgisNode.appendChild( styleSettingsElem );
3600 const QDomElement timeSettingsElement = mTimeSettings->writeXml( *doc, context );
3601 qgisNode.appendChild( timeSettingsElement );
3605 const QDomElement elevationPropertiesElement = mElevationProperties->writeXml( *doc, context );
3606 qgisNode.appendChild( elevationPropertiesElement );
3610 const QDomElement displaySettingsElem = mDisplaySettings->writeXml( *doc, context );
3611 qgisNode.appendChild( displaySettingsElem );
3615 const QDomElement gpsSettingsElem = mGpsSettings->writeXml( *doc, context );
3616 qgisNode.appendChild( gpsSettingsElem );
3625 QFile backupFile( u
"%1~"_s.arg( filename ) );
3627 ok &= backupFile.open( QIODevice::WriteOnly | QIODevice::Truncate );
3628 ok &= projectFile.open( QIODevice::ReadOnly );
3631 while ( ok && !projectFile.atEnd() )
3633 ba = projectFile.read( 10240 );
3634 ok &= backupFile.write( ba ) == ba.size();
3637 projectFile.close();
3642 setError( tr(
"Unable to create backup file %1" ).arg( backupFile.fileName() ) );
3647 struct utimbuf tb = {
static_cast<time_t
>( fi.lastRead().toSecsSinceEpoch() ),
static_cast<time_t
>( fi.lastModified().toSecsSinceEpoch() ) };
3648 utime( backupFile.fileName().toUtf8().constData(), &tb );
3651 if ( !projectFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
3653 projectFile.close();
3656 setError( tr(
"Unable to save to file %1" ).arg( projectFile.fileName() ) );
3660 QTemporaryFile tempFile;
3661 bool ok = tempFile.open();
3664 QTextStream projectFileStream( &tempFile );
3665 doc->save( projectFileStream, 2 );
3666 ok &= projectFileStream.pos() > -1;
3668 ok &= tempFile.seek( 0 );
3671 while ( ok && !tempFile.atEnd() )
3673 ba = tempFile.read( 10240 );
3674 ok &= projectFile.write( ba ) == ba.size();
3677 ok &= projectFile.error() == QFile::NoError;
3679 projectFile.close();
3687 "Unable to save to file %1. Your project "
3688 "may be corrupted on disk. Try clearing some space on the volume and "
3689 "check file permissions before pressing save again."
3691 .arg( projectFile.fileName() ) );
3705 bool propertiesModified;
3706 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3708 if ( propertiesModified )
3718 bool propertiesModified;
3719 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3721 if ( propertiesModified )
3731 bool propertiesModified;
3732 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3734 if ( propertiesModified )
3744 bool propertiesModified;
3745 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3747 if ( propertiesModified )
3757 bool propertiesModified;
3758 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3760 if ( propertiesModified )
3777 value =
property->value();
3779 const bool valid = QMetaType::Type::QStringList == value.userType();
3785 return value.toStringList();
3805 value =
property->value();
3807 const bool valid = value.canConvert( QMetaType::Type::QString );
3812 return value.toString();
3830 value =
property->value();
3833 const bool valid = value.canConvert( QMetaType::Type::Int );
3842 return value.toInt();
3855 const QVariant value =
property->value();
3857 const bool valid = value.canConvert( QMetaType::Type::Double );
3862 return value.toDouble();
3878 const QVariant value =
property->value();
3880 const bool valid = value.canConvert( QMetaType::Type::Bool );
3885 return value.toBool();
3897 if (
findKey_( scope, key, mProperties ) )
3903 return !
findKey_( scope, key, mProperties );
3912 QStringList entries;
3914 if ( foundProperty )
3933 QStringList entries;
3935 if ( foundProperty )
3952 dump_( mProperties );
3972 filePath = storage->filePath( mFile.fileName() );
3999void QgsProject::setError(
const QString &errorMessage )
4003 mErrorMessage = errorMessage;
4010 return mErrorMessage;
4013void QgsProject::clearError()
4017 setError( QString() );
4024 mBadLayerHandler.reset( handler );
4031 const QHash< QString, QPair< QString, bool > >::const_iterator it = mEmbeddedLayers.find(
id );
4032 if ( it == mEmbeddedLayers.constEnd() )
4036 return it.value().first;
4045 static QString sPrevProjectFilePath;
4046 static QDateTime sPrevProjectFileTimestamp;
4047 static QDomDocument sProjectDocument;
4049 QString qgsProjectFile = projectFilePath;
4051 if ( projectFilePath.endsWith(
".qgz"_L1, Qt::CaseInsensitive ) )
4053 archive.
unzip( projectFilePath );
4057 const QDateTime projectFileTimestamp = QFileInfo( projectFilePath ).lastModified();
4059 if ( projectFilePath != sPrevProjectFilePath || projectFileTimestamp != sPrevProjectFileTimestamp )
4061 sPrevProjectFilePath.clear();
4063 QFile projectFile( qgsProjectFile );
4064 if ( !projectFile.open( QIODevice::ReadOnly ) )
4069 if ( !sProjectDocument.setContent( &projectFile ) )
4074 sPrevProjectFilePath = projectFilePath;
4075 sPrevProjectFileTimestamp = projectFileTimestamp;
4079 bool useAbsolutePaths =
true;
4081 const QDomElement propertiesElem = sProjectDocument.documentElement().firstChildElement( u
"properties"_s );
4082 if ( !propertiesElem.isNull() )
4084 QDomElement e = propertiesElem.firstChildElement( u
"Paths"_s );
4087 e = propertiesElem.firstChildElement( u
"properties"_s );
4088 while ( !e.isNull() && e.attribute( u
"name"_s ) !=
"Paths"_L1 )
4089 e = e.nextSiblingElement( u
"properties"_s );
4091 e = e.firstChildElement( u
"properties"_s );
4092 while ( !e.isNull() && e.attribute( u
"name"_s ) !=
"Absolute"_L1 )
4093 e = e.nextSiblingElement( u
"properties"_s );
4097 e = e.firstChildElement( u
"Absolute"_s );
4102 useAbsolutePaths = e.text().compare(
"true"_L1, Qt::CaseInsensitive ) == 0;
4107 if ( !useAbsolutePaths )
4113 const QDomElement projectLayersElem = sProjectDocument.documentElement().firstChildElement( u
"projectlayers"_s );
4114 if ( projectLayersElem.isNull() )
4119 QDomElement mapLayerElem = projectLayersElem.firstChildElement( u
"maplayer"_s );
4120 while ( !mapLayerElem.isNull() )
4123 const QString
id = mapLayerElem.firstChildElement( u
"id"_s ).text();
4124 if (
id == layerId )
4127 if ( mapLayerElem.attribute( u
"embedded"_s ) ==
"1"_L1 )
4132 mEmbeddedLayers.insert( layerId, qMakePair( projectFilePath, saveFlag ) );
4134 if ( addLayer( mapLayerElem, brokenNodes, embeddedContext,
flags ) )
4140 mEmbeddedLayers.remove( layerId );
4144 mapLayerElem = mapLayerElem.nextSiblingElement( u
"maplayer"_s );
4154 QString qgsProjectFile = projectFilePath;
4156 if ( projectFilePath.endsWith(
".qgz"_L1, Qt::CaseInsensitive ) )
4158 archive.
unzip( projectFilePath );
4163 QFile projectFile( qgsProjectFile );
4164 if ( !projectFile.open( QIODevice::ReadOnly ) )
4169 QDomDocument projectDocument;
4170 if ( !projectDocument.setContent( &projectFile ) )
4180 auto root = std::make_unique< QgsLayerTreeGroup >();
4182 QDomElement layerTreeElem = projectDocument.documentElement().firstChildElement( u
"layer-tree-group"_s );
4183 if ( !layerTreeElem.isNull() )
4185 root->readChildrenFromXml( layerTreeElem, context );
4203 newGroup->setCustomProperty( u
"embedded"_s, 1 );
4204 newGroup->setCustomProperty( u
"embedded_project"_s, projectFilePath );
4207 mLayerTreeRegistryBridge->setEnabled(
false );
4208 initializeEmbeddedSubtree( projectFilePath, newGroup.get(),
flags );
4209 mLayerTreeRegistryBridge->setEnabled(
true );
4212 const QStringList constFindLayerIds = newGroup->findLayerIds();
4213 for (
const QString &layerId : constFindLayerIds )
4230 const auto constChildren = group->
children();
4234 child->setCustomProperty( u
"embedded"_s, 1 );
4243 QList<QDomNode> brokenNodes;
4267 writeEntry( u
"Digitizing"_s, u
"/TopologicalEditing"_s, ( enabled ? 1 : 0 ) );
4275 return readNumEntry( u
"Digitizing"_s, u
"/TopologicalEditing"_s, 0 );
4282 if ( mDistanceUnits == unit )
4285 mDistanceUnits = unit;
4294 if ( mAreaUnits == unit )
4306 if ( mScaleMethod == method )
4309 mScaleMethod = method;
4319 if ( !mCachedHomePath.isEmpty() )
4320 return mCachedHomePath;
4324 if ( !mHomePath.isEmpty() )
4326 const QFileInfo homeInfo( mHomePath );
4327 if ( !homeInfo.isRelative() )
4329 mCachedHomePath = mHomePath;
4338 const QString storagePath { storage->filePath(
fileName() ) };
4339 if ( !storagePath.isEmpty() && QFileInfo::exists( storagePath ) )
4341 mCachedHomePath = QFileInfo( storagePath ).path();
4342 return mCachedHomePath;
4346 mCachedHomePath = pfi.path();
4347 return mCachedHomePath;
4350 if ( !pfi.exists() )
4352 mCachedHomePath = mHomePath;
4356 if ( !mHomePath.isEmpty() )
4359 mCachedHomePath = QDir::cleanPath( pfi.path() +
'/' + mHomePath );
4363 mCachedHomePath = pfi.canonicalPath();
4365 return mCachedHomePath;
4380 return mRelationManager.get();
4387 return mLayoutManager.get();
4394 return mLayoutManager.get();
4401 return mElevationProfileManager.get();
4408 return mElevationProfileManager.get();
4415 return mSelectiveMaskingSourceSetManager.get();
4422 return mSelectiveMaskingSourceSetManager.get();
4429 return m3DViewsManager.get();
4436 return m3DViewsManager.get();
4443 return mBookmarkManager;
4450 return mBookmarkManager;
4457 return mSensorManager;
4464 return mSensorManager;
4471 return mViewSettings;
4478 return mViewSettings;
4485 return mStyleSettings;
4493 return mStyleSettings;
4500 return mTimeSettings;
4507 return mTimeSettings;
4514 return mElevationProperties;
4521 return mElevationProperties;
4528 return mDisplaySettings;
4535 return mDisplaySettings;
4542 return mGpsSettings;
4549 return mGpsSettings;
4556 return mRootGroup.get();
4563 return mMapThemeCollection.get();
4570 return mAnnotationManager.get();
4577 return mAnnotationManager.get();
4584 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
4585 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
4590 if (
layers.contains( it.value() ) )
4607 for (
const QString &layerId : layerIds )
4625 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
4657 updateTransactionGroups();
4664 return mTransactionMode;
4675 const auto constLayers =
mapLayers().values();
4678 if ( layer->isEditable() )
4680 QgsLogger::warning( tr(
"Transaction mode can be changed only if all layers are not editable." ) );
4686 updateTransactionGroups();
4695 return mTransactionGroups;
4708 return mLayerStore->count();
4715 return mLayerStore->validCount();
4723 if ( mMainAnnotationLayer && layerId == mMainAnnotationLayer->id() )
4724 return mMainAnnotationLayer;
4726 return mLayerStore->mapLayer( layerId );
4733 return mLayerStore->mapLayersByName( layerName );
4740 QList<QgsMapLayer *>
layers;
4741 const auto constMapLayers { mLayerStore->mapLayers() };
4742 for (
const auto &l : constMapLayers )
4744 if ( !l->serverProperties()->shortName().isEmpty() )
4746 if ( l->serverProperties()->shortName() == shortName )
4749 else if ( l->name() == shortName )
4762 auto archive = std::make_unique<QgsProjectArchive>();
4765 if ( !archive->unzip( filename ) )
4767 setError( tr(
"Unable to unzip file '%1'" ).arg( filename ) );
4772 if ( archive->projectFile().isEmpty() )
4774 setError( tr(
"Zip archive does not provide a project file" ) );
4779 releaseHandlesToProjectArchive();
4780 mArchive = std::move( archive );
4783 if ( !
static_cast<QgsProjectArchive *
>( mArchive.get() )->auxiliaryStorageFile().isEmpty() )
4787 mAuxiliaryStorage = std::make_unique< QgsAuxiliaryStorage >(
static_cast<QgsProjectArchive *
>( mArchive.get() )->auxiliaryStorageFile(),
false );
4791 mAuxiliaryStorage = std::make_unique< QgsAuxiliaryStorage >( *
this );
4795 if ( !readProjectFile(
static_cast<QgsProjectArchive *
>( mArchive.get() )->projectFile(),
flags ) )
4797 setError( tr(
"Cannot read unzipped qgs project file" ) + u
": "_s +
error() );
4802 static_cast<QgsProjectArchive *
>( mArchive.get() )->clearProjectFile();
4807bool QgsProject::zip(
const QString &filename )
4814 auto archive = std::make_unique<QgsProjectArchive>();
4815 const QString
baseName = QFileInfo( filename ).baseName();
4816 const QString qgsFileName = u
"%1.qgs"_s.arg(
baseName );
4817 QFile qgsFile( QDir( archive->dir() ).filePath( qgsFileName ) );
4819 bool writeOk =
false;
4820 if ( qgsFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
4822 writeOk = writeProjectFile( qgsFile.fileName() );
4829 setError( tr(
"Unable to write temporary qgs file" ) );
4834 const QFileInfo info( qgsFile );
4836 const QString asFileName = info.path() + QDir::separator() + info.completeBaseName() + asExt;
4838 bool auxiliaryStorageSavedOk =
true;
4839 if ( !saveAuxiliaryStorage( asFileName ) )
4841 const QString err = mAuxiliaryStorage->errorString();
4843 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 )
4845 auxiliaryStorageSavedOk =
false;
4848 if ( !mArchive->exists() )
4850 releaseHandlesToProjectArchive();
4851 mArchive = std::make_unique< QgsProjectArchive >();
4852 mArchive->unzip( mFile.fileName() );
4853 static_cast<QgsProjectArchive *
>( mArchive.get() )->clearProjectFile();
4855 const QString auxiliaryStorageFile =
static_cast<QgsProjectArchive *
>( mArchive.get() )->auxiliaryStorageFile();
4856 if ( !auxiliaryStorageFile.isEmpty() )
4858 archive->addFile( auxiliaryStorageFile );
4859 mAuxiliaryStorage = std::make_unique< QgsAuxiliaryStorage >( auxiliaryStorageFile,
false );
4867 if ( QFile::exists( asFileName ) )
4869 archive->addFile( asFileName );
4874 archive->addFile( qgsFile.fileName() );
4877 const QStringList &files = mArchive->files();
4878 for (
const QString &file : files )
4880 if ( !file.endsWith(
".qgs"_L1, Qt::CaseInsensitive ) && !file.endsWith( asExt, Qt::CaseInsensitive ) )
4882 archive->addFile( file );
4888 if ( !archive->zip( filename ) )
4890 setError( tr(
"Unable to perform zip" ) );
4894 return auxiliaryStorageSavedOk && zipOk;
4908 const QList<QgsMapLayer *> myResultList { mLayerStore->addMapLayers(
layers, takeOwnership ) };
4909 if ( !myResultList.isEmpty() )
4912 for (
auto &l : myResultList )
4926 if ( mAuxiliaryStorage )
4941 mProjectScope.reset();
4943 return myResultList;
4950 QList<QgsMapLayer *> addedLayers;
4951 addedLayers =
addMapLayers( QList<QgsMapLayer *>() << layer, addToLegend, takeOwnership );
4952 return addedLayers.isEmpty() ? nullptr : addedLayers[0];
4955void QgsProject::removeAuxiliaryLayer(
const QgsMapLayer *ml )
4962 const QgsVectorLayer *vl = qobject_cast<const QgsVectorLayer *>( ml );
4974 for (
const auto &layerId : layerIds )
4975 removeAuxiliaryLayer( mLayerStore->mapLayer( layerId ) );
4977 mProjectScope.reset();
4978 mLayerStore->removeMapLayers( layerIds );
4985 for (
const auto &layer :
layers )
4986 removeAuxiliaryLayer( layer );
4988 mProjectScope.reset();
4989 mLayerStore->removeMapLayers(
layers );
4996 removeAuxiliaryLayer( mLayerStore->mapLayer( layerId ) );
4997 mProjectScope.reset();
4998 mLayerStore->removeMapLayer( layerId );
5005 removeAuxiliaryLayer( layer );
5006 mProjectScope.reset();
5007 mLayerStore->removeMapLayer( layer );
5014 mProjectScope.reset();
5015 return mLayerStore->takeMapLayer( layer );
5022 return mMainAnnotationLayer;
5029 if ( mLayerStore->count() == 0 )
5032 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
5033 mProjectScope.reset();
5034 mLayerStore->removeAllMapLayers();
5036 snapSingleBlocker.release();
5037 mSnappingConfig.clearIndividualLayerSettings();
5038 if ( !mBlockSnappingUpdates )
5046 const QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
5047 QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin();
5048 for ( ; it !=
layers.constEnd(); ++it )
5050 it.value()->reload();
5059 return validOnly ? mLayerStore->validMapLayers() : mLayerStore->mapLayers();
5066 return mTransactionGroups.value( qMakePair( providerKey, connString ) );
5073 return &mEditBufferGroup;
5112bool QgsProject::saveAuxiliaryStorage(
const QString &filename )
5118 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5123 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() );
5131 if ( !mAuxiliaryStorage->exists( *
this ) && empty )
5135 else if ( !filename.isEmpty() )
5137 return mAuxiliaryStorage->saveAs( filename );
5141 return mAuxiliaryStorage->saveAs( *
this );
5150 return sPropertyDefinitions;
5163 return mAuxiliaryStorage.get();
5170 return mAuxiliaryStorage.get();
5177 const QDir archiveDir( mArchive->dir() );
5178 QTemporaryFile tmpFile( archiveDir.filePath(
"XXXXXX_" + nameTemplate ),
this );
5179 tmpFile.setAutoRemove(
false );
5180 if ( !tmpFile.open() )
5182 setError( tr(
"Unable to open %1" ).arg( tmpFile.fileName() ) );
5185 mArchive->addFile( tmpFile.fileName() );
5186 return tmpFile.fileName();
5193 QStringList attachments;
5195 const QStringList files = mArchive->files();
5196 attachments.reserve( files.size() );
5197 for (
const QString &file : files )
5201 attachments.append( file );
5211 return mArchive->removeFile( path );
5218 return u
"attachment:///%1"_s.arg( QFileInfo( attachedFile ).
fileName() );
5225 if ( identifier.startsWith(
"attachment:///"_L1 ) )
5227 return QDir( mArchive->dir() ).absoluteFilePath( identifier.mid( 14 ) );
5248 mProjectScope.reset();
5263 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5277 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
5278 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
5283 if (
layers.contains( it.value() ) )
5295 QStringList customColors;
5296 QStringList customColorLabels;
5298 QgsNamedColorList::const_iterator colorIt = colors.constBegin();
5299 for ( ; colorIt != colors.constEnd(); ++colorIt )
5302 const QString label = ( *colorIt ).second;
5303 customColors.append( color );
5304 customColorLabels.append( label );
5306 writeEntry( u
"Palette"_s, u
"/Colors"_s, customColors );
5307 writeEntry( u
"Palette"_s, u
"/Labels"_s, customColorLabels );
5308 mProjectScope.reset();
5316 if ( mBackgroundColor == color )
5319 mBackgroundColor = color;
5327 return mBackgroundColor;
5334 if ( mSelectionColor == color )
5337 mSelectionColor = color;
5345 return mSelectionColor;
5352 mViewSettings->setMapScales( scales );
5359 return mViewSettings->mapScales();
5366 mViewSettings->setUseProjectScales( enabled );
5373 return mViewSettings->useProjectScales();
5386 translationContext.writeTsFile( locale );
5389QString
QgsProject::translate(
const QString &context,
const QString &sourceText,
const char *disambiguation,
int n )
const
5398 QString result = mTranslator->translate( context.toUtf8(), sourceText.toUtf8(), disambiguation, n );
5400 if ( result.isEmpty() )
5414 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5419 if ( !( ( *it )->accept( visitor ) ) )
5428 if ( !mLayoutManager->accept( visitor ) )
5431 if ( !mAnnotationManager->accept( visitor ) )
5441 const QString macros =
readEntry( u
"Macros"_s, u
"/pythonCode"_s, QString() );
5442 if ( !macros.isEmpty() )
5451 const QString expressionFunctions =
readEntry( u
"ExpressionFunctions"_s, u
"/pythonCode"_s );
5452 if ( !expressionFunctions.isEmpty() )
5464 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5466 if ( !( ( *it )->accept( visitor, context ) ) )
5478 return mElevationShadingRenderer;
5481void QgsProject::loadProjectFlags(
const QDomDocument *doc )
5485 QDomElement element = doc->documentElement().firstChildElement( u
"projectFlags"_s );
5487 if ( !element.isNull() )
5494 element = doc->documentElement().firstChildElement( u
"evaluateDefaultValues"_s );
5495 if ( !element.isNull() )
5497 if ( element.attribute( u
"active"_s, u
"0"_s ).toInt() == 1 )
5502 element = doc->documentElement().firstChildElement( u
"trust"_s );
5503 if ( !element.isNull() )
5505 if ( element.attribute( u
"active"_s, u
"0"_s ).toInt() == 1 )
5519 const QString projectFunctions =
readEntry( u
"ExpressionFunctions"_s, u
"/pythonCode"_s, QString() );
5520 if ( !projectFunctions.isEmpty() )
5540QHash< QString, QColor > loadColorsFromProject(
const QgsProject *project )
5542 QHash< QString, QColor > colors;
5545 QStringList colorStrings = project->
readListEntry( u
"Palette"_s, u
"/Colors"_s );
5546 const QStringList colorLabels = project->
readListEntry( u
"Palette"_s, u
"/Labels"_s );
5550 for ( QStringList::iterator it = colorStrings.begin(); it != colorStrings.end(); ++it )
5554 if ( colorLabels.length() > colorIndex )
5556 label = colorLabels.at( colorIndex );
5559 colors.insert( label.toLower(), color );
5567GetNamedProjectColor::GetNamedProjectColor(
const QgsProject *project )
5573 mColors = loadColorsFromProject( project );
5576GetNamedProjectColor::GetNamedProjectColor(
const QHash<QString, QColor> &colors )
5583 const QString colorName = values.at( 0 ).toString().toLower();
5584 if ( mColors.contains( colorName ) )
5586 return u
"%1,%2,%3"_s.arg( mColors.value( colorName ).red() ).arg( mColors.value( colorName ).green() ).arg( mColors.value( colorName ).blue() );
5594 return new GetNamedProjectColor( mColors );
5597GetNamedProjectColorObject::GetNamedProjectColorObject(
const QgsProject *project )
5603 mColors = loadColorsFromProject( project );
5606GetNamedProjectColorObject::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 )
5631 , mSensorData( sensorData )
5636 const QString sensorName = values.at( 0 ).toString();
5637 const int expiration = values.at( 1 ).toInt();
5638 const qint64 timestamp = QDateTime::currentMSecsSinceEpoch();
5639 if ( mSensorData.contains( sensorName ) )
5641 if ( expiration <= 0 || ( timestamp - mSensorData[sensorName].lastTimestamp.toMSecsSinceEpoch() ) < expiration )
5643 return mSensorData[sensorName].lastValue;
5652 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.
@ UseProjectCrs
Copy the current project's CRS.
QFlags< ProjectFlag > ProjectFlags
static QString geoNone()
Constant that holds the string representation for "No ellipse/No CRS".
@ Preferred
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
virtual bool readXml(const QDomElement &collectionElem, const QgsPropertiesDefinition &definitions)
Reads property collection state from an XML element.
QList< QgsAction > actions(const QString &actionScope=QString()) const
Returns a list of actions that are available in the given action scope.
Utility class that encapsulates an action based on vector attributes.
Represents a map layer containing a set of georeferenced annotations, e.g.
Manages storage of a set of QgsAnnotation annotation objects.
static QgsApplication * instance()
Returns the singleton instance of the QgsApplication.
static QgsProjectStorageRegistry * projectStorageRegistry()
Returns registry of available project storage implementations.
static const QgsSettingsEntryString * settingsLocaleUserLocale
Settings entry locale user locale.
static QgsRuntimeProfiler * profiler()
Returns the application runtime profiler.
void collectTranslatableObjects(QgsTranslationContext *translationContext)
Emits the signal to collect all the strings of .qgs to be included in ts file.
static QgsPluginLayerRegistry * pluginLayerRegistry()
Returns the application's plugin layer registry, used for managing plugin layer types.
void requestForTranslatableObjects(QgsTranslationContext *translationContext)
Emitted when project strings which require translation are being collected for inclusion in a ....
static QString userFullName()
Returns the user's operating system login account full display name.
static QString userLoginName()
Returns the user's operating system login account name.
Manages zip/unzip operations for an archive.
A container for attribute editors, used to group them visually in the attribute form if it is set to ...
QList< QgsAttributeEditorElement * > children() const
Gets a list of the children elements of this container.
An abstract base class for any elements of a drag and drop form.
QString name() const
Returns the name of this element.
QgsFields auxiliaryFields() const
Returns a list of all auxiliary fields currently managed by the layer.
bool save()
Commits changes and starts editing then.
Providing some utility methods to manage auxiliary storage.
static QString extension()
Returns the extension used for auxiliary databases.
static bool deleteTable(const QgsDataSourceUri &uri)
Removes a table from the auxiliary storage.
Manages storage of a set of bookmarks.
static QColor colorFromString(const QString &string)
Decodes a string into a color value.
static QString colorToString(const QColor &color)
Encodes a color into a string value.
Represents a coordinate reference system (CRS).
static QgsCoordinateReferenceSystem fromOgcWmsCrs(const QString &ogcCrs)
Creates a CRS from a given OGC WMS-format Coordinate Reference System string.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
QString toProj() const
Returns a Proj string representation of this CRS.
bool readXml(const QDomNode &node)
Restores state from the given DOM node.
static QgsCoordinateReferenceSystem createCompoundCrs(const QgsCoordinateReferenceSystem &horizontalCrs, const QgsCoordinateReferenceSystem &verticalCrs, QString &error)
Given a horizontal and vertical CRS, attempts to create a compound CRS from them.
QString ellipsoidAcronym() const
Returns the ellipsoid acronym for the ellipsoid used by the CRS.
QString projectionAcronym() const
Returns the projection acronym for the projection used by the CRS.
static QgsCoordinateReferenceSystem fromProj(const QString &proj)
Creates a CRS from a proj style formatted string.
QString toWkt(Qgis::CrsWktVariant variant=Qgis::CrsWktVariant::Wkt1Gdal, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
static QgsCoordinateReferenceSystem fromSrsId(long srsId)
Creates a CRS from a specified QGIS SRS ID.
Qgis::DistanceUnit mapUnits
Contains information about the context in which a coordinate transform is executed.
void readSettings()
Reads the context's state from application settings.
Abstract base class for spatial data provider implementations.
@ EvaluateDefaultValues
Evaluate default values on provider side when calling QgsVectorDataProvider::defaultValue( int index ...
Stores the component parts of a data source URI (e.g.
Manages storage of a set of elevation profiles.
Renders elevation shading on an image with different methods (eye dome lighting, hillshading,...
A embedded script entity for QgsObjectEntityVisitorInterface.
Single scope for storing variables and functions for use within a QgsExpressionContext.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
An abstract base class for defining QgsExpression functions.
An expression node for expression functions.
Handles parsing and evaluation of expressions (formerly called "search strings").
virtual QgsLegendSymbolList legendSymbolItems() const
Returns a list of symbology items for the legend.
Encapsulate a field in an attribute table or data source.
Container of fields for a vector layer.
Stores global configuration for labeling engine.
Layer tree group node serves as a container for layers and further groups.
QgsLayerTreeGroup * findGroup(const QString &name)
Find group node with specified name.
void readChildrenFromXml(const QDomElement &element, const QgsReadWriteContext &context)
Read children from XML and append them to the group.
QString name() const override
Returns the group's name.
void insertChildNodes(int index, const QList< QgsLayerTreeNode * > &nodes)
Insert existing nodes at specified position.
QgsLayerTreeGroup * clone() const override
Returns a clone of the group.
Layer tree node points to a map layer.
void resolveReferences(const QgsProject *project, bool looseMatching=false) override
Resolves reference to layer from stored layer ID (if it has not been resolved already).
Base class for nodes in a layer tree.
QList< QgsLayerTreeNode * > abandonChildren()
Removes the children, disconnect all the forwarded and external signals and sets their parent to null...
void setCustomProperty(const QString &key, const QVariant &value)
Sets a custom property for the node. Properties are stored in a map and saved in project file.
QList< QgsLayerTreeNode * > children()
Gets list of children of the node. Children are owned by the parent.
QVariant customProperty(const QString &key, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer. Properties are stored in a map and saved in project file.
void setItemVisibilityChecked(bool checked)
Check or uncheck a node (independently of its ancestors or children).
static void replaceChildrenOfEmbeddedGroups(QgsLayerTreeGroup *group)
Remove subtree of embedded groups and replaces it with a custom property embedded-visible-layers.
static void storeOriginalLayersProperties(QgsLayerTreeGroup *group, const QDomDocument *doc)
Stores in a layer's originalXmlProperties the layer properties information.
static void updateEmbeddedGroupsProjectPath(QgsLayerTreeGroup *group, const QgsProject *project)
Updates an embedded group from a project.
static bool readOldLegend(QgsLayerTreeGroup *root, const QDomElement &legendElem)
Try to load layer tree from.
Namespace with helper functions for layer tree operations.
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
static bool isLayer(const QgsLayerTreeNode *node)
Check whether the node is a valid layer node.
static bool isGroup(QgsLayerTreeNode *node)
Check whether the node is a valid group node.
static QgsLayerTreeGroup * toGroup(QgsLayerTreeNode *node)
Cast node to a group.
Manages storage of a set of layouts.
Stores information about one class/rule of a vector layer renderer in a unified way that can be used ...
static void warning(const QString &msg)
Goes to qWarning.
static Qgis::LayerType typeFromString(const QString &string, bool &ok)
Returns the map layer type corresponding a string value.
A storage object for map layers, in which the layers are owned by the store and have their lifetime b...
void layersWillBeRemoved(const QStringList &layerIds)
Emitted when one or more layers are about to be removed from the store.
void layerWillBeRemoved(const QString &layerId)
Emitted when a layer is about to be removed from the store.
void layersRemoved(const QStringList &layerIds)
Emitted after one or more layers were removed from the store.
void allLayersRemoved()
Emitted when all layers are removed, before layersWillBeRemoved() and layerWillBeRemoved() signals ar...
void layerRemoved(const QString &layerId)
Emitted after a layer was removed from the store.
void layerWasAdded(QgsMapLayer *layer)
Emitted when a layer was added to the store.
QgsMapLayer * mapLayer(const QString &id) const
Retrieve a pointer to a layer by layer id.
void layersAdded(const QList< QgsMapLayer * > &layers)
Emitted when one or more layers were added to the store.
Base class for all map layer types.
QFlags< ReadFlag > ReadFlags
QString source() const
Returns the source for the layer.
QString providerType() const
Returns the provider type (provider key) for this layer.
void configChanged()
Emitted whenever the configuration is changed.
static Qgis::DataProviderReadFlags providerReadFlags(const QDomNode &layerNode, QgsMapLayer::ReadFlags layerReadFlags)
Returns provider read flag deduced from layer read flags layerReadFlags and a dom node layerNode that...
QString originalXmlProperties() const
Returns the XML properties of the original layer as they were when the layer was first read from the ...
virtual bool isEditable() const
Returns true if the layer can be edited.
bool writeLayerXml(QDomElement &layerElement, QDomDocument &document, const QgsReadWriteContext &context) const
Stores state in DOM node.
@ Identifiable
If the layer is identifiable using the identify map tool and as a WMS layer.
@ Removable
If the layer can be removed from the project. The layer will not be removable from the legend menu en...
@ FlagReadExtentFromXml
Read extent from xml and skip get extent from provider.
@ FlagTrustLayerMetadata
Trust layer metadata. Improves layer load time by skipping expensive checks like primary key unicity,...
@ FlagForceReadOnly
Force open as read only.
@ FlagDontResolveLayers
Don't resolve layer paths or create data providers for layers.
Container class that allows storage of map themes consisting of visible map layers and layer styles.
Manages storage of a set of views.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
Adds a message to the log instance (and creates it if necessary).
An interface for classes which can visit various object entity (e.g.
virtual bool visitEmbeddedScript(const QgsEmbeddedScriptEntity &entity, const QgsObjectVisitorContext &context)
Called when the visitor will visit an embedded script entity.
A QgsObjectEntityVisitorInterface context object.
Resolves relative paths into absolute paths and vice versa.
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
Allows managing the zip/unzip actions on project files.
QString projectFile() const
Returns the current .qgs project file or an empty string if there's none.
bool unzip(const QString &zipFilename) override
Clear the current content of this archive and unzip.
Interface for classes that handle missing layer files when reading project files.
Contains settings and properties relating to how a QgsProject should display values such as map coord...
Contains elevation properties for a QgsProject.
Contains settings and properties relating to how a QgsProject should interact with a GPS device.
Project property key node.
QString name() const
The name of the property is used as identifier.
QgsProjectProperty * find(const QString &propertyName) const
Attempts to find a property with a matching sub-key name.
void removeKey(const QString &keyName)
Removes the specified key.
void dump(int tabs=0) const override
Dumps out the keys and values.
void subkeyList(QStringList &entries) const
Returns any sub-keys contained by this property which themselves contain other keys.
QgsProjectPropertyKey * addKey(const QString &keyName)
Adds the specified property key as a sub-key.
QVariant value() const override
If this key has a value, it will be stored by its name in its properties.
QgsProjectPropertyValue * setValue(const QString &name, const QVariant &value)
Sets the value associated with this key.
void entryList(QStringList &entries) const
Returns any sub-keys contained by this property that do not contain other keys.
bool readXml(const QDomNode &keyNode) override
Restores the property hierarchy from a specified DOM node.
An abstract base class for QGIS project property hierarchys.
virtual bool isKey() const =0
Returns true if the property is a QgsProjectPropertyKey.
virtual bool isValue() const =0
Returns true if the property is a QgsProjectPropertyValue.
QgsProjectStorage * projectStorageFromUri(const QString &uri)
Returns storage implementation if the URI matches one. Returns nullptr otherwise (it is a normal file...
Abstract interface for project storage - to be implemented by various backends and registered in QgsP...
Contains settings and properties relating to how a QgsProject should handle styling.
void setDefaultSymbol(Qgis::SymbolType symbolType, QgsSymbol *symbol)
Sets the project default symbol for a given type.
void setRandomizeDefaultSymbolColor(bool randomized)
Sets whether the default symbol fill color is randomized.
void setDefaultColorRamp(QgsColorRamp *colorRamp)
Sets the project default color ramp.
void setDefaultSymbolOpacity(double opacity)
Sets the default symbol opacity.
Contains temporal settings and properties for the project, this may be used when animating maps or sh...
static Qgis::ProjectTrustStatus checkUserTrust(QgsProject *project)
Returns the current trust status of the specified project.
Describes the version of a project.
QString text() const
Returns a string representation of the version.
int majorVersion() const
Returns the major version number.
Contains settings and properties relating to how a QgsProject should be displayed inside map canvas,...
void mapScalesChanged()
Emitted when the list of custom project map scales changes.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
bool isZipped() const
Returns true if the project comes from a zip archive, false otherwise.
bool removeAttachedFile(const QString &path)
Removes the attached file.
QgsRelationManager * relationManager
bool write()
Writes the project to its current associated file (see fileName() ).
QgsProject(QObject *parent=nullptr, Qgis::ProjectCapabilities capabilities=Qgis::ProjectCapability::ProjectStyles)
Create a new QgsProject.
void removeMapLayer(const QString &layerId)
Remove a layer from the registry by layer ID.
Q_DECL_DEPRECATED void oldProjectVersionWarning(const QString &warning)
Emitted when an old project file is read.
Q_DECL_DEPRECATED bool evaluateDefaultValues() const
Should default values be evaluated on provider side when requested and not when committed.
Qgis::DistanceUnit distanceUnits
void layersAddedWithoutLegend(const QList< QgsMapLayer * > &layers)
Emitted when layers were added to the registry without adding to the legend.
void layersRemoved(const QStringList &layerIds)
Emitted after one or more layers were removed from the registry.
void clear()
Clears the project, removing all settings and resetting it back to an empty, default state.
QString error() const
Returns error message from previous read/write.
Q_DECL_DEPRECATED void setUseProjectScales(bool enabled)
Sets whether project mapScales() are enabled.
void readProjectWithContext(const QDomDocument &document, QgsReadWriteContext &context)
Emitted when a project is being read.
int readNumEntry(const QString &scope, const QString &key, int def=0, bool *ok=nullptr) const
Reads an integer from the specified scope and key.
Q_DECL_DEPRECATED void setNonIdentifiableLayers(const QList< QgsMapLayer * > &layers)
Set a list of layers which should not be taken into account on map identification.
QList< QgsMapLayer * > addMapLayers(const QList< QgsMapLayer * > &mapLayers, bool addToLegend=true, bool takeOwnership=true)
Add a list of layers to the map of loaded layers.
Qgis::ProjectFlags flags() const
Returns the project's flags, which dictate the behavior of the project.
Q_DECL_DEPRECATED QFileInfo fileInfo() const
Returns QFileInfo object for the project's associated file.
QString presetHomePath() const
Returns any manual project home path setting, or an empty string if not set.
void setBackgroundColor(const QColor &color)
Sets the default background color used by default map canvases.
void setCrs(const QgsCoordinateReferenceSystem &crs, bool adjustEllipsoid=false)
Sets the project's native coordinate reference system.
bool commitChanges(QStringList &commitErrors, bool stopEditing=true, QgsVectorLayer *vectorLayer=nullptr)
Attempts to commit to the underlying data provider any buffered changes made since the last to call t...
void mapThemeCollectionChanged()
Emitted when the map theme collection changes.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Qgis::FilePathType filePathStorage() const
Returns the type of paths used when storing file paths in a QGS/QGZ project file.
QString createAttachedFile(const QString &nameTemplate)
Attaches a file to the project.
Q_DECL_DEPRECATED void mapScalesChanged()
Emitted when the list of custom project map scales changes.
void readVersionMismatchOccurred(const QString &fileVersion)
Emitted when a project is read and the version of QGIS used to save the project differs from the curr...
void fileNameChanged()
Emitted when the file name of the project changes.
void titleChanged()
Emitted when the title of the project changes.
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
void writeMapLayer(QgsMapLayer *mapLayer, QDomElement &layerElem, QDomDocument &doc)
Emitted when a layer is being saved.
const QgsSensorManager * sensorManager() const
Returns the project's sensor manager, which manages sensors within the project.
void setSnappingConfig(const QgsSnappingConfig &snappingConfig)
The snapping configuration for this project.
void areaUnitsChanged()
Emitted when the default area units changes.
QgsPropertyCollection dataDefinedServerProperties() const
Returns the data defined properties used for overrides in user defined server parameters.
Q_DECL_DEPRECATED void nonIdentifiableLayersChanged(QStringList nonIdentifiableLayers)
Emitted when the list of layer which are excluded from map identification changes.
void layersWillBeRemoved(const QStringList &layerIds)
Emitted when one or more layers are about to be removed from the registry.
QString attachmentIdentifier(const QString &attachedFile) const
Returns an identifier for an attachment file path An attachment identifier is a string which does not...
void setScaleMethod(Qgis::ScaleCalculationMethod method)
Sets the method to use for map scale calculations for the project.
QgsVectorLayerEditBufferGroup * editBufferGroup()
Returns the edit buffer group.
void setSelectionColor(const QColor &color)
Sets the color used to highlight selected features.
bool rollBack(QStringList &rollbackErrors, bool stopEditing=true, QgsVectorLayer *vectorLayer=nullptr)
Stops a current editing operation on vectorLayer and discards any uncommitted edits.
void snappingConfigChanged(const QgsSnappingConfig &config)
Emitted whenever the configuration for snapping has changed.
QgsPathResolver pathResolver() const
Returns path resolver object with considering whether the project uses absolute or relative paths and...
void setBadLayerHandler(QgsProjectBadLayerHandler *handler)
Change handler for missing layers.
Q_DECL_DEPRECATED void setEvaluateDefaultValues(bool evaluateDefaultValues)
Defines if default values should be evaluated on provider side when requested and not when committed.
void crsChanged()
Emitted when the crs() of the project has changed.
QString translate(const QString &context, const QString &sourceText, const char *disambiguation=nullptr, int n=-1) const override
Translates a string using the Qt QTranslator mechanism.
const QgsProjectStyleSettings * styleSettings() const
Returns the project's style settings, which contains settings and properties relating to how a QgsPro...
QgsSnappingConfig snappingConfig
const QgsProjectGpsSettings * gpsSettings() const
Returns the project's GPS settings, which contains settings and properties relating to how a QgsProje...
void setFileName(const QString &name)
Sets the file name associated with the project.
void avoidIntersectionsLayersChanged()
Emitted whenever avoidIntersectionsLayers has changed.
void setDataDefinedServerProperties(const QgsPropertyCollection &properties)
Sets the data defined properties used for overrides in user defined server parameters to properties.
void registerTranslatableObjects(QgsTranslationContext *translationContext)
Registers the objects that require translation into the translationContext.
void distanceUnitsChanged()
Emitted when the default distance units changes.
QgsAnnotationLayer * mainAnnotationLayer()
Returns the main annotation layer associated with the project.
const QgsBookmarkManager * bookmarkManager() const
Returns the project's bookmark manager, which manages bookmarks within the project.
void readMapLayer(QgsMapLayer *mapLayer, const QDomElement &layerNode)
Emitted after the basic initialization of a layer from the project file is done.
std::unique_ptr< QgsLayerTreeGroup > createEmbeddedGroup(const QString &groupName, const QString &projectFilePath, const QStringList &invisibleLayers, Qgis::ProjectReadFlags flags=Qgis::ProjectReadFlags())
Create layer group instance defined in an arbitrary project file.
Q_DECL_DEPRECATED void setAutoTransaction(bool autoTransaction)
Transactional editing means that on supported datasources (postgres databases) the edit state of all ...
@ WMSOnlineResource
Alias.
bool startEditing(QgsVectorLayer *vectorLayer=nullptr)
Makes the layer editable.
void aboutToBeCleared()
Emitted when the project is about to be cleared.
Q_DECL_DEPRECATED void setTrustLayerMetadata(bool trust)
Sets the trust option allowing to indicate if the extent has to be read from the XML document when da...
void cleared()
Emitted when the project is cleared (and additionally when an open project is cleared just before a n...
bool setVerticalCrs(const QgsCoordinateReferenceSystem &crs, QString *errorMessage=nullptr)
Sets the project's vertical coordinate reference system.
void setLabelingEngineSettings(const QgsLabelingEngineSettings &settings)
Sets project's global labeling engine settings.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
void metadataChanged()
Emitted when the project's metadata is changed.
QString resolveAttachmentIdentifier(const QString &identifier) const
Resolves an attachment identifier to a attachment file path.
const QgsProjectElevationProperties * elevationProperties() const
Returns the project's elevation properties, which contains the project's elevation related settings.
QString absolutePath() const
Returns full absolute path to the project folder if the project is stored in a file system - derived ...
void crs3DChanged()
Emitted when the crs3D() of the project has changed.
void scaleMethodChanged()
Emitted when the project's scale method is changed.
void removeMapLayers(const QStringList &layerIds)
Remove a set of layers from the registry by layer ID.
Q_DECL_DEPRECATED void setRequiredLayers(const QSet< QgsMapLayer * > &layers)
Configures a set of map layers that are required in the project and therefore they should not get rem...
bool createEmbeddedLayer(const QString &layerId, const QString &projectFilePath, QList< QDomNode > &brokenNodes, bool saveFlag=true, Qgis::ProjectReadFlags flags=Qgis::ProjectReadFlags())
Creates a maplayer instance defined in an arbitrary project file.
QList< QgsVectorLayer * > avoidIntersectionsLayers
QString readEntry(const QString &scope, const QString &key, const QString &def=QString(), bool *ok=nullptr) const
Reads a string from the specified scope and key.
QgsExpressionContextScope * createExpressionContextScope() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
QString baseName() const
Returns the base name of the project file without the path and without extension - derived from fileN...
void ellipsoidChanged(const QString &ellipsoid)
Emitted when the project ellipsoid is changed.
QgsMapThemeCollection * mapThemeCollection
void generateTsFile(const QString &locale)
Triggers the collection strings of .qgs to be included in ts file and calls writeTsFile().
QStringList entryList(const QString &scope, const QString &key) const
Returns a list of child keys with values which exist within the specified scope and key.
Qgis::TransactionMode transactionMode
QgsAnnotationManager * annotationManager()
Returns pointer to the project's annotation manager.
QgsProjectDisplaySettings * displaySettings
QgsProjectMetadata metadata
void projectColorsChanged()
Emitted whenever the project's color scheme has been changed.
QString saveUser() const
Returns the user name that did the last save.
QVector< T > layers() const
Returns a list of registered map layers with a specified layer type.
void setProjectColors(const QgsNamedColorList &colors)
Sets the colors for the project's color scheme (see QgsProjectColorScheme).
bool setTransactionMode(Qgis::TransactionMode transactionMode)
Set transaction mode.
QgsCoordinateTransformContext transformContext
void transactionModeChanged()
Emitted when the transaction mode has changed.
void labelingEngineSettingsChanged()
Emitted when global configuration of the labeling engine changes.
void customVariablesChanged()
Emitted whenever the expression variables stored in the project have been changed.
QgsLayerTree * layerTreeRoot() const
Returns pointer to the root (invisible) node of the project's layer tree.
bool readBoolEntry(const QString &scope, const QString &key, bool def=false, bool *ok=nullptr) const
Reads a boolean from the specified scope and key.
QgsMapLayerStore * layerStore()
Returns a pointer to the project's internal layer store.
QString originalPath() const
Returns the original path associated with the project.
void setOriginalPath(const QString &path)
Sets the original path associated with the project.
void dumpProperties() const
Dump out current project properties to stderr.
QgsElevationShadingRenderer elevationShadingRenderer() const
Returns the elevation shading renderer used for map shading.
const QgsMapViewsManager * viewsManager() const
Returns the project's views manager, which manages map views (including 3d maps) in the project.
static void setInstance(QgsProject *project)
Set the current project singleton instance to project.
int validCount() const
Returns the number of registered valid layers.
const QgsLayoutManager * layoutManager() const
Returns the project's layout manager, which manages print layouts, atlases and reports within the pro...
void elevationShadingRendererChanged()
Emitted when the map shading renderer changes.
Q_INVOKABLE QList< QgsMapLayer * > mapLayersByName(const QString &layerName) const
Retrieve a list of matching registered layers by layer name.
QgsCoordinateReferenceSystem crs3D() const
Returns the CRS to use for the project when transforming 3D data, or when z/elevation value handling ...
Q_DECL_DEPRECATED bool autoTransaction() const
Transactional editing means that on supported datasources (postgres databases) the edit state of all ...
bool accept(QgsStyleEntityVisitorInterface *visitor) const
Accepts the specified style entity visitor, causing it to visit all style entities associated with th...
QStringList attachedFiles() const
Returns a map of all attached files with identifier and real paths.
void setMetadata(const QgsProjectMetadata &metadata)
Sets the project's metadata store.
void missingDatumTransforms(const QStringList &missingTransforms)
Emitted when datum transforms stored in the project are not available locally.
QgsTransactionGroup * transactionGroup(const QString &providerKey, const QString &connString)
Returns the matching transaction group from a provider key and connection string.
QgsCoordinateReferenceSystem crs
QgsMapLayer * addMapLayer(QgsMapLayer *mapLayer, bool addToLegend=true, bool takeOwnership=true)
Add a layer to the map of loaded layers.
QStringList nonIdentifiableLayers
void setAvoidIntersectionsMode(const Qgis::AvoidIntersectionsMode mode)
Sets the avoid intersections mode.
void transactionGroupsChanged()
Emitted whenever a new transaction group has been created or a transaction group has been removed.
const QgsAuxiliaryStorage * auxiliaryStorage() const
Returns the current const auxiliary storage.
void reloadAllLayers()
Reload all registered layer's provider data caches, synchronising the layer with any changes in the d...
int count() const
Returns the number of registered layers.
void loadingLayerMessageReceived(const QString &layerName, const QList< QgsReadWriteContext::ReadWriteMessage > &messages)
Emitted when loading layers has produced some messages.
void setAreaUnits(Qgis::AreaUnit unit)
Sets the default area measurement units for the project.
void setTitle(const QString &title)
Sets the project's title.
QMap< QPair< QString, QString >, QgsTransactionGroup * > transactionGroups()
Map of transaction groups.
void setFlag(Qgis::ProjectFlag flag, bool enabled=true)
Sets whether a project flag is enabled.
QDateTime lastModified() const
Returns last modified time of the project file as returned by the file system (or other project stora...
static const QgsSettingsEntryBool * settingsAnonymizeSavedProjects
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.
static const QgsSettingsEntryBool * settingsAnonymizeNewProjects
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.
static const QgsSettingsEntryBool * settingsDefaultProjectPathsRelative
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.
A boolean settings entry.
static const QgsSettingsEntryColor * settingsDefaultCanvasColor
Settings entry for default canvas background color.
static const QgsSettingsEntryEnumFlag< Qgis::UnknownLayerCrsBehavior > * settingsUnknownCrsBehavior
Settings entry for behavior when encountering a layer with an unknown CRS (NoAction,...
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.
static const QgsSettingsEntryString * settingsMeasureAreaUnits
Settings entry for area display units.
static const QgsSettingsEntryColor * settingsDefaultSelectionColor
Settings entry for default selection color.
static const QgsSettingsEntryString * settingsLayerDefaultCrs
Settings entry for the default CRS used for layers with unknown CRS.
static const QgsSettingsEntryString * settingsMeasureDisplayUnits
Settings entry for distance display units.
static QgsSettingsTreeNode * sTreeProject
static QgsSettingsTreeNode * sTreeCore
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.
static QString threadDescription(QThread *thread)
Returns a descriptive identifier for a thread.
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.