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();
694 translationContext->
registerTranslation( u
"project:layers:%1:fieldaliases"_s.arg( vlayer->
id() ), fieldName );
696 if ( !field.customComment().isEmpty() )
698 translationContext->
registerTranslation( u
"project:layers:%1:fieldcustomcomments"_s.arg( vlayer->
id() ), field.customComment() );
701 if ( !field.constraints().constraintDescription().isEmpty() )
702 translationContext->
registerTranslation( u
"project:layers:%1:constraintdescriptions"_s.arg( vlayer->
id() ), field.constraints().constraintDescription() );
706 if ( field.editorWidgetSetup().type() ==
"ValueRelation"_L1 )
708 translationContext->
registerTranslation( u
"project:layers:%1:fields:%2:valuerelationvalue"_s.arg( vlayer->
id(), field.name() ), field.editorWidgetSetup().config().value( u
"Value"_s ).toString() );
710 ->
registerTranslation( u
"project:layers:%1:fields:%2:valuerelationdescription"_s.arg( vlayer->
id(), field.name() ), field.editorWidgetSetup().config().value( u
"Description"_s ).toString() );
714 if ( field.editorWidgetSetup().type() ==
"ValueMap"_L1 )
716 if ( field.editorWidgetSetup().config().value( u
"map"_s ).canConvert<QList<QVariant>>() )
718 const QList<QVariant> valueList = field.editorWidgetSetup().config().value( u
"map"_s ).toList();
720 for (
int i = 0; i < valueList.count(); i++ )
722 translationContext->
registerTranslation( u
"project:layers:%1:fields:%2:valuemapdescriptions"_s.arg( vlayer->
id(), field.name() ), valueList[i].toMap().constBegin().key() );
734 translationContext->
registerTranslation( u
"project:layers:%1:actiondescriptions"_s.arg( vlayer->
id() ), action.name() );
735 translationContext->
registerTranslation( u
"project:layers:%1:actionshorttitles"_s.arg( vlayer->
id() ), action.shortTitle() );
743 translationContext->
registerTranslation( u
"project:layers:%1:legendsymbollabels"_s.arg( vlayer->
id() ), item.label() );
761 mapLayer->metadata().registerTranslations( translationContext );
766 const QList<QgsLayerTreeGroup *> groupLayers = mRootGroup->findGroups(
true );
773 const QList<QgsRelation> &relations = mRelationManager->relations().values();
780 mMetadata.registerTranslations( translationContext );
787 mDataDefinedServerProperties = properties;
794 return mDataDefinedServerProperties;
801 switch ( mTransactionMode )
812 return mEditBufferGroup.startEditing();
822 switch ( mTransactionMode )
829 commitErrors.append( tr(
"Trying to commit changes without a layer specified. This only works if the transaction mode is buffered" ) );
838 return mEditBufferGroup.commitChanges( commitErrors, stopEditing );
848 switch ( mTransactionMode )
855 rollbackErrors.append( tr(
"Trying to roll back changes without a layer specified. This only works if the transaction mode is buffered" ) );
858 bool success = vectorLayer->
rollBack( stopEditing );
864 return mEditBufferGroup.rollBack( rollbackErrors, stopEditing );
874 if ( name == mFile.fileName() )
877 const QString oldHomePath =
homePath();
879 mFile.setFileName( name );
880 mCachedHomePath.clear();
881 mProjectScope.reset();
885 const QString newHomePath =
homePath();
886 if ( newHomePath != oldHomePath )
897 return mFile.fileName();
904 mOriginalPath = path;
911 return mOriginalPath;
918 return QFileInfo( mFile );
936 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
941 return QFileInfo( mFile.fileName() ).lastModified();
952 if ( mFile.fileName().isEmpty() )
955 return QFileInfo( mFile.fileName() ).absolutePath();
966 if ( mFile.fileName().isEmpty() )
969 return QFileInfo( mFile.fileName() ).absoluteFilePath();
980 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
985 return QFileInfo( mFile.fileName() ).completeBaseName();
993 const bool absolutePaths =
readBoolEntry( u
"Paths"_s, u
"/Absolute"_s,
false );
1004 writeEntry( u
"Paths"_s, u
"/Absolute"_s,
true );
1007 writeEntry( u
"Paths"_s, u
"/Absolute"_s,
false );
1024 return mCrs3D.isValid() ? mCrs3D : mCrs;
1038 if ( adjustEllipsoid && !mCrs.isSameCelestialBody(
crs ) )
1040 mBlockEllipsoidChangedSignal =
true;
1042 mBlockEllipsoidChangedSignal =
false;
1049 writeEntry( u
"SpatialRefSys"_s, u
"/ProjectionsEnabled"_s,
crs.isValid() ? 1 : 0 );
1050 mProjectScope.reset();
1054 if ( !mMainAnnotationLayer->crs().isValid() || mMainAnnotationLayer->isEmpty() )
1055 mMainAnnotationLayer->setCrs(
crs );
1064 if ( oldCrs3D != mCrs3D )
1068 if ( adjustEllipsoid )
1077 if ( !
crs().isValid() )
1090 mProjectScope.reset();
1093 if ( !mBlockEllipsoidChangedSignal )
1102 switch ( mCrs.type() )
1105 QgsDebugError( u
"Project has a vertical CRS set as the horizontal CRS!"_s );
1109 return mCrs.verticalCrs();
1124 return mVerticalCrs;
1131 if (
crs.isValid() )
1134 switch (
crs.type() )
1152 *errorMessage = QObject::tr(
"Specified CRS is a %1 CRS, not a Vertical CRS" ).arg(
qgsEnumValueToKey(
crs.type() ) );
1157 if (
crs != mVerticalCrs )
1162 switch ( mCrs.type() )
1165 if (
crs != oldVerticalCrs )
1168 *errorMessage = QObject::tr(
"Project CRS is a Compound CRS, specified Vertical CRS will be ignored" );
1174 if (
crs != oldVerticalCrs )
1177 *errorMessage = QObject::tr(
"Project CRS is a Geographic 3D CRS, specified Vertical CRS will be ignored" );
1183 if (
crs != oldVerticalCrs )
1186 *errorMessage = QObject::tr(
"Project CRS is a Geocentric CRS, specified Vertical CRS will be ignored" );
1192 if ( mCrs.hasVerticalAxis() &&
crs != oldVerticalCrs )
1195 *errorMessage = QObject::tr(
"Project CRS is a Projected 3D CRS, specified Vertical CRS will be ignored" );
1213 res = rebuildCrs3D( errorMessage );
1214 mProjectScope.reset();
1221 if ( mCrs3D != oldCrs3D )
1232 return mTransformContext;
1239 if ( context == mTransformContext )
1242 mTransformContext = context;
1243 mProjectScope.reset();
1245 mMainAnnotationLayer->setTransformContext( context );
1246 for (
auto &layer : mLayerStore.get()->mapLayers() )
1248 layer->setTransformContext( context );
1257 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
1261 if ( !mIsBeingDeleted )
1270 mProjectScope.reset();
1271 mFile.setFileName( QString() );
1272 mProperties.clearKeys();
1274 mSaveUserFull.clear();
1275 mSaveDateTime = QDateTime();
1278 mCachedHomePath.clear();
1282 mCustomVariables.clear();
1290 mMetadata.setCreationDateTime( QDateTime::currentDateTime() );
1309 mEmbeddedLayers.clear();
1310 mRelationManager->clear();
1311 mAnnotationManager->clear();
1312 mLayoutManager->clear();
1313 mElevationProfileManager->clear();
1314 mSelectiveMaskingSourceSetManager->clear();
1315 m3DViewsManager->clear();
1316 mBookmarkManager->clear();
1317 mSensorManager->clear();
1318 mViewSettings->reset();
1319 mTimeSettings->reset();
1320 mElevationProperties->reset();
1321 mDisplaySettings->reset();
1322 mGpsSettings->reset();
1323 mSnappingConfig.reset();
1328 mMapThemeCollection = std::make_unique< QgsMapThemeCollection >(
this );
1331 mLabelingEngineSettings->clear();
1335 releaseHandlesToProjectArchive();
1337 mAuxiliaryStorage = std::make_unique< QgsAuxiliaryStorage >();
1338 mArchive = std::make_unique< QgsArchive >();
1341 mStyleSettings->reset();
1345 if ( !mIsBeingDeleted )
1353 writeEntry( u
"PositionPrecision"_s, u
"/Automatic"_s,
true );
1354 writeEntry( u
"PositionPrecision"_s, u
"/DecimalPlaces"_s, 2 );
1363 mSnappingConfig.clearIndividualLayerSettings();
1366 mRootGroup->clear();
1367 if ( mMainAnnotationLayer )
1368 mMainAnnotationLayer->reset();
1370 snapSingleBlocker.release();
1372 if ( !mBlockSnappingUpdates )
1378 if ( !mBlockChangeSignalsDuringClear )
1390 topQgsPropertyKey.
dump();
1423 const QDomElement propertiesElem = doc.documentElement().firstChildElement( u
"properties"_s );
1425 if ( propertiesElem.isNull() )
1430 const QDomNodeList scopes = propertiesElem.childNodes();
1432 if ( propertiesElem.firstChild().isNull() )
1434 QgsDebugError( u
"empty ``properties'' XML tag ... bailing"_s );
1438 if ( !project_properties.
readXml( propertiesElem ) )
1454 const QDomElement ddElem = doc.documentElement().firstChildElement( u
"dataDefinedServerProperties"_s );
1455 if ( !ddElem.isNull() )
1457 if ( !ddServerProperties.
readXml( ddElem, dataDefinedServerPropertyDefinitions ) )
1459 QgsDebugError( u
"dataDefinedServerProperties.readXml() failed"_s );
1462 return ddServerProperties;
1469static void _getTitle(
const QDomDocument &doc, QString &title )
1471 const QDomElement titleNode = doc.documentElement().firstChildElement( u
"title"_s );
1475 if ( titleNode.isNull() )
1481 if ( !titleNode.hasChildNodes() )
1487 const QDomNode titleTextNode = titleNode.firstChild();
1489 if ( !titleTextNode.isText() )
1495 const QDomText titleText = titleTextNode.toText();
1497 title = titleText.data();
1500static void readProjectFileMetadata(
const QDomDocument &doc, QString &lastUser, QString &lastUserFull, QDateTime &lastSaveDateTime )
1502 const QDomNodeList nl = doc.elementsByTagName( u
"qgis"_s );
1510 const QDomNode qgisNode = nl.item( 0 );
1512 const QDomElement qgisElement = qgisNode.toElement();
1513 lastUser = qgisElement.attribute( u
"saveUser"_s, QString() );
1514 lastUserFull = qgisElement.attribute( u
"saveUserFull"_s, QString() );
1515 lastSaveDateTime = QDateTime::fromString( qgisElement.attribute( u
"saveDateTime"_s, QString() ), Qt::ISODate );
1520 const QDomNodeList nl = doc.elementsByTagName( u
"qgis"_s );
1524 QgsDebugError( u
" unable to find qgis element in project file"_s );
1528 const QDomNode qgisNode = nl.item( 0 );
1530 const QDomElement qgisElement = qgisNode.toElement();
1532 return projectVersion;
1539 return mSnappingConfig;
1558 if ( mAvoidIntersectionsMode == mode )
1561 mAvoidIntersectionsMode = mode;
1595void QgsProject::preloadProviders(
1602 QMap<QString, LayerToLoad> layersToLoad;
1604 for (
const QDomNode &node : parallelLayerNodes )
1608 const QDomElement layerElement = node.toElement();
1610 layerToLoad.
layerId = layerElement.namedItem( u
"id"_s ).toElement().text();
1611 layerToLoad.
provider = layerElement.namedItem( u
"provider"_s ).toElement().text();
1612 layerToLoad.
dataSource = layerElement.namedItem( u
"datasource"_s ).toElement().text();
1623 layersToLoad.insert( layerToLoad.
layerId, layerToLoad );
1626 while ( !layersToLoad.isEmpty() )
1628 const QList<LayerToLoad> layersToAttemptInParallel = layersToLoad.values();
1629 QString layerToAttemptInMainThread;
1631 QHash<QString, QgsRunnableProviderCreator *> runnables;
1632 QThreadPool threadPool;
1635 for (
const LayerToLoad &lay : layersToAttemptInParallel )
1637 QgsRunnableProviderCreator *run =
new QgsRunnableProviderCreator( lay.layerId, lay.provider, lay.dataSource, lay.options, lay.flags );
1638 runnables.insert( lay.layerId, run );
1643 layersToLoad.remove( layId );
1645 QgsRunnableProviderCreator *finishedRun = runnables.value( layId,
nullptr );
1646 Q_ASSERT( finishedRun );
1648 std::unique_ptr<QgsDataProvider> provider( finishedRun->
dataProvider() );
1649 Q_ASSERT( provider && provider->isValid() );
1651 provider->moveToThread( QThread::currentThread() );
1654 loadedProviders.insert( layId, provider.release() );
1659 if ( layerToAttemptInMainThread.isEmpty() )
1660 layerToAttemptInMainThread = layId;
1664 if ( i == parallelLayerNodes.count() || !isValid )
1667 threadPool.start( run );
1671 threadPool.waitForDone();
1673 qDeleteAll( runnables );
1676 auto it = layersToLoad.find( layerToAttemptInMainThread );
1677 if ( it != layersToLoad.end() )
1679 std::unique_ptr<QgsDataProvider> provider;
1682 const LayerToLoad &lay = it.value();
1686 QgsScopedRuntimeProfile profile(
"Create data providers/" + lay.
layerId, u
"projectload"_s );
1689 if ( provider && provider->isValid() )
1694 layersToLoad.erase( it );
1697 loadedProviders.insert( layerId, provider.release() );
1704void QgsProject::releaseHandlesToProjectArchive()
1706 mStyleSettings->removeProjectStyle();
1709bool QgsProject::rebuildCrs3D( QString *error )
1712 if ( !mCrs.isValid() )
1714 mCrs3D = QgsCoordinateReferenceSystem();
1716 else if ( !mVerticalCrs.isValid() )
1722 switch ( mCrs.type() )
1734 res = mCrs3D.isValid();
1740 mCrs3D = QgsCoordinateReferenceSystem();
1755 res = mCrs3D.isValid();
1763bool QgsProject::_getMapLayers(
const QDomDocument &doc, QList<QDomNode> &brokenNodes,
Qgis::ProjectReadFlags flags )
1770 QDomElement layerElement = doc.documentElement().firstChildElement( u
"projectlayers"_s ).firstChildElement( u
"maplayer"_s );
1774 if ( layerElement.isNull() )
1784 bool returnStatus =
true;
1787 while ( !layerElement.isNull() )
1790 layerElement = layerElement.nextSiblingElement( u
"maplayer"_s );
1794 QgsScopedRuntimeProfile profile( tr(
"Sorting layers" ), u
"projectload"_s );
1795 const QgsLayerDefinition::DependencySorter depSorter( doc );
1796 if ( depSorter.hasCycle() )
1800 if ( depSorter.hasMissingDependency() )
1801 returnStatus =
false;
1805 const QVector<QDomNode> sortedLayerNodes = depSorter.sortedLayerNodes();
1806 const int totalLayerCount = sortedLayerNodes.count();
1808 QVector<QDomNode> parallelLoading;
1809 QMap<QString, QgsDataProvider *> loadedProviders;
1813 profile.switchTask( tr(
"Load providers in parallel" ) );
1814 for (
const QDomNode &node : sortedLayerNodes )
1816 const QDomElement element = node.toElement();
1817 if ( element.attribute( u
"embedded"_s ) !=
"1"_L1 )
1819 const QString layerId = node.namedItem( u
"id"_s ).toElement().text();
1820 if ( !depSorter.isLayerDependent( layerId ) )
1822 const QDomNode mnl = element.namedItem( u
"provider"_s );
1823 const QDomElement mne = mnl.toElement();
1824 const QString provider = mne.text();
1828 parallelLoading.append( node );
1835 QgsReadWriteContext context;
1837 if ( !parallelLoading.isEmpty() )
1838 preloadProviders( parallelLoading, context, loadedProviders, projectFlagsToLayerReadFlags(
flags, mFlags ), sortedLayerNodes.count() );
1841 int i = loadedProviders.count();
1842 for (
const QDomNode &node : std::as_const( sortedLayerNodes ) )
1844 const QDomElement element = node.toElement();
1845 const QString name =
translate( u
"project:layers:%1"_s.arg( node.namedItem( u
"id"_s ).toElement().text() ), node.namedItem( u
"layername"_s ).toElement().text() );
1846 if ( !name.isNull() )
1847 emit
loadingLayer( tr(
"Loading layer %1" ).arg( name ) );
1849 profile.switchTask( name );
1850 if ( element.attribute( u
"embedded"_s ) ==
"1"_L1 )
1856 QgsReadWriteContext context;
1860 QString layerId = element.namedItem( u
"id"_s ).toElement().text();
1862 if ( !addLayer( element, brokenNodes, context,
flags, loadedProviders.take( layerId ) ) )
1864 returnStatus =
false;
1867 if ( !messages.isEmpty() )
1876 return returnStatus;
1883 const QString type = layerElem.attribute( u
"type"_s );
1885 std::unique_ptr<QgsMapLayer>
mapLayer;
1887 QgsScopedRuntimeProfile profile( tr(
"Create layer" ), u
"projectload"_s );
1893 QgsDebugError( u
"Unknown layer type \"%1\""_s.arg( type ) );
1897 switch ( layerType )
1900 mapLayer = std::make_unique<QgsVectorLayer>();
1904 mapLayer = std::make_unique<QgsRasterLayer>();
1908 mapLayer = std::make_unique<QgsMeshLayer>();
1912 mapLayer = std::make_unique<QgsVectorTileLayer>();
1916 mapLayer = std::make_unique<QgsPointCloudLayer>();
1920 mapLayer = std::make_unique<QgsTiledSceneLayer>();
1925 const QString typeName = layerElem.attribute( u
"name"_s );
1932 const QgsAnnotationLayer::LayerOptions options( mTransformContext );
1933 mapLayer = std::make_unique<QgsAnnotationLayer>( QString(), options );
1939 const QgsGroupLayer::LayerOptions options( mTransformContext );
1940 mapLayer = std::make_unique<QgsGroupLayer>( QString(), options );
1955 const QString layerId { layerElem.namedItem( u
"id"_s ).toElement().text() };
1956 Q_ASSERT( !layerId.isEmpty() );
1962 profile.switchTask( tr(
"Load layer source" ) );
1963 const bool layerIsValid =
mapLayer->readLayerXml( layerElem, context, layerFlags, provider ) &&
mapLayer->isValid();
1966 if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>(
mapLayer.get() ) )
1969 if ( vl->dataProvider() )
1976 profile.switchTask( tr(
"Add layer to project" ) );
1977 QList<QgsMapLayer *> newLayers;
1987 if ( QgsVectorLayer *vLayer = qobject_cast<QgsVectorLayer *>(
mapLayer.get() ) )
1989 vLayer->joinBuffer()->resolveReferences(
this );
1998 brokenNodes.push_back( layerElem );
2001 const bool wasEditable = layerElem.attribute( u
"editable"_s, u
"0"_s ).toInt();
2004 mapLayer->setCustomProperty( u
"_layer_was_editable"_s,
true );
2008 mapLayer->removeCustomProperty( u
"_layer_was_editable"_s );
2013 if ( !layerWasStored )
2018 return layerIsValid;
2025 mFile.setFileName( filename );
2026 mCachedHomePath.clear();
2027 mProjectScope.reset();
2036 const QString filename = mFile.fileName();
2041 QTemporaryFile inDevice;
2042 if ( !inDevice.open() )
2044 setError( tr(
"Unable to open %1" ).arg( inDevice.fileName() ) );
2050 if ( !storage->readProject( filename, &inDevice, context ) )
2052 QString err = tr(
"Unable to open %1" ).arg( filename );
2053 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
2054 if ( !messages.isEmpty() )
2055 err += u
"\n\n"_s + messages.last().message();
2059 returnValue = unzip( inDevice.fileName(),
flags );
2065 returnValue = unzip( mFile.fileName(),
flags );
2069 mAuxiliaryStorage = std::make_unique< QgsAuxiliaryStorage >( *
this );
2070 const QFileInfo finfo( mFile.fileName() );
2071 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( u
"%1_attachments.zip"_s.arg( finfo.completeBaseName() ) );
2072 if ( QFile( attachmentsZip ).exists() )
2074 auto archive = std::make_unique<QgsArchive>();
2075 if ( archive->unzip( attachmentsZip ) )
2077 releaseHandlesToProjectArchive();
2078 mArchive = std::move( archive );
2081 returnValue = readProjectFile( mFile.fileName(),
flags );
2087 mFile.setFileName( filename );
2088 mCachedHomePath.clear();
2089 mProjectScope.reset();
2094 mTranslator.reset(
nullptr );
2107 ScopedIntIncrementor snapSignalBlock( &mBlockSnappingUpdates );
2109 QFile projectFile( filename );
2116 const QString projectBaseName = QFileInfo( mFile ).baseName();
2117 const QString projectDir = QFileInfo( mFile ).absolutePath();
2118 QString localeFileName = u
"%1_%2"_s.arg( projectBaseName, locale );
2120 if ( !QFile( u
"%1/%2.qm"_s.arg( projectDir, localeFileName ) ).exists() && locale.contains(
'_' ) )
2123 localeFileName = u
"%1_%2"_s.arg( projectBaseName, locale.left( locale.indexOf(
'_' ) ) );
2126 if ( QFile( u
"%1/%2.qm"_s.arg( projectDir, localeFileName ) ).exists() )
2128 mTranslator = std::make_unique< QTranslator >();
2129 ( void ) mTranslator->load( localeFileName, projectDir );
2132 profile.switchTask( tr(
"Reading project file" ) );
2133 auto doc = std::make_unique<QDomDocument>( u
"qgis"_s );
2135 if ( !projectFile.open( QIODevice::ReadOnly | QIODevice::Text ) )
2137 projectFile.close();
2139 setError( tr(
"Unable to open %1" ).arg( projectFile.fileName() ) );
2144 if ( !doc->setContent( &projectFile ) )
2146 projectFile.seek( 0 );
2147 QTextStream textStream( &projectFile );
2148 QString projectString;
2151 QString part = textStream.read( 65536 );
2152 if ( part.isEmpty() )
2155 for (
int i = 0; i < 32; i++ )
2157 if ( i == 9 || i == 10 || i == 13 )
2161 part.replace( QChar( i ), u
"%1%2%1"_s.arg(
FONTMARKER_CHR_FIX, QString::number( i ) ) );
2163 projectString.append( part );
2165 projectFile.close();
2169 if ( !doc->setContent( projectString, &errorMsg, &line, &column ) )
2171 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 );
2173 setError( errorString );
2180 projectFile.close();
2186 const QgsProjectVersion fileVersion =
getVersion( *doc );
2189 profile.switchTask( tr(
"Updating project file" ) );
2190 if ( thisVersion > fileVersion )
2192 const bool isOlderMajorVersion = fileVersion.
majorVersion() < thisVersion.majorVersion();
2194 if ( isOlderMajorVersion )
2197 "Loading a file that was saved with an older "
2198 "version of qgis (saved in "
2199 + fileVersion.
text()
2202 +
"). Problems may occur."
2206 QgsProjectFileTransform projectFile( *doc, fileVersion );
2214 projectFile.updateRevision( thisVersion );
2216 else if ( fileVersion > thisVersion )
2219 "Loading a file that was saved with a newer "
2220 "version of qgis (saved in "
2221 + fileVersion.
text()
2224 +
"). Problems may occur."
2231 profile.switchTask( tr(
"Creating auxiliary storage" ) );
2232 const QString
fileName = mFile.fileName();
2234 const QgsCoordinateReferenceSystem oldVerticalCrs =
verticalCrs();
2235 const QgsCoordinateReferenceSystem oldCrs3D = mCrs3D;
2239 std::unique_ptr<QgsAuxiliaryStorage> aStorage = std::move( mAuxiliaryStorage );
2240 std::unique_ptr<QgsArchive> archive = std::move( mArchive );
2244 mBlockChangeSignalsDuringClear =
true;
2246 mBlockChangeSignalsDuringClear =
false;
2251 releaseHandlesToProjectArchive();
2253 mAuxiliaryStorage = std::move( aStorage );
2254 mArchive = std::move( archive );
2257 mCachedHomePath.clear();
2258 mProjectScope.reset();
2259 mSaveVersion = fileVersion;
2262 profile.switchTask( tr(
"Reading properties" ) );
2268 QgsDebugMsgLevel( QString::number( mProperties.count() ) +
" properties read", 2 );
2271 dump_( mProperties );
2276 _getTitle( *doc, oldTitle );
2278 readProjectFileMetadata( *doc, mSaveUser, mSaveUserFull, mSaveDateTime );
2280 const QDomNodeList homePathNl = doc->elementsByTagName( u
"homePath"_s );
2281 if ( homePathNl.count() > 0 )
2283 const QDomElement homePathElement = homePathNl.at( 0 ).toElement();
2284 const QString
homePath = homePathElement.attribute( u
"path"_s );
2296 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 ) );
2300 const QString distanceUnitString =
readEntry( u
"Measurement"_s, u
"/DistanceUnits"_s, QString() );
2301 if ( !distanceUnitString.isEmpty() )
2304 const QString areaUnitString =
readEntry( u
"Measurement"_s, u
"/AreaUnits"_s, QString() );
2305 if ( !areaUnitString.isEmpty() )
2310 QgsReadWriteContext context;
2315 QgsCoordinateReferenceSystem projectCrs;
2316 if (
readNumEntry( u
"SpatialRefSys"_s, u
"/ProjectionsEnabled"_s, 0 ) )
2319 const QDomNode srsNode = doc->documentElement().namedItem( u
"projectCrs"_s );
2320 if ( !srsNode.isNull() )
2322 projectCrs.
readXml( srsNode );
2327 const QString projCrsString =
readEntry( u
"SpatialRefSys"_s, u
"/ProjectCRSProj4String"_s );
2328 const long currentCRS =
readNumEntry( u
"SpatialRefSys"_s, u
"/ProjectCRSID"_s, -1 );
2329 const QString authid =
readEntry( u
"SpatialRefSys"_s, u
"/ProjectCrs"_s );
2332 const bool isUserAuthId = authid.startsWith(
"USER:"_L1, Qt::CaseInsensitive );
2333 if ( !authid.isEmpty() && !isUserAuthId )
2334 projectCrs = QgsCoordinateReferenceSystem( authid );
2337 if ( !projectCrs.
isValid() && currentCRS >= 0 )
2343 if ( !projCrsString.isEmpty() && ( authid.isEmpty() || isUserAuthId ) && ( !projectCrs.
isValid() || projectCrs.
toProj() != projCrsString ) )
2360 const QDomNode verticalCrsNode = doc->documentElement().namedItem( u
"verticalCrs"_s );
2361 if ( !verticalCrsNode.isNull() )
2369 QStringList datumErrors;
2370 if ( !mTransformContext.readXml( doc->documentElement(), context, datumErrors ) && !datumErrors.empty() )
2377 const QDomNode elevationShadingNode = doc->documentElement().namedItem( u
"elevation-shading-renderer"_s );
2378 if ( !elevationShadingNode.isNull() )
2380 mElevationShadingRenderer.readXml( elevationShadingNode.toElement(), context );
2387 const QStringList variableNames =
readListEntry( u
"Variables"_s, u
"/variableNames"_s );
2388 const QStringList variableValues =
readListEntry( u
"Variables"_s, u
"/variableValues"_s );
2390 mCustomVariables.clear();
2391 if ( variableNames.length() == variableValues.length() )
2393 for (
int i = 0; i < variableNames.length(); ++i )
2395 mCustomVariables.insert( variableNames.at( i ), variableValues.at( i ) );
2400 QgsMessageLog::logMessage( tr(
"Project Variables Invalid" ), tr(
"The project contains invalid variable settings." ) );
2408 QDomElement element = doc->documentElement().firstChildElement( u
"projectMetadata"_s );
2410 if ( !element.isNull() )
2412 mMetadata.readMetadataXml( element, context );
2417 mMetadata = QgsProjectMetadata();
2419 if ( mMetadata.title().isEmpty() && !oldTitle.isEmpty() )
2422 mMetadata.setTitle( oldTitle );
2428 element = doc->documentElement().firstChildElement( u
"transaction"_s );
2429 if ( !element.isNull() )
2436 element = doc->documentElement().firstChildElement( u
"autotransaction"_s );
2437 if ( !element.isNull() )
2439 mTransactionMode =
static_cast<Qgis::TransactionMode>( element.attribute( u
"active"_s, u
"0"_s ).toInt() );
2444 profile.switchTask( tr(
"Loading layer tree" ) );
2445 mRootGroup->setCustomProperty( u
"loading"_s, 1 );
2447 QDomElement layerTreeElem = doc->documentElement().firstChildElement( u
"layer-tree-group"_s );
2448 if ( !layerTreeElem.isNull() )
2451 QgsLayerTree tempTree;
2460 mLayerTreeRegistryBridge->setEnabled(
false );
2463 profile.switchTask( tr(
"Reading map layers" ) );
2465 loadProjectFlags( doc.get() );
2467 QList<QDomNode> brokenNodes;
2468 const bool clean = _getMapLayers( *doc, brokenNodes,
flags );
2473 QgsDebugError( u
"Unable to get map layers from project file."_s );
2475 if ( !brokenNodes.isEmpty() )
2477 QgsDebugError(
"there are " + QString::number( brokenNodes.size() ) +
" broken layers" );
2482 mBadLayerHandler->handleBadLayers( brokenNodes );
2485 mMainAnnotationLayer->readLayerXml( doc->documentElement().firstChildElement( u
"main-annotation-layer"_s ), context );
2486 mMainAnnotationLayer->setTransformContext( mTransformContext );
2489 profile.switchTask( tr(
"Loading embedded layers" ) );
2490 loadEmbeddedNodes( mRootGroup.get(),
flags );
2494 profile.switchTask( tr(
"Resolving layer references" ) );
2495 QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
2496 for ( QMap<QString, QgsMapLayer *>::iterator it =
layers.begin(); it !=
layers.end(); ++it )
2498 it.value()->resolveReferences(
this );
2500 mMainAnnotationLayer->resolveReferences(
this );
2502 mLayerTreeRegistryBridge->setEnabled(
true );
2505 profile.switchTask( tr(
"Resolving references" ) );
2506 mRootGroup->resolveReferences(
this );
2509 if ( QgsProjectVersion( 3, 28, 0 ) > mSaveVersion )
2516 if ( !layerTreeElem.isNull() )
2518 mRootGroup->readLayerOrderFromXml( layerTreeElem );
2522 const QDomElement layerTreeCanvasElem = doc->documentElement().firstChildElement( u
"layer-tree-canvas"_s );
2523 if ( !layerTreeCanvasElem.isNull() )
2525 mRootGroup->readLayerOrderFromXml( layerTreeCanvasElem );
2529 if ( QgsProjectVersion( 3, 4, 0 ) > mSaveVersion )
2531 const QStringList requiredLayerIds =
readListEntry( u
"RequiredLayers"_s, u
"Layers"_s );
2532 for (
const QString &layerId : requiredLayerIds )
2534 if ( QgsMapLayer *layer =
mapLayer( layerId ) )
2539 const QStringList disabledLayerIds =
readListEntry( u
"Identify"_s, u
"/disabledLayers"_s );
2540 for (
const QString &layerId : disabledLayerIds )
2542 if ( QgsMapLayer *layer =
mapLayer( layerId ) )
2550 if ( QgsProjectVersion( 3, 26, 0 ) > mSaveVersion )
2553 QString styleName =
readEntry( u
"DefaultStyles"_s, u
"/Marker"_s );
2554 if ( !styleName.isEmpty() )
2559 styleName =
readEntry( u
"DefaultStyles"_s, u
"/Line"_s );
2560 if ( !styleName.isEmpty() )
2565 styleName =
readEntry( u
"DefaultStyles"_s, u
"/Fill"_s );
2566 if ( !styleName.isEmpty() )
2571 styleName =
readEntry( u
"DefaultStyles"_s, u
"/ColorRamp"_s );
2572 if ( !styleName.isEmpty() )
2582 double opacity = 1.0;
2585 double alpha =
readDoubleEntry( u
"DefaultStyles"_s, u
"/AlphaInt"_s, 255, &ok );
2587 opacity = alpha / 255.0;
2588 double newOpacity =
readDoubleEntry( u
"DefaultStyles"_s, u
"/Opacity"_s, 1.0, &ok );
2590 opacity = newOpacity;
2597 removeEntry( u
"DefaultStyles"_s, u
"/ColorRamp"_s );
2598 removeEntry( u
"DefaultStyles"_s, u
"/RandomColors"_s );
2599 removeEntry( u
"DefaultStyles"_s, u
"/AlphaInt"_s );
2608 profile.switchTask( tr(
"Storing original layer properties" ) );
2612 mRootGroup->removeCustomProperty( u
"loading"_s );
2614 profile.switchTask( tr(
"Loading map themes" ) );
2615 mMapThemeCollection = std::make_unique< QgsMapThemeCollection >(
this );
2617 mMapThemeCollection->readXml( *doc );
2619 profile.switchTask( tr(
"Loading label settings" ) );
2620 mLabelingEngineSettings->readSettingsFromProject(
this );
2622 const QDomElement labelEngineSettingsElement = doc->documentElement().firstChildElement( u
"labelEngineSettings"_s );
2623 mLabelingEngineSettings->readXml( labelEngineSettingsElement, context );
2625 mLabelingEngineSettings->resolveReferences(
this );
2629 profile.switchTask( tr(
"Loading annotations" ) );
2632 mAnnotationManager->readXml( doc->documentElement(), context );
2636 mAnnotationManager->readXmlAndUpgradeToAnnotationLayerItems( doc->documentElement(), context, mMainAnnotationLayer, mTransformContext );
2640 profile.switchTask( tr(
"Loading layouts" ) );
2641 mLayoutManager->readXml( doc->documentElement(), *doc );
2645 profile.switchTask( tr(
"Loading elevation profiles" ) );
2646 mElevationProfileManager->readXml( doc->documentElement(), *doc, context );
2647 mElevationProfileManager->resolveReferences(
this );
2651 profile.switchTask( tr(
"Loading selective masking source sets" ) );
2652 mSelectiveMaskingSourceSetManager->readXml( doc->documentElement(), *doc, context );
2657 profile.switchTask( tr(
"Loading 3D Views" ) );
2658 m3DViewsManager->readXml( doc->documentElement(), *doc );
2661 profile.switchTask( tr(
"Loading bookmarks" ) );
2662 mBookmarkManager->readXml( doc->documentElement(), *doc );
2664 profile.switchTask( tr(
"Loading sensors" ) );
2665 mSensorManager->readXml( doc->documentElement(), *doc );
2668 QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
2669 for ( QMap<QString, QgsMapLayer *>::iterator it = existingMaps.begin(); it != existingMaps.end(); ++it )
2671 it.value()->setDependencies( it.value()->dependencies() );
2674 profile.switchTask( tr(
"Loading snapping settings" ) );
2675 mSnappingConfig.readProject( *doc );
2680 profile.switchTask( tr(
"Loading view settings" ) );
2682 mViewSettings->setUseProjectScales(
readBoolEntry( u
"Scales"_s, u
"/useProjectScales"_s ) );
2683 const QStringList scales =
readListEntry( u
"Scales"_s, u
"/ScalesList"_s );
2684 QVector<double> res;
2685 for (
const QString &scale : scales )
2687 const QStringList parts = scale.split(
':' );
2688 if ( parts.size() != 2 )
2692 const double denominator = QLocale().toDouble( parts[1], &ok );
2698 mViewSettings->setMapScales( res );
2699 const QDomElement viewSettingsElement = doc->documentElement().firstChildElement( u
"ProjectViewSettings"_s );
2700 if ( !viewSettingsElement.isNull() )
2701 mViewSettings->readXml( viewSettingsElement, context );
2704 profile.switchTask( tr(
"Loading style properties" ) );
2705 const QDomElement styleSettingsElement = doc->documentElement().firstChildElement( u
"ProjectStyleSettings"_s );
2706 if ( !styleSettingsElement.isNull() )
2708 mStyleSettings->removeProjectStyle();
2709 mStyleSettings->readXml( styleSettingsElement, context,
flags );
2713 profile.switchTask( tr(
"Loading temporal settings" ) );
2714 const QDomElement timeSettingsElement = doc->documentElement().firstChildElement( u
"ProjectTimeSettings"_s );
2715 if ( !timeSettingsElement.isNull() )
2716 mTimeSettings->readXml( timeSettingsElement, context );
2719 profile.switchTask( tr(
"Loading elevation properties" ) );
2720 const QDomElement elevationPropertiesElement = doc->documentElement().firstChildElement( u
"ElevationProperties"_s );
2721 if ( !elevationPropertiesElement.isNull() )
2722 mElevationProperties->readXml( elevationPropertiesElement, context );
2723 mElevationProperties->resolveReferences(
this );
2725 profile.switchTask( tr(
"Loading display settings" ) );
2727 const QDomElement displaySettingsElement = doc->documentElement().firstChildElement( u
"ProjectDisplaySettings"_s );
2728 if ( !displaySettingsElement.isNull() )
2729 mDisplaySettings->readXml( displaySettingsElement, context );
2732 profile.switchTask( tr(
"Loading GPS settings" ) );
2734 const QDomElement gpsSettingsElement = doc->documentElement().firstChildElement( u
"ProjectGpsSettings"_s );
2735 if ( !gpsSettingsElement.isNull() )
2736 mGpsSettings->readXml( gpsSettingsElement, context );
2737 mGpsSettings->resolveReferences(
this );
2740 profile.switchTask( tr(
"Updating variables" ) );
2742 profile.switchTask( tr(
"Updating CRS" ) );
2746 if ( mCrs3D != oldCrs3D )
2751 profile.switchTask( tr(
"Reading external settings" ) );
2755 profile.switchTask( tr(
"Updating interface" ) );
2757 snapSignalBlock.release();
2758 if ( !mBlockSnappingUpdates )
2779 const QString newFileName( u
"%1/%2.qgs"_s.arg( QFileInfo( mFile ).
absolutePath(), localeFileName ) );
2793 const QMap<QString, QgsMapLayer *> loadedLayers =
mapLayers();
2794 for (
auto it = loadedLayers.constBegin(); it != loadedLayers.constEnd(); ++it )
2796 if ( it.value()->isValid() && it.value()->customProperty( u
"_layer_was_editable"_s ).toBool() )
2798 if ( QgsVectorLayer *vl = qobject_cast< QgsVectorLayer * >( it.value() ) )
2800 it.value()->removeCustomProperty( u
"_layer_was_editable"_s );
2812 const auto constChildren = group->
children();
2813 for ( QgsLayerTreeNode *child : constChildren )
2826 QList<QgsLayerTreeNode *> clonedChildren;
2827 const QList<QgsLayerTreeNode *> constChildren = newGroup->children();
2828 clonedChildren.reserve( constChildren.size() );
2829 for ( QgsLayerTreeNode *newGroupChild : constChildren )
2830 clonedChildren << newGroupChild->clone();
2837 loadEmbeddedNodes( childGroup,
flags );
2842 if ( child->customProperty( u
"embedded"_s ).toInt() )
2844 QList<QDomNode> brokenNodes;
2847 valid = valid &&
false;
2861 return mCustomVariables;
2868 if ( variables == mCustomVariables )
2872 QStringList variableNames;
2873 QStringList variableValues;
2875 QVariantMap::const_iterator it = variables.constBegin();
2876 for ( ; it != variables.constEnd(); ++it )
2878 variableNames << it.key();
2879 variableValues << it.value().toString();
2882 writeEntry( u
"Variables"_s, u
"/variableNames"_s, variableNames );
2883 writeEntry( u
"Variables"_s, u
"/variableValues"_s, variableValues );
2885 mCustomVariables = variables;
2886 mProjectScope.reset();
2895 *mLabelingEngineSettings = settings;
2903 return *mLabelingEngineSettings;
2910 mProjectScope.reset();
2911 return mLayerStore.get();
2918 return mLayerStore.get();
2925 QList<QgsVectorLayer *>
layers;
2926 const QStringList layerIds =
readListEntry( u
"Digitizing"_s, u
"/AvoidIntersectionsList"_s, QStringList() );
2927 const auto constLayerIds = layerIds;
2928 for (
const QString &layerId : constLayerIds )
2941 list.reserve(
layers.size() );
2946 list << layer->id();
2949 writeEntry( u
"Digitizing"_s, u
"/AvoidIntersectionsList"_s, list );
2970 if ( mProjectScope )
2972 auto projectScope = std::make_unique< QgsExpressionContextScope >( *mProjectScope );
2979 projectScope->addFunction( u
"sensor_data"_s,
new GetSensorData(
sensorManager()->sensorsData() ) );
2981 projectScope->addLayerStore( mLayerStore.get() );
2983 return projectScope.release();
2986 mProjectScope = std::make_unique< QgsExpressionContextScope >( QObject::tr(
"Project" ) );
2990 QVariantMap::const_iterator it = vars.constBegin();
2992 for ( ; it != vars.constEnd(); ++it )
2994 mProjectScope->setVariable( it.key(), it.value(),
true );
2998 if ( projectPath.isEmpty() )
2999 projectPath = mOriginalPath;
3000 const QString projectFolder = QFileInfo( projectPath ).path();
3001 const QString projectFilename = QFileInfo( projectPath ).fileName();
3002 const QString projectBasename =
baseName();
3039 QVariantMap keywords;
3041 for (
auto it = metadataKeywords.constBegin(); it != metadataKeywords.constEnd(); ++it )
3043 keywords.insert( it.key(), it.value() );
3048 QVariantList layersIds;
3050 const QMap<QString, QgsMapLayer *> layersInProject = mLayerStore->mapLayers();
3051 layersIds.reserve( layersInProject.count() );
3052 layers.reserve( layersInProject.count() );
3053 for (
auto it = layersInProject.constBegin(); it != layersInProject.constEnd(); ++it )
3055 layersIds << it.value()->id();
3061 mProjectScope->addFunction( u
"project_color"_s,
new GetNamedProjectColor(
this ) );
3062 mProjectScope->addFunction( u
"project_color_object"_s,
new GetNamedProjectColorObject(
this ) );
3067void QgsProject::onMapLayersAdded(
const QList<QgsMapLayer *> &layers )
3071 const QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
3073 const auto constLayers =
layers;
3076 if ( !layer->isValid() )
3079 if (
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer ) )
3082 if ( vlayer->dataProvider() )
3089 for ( QMap<QString, QgsMapLayer *>::const_iterator it = existingMaps.cbegin(); it != existingMaps.cend(); ++it )
3091 const QSet<QgsMapLayerDependency> deps = it.value()->dependencies();
3092 if ( deps.contains( layer->id() ) )
3095 it.value()->setDependencies( deps );
3100 updateTransactionGroups();
3102 if ( !mBlockSnappingUpdates && mSnappingConfig.addLayers(
layers ) )
3106void QgsProject::onMapLayersRemoved(
const QList<QgsMapLayer *> &layers )
3110 if ( !mBlockSnappingUpdates && mSnappingConfig.removeLayers(
layers ) )
3113 for ( QgsMapLayer *layer :
layers )
3115 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
3119 mEditBufferGroup.removeLayer( vlayer );
3123void QgsProject::cleanTransactionGroups(
bool force )
3127 bool changed =
false;
3128 for ( QMap< QPair< QString, QString>, QgsTransactionGroup *>::Iterator tg = mTransactionGroups.begin(); tg != mTransactionGroups.end(); )
3130 if ( tg.value()->isEmpty() || force )
3133 tg = mTransactionGroups.erase( tg );
3145void QgsProject::updateTransactionGroups()
3149 mEditBufferGroup.clear();
3151 switch ( mTransactionMode )
3155 cleanTransactionGroups(
true );
3160 cleanTransactionGroups(
true );
3163 cleanTransactionGroups(
false );
3167 bool tgChanged =
false;
3168 const auto constLayers =
mapLayers().values();
3169 for ( QgsMapLayer *layer : constLayers )
3171 if ( !layer->isValid() )
3174 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
3178 switch ( mTransactionMode )
3190 QgsTransactionGroup *tg = mTransactionGroups.value( qMakePair( key, connString ) );
3194 tg =
new QgsTransactionGroup();
3195 mTransactionGroups.insert( qMakePair( key, connString ), tg );
3205 mEditBufferGroup.addLayer( vlayer );
3221 context.setProjectTranslator(
this );
3223 context.setCurrentLayerId( layerNode.toElement().firstChildElement( u
"id"_s ).text() );
3224 QList<QDomNode> brokenNodes;
3225 if ( addLayer( layerNode.toElement(), brokenNodes, context ) )
3233 layer->resolveReferences(
this );
3235 if ( layer->isValid() && layer->customProperty( u
"_layer_was_editable"_s ).toBool() )
3237 layer->startEditing();
3238 layer->removeCustomProperty( u
"_layer_was_editable"_s );
3250 mFile.setFileName( filename );
3252 mCachedHomePath.clear();
3260 mProjectScope.reset();
3266 const QString storageFilePath { storage->filePath( mFile.fileName() ) };
3267 if ( storageFilePath.isEmpty() )
3273 const QString tempPath = QStandardPaths::standardLocations( QStandardPaths::TempLocation ).at( 0 );
3274 const QString tmpZipFilename( tempPath + QDir::separator() + QUuid::createUuid().toString() );
3276 if ( !zip( tmpZipFilename ) )
3279 QFile tmpZipFile( tmpZipFilename );
3280 if ( !tmpZipFile.open( QIODevice::ReadOnly ) )
3282 setError( tr(
"Unable to read file %1" ).arg( tmpZipFilename ) );
3287 if ( !storage->writeProject( mFile.fileName(), &tmpZipFile, context ) )
3289 QString err = tr(
"Unable to save project to storage %1" ).arg( mFile.fileName() );
3290 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
3291 if ( !messages.isEmpty() )
3292 err += u
"\n\n"_s + messages.last().message();
3298 QFile::remove( tmpZipFilename );
3305 return zip( mFile.fileName() );
3311 const bool asOk = saveAuxiliaryStorage();
3312 const bool writeOk = writeProjectFile( mFile.fileName() );
3313 bool attachmentsOk =
true;
3314 if ( !mArchive->files().isEmpty() )
3316 const QFileInfo finfo( mFile.fileName() );
3317 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( u
"%1_attachments.zip"_s.arg( finfo.completeBaseName() ) );
3318 attachmentsOk = mArchive->zip( attachmentsZip );
3322 if ( ( !asOk || !attachmentsOk ) && writeOk )
3324 QStringList errorMessage;
3327 const QString err = mAuxiliaryStorage->errorString();
3328 errorMessage.append( tr(
"Unable to save auxiliary storage ('%1')" ).arg( err ) );
3330 if ( !attachmentsOk )
3332 errorMessage.append( tr(
"Unable to save attachments archive" ) );
3334 setError( errorMessage.join(
'\n' ) );
3337 return asOk && writeOk && attachmentsOk;
3341bool QgsProject::writeProjectFile(
const QString &filename )
3345 QFile projectFile( filename );
3351 const QFileInfo myFileInfo( projectFile );
3352 if ( myFileInfo.exists() && !myFileInfo.isWritable() )
3354 setError( tr(
"%1 is not writable. Please adjust permissions (if possible) and try again." ).arg( projectFile.fileName() ) );
3358 QgsReadWriteContext context;
3362 QDomImplementation::setInvalidDataPolicy( QDomImplementation::DropInvalidChars );
3364 const QDomDocumentType documentType = QDomImplementation().createDocumentType( u
"qgis"_s, u
"http://mrcc.com/qgis.dtd"_s, u
"SYSTEM"_s );
3365 auto doc = std::make_unique<QDomDocument>( documentType );
3367 QDomElement qgisNode = doc->createElement( u
"qgis"_s );
3368 qgisNode.setAttribute( u
"projectname"_s,
title() );
3375 qgisNode.setAttribute( u
"saveUser"_s, newSaveUser );
3376 qgisNode.setAttribute( u
"saveUserFull"_s, newSaveUserFull );
3377 mSaveUser = newSaveUser;
3378 mSaveUserFull = newSaveUserFull;
3379 if ( mMetadata.author().isEmpty() )
3383 if ( !mMetadata.creationDateTime().isValid() )
3385 mMetadata.setCreationDateTime( QDateTime( QDateTime::currentDateTime() ) );
3387 mSaveDateTime = QDateTime::currentDateTime();
3388 qgisNode.setAttribute( u
"saveDateTime"_s, mSaveDateTime.toString( Qt::ISODate ) );
3393 mSaveUserFull.clear();
3394 mMetadata.setAuthor( QString() );
3395 mMetadata.setCreationDateTime( QDateTime() );
3396 mSaveDateTime = QDateTime();
3398 doc->appendChild( qgisNode );
3401 QDomElement homePathNode = doc->createElement( u
"homePath"_s );
3402 homePathNode.setAttribute( u
"path"_s, mHomePath );
3403 qgisNode.appendChild( homePathNode );
3406 QDomElement titleNode = doc->createElement( u
"title"_s );
3407 qgisNode.appendChild( titleNode );
3409 QDomElement transactionNode = doc->createElement( u
"transaction"_s );
3410 transactionNode.setAttribute( u
"mode"_s,
qgsEnumValueToKey( mTransactionMode ) );
3411 qgisNode.appendChild( transactionNode );
3413 QDomElement flagsNode = doc->createElement( u
"projectFlags"_s );
3415 qgisNode.appendChild( flagsNode );
3417 const QDomText titleText = doc->createTextNode(
title() );
3418 titleNode.appendChild( titleText );
3422 QDomElement srsNode = doc->createElement( u
"projectCrs"_s );
3423 mCrs.writeXml( srsNode, *doc );
3424 qgisNode.appendChild( srsNode );
3427 QDomElement verticalSrsNode = doc->createElement( u
"verticalCrs"_s );
3428 mVerticalCrs.writeXml( verticalSrsNode, *doc );
3429 qgisNode.appendChild( verticalSrsNode );
3431 QDomElement elevationShadingNode = doc->createElement( u
"elevation-shading-renderer"_s );
3432 mElevationShadingRenderer.writeXml( elevationShadingNode, context );
3433 qgisNode.appendChild( elevationShadingNode );
3436 std::unique_ptr< QgsLayerTreeNode > clonedRoot( mRootGroup->clone() );
3440 clonedRoot->writeXml( qgisNode, context );
3443 mSnappingConfig.writeProject( *doc );
3444 writeEntry( u
"Digitizing"_s, u
"/AvoidIntersectionsMode"_s,
static_cast<int>( mAvoidIntersectionsMode ) );
3452 QDomElement annotationLayerNode = doc->createElement( u
"main-annotation-layer"_s );
3453 mMainAnnotationLayer->writeLayerXml( annotationLayerNode, *doc, context );
3454 qgisNode.appendChild( annotationLayerNode );
3458 QDomElement projectLayersNode = doc->createElement( u
"projectlayers"_s );
3460 QMap<QString, QgsMapLayer *>::ConstIterator li =
layers.constBegin();
3461 while ( li !=
layers.end() )
3463 QgsMapLayer *ml = li.value();
3467 const QHash< QString, QPair< QString, bool> >::const_iterator emIt = mEmbeddedLayers.constFind( ml->
id() );
3468 if ( emIt == mEmbeddedLayers.constEnd() )
3470 QDomElement maplayerElem;
3476 maplayerElem = doc->createElement( u
"maplayer"_s );
3480 maplayerElem.setAttribute( u
"editable"_s, u
"1"_s );
3484 QDomDocument document;
3487 maplayerElem = document.firstChildElement();
3491 QgsDebugError( u
"Could not restore layer properties for layer %1"_s.arg( ml->
id() ) );
3497 projectLayersNode.appendChild( maplayerElem );
3503 if ( emIt.value().second )
3505 QDomElement mapLayerElem = doc->createElement( u
"maplayer"_s );
3506 mapLayerElem.setAttribute( u
"embedded"_s, 1 );
3507 mapLayerElem.setAttribute( u
"project"_s,
writePath( emIt.value().first ) );
3508 mapLayerElem.setAttribute( u
"id"_s, ml->
id() );
3509 projectLayersNode.appendChild( mapLayerElem );
3516 qgisNode.appendChild( projectLayersNode );
3518 QDomElement layerOrderNode = doc->createElement( u
"layerorder"_s );
3519 const auto constCustomLayerOrder = mRootGroup->customLayerOrder();
3520 for ( QgsMapLayer *layer : constCustomLayerOrder )
3522 QDomElement mapLayerElem = doc->createElement( u
"layer"_s );
3523 mapLayerElem.setAttribute( u
"id"_s, layer->id() );
3524 layerOrderNode.appendChild( mapLayerElem );
3526 qgisNode.appendChild( layerOrderNode );
3528 mLabelingEngineSettings->writeSettingsToProject(
this );
3530 QDomElement labelEngineSettingsElement = doc->createElement( u
"labelEngineSettings"_s );
3531 mLabelingEngineSettings->writeXml( *doc, labelEngineSettingsElement, context );
3532 qgisNode.appendChild( labelEngineSettingsElement );
3535 writeEntry( u
"Gui"_s, u
"/CanvasColorRedPart"_s, mBackgroundColor.red() );
3536 writeEntry( u
"Gui"_s, u
"/CanvasColorGreenPart"_s, mBackgroundColor.green() );
3537 writeEntry( u
"Gui"_s, u
"/CanvasColorBluePart"_s, mBackgroundColor.blue() );
3539 writeEntry( u
"Gui"_s, u
"/SelectionColorRedPart"_s, mSelectionColor.red() );
3540 writeEntry( u
"Gui"_s, u
"/SelectionColorGreenPart"_s, mSelectionColor.green() );
3541 writeEntry( u
"Gui"_s, u
"/SelectionColorBluePart"_s, mSelectionColor.blue() );
3542 writeEntry( u
"Gui"_s, u
"/SelectionColorAlphaPart"_s, mSelectionColor.alpha() );
3550 dump_( mProperties );
3553 QgsDebugMsgLevel( u
"there are %1 property scopes"_s.arg(
static_cast<int>( mProperties.count() ) ), 2 );
3555 if ( !mProperties.isEmpty() )
3558 mProperties.writeXml( u
"properties"_s, qgisNode, *doc );
3561 QDomElement ddElem = doc->createElement( u
"dataDefinedServerProperties"_s );
3562 mDataDefinedServerProperties.writeXml( ddElem, dataDefinedServerPropertyDefinitions() );
3563 qgisNode.appendChild( ddElem );
3565 mMapThemeCollection->writeXml( *doc );
3567 mTransformContext.writeXml( qgisNode, context );
3569 QDomElement metadataElem = doc->createElement( u
"projectMetadata"_s );
3570 mMetadata.writeMetadataXml( metadataElem, *doc );
3571 qgisNode.appendChild( metadataElem );
3574 const QDomElement annotationsElem = mAnnotationManager->writeXml( *doc, context );
3575 qgisNode.appendChild( annotationsElem );
3579 const QDomElement layoutElem = mLayoutManager->writeXml( *doc );
3580 qgisNode.appendChild( layoutElem );
3584 const QDomElement elevationProfileElem = mElevationProfileManager->writeXml( *doc, context );
3585 qgisNode.appendChild( elevationProfileElem );
3589 const QDomElement selectiveMaskingSourceSetElem = mSelectiveMaskingSourceSetManager->writeXml( *doc, context );
3590 qgisNode.appendChild( selectiveMaskingSourceSetElem );
3594 const QDomElement views3DElem = m3DViewsManager->writeXml( *doc );
3595 qgisNode.appendChild( views3DElem );
3599 const QDomElement bookmarkElem = mBookmarkManager->writeXml( *doc );
3600 qgisNode.appendChild( bookmarkElem );
3604 const QDomElement sensorElem = mSensorManager->writeXml( *doc );
3605 qgisNode.appendChild( sensorElem );
3609 const QDomElement viewSettingsElem = mViewSettings->writeXml( *doc, context );
3610 qgisNode.appendChild( viewSettingsElem );
3614 const QDomElement styleSettingsElem = mStyleSettings->writeXml( *doc, context );
3615 qgisNode.appendChild( styleSettingsElem );
3619 const QDomElement timeSettingsElement = mTimeSettings->writeXml( *doc, context );
3620 qgisNode.appendChild( timeSettingsElement );
3624 const QDomElement elevationPropertiesElement = mElevationProperties->writeXml( *doc, context );
3625 qgisNode.appendChild( elevationPropertiesElement );
3629 const QDomElement displaySettingsElem = mDisplaySettings->writeXml( *doc, context );
3630 qgisNode.appendChild( displaySettingsElem );
3634 const QDomElement gpsSettingsElem = mGpsSettings->writeXml( *doc, context );
3635 qgisNode.appendChild( gpsSettingsElem );
3644 QFile backupFile( u
"%1~"_s.arg( filename ) );
3646 ok &= backupFile.open( QIODevice::WriteOnly | QIODevice::Truncate );
3647 ok &= projectFile.open( QIODevice::ReadOnly );
3650 while ( ok && !projectFile.atEnd() )
3652 ba = projectFile.read( 10240 );
3653 ok &= backupFile.write( ba ) == ba.size();
3656 projectFile.close();
3661 setError( tr(
"Unable to create backup file %1" ).arg( backupFile.fileName() ) );
3666 struct utimbuf tb = {
static_cast<time_t
>( fi.lastRead().toSecsSinceEpoch() ),
static_cast<time_t
>( fi.lastModified().toSecsSinceEpoch() ) };
3667 utime( backupFile.fileName().toUtf8().constData(), &tb );
3670 if ( !projectFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
3672 projectFile.close();
3675 setError( tr(
"Unable to save to file %1" ).arg( projectFile.fileName() ) );
3679 QTemporaryFile tempFile;
3680 bool ok = tempFile.open();
3683 QTextStream projectFileStream( &tempFile );
3684 doc->save( projectFileStream, 2 );
3685 ok &= projectFileStream.pos() > -1;
3687 ok &= tempFile.seek( 0 );
3690 while ( ok && !tempFile.atEnd() )
3692 ba = tempFile.read( 10240 );
3693 ok &= projectFile.write( ba ) == ba.size();
3696 ok &= projectFile.error() == QFile::NoError;
3698 projectFile.close();
3706 "Unable to save to file %1. Your project "
3707 "may be corrupted on disk. Try clearing some space on the volume and "
3708 "check file permissions before pressing save again."
3710 .arg( projectFile.fileName() ) );
3724 bool propertiesModified;
3725 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3727 if ( propertiesModified )
3737 bool propertiesModified;
3738 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3740 if ( propertiesModified )
3750 bool propertiesModified;
3751 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3753 if ( propertiesModified )
3763 bool propertiesModified;
3764 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3766 if ( propertiesModified )
3776 bool propertiesModified;
3777 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3779 if ( propertiesModified )
3796 value =
property->value();
3798 const bool valid = QMetaType::Type::QStringList == value.userType();
3804 return value.toStringList();
3824 value =
property->value();
3826 const bool valid = value.canConvert( QMetaType::Type::QString );
3831 return value.toString();
3849 value =
property->value();
3852 const bool valid = value.canConvert( QMetaType::Type::Int );
3861 return value.toInt();
3874 const QVariant value =
property->value();
3876 const bool valid = value.canConvert( QMetaType::Type::Double );
3881 return value.toDouble();
3897 const QVariant value =
property->value();
3899 const bool valid = value.canConvert( QMetaType::Type::Bool );
3904 return value.toBool();
3916 if (
findKey_( scope, key, mProperties ) )
3922 return !
findKey_( scope, key, mProperties );
3931 QStringList entries;
3933 if ( foundProperty )
3952 QStringList entries;
3954 if ( foundProperty )
3971 dump_( mProperties );
3991 filePath = storage->filePath( mFile.fileName() );
4018void QgsProject::setError(
const QString &errorMessage )
4022 mErrorMessage = errorMessage;
4029 return mErrorMessage;
4032void QgsProject::clearError()
4036 setError( QString() );
4043 mBadLayerHandler.reset( handler );
4050 const QHash< QString, QPair< QString, bool > >::const_iterator it = mEmbeddedLayers.find(
id );
4051 if ( it == mEmbeddedLayers.constEnd() )
4055 return it.value().first;
4064 static QString sPrevProjectFilePath;
4065 static QDateTime sPrevProjectFileTimestamp;
4066 static QDomDocument sProjectDocument;
4068 QString qgsProjectFile = projectFilePath;
4070 if ( projectFilePath.endsWith(
".qgz"_L1, Qt::CaseInsensitive ) )
4072 archive.
unzip( projectFilePath );
4076 const QDateTime projectFileTimestamp = QFileInfo( projectFilePath ).lastModified();
4078 if ( projectFilePath != sPrevProjectFilePath || projectFileTimestamp != sPrevProjectFileTimestamp )
4080 sPrevProjectFilePath.clear();
4082 QFile projectFile( qgsProjectFile );
4083 if ( !projectFile.open( QIODevice::ReadOnly ) )
4088 if ( !sProjectDocument.setContent( &projectFile ) )
4093 sPrevProjectFilePath = projectFilePath;
4094 sPrevProjectFileTimestamp = projectFileTimestamp;
4098 bool useAbsolutePaths =
true;
4100 const QDomElement propertiesElem = sProjectDocument.documentElement().firstChildElement( u
"properties"_s );
4101 if ( !propertiesElem.isNull() )
4103 QDomElement e = propertiesElem.firstChildElement( u
"Paths"_s );
4106 e = propertiesElem.firstChildElement( u
"properties"_s );
4107 while ( !e.isNull() && e.attribute( u
"name"_s ) !=
"Paths"_L1 )
4108 e = e.nextSiblingElement( u
"properties"_s );
4110 e = e.firstChildElement( u
"properties"_s );
4111 while ( !e.isNull() && e.attribute( u
"name"_s ) !=
"Absolute"_L1 )
4112 e = e.nextSiblingElement( u
"properties"_s );
4116 e = e.firstChildElement( u
"Absolute"_s );
4121 useAbsolutePaths = e.text().compare(
"true"_L1, Qt::CaseInsensitive ) == 0;
4126 if ( !useAbsolutePaths )
4132 const QDomElement projectLayersElem = sProjectDocument.documentElement().firstChildElement( u
"projectlayers"_s );
4133 if ( projectLayersElem.isNull() )
4138 QDomElement mapLayerElem = projectLayersElem.firstChildElement( u
"maplayer"_s );
4139 while ( !mapLayerElem.isNull() )
4142 const QString
id = mapLayerElem.firstChildElement( u
"id"_s ).text();
4143 if (
id == layerId )
4146 if ( mapLayerElem.attribute( u
"embedded"_s ) ==
"1"_L1 )
4151 mEmbeddedLayers.insert( layerId, qMakePair( projectFilePath, saveFlag ) );
4153 if ( addLayer( mapLayerElem, brokenNodes, embeddedContext,
flags ) )
4159 mEmbeddedLayers.remove( layerId );
4163 mapLayerElem = mapLayerElem.nextSiblingElement( u
"maplayer"_s );
4173 QString qgsProjectFile = projectFilePath;
4175 if ( projectFilePath.endsWith(
".qgz"_L1, Qt::CaseInsensitive ) )
4177 archive.
unzip( projectFilePath );
4182 QFile projectFile( qgsProjectFile );
4183 if ( !projectFile.open( QIODevice::ReadOnly ) )
4188 QDomDocument projectDocument;
4189 if ( !projectDocument.setContent( &projectFile ) )
4199 auto root = std::make_unique< QgsLayerTreeGroup >();
4201 QDomElement layerTreeElem = projectDocument.documentElement().firstChildElement( u
"layer-tree-group"_s );
4202 if ( !layerTreeElem.isNull() )
4204 root->readChildrenFromXml( layerTreeElem, context );
4222 newGroup->setCustomProperty( u
"embedded"_s, 1 );
4223 newGroup->setCustomProperty( u
"embedded_project"_s, projectFilePath );
4226 mLayerTreeRegistryBridge->setEnabled(
false );
4227 initializeEmbeddedSubtree( projectFilePath, newGroup.get(),
flags );
4228 mLayerTreeRegistryBridge->setEnabled(
true );
4231 const QStringList constFindLayerIds = newGroup->findLayerIds();
4232 for (
const QString &layerId : constFindLayerIds )
4249 const auto constChildren = group->
children();
4253 child->setCustomProperty( u
"embedded"_s, 1 );
4262 QList<QDomNode> brokenNodes;
4286 writeEntry( u
"Digitizing"_s, u
"/TopologicalEditing"_s, ( enabled ? 1 : 0 ) );
4294 return readNumEntry( u
"Digitizing"_s, u
"/TopologicalEditing"_s, 0 );
4301 if ( mDistanceUnits == unit )
4304 mDistanceUnits = unit;
4313 if ( mAreaUnits == unit )
4325 if ( mScaleMethod == method )
4328 mScaleMethod = method;
4338 if ( !mCachedHomePath.isEmpty() )
4339 return mCachedHomePath;
4343 if ( !mHomePath.isEmpty() )
4345 const QFileInfo homeInfo( mHomePath );
4346 if ( !homeInfo.isRelative() )
4348 mCachedHomePath = mHomePath;
4357 const QString storagePath { storage->filePath(
fileName() ) };
4358 if ( !storagePath.isEmpty() && QFileInfo::exists( storagePath ) )
4360 mCachedHomePath = QFileInfo( storagePath ).path();
4361 return mCachedHomePath;
4365 mCachedHomePath = pfi.path();
4366 return mCachedHomePath;
4369 if ( !pfi.exists() )
4371 mCachedHomePath = mHomePath;
4375 if ( !mHomePath.isEmpty() )
4378 mCachedHomePath = QDir::cleanPath( pfi.path() +
'/' + mHomePath );
4382 mCachedHomePath = pfi.canonicalPath();
4384 return mCachedHomePath;
4399 return mRelationManager.get();
4406 return mLayoutManager.get();
4413 return mLayoutManager.get();
4420 return mElevationProfileManager.get();
4427 return mElevationProfileManager.get();
4434 return mSelectiveMaskingSourceSetManager.get();
4441 return mSelectiveMaskingSourceSetManager.get();
4448 return m3DViewsManager.get();
4455 return m3DViewsManager.get();
4462 return mBookmarkManager;
4469 return mBookmarkManager;
4476 return mSensorManager;
4483 return mSensorManager;
4490 return mViewSettings;
4497 return mViewSettings;
4504 return mStyleSettings;
4512 return mStyleSettings;
4519 return mTimeSettings;
4526 return mTimeSettings;
4533 return mElevationProperties;
4540 return mElevationProperties;
4547 return mDisplaySettings;
4554 return mDisplaySettings;
4561 return mGpsSettings;
4568 return mGpsSettings;
4575 return mRootGroup.get();
4582 return mMapThemeCollection.get();
4589 return mAnnotationManager.get();
4596 return mAnnotationManager.get();
4603 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
4604 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
4609 if (
layers.contains( it.value() ) )
4626 for (
const QString &layerId : layerIds )
4644 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
4676 updateTransactionGroups();
4683 return mTransactionMode;
4694 const auto constLayers =
mapLayers().values();
4697 if ( layer->isEditable() )
4699 QgsLogger::warning( tr(
"Transaction mode can be changed only if all layers are not editable." ) );
4705 updateTransactionGroups();
4714 return mTransactionGroups;
4727 return mLayerStore->count();
4734 return mLayerStore->validCount();
4742 if ( mMainAnnotationLayer && layerId == mMainAnnotationLayer->id() )
4743 return mMainAnnotationLayer;
4745 return mLayerStore->mapLayer( layerId );
4752 return mLayerStore->mapLayersByName( layerName );
4759 QList<QgsMapLayer *>
layers;
4760 const auto constMapLayers { mLayerStore->mapLayers() };
4761 for (
const auto &l : constMapLayers )
4763 if ( !l->serverProperties()->shortName().isEmpty() )
4765 if ( l->serverProperties()->shortName() == shortName )
4768 else if ( l->name() == shortName )
4781 auto archive = std::make_unique<QgsProjectArchive>();
4784 if ( !archive->unzip( filename ) )
4786 setError( tr(
"Unable to unzip file '%1'" ).arg( filename ) );
4791 if ( archive->projectFile().isEmpty() )
4793 setError( tr(
"Zip archive does not provide a project file" ) );
4798 releaseHandlesToProjectArchive();
4799 mArchive = std::move( archive );
4802 if ( !
static_cast<QgsProjectArchive *
>( mArchive.get() )->auxiliaryStorageFile().isEmpty() )
4806 mAuxiliaryStorage = std::make_unique< QgsAuxiliaryStorage >(
static_cast<QgsProjectArchive *
>( mArchive.get() )->auxiliaryStorageFile(),
false );
4810 mAuxiliaryStorage = std::make_unique< QgsAuxiliaryStorage >( *
this );
4814 if ( !readProjectFile(
static_cast<QgsProjectArchive *
>( mArchive.get() )->projectFile(),
flags ) )
4816 setError( tr(
"Cannot read unzipped qgs project file" ) + u
": "_s +
error() );
4821 static_cast<QgsProjectArchive *
>( mArchive.get() )->clearProjectFile();
4826bool QgsProject::zip(
const QString &filename )
4833 auto archive = std::make_unique<QgsProjectArchive>();
4834 const QString
baseName = QFileInfo( filename ).baseName();
4835 const QString qgsFileName = u
"%1.qgs"_s.arg(
baseName );
4836 QFile qgsFile( QDir( archive->dir() ).filePath( qgsFileName ) );
4838 bool writeOk =
false;
4839 if ( qgsFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
4841 writeOk = writeProjectFile( qgsFile.fileName() );
4848 setError( tr(
"Unable to write temporary qgs file" ) );
4853 const QFileInfo info( qgsFile );
4855 const QString asFileName = info.path() + QDir::separator() + info.completeBaseName() + asExt;
4857 bool auxiliaryStorageSavedOk =
true;
4858 if ( !saveAuxiliaryStorage( asFileName ) )
4860 const QString err = mAuxiliaryStorage->errorString();
4862 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 )
4864 auxiliaryStorageSavedOk =
false;
4867 if ( !mArchive->exists() )
4869 releaseHandlesToProjectArchive();
4870 mArchive = std::make_unique< QgsProjectArchive >();
4871 mArchive->unzip( mFile.fileName() );
4872 static_cast<QgsProjectArchive *
>( mArchive.get() )->clearProjectFile();
4874 const QString auxiliaryStorageFile =
static_cast<QgsProjectArchive *
>( mArchive.get() )->auxiliaryStorageFile();
4875 if ( !auxiliaryStorageFile.isEmpty() )
4877 archive->addFile( auxiliaryStorageFile );
4878 mAuxiliaryStorage = std::make_unique< QgsAuxiliaryStorage >( auxiliaryStorageFile,
false );
4886 if ( QFile::exists( asFileName ) )
4888 archive->addFile( asFileName );
4893 archive->addFile( qgsFile.fileName() );
4896 const QStringList &files = mArchive->files();
4897 for (
const QString &file : files )
4899 if ( !file.endsWith(
".qgs"_L1, Qt::CaseInsensitive ) && !file.endsWith( asExt, Qt::CaseInsensitive ) )
4901 archive->addFile( file );
4907 if ( !archive->zip( filename ) )
4909 setError( tr(
"Unable to perform zip" ) );
4913 return auxiliaryStorageSavedOk && zipOk;
4927 const QList<QgsMapLayer *> myResultList { mLayerStore->addMapLayers(
layers, takeOwnership ) };
4928 if ( !myResultList.isEmpty() )
4931 for (
auto &l : myResultList )
4945 if ( mAuxiliaryStorage )
4960 mProjectScope.reset();
4962 return myResultList;
4969 QList<QgsMapLayer *> addedLayers;
4970 addedLayers =
addMapLayers( QList<QgsMapLayer *>() << layer, addToLegend, takeOwnership );
4971 return addedLayers.isEmpty() ? nullptr : addedLayers[0];
4974void QgsProject::removeAuxiliaryLayer(
const QgsMapLayer *ml )
4981 const QgsVectorLayer *vl = qobject_cast<const QgsVectorLayer *>( ml );
4993 for (
const auto &layerId : layerIds )
4994 removeAuxiliaryLayer( mLayerStore->mapLayer( layerId ) );
4996 mProjectScope.reset();
4997 mLayerStore->removeMapLayers( layerIds );
5004 for (
const auto &layer :
layers )
5005 removeAuxiliaryLayer( layer );
5007 mProjectScope.reset();
5008 mLayerStore->removeMapLayers(
layers );
5015 removeAuxiliaryLayer( mLayerStore->mapLayer( layerId ) );
5016 mProjectScope.reset();
5017 mLayerStore->removeMapLayer( layerId );
5024 removeAuxiliaryLayer( layer );
5025 mProjectScope.reset();
5026 mLayerStore->removeMapLayer( layer );
5033 mProjectScope.reset();
5034 return mLayerStore->takeMapLayer( layer );
5041 return mMainAnnotationLayer;
5048 if ( mLayerStore->count() == 0 )
5051 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
5052 mProjectScope.reset();
5053 mLayerStore->removeAllMapLayers();
5055 snapSingleBlocker.release();
5056 mSnappingConfig.clearIndividualLayerSettings();
5057 if ( !mBlockSnappingUpdates )
5065 const QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
5066 QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin();
5067 for ( ; it !=
layers.constEnd(); ++it )
5069 it.value()->reload();
5078 return validOnly ? mLayerStore->validMapLayers() : mLayerStore->mapLayers();
5085 return mTransactionGroups.value( qMakePair( providerKey, connString ) );
5092 return &mEditBufferGroup;
5131bool QgsProject::saveAuxiliaryStorage(
const QString &filename )
5137 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5142 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() );
5150 if ( !mAuxiliaryStorage->exists( *
this ) && empty )
5154 else if ( !filename.isEmpty() )
5156 return mAuxiliaryStorage->saveAs( filename );
5160 return mAuxiliaryStorage->saveAs( *
this );
5169 return sPropertyDefinitions;
5182 return mAuxiliaryStorage.get();
5189 return mAuxiliaryStorage.get();
5196 const QDir archiveDir( mArchive->dir() );
5197 QTemporaryFile tmpFile( archiveDir.filePath(
"XXXXXX_" + nameTemplate ),
this );
5198 tmpFile.setAutoRemove(
false );
5199 if ( !tmpFile.open() )
5201 setError( tr(
"Unable to open %1" ).arg( tmpFile.fileName() ) );
5204 mArchive->addFile( tmpFile.fileName() );
5205 return tmpFile.fileName();
5212 QStringList attachments;
5214 const QStringList files = mArchive->files();
5215 attachments.reserve( files.size() );
5216 for (
const QString &file : files )
5220 attachments.append( file );
5230 return mArchive->removeFile( path );
5237 return u
"attachment:///%1"_s.arg( QFileInfo( attachedFile ).
fileName() );
5244 if ( identifier.startsWith(
"attachment:///"_L1 ) )
5246 return QDir( mArchive->dir() ).absoluteFilePath( identifier.mid( 14 ) );
5267 mProjectScope.reset();
5282 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5296 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
5297 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
5302 if (
layers.contains( it.value() ) )
5314 QStringList customColors;
5315 QStringList customColorLabels;
5317 QgsNamedColorList::const_iterator colorIt = colors.constBegin();
5318 for ( ; colorIt != colors.constEnd(); ++colorIt )
5321 const QString label = ( *colorIt ).second;
5322 customColors.append( color );
5323 customColorLabels.append( label );
5325 writeEntry( u
"Palette"_s, u
"/Colors"_s, customColors );
5326 writeEntry( u
"Palette"_s, u
"/Labels"_s, customColorLabels );
5327 mProjectScope.reset();
5335 if ( mBackgroundColor == color )
5338 mBackgroundColor = color;
5346 return mBackgroundColor;
5353 if ( mSelectionColor == color )
5356 mSelectionColor = color;
5364 return mSelectionColor;
5371 mViewSettings->setMapScales( scales );
5378 return mViewSettings->mapScales();
5385 mViewSettings->setUseProjectScales( enabled );
5392 return mViewSettings->useProjectScales();
5405 translationContext.writeTsFile( locale );
5408QString
QgsProject::translate(
const QString &context,
const QString &sourceText,
const char *disambiguation,
int n )
const
5417 QString result = mTranslator->translate( context.toUtf8(), sourceText.toUtf8(), disambiguation, n );
5419 if ( result.isEmpty() )
5433 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5438 if ( !( ( *it )->accept( visitor ) ) )
5447 if ( !mLayoutManager->accept( visitor ) )
5450 if ( !mAnnotationManager->accept( visitor ) )
5460 const QString macros =
readEntry( u
"Macros"_s, u
"/pythonCode"_s, QString() );
5461 if ( !macros.isEmpty() )
5470 const QString expressionFunctions =
readEntry( u
"ExpressionFunctions"_s, u
"/pythonCode"_s );
5471 if ( !expressionFunctions.isEmpty() )
5483 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5485 if ( !( ( *it )->accept( visitor, context ) ) )
5497 return mElevationShadingRenderer;
5500void QgsProject::loadProjectFlags(
const QDomDocument *doc )
5504 QDomElement element = doc->documentElement().firstChildElement( u
"projectFlags"_s );
5506 if ( !element.isNull() )
5513 element = doc->documentElement().firstChildElement( u
"evaluateDefaultValues"_s );
5514 if ( !element.isNull() )
5516 if ( element.attribute( u
"active"_s, u
"0"_s ).toInt() == 1 )
5521 element = doc->documentElement().firstChildElement( u
"trust"_s );
5522 if ( !element.isNull() )
5524 if ( element.attribute( u
"active"_s, u
"0"_s ).toInt() == 1 )
5538 const QString projectFunctions =
readEntry( u
"ExpressionFunctions"_s, u
"/pythonCode"_s, QString() );
5539 if ( !projectFunctions.isEmpty() )
5559QHash< QString, QColor > loadColorsFromProject(
const QgsProject *project )
5561 QHash< QString, QColor > colors;
5564 QStringList colorStrings = project->
readListEntry( u
"Palette"_s, u
"/Colors"_s );
5565 const QStringList colorLabels = project->
readListEntry( u
"Palette"_s, u
"/Labels"_s );
5569 for ( QStringList::iterator it = colorStrings.begin(); it != colorStrings.end(); ++it )
5573 if ( colorLabels.length() > colorIndex )
5575 label = colorLabels.at( colorIndex );
5578 colors.insert( label.toLower(), color );
5586GetNamedProjectColor::GetNamedProjectColor(
const QgsProject *project )
5592 mColors = loadColorsFromProject( project );
5595GetNamedProjectColor::GetNamedProjectColor(
const QHash<QString, QColor> &colors )
5602 const QString colorName = values.at( 0 ).toString().toLower();
5603 if ( mColors.contains( colorName ) )
5605 return u
"%1,%2,%3"_s.arg( mColors.value( colorName ).red() ).arg( mColors.value( colorName ).green() ).arg( mColors.value( colorName ).blue() );
5613 return new GetNamedProjectColor( mColors );
5616GetNamedProjectColorObject::GetNamedProjectColorObject(
const QgsProject *project )
5622 mColors = loadColorsFromProject( project );
5625GetNamedProjectColorObject::GetNamedProjectColorObject(
const QHash<QString, QColor> &colors )
5632 const QString colorName = values.at( 0 ).toString().toLower();
5633 if ( mColors.contains( colorName ) )
5635 return mColors.value( colorName );
5643 return new GetNamedProjectColorObject( mColors );
5648GetSensorData::GetSensorData(
const QMap<QString, QgsAbstractSensor::SensorData> &sensorData )
5650 , mSensorData( sensorData )
5655 const QString sensorName = values.at( 0 ).toString();
5656 const int expiration = values.at( 1 ).toInt();
5657 const qint64 timestamp = QDateTime::currentMSecsSinceEpoch();
5658 if ( mSensorData.contains( sensorName ) )
5660 if ( expiration <= 0 || ( timestamp - mSensorData[sensorName].lastTimestamp.toMSecsSinceEpoch() ) < expiration )
5662 return mSensorData[sensorName].lastValue;
5671 return new GetSensorData( mSensorData );
@ ExpressionFunction
Expression functions.
@ 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 has been determined by the user as trusted.
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.