19#include "moc_qgsproject.cpp"
81#include <QApplication>
86#include <QTemporaryFile>
89#include <QStandardPaths>
91#include <QRegularExpression>
113 QStringList keyTokens = QStringList( scope );
114 keyTokens += key.split(
'/', Qt::SkipEmptyParts );
117 keyTokens.push_front( QStringLiteral(
"properties" ) );
142 while ( !keySequence.isEmpty() )
146 if ( keySequence.first() == currentProperty->
name() )
149 keySequence.pop_front();
151 if ( 1 == keySequence.count() )
154 return currentProperty->
find( keySequence.front() );
156 else if ( keySequence.isEmpty() )
161 return currentProperty;
163 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
165 if ( nextProperty->
isKey() )
169 else if ( nextProperty->
isValue() && 1 == keySequence.count() )
175 return currentProperty;
213 const QVariant &value,
214 bool &propertiesModified )
223 propertiesModified =
false;
224 while ( ! keySequence.isEmpty() )
228 if ( keySequence.first() == currentProperty->
name() )
231 keySequence.pop_front();
235 if ( 1 == keySequence.count() )
238 if ( !property || property->value() != value )
240 currentProperty->
setValue( keySequence.front(), value );
241 propertiesModified =
true;
244 return currentProperty;
248 else if ( keySequence.isEmpty() )
250 if ( currentProperty->
value() != value )
253 propertiesModified =
true;
256 return currentProperty;
258 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
262 if ( currentProperty )
273 if ( ( newPropertyKey = currentProperty->
addKey( keySequence.first() ) ) )
275 currentProperty = newPropertyKey;
307 while ( ! keySequence.isEmpty() )
311 if ( keySequence.first() == currentProperty->
name() )
314 keySequence.pop_front();
318 if ( 1 == keySequence.count() )
320 currentProperty->
removeKey( keySequence.front() );
325 else if ( keySequence.isEmpty() )
327 previousQgsPropertyKey->
removeKey( currentProperty->
name() );
329 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
331 previousQgsPropertyKey = currentProperty;
334 if ( currentProperty )
358 , mCapabilities( capabilities )
361 , mSnappingConfig( this )
379 mProperties.
setName( QStringLiteral(
"properties" ) );
382 mMainAnnotationLayer->setParent(
this );
389 mLayerTreeRegistryBridge = std::make_unique<QgsLayerTreeRegistryBridge>( mRootGroup.get(),
this,
this );
396 this, [
this](
const QStringList &
layers ) { mProjectScope.reset(); emit layersWillBeRemoved( layers ); } );
398 this, [
this](
const QList<QgsMapLayer *> &
layers ) { mProjectScope.reset(); emit layersWillBeRemoved( layers ); } );
400 this, [
this](
const QString & layer ) { mProjectScope.reset(); emit layerWillBeRemoved( layer ); } );
402 this, [
this](
QgsMapLayer * layer ) { mProjectScope.reset(); emit layerWillBeRemoved( layer ); } );
404 [
this](
const QStringList &
layers ) { mProjectScope.reset(); emit layersRemoved( layers ); } );
406 [
this](
const QString & layer ) { mProjectScope.reset(); emit layerRemoved( layer ); } );
408 [
this]() { mProjectScope.reset(); emit removeAll(); } );
410 [
this](
const QList< QgsMapLayer * > &
layers ) { mProjectScope.reset(); emit layersAdded( layers ); } );
412 [
this](
QgsMapLayer * layer ) { mProjectScope.reset(); emit layerWasAdded( layer ); } );
420 [
this](
const QList<QgsMapLayer *> &
layers )
422 for ( const auto &layer : layers )
424 disconnect( layer, &QgsMapLayer::dataSourceChanged, mRelationManager.get(), &QgsRelationManager::updateRelationsStatus );
429 [
this](
const QList<QgsMapLayer *> &layers )
431 for ( const auto &layer : layers )
433 connect( layer, &QgsMapLayer::dataSourceChanged, mRelationManager.get(), &QgsRelationManager::updateRelationsStatus );
442 mStyleSettings->combinedStyleModel()->addDefaultStyle();
448 mIsBeingDeleted =
true;
451 releaseHandlesToProjectArchive();
453 if (
this == sProject )
484 mProjectScope.reset();
495 return mMetadata.
title();
504 if ( oldEvaluateDefaultValues != newEvaluateDefaultValues )
507 for (
auto layerIt =
layers.constBegin(); layerIt !=
layers.constEnd(); ++layerIt )
509 if (
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layerIt.value() ) )
510 if ( vl->dataProvider() )
517 if ( oldTrustLayerMetadata != newTrustLayerMetadata )
520 for (
auto layerIt =
layers.constBegin(); layerIt !=
layers.constEnd(); ++layerIt )
522 if (
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layerIt.value() ) )
524 vl->setReadExtentFromXml( newTrustLayerMetadata );
529 if ( mFlags !=
flags )
544 newFlags &= ~(
static_cast< int >( flag ) );
559 return mSaveUserFull;
566 return mSaveDateTime;
587 if ( dirty && mDirtyBlockCount > 0 )
593 if ( mDirty == dirty )
604 if ( path == mHomePath )
608 mCachedHomePath.clear();
609 mProjectScope.reset();
620 const QList<QgsAttributeEditorElement *> elements = parent->
children();
628 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:formcontainers" ).arg( layerId ), container->
name() );
630 if ( !container->
children().empty() )
641 const QList<QgsLayerTreeLayer *>
layers = mRootGroup->findLayers();
645 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1" ).arg( layer->layerId() ), layer->name() );
654 for (
const QgsField &field : fields )
657 if ( field.alias().isEmpty() )
658 fieldName = field.name();
660 fieldName = field.alias();
662 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:fieldaliases" ).arg( vlayer->
id() ), fieldName );
664 if ( field.editorWidgetSetup().type() == QStringLiteral(
"ValueRelation" ) )
666 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:fields:%2:valuerelationvalue" ).arg( vlayer->
id(), field.name() ), field.editorWidgetSetup().config().value( QStringLiteral(
"Value" ) ).toString() );
668 if ( field.editorWidgetSetup().type() == QStringLiteral(
"ValueMap" ) )
670 if ( field.editorWidgetSetup().config().value( QStringLiteral(
"map" ) ).canConvert<QList<QVariant>>() )
672 const QList<QVariant> valueList = field.editorWidgetSetup().config().value( QStringLiteral(
"map" ) ).toList();
674 for (
int i = 0, row = 0; i < valueList.count(); i++, row++ )
676 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:fields:%2:valuemapdescriptions" ).arg( vlayer->
id(), field.name() ), valueList[i].toMap().constBegin().key() );
689 const QList<QgsLayerTreeGroup *> groupLayers = mRootGroup->findGroups();
692 translationContext->
registerTranslation( QStringLiteral(
"project:layergroups" ), groupLayer->name() );
696 const QList<QgsRelation> &relations = mRelationManager->relations().values();
699 translationContext->
registerTranslation( QStringLiteral(
"project:relations" ), relation.name() );
707 mDataDefinedServerProperties = properties;
714 return mDataDefinedServerProperties;
721 switch ( mTransactionMode )
742 switch ( mTransactionMode )
749 commitErrors.append( tr(
"Trying to commit changes without a layer specified. This only works if the transaction mode is buffered" ) );
758 return mEditBufferGroup.
commitChanges( commitErrors, stopEditing );
768 switch ( mTransactionMode )
775 rollbackErrors.append( tr(
"Trying to roll back changes without a layer specified. This only works if the transaction mode is buffered" ) );
778 bool success = vectorLayer->
rollBack( stopEditing );
784 return mEditBufferGroup.
rollBack( rollbackErrors, stopEditing );
794 if ( name == mFile.fileName() )
797 const QString oldHomePath =
homePath();
799 mFile.setFileName( name );
800 mCachedHomePath.clear();
801 mProjectScope.reset();
805 const QString newHomePath =
homePath();
806 if ( newHomePath != oldHomePath )
817 return mFile.fileName();
824 mOriginalPath = path;
831 return mOriginalPath;
838 return QFileInfo( mFile );
856 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
861 return QFileInfo( mFile.fileName() ).lastModified();
872 if ( mFile.fileName().isEmpty() )
875 return QFileInfo( mFile.fileName() ).absolutePath();
886 if ( mFile.fileName().isEmpty() )
889 return QFileInfo( mFile.fileName() ).absoluteFilePath();
900 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
905 return QFileInfo( mFile.fileName() ).completeBaseName();
913 const bool absolutePaths =
readBoolEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
false );
924 writeEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
true );
927 writeEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
false );
944 return mCrs3D.
isValid() ? mCrs3D : mCrs;
956 writeEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectionsEnabled" ),
crs.
isValid() ? 1 : 0 );
957 mProjectScope.reset();
971 if ( oldCrs3D != mCrs3D )
975 if ( adjustEllipsoid )
984 if ( !
crs().isValid() )
994 if (
ellipsoid ==
readEntry( QStringLiteral(
"Measure" ), QStringLiteral(
"/Ellipsoid" ) ) )
997 mProjectScope.reset();
1007 switch ( mCrs.
type() )
1010 QgsDebugError( QStringLiteral(
"Project has a vertical CRS set as the horizontal CRS!" ) );
1029 return mVerticalCrs;
1057 *errorMessage = QObject::tr(
"Specified CRS is a %1 CRS, not a Vertical CRS" ).arg(
qgsEnumValueToKey(
crs.
type() ) );
1062 if (
crs != mVerticalCrs )
1067 switch ( mCrs.
type() )
1070 if (
crs != oldVerticalCrs )
1073 *errorMessage = QObject::tr(
"Project CRS is a Compound CRS, specified Vertical CRS will be ignored" );
1079 if (
crs != oldVerticalCrs )
1082 *errorMessage = QObject::tr(
"Project CRS is a Geographic 3D CRS, specified Vertical CRS will be ignored" );
1088 if (
crs != oldVerticalCrs )
1091 *errorMessage = QObject::tr(
"Project CRS is a Geocentric CRS, specified Vertical CRS will be ignored" );
1100 *errorMessage = QObject::tr(
"Project CRS is a Projected 3D CRS, specified Vertical CRS will be ignored" );
1118 res = rebuildCrs3D( errorMessage );
1119 mProjectScope.reset();
1126 if ( mCrs3D != oldCrs3D )
1137 return mTransformContext;
1144 if ( context == mTransformContext )
1147 mTransformContext = context;
1148 mProjectScope.reset();
1151 for (
auto &layer : mLayerStore.get()->mapLayers() )
1153 layer->setTransformContext( context );
1162 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
1166 if ( !mIsBeingDeleted )
1175 mProjectScope.reset();
1176 mFile.setFileName( QString() );
1179 mSaveUserFull.clear();
1180 mSaveDateTime = QDateTime();
1183 mCachedHomePath.clear();
1187 mCustomVariables.clear();
1193 if ( !mSettings.
value( QStringLiteral(
"projects/anonymize_new_projects" ),
false,
QgsSettings::Core ).toBool() )
1214 mEmbeddedLayers.clear();
1215 mRelationManager->clear();
1216 mAnnotationManager->clear();
1217 mLayoutManager->clear();
1218 m3DViewsManager->clear();
1219 mBookmarkManager->
clear();
1220 mSensorManager->
clear();
1221 mViewSettings->
reset();
1222 mTimeSettings->
reset();
1223 mElevationProperties->
reset();
1224 mDisplaySettings->
reset();
1225 mGpsSettings->
reset();
1226 mSnappingConfig.
reset();
1234 mLabelingEngineSettings->clear();
1238 releaseHandlesToProjectArchive();
1244 mStyleSettings->
reset();
1248 if ( !mIsBeingDeleted )
1256 writeEntry( QStringLiteral(
"PositionPrecision" ), QStringLiteral(
"/Automatic" ),
true );
1257 writeEntry( QStringLiteral(
"PositionPrecision" ), QStringLiteral(
"/DecimalPlaces" ), 2 );
1259 const bool defaultRelativePaths = mSettings.
value( QStringLiteral(
"/qgis/defaultProjectPathsRelative" ),
true ).toBool();
1262 int red = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_red" ), 255 ).toInt();
1263 int green = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_green" ), 255 ).toInt();
1264 int blue = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_blue" ), 255 ).toInt();
1267 red = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_red" ), 255 ).toInt();
1268 green = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_green" ), 255 ).toInt();
1269 blue = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_blue" ), 0 ).toInt();
1270 const int alpha = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_alpha" ), 255 ).toInt();
1276 mRootGroup->clear();
1277 if ( mMainAnnotationLayer )
1278 mMainAnnotationLayer->
reset();
1280 snapSingleBlocker.release();
1282 if ( !mBlockSnappingUpdates )
1287 if ( !mBlockChangeSignalsDuringClear )
1299 topQgsPropertyKey.
dump();
1332 const QDomElement propertiesElem = doc.documentElement().firstChildElement( QStringLiteral(
"properties" ) );
1334 if ( propertiesElem.isNull() )
1339 const QDomNodeList scopes = propertiesElem.childNodes();
1341 if ( propertiesElem.firstChild().isNull() )
1343 QgsDebugError( QStringLiteral(
"empty ``properties'' XML tag ... bailing" ) );
1347 if ( ! project_properties.
readXml( propertiesElem ) )
1349 QgsDebugError( QStringLiteral(
"Project_properties.readXml() failed" ) );
1363 const QDomElement ddElem = doc.documentElement().firstChildElement( QStringLiteral(
"dataDefinedServerProperties" ) );
1364 if ( !ddElem.isNull() )
1366 if ( !ddServerProperties.
readXml( ddElem, dataDefinedServerPropertyDefinitions ) )
1368 QgsDebugError( QStringLiteral(
"dataDefinedServerProperties.readXml() failed" ) );
1371 return ddServerProperties;
1378static void _getTitle(
const QDomDocument &doc, QString &title )
1380 const QDomElement titleNode = doc.documentElement().firstChildElement( QStringLiteral(
"title" ) );
1384 if ( titleNode.isNull() )
1390 if ( !titleNode.hasChildNodes() )
1396 const QDomNode titleTextNode = titleNode.firstChild();
1398 if ( !titleTextNode.isText() )
1404 const QDomText titleText = titleTextNode.toText();
1406 title = titleText.data();
1410static void readProjectFileMetadata(
const QDomDocument &doc, QString &lastUser, QString &lastUserFull, QDateTime &lastSaveDateTime )
1412 const QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"qgis" ) );
1416 QgsDebugError( QStringLiteral(
"unable to find qgis element" ) );
1420 const QDomNode qgisNode = nl.item( 0 );
1422 const QDomElement qgisElement = qgisNode.toElement();
1423 lastUser = qgisElement.attribute( QStringLiteral(
"saveUser" ), QString() );
1424 lastUserFull = qgisElement.attribute( QStringLiteral(
"saveUserFull" ), QString() );
1425 lastSaveDateTime = QDateTime::fromString( qgisElement.attribute( QStringLiteral(
"saveDateTime" ), QString() ), Qt::ISODate );
1430 const QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"qgis" ) );
1434 QgsDebugError( QStringLiteral(
" unable to find qgis element in project file" ) );
1438 const QDomNode qgisNode = nl.item( 0 );
1440 const QDomElement qgisElement = qgisNode.toElement();
1441 QgsProjectVersion projectVersion( qgisElement.attribute( QStringLiteral(
"version" ) ) );
1442 return projectVersion;
1449 return mSnappingConfig;
1468 if ( mAvoidIntersectionsMode == mode )
1471 mAvoidIntersectionsMode = mode;
1505void QgsProject::preloadProviders(
const QVector<QDomNode> ¶llelLayerNodes,
1507 QMap<QString, QgsDataProvider *> &loadedProviders,
1509 int totalProviderCount )
1514 QMap<QString, LayerToLoad> layersToLoad;
1516 for (
const QDomNode &node : parallelLayerNodes )
1520 const QDomElement layerElement = node.toElement();
1522 layerToLoad.
layerId = layerElement.namedItem( QStringLiteral(
"id" ) ).toElement().text();
1523 layerToLoad.
provider = layerElement.namedItem( QStringLiteral(
"provider" ) ).toElement().text();
1524 layerToLoad.
dataSource = layerElement.namedItem( QStringLiteral(
"datasource" ) ).toElement().text();
1535 layersToLoad.insert( layerToLoad.
layerId, layerToLoad );
1538 while ( !layersToLoad.isEmpty() )
1540 const QList<LayerToLoad> layersToAttemptInParallel = layersToLoad.values();
1541 QString layerToAttemptInMainThread;
1543 QHash<QString, QgsRunnableProviderCreator *> runnables;
1544 QThreadPool threadPool;
1547 for (
const LayerToLoad &lay : layersToAttemptInParallel )
1550 runnables.insert( lay.layerId, run );
1556 layersToLoad.remove( layId );
1559 Q_ASSERT( finishedRun );
1561 std::unique_ptr<QgsDataProvider> provider( finishedRun->
dataProvider() );
1562 Q_ASSERT( provider && provider->isValid() );
1564 loadedProviders.insert( layId, provider.release() );
1569 if ( layerToAttemptInMainThread.isEmpty() )
1570 layerToAttemptInMainThread = layId;
1574 if ( i == parallelLayerNodes.count() || !isValid )
1577 threadPool.start( run );
1581 threadPool.waitForDone();
1583 qDeleteAll( runnables );
1586 auto it = layersToLoad.find( layerToAttemptInMainThread );
1587 if ( it != layersToLoad.end() )
1589 std::unique_ptr<QgsDataProvider> provider;
1599 if ( provider && provider->isValid() )
1604 layersToLoad.erase( it );
1607 loadedProviders.insert( layerId, provider.release() );
1615void QgsProject::releaseHandlesToProjectArchive()
1620bool QgsProject::rebuildCrs3D( QString *error )
1627 else if ( !mVerticalCrs.
isValid() )
1633 switch ( mCrs.
type() )
1674bool QgsProject::_getMapLayers(
const QDomDocument &doc, QList<QDomNode> &brokenNodes,
Qgis::ProjectReadFlags flags )
1681 QDomElement layerElement = doc.documentElement().firstChildElement( QStringLiteral(
"projectlayers" ) ).firstChildElement( QStringLiteral(
"maplayer" ) );
1685 if ( layerElement.isNull() )
1695 bool returnStatus =
true;
1698 while ( ! layerElement.isNull() )
1701 layerElement = layerElement.nextSiblingElement( QStringLiteral(
"maplayer" ) );
1707 if ( depSorter.hasCycle() )
1711 if ( depSorter.hasMissingDependency() )
1712 returnStatus =
false;
1716 const QVector<QDomNode> sortedLayerNodes = depSorter.sortedLayerNodes();
1717 const int totalLayerCount = sortedLayerNodes.count();
1719 QVector<QDomNode> parallelLoading;
1720 QMap<QString, QgsDataProvider *> loadedProviders;
1725 profile.switchTask( tr(
"Load providers in parallel" ) );
1726 for (
const QDomNode &node : sortedLayerNodes )
1728 const QDomElement element = node.toElement();
1729 if ( element.attribute( QStringLiteral(
"embedded" ) ) != QLatin1String(
"1" ) )
1731 const QString layerId = node.namedItem( QStringLiteral(
"id" ) ).toElement().text();
1732 if ( !depSorter.isLayerDependent( layerId ) )
1734 const QDomNode mnl = element.namedItem( QStringLiteral(
"provider" ) );
1735 const QDomElement mne = mnl.toElement();
1736 const QString provider = mne.text();
1740 parallelLoading.append( node );
1749 if ( !parallelLoading.isEmpty() )
1750 preloadProviders( parallelLoading, context, loadedProviders, projectFlagsToLayerReadFlags(
flags, mFlags ), sortedLayerNodes.count() );
1753 int i = loadedProviders.count();
1754 for (
const QDomNode &node : std::as_const( sortedLayerNodes ) )
1756 const QDomElement element = node.toElement();
1757 const QString name =
translate( QStringLiteral(
"project:layers:%1" ).arg( node.namedItem( QStringLiteral(
"id" ) ).toElement().text() ), node.namedItem( QStringLiteral(
"layername" ) ).toElement().text() );
1758 if ( !name.isNull() )
1759 emit
loadingLayer( tr(
"Loading layer %1" ).arg( name ) );
1761 profile.switchTask( name );
1762 if ( element.attribute( QStringLiteral(
"embedded" ) ) == QLatin1String(
"1" ) )
1764 createEmbeddedLayer( element.attribute( QStringLiteral(
"id" ) ),
readPath( element.attribute( QStringLiteral(
"project" ) ) ), brokenNodes,
true,
flags );
1772 QString layerId = element.namedItem( QStringLiteral(
"id" ) ).toElement().text();
1774 if ( !addLayer( element, brokenNodes, context,
flags, loadedProviders.take( layerId ) ) )
1776 returnStatus =
false;
1779 if ( !messages.isEmpty() )
1788 return returnStatus;
1791bool QgsProject::addLayer(
const QDomElement &layerElem,
1792 QList<QDomNode> &brokenNodes,
1799 const QString type = layerElem.attribute( QStringLiteral(
"type" ) );
1801 std::unique_ptr<QgsMapLayer>
mapLayer;
1809 QgsDebugError( QStringLiteral(
"Unknown layer type \"%1\"" ).arg( type ) );
1813 switch ( layerType )
1816 mapLayer = std::make_unique<QgsVectorLayer>();
1820 mapLayer = std::make_unique<QgsRasterLayer>();
1824 mapLayer = std::make_unique<QgsMeshLayer>();
1828 mapLayer = std::make_unique<QgsVectorTileLayer>();
1832 mapLayer = std::make_unique<QgsPointCloudLayer>();
1836 mapLayer = std::make_unique<QgsTiledSceneLayer>();
1841 const QString
typeName = layerElem.attribute( QStringLiteral(
"name" ) );
1849 mapLayer = std::make_unique<QgsAnnotationLayer>( QString(), options );
1856 mapLayer = std::make_unique<QgsGroupLayer>( QString(), options );
1863 QgsDebugError( QStringLiteral(
"Unable to create layer" ) );
1871 const QString layerId { layerElem.namedItem( QStringLiteral(
"id" ) ).toElement().text() };
1872 Q_ASSERT( ! layerId.isEmpty() );
1878 profile.switchTask( tr(
"Load layer source" ) );
1885 if ( vl->dataProvider() )
1892 profile.switchTask( tr(
"Add layer to project" ) );
1893 QList<QgsMapLayer *> newLayers;
1905 vLayer->joinBuffer()->resolveReferences(
this );
1914 brokenNodes.push_back( layerElem );
1917 const bool wasEditable = layerElem.attribute( QStringLiteral(
"editable" ), QStringLiteral(
"0" ) ).toInt();
1929 if ( ! layerWasStored )
1934 return layerIsValid;
1941 mFile.setFileName( filename );
1942 mCachedHomePath.clear();
1943 mProjectScope.reset();
1952 const QString filename = mFile.fileName();
1957 QTemporaryFile inDevice;
1958 if ( !inDevice.open() )
1960 setError( tr(
"Unable to open %1" ).arg( inDevice.fileName() ) );
1966 if ( !storage->readProject( filename, &inDevice, context ) )
1968 QString err = tr(
"Unable to open %1" ).arg( filename );
1969 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
1970 if ( !messages.isEmpty() )
1971 err += QStringLiteral(
"\n\n" ) + messages.last().message();
1975 returnValue = unzip( inDevice.fileName(),
flags );
1981 returnValue = unzip( mFile.fileName(),
flags );
1986 const QFileInfo finfo( mFile.fileName() );
1987 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( QStringLiteral(
"%1_attachments.zip" ).arg( finfo.completeBaseName() ) );
1988 if ( QFile( attachmentsZip ).exists() )
1990 auto archive = std::make_unique<QgsArchive>();
1991 if ( archive->unzip( attachmentsZip ) )
1993 releaseHandlesToProjectArchive();
1994 mArchive = std::move( archive );
1997 returnValue = readProjectFile( mFile.fileName(),
flags );
2003 mFile.setFileName( filename );
2004 mCachedHomePath.clear();
2005 mProjectScope.reset();
2010 mTranslator.reset(
nullptr );
2022 ScopedIntIncrementor snapSignalBlock( &mBlockSnappingUpdates );
2024 QFile projectFile( filename );
2032 if ( QFile( QStringLiteral(
"%1/%2.qm" ).arg( QFileInfo( projectFile.fileName() ).absolutePath(), localeFileName ) ).exists() )
2034 mTranslator.reset(
new QTranslator() );
2035 ( void )mTranslator->load( localeFileName, QFileInfo( projectFile.fileName() ).absolutePath() );
2038 profile.switchTask( tr(
"Reading project file" ) );
2039 auto doc = std::make_unique<QDomDocument>( QStringLiteral(
"qgis" ) );
2041 if ( !projectFile.open( QIODevice::ReadOnly | QIODevice::Text ) )
2043 projectFile.close();
2045 setError( tr(
"Unable to open %1" ).arg( projectFile.fileName() ) );
2050 QTextStream textStream( &projectFile );
2051#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
2052 textStream.setCodec(
"UTF-8" );
2054 QString projectString = textStream.readAll();
2055 projectFile.close();
2057 for (
int i = 0; i < 32; i++ )
2059 if ( i == 9 || i == 10 || i == 13 )
2063 projectString.replace( QChar( i ), QStringLiteral(
"%1%2%1" ).arg(
FONTMARKER_CHR_FIX, QString::number( i ) ) );
2069 if ( !doc->setContent( projectString, &errorMsg, &line, &column ) )
2071 const QString errorString = tr(
"Project file read error in file %1: %2 at line %3 column %4" )
2072 .arg( projectFile.fileName(), errorMsg ).arg( line ).arg( column );
2074 setError( errorString );
2079 projectFile.close();
2087 profile.switchTask( tr(
"Updating project file" ) );
2088 if ( thisVersion > fileVersion )
2090 const bool isOlderMajorVersion = fileVersion.
majorVersion() < thisVersion.majorVersion();
2092 if ( isOlderMajorVersion )
2095 "version of qgis (saved in " + fileVersion.
text() +
2097 "). Problems may occur." );
2108 projectFile.updateRevision( thisVersion );
2110 else if ( fileVersion > thisVersion )
2113 "version of qgis (saved in " + fileVersion.
text() +
2115 "). Problems may occur." );
2121 profile.switchTask( tr(
"Creating auxiliary storage" ) );
2122 const QString
fileName = mFile.fileName();
2129 std::unique_ptr<QgsAuxiliaryStorage> aStorage = std::move( mAuxiliaryStorage );
2130 std::unique_ptr<QgsArchive> archive = std::move( mArchive );
2134 mBlockChangeSignalsDuringClear =
true;
2136 mBlockChangeSignalsDuringClear =
false;
2141 releaseHandlesToProjectArchive();
2143 mAuxiliaryStorage = std::move( aStorage );
2144 mArchive = std::move( archive );
2147 mCachedHomePath.clear();
2148 mProjectScope.reset();
2149 mSaveVersion = fileVersion;
2152 profile.switchTask( tr(
"Reading properties" ) );
2161 dump_( mProperties );
2166 _getTitle( *doc, oldTitle );
2168 readProjectFileMetadata( *doc, mSaveUser, mSaveUserFull, mSaveDateTime );
2170 const QDomNodeList homePathNl = doc->elementsByTagName( QStringLiteral(
"homePath" ) );
2171 if ( homePathNl.count() > 0 )
2173 const QDomElement homePathElement = homePathNl.at( 0 ).toElement();
2174 const QString
homePath = homePathElement.attribute( QStringLiteral(
"path" ) );
2184 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorGreenPart" ), 255 ),
2185 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorBluePart" ), 255 ) );
2188 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorGreenPart" ), 255 ),
2189 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorBluePart" ), 255 ),
2190 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorAlphaPart" ), 255 ) );
2194 const QString distanceUnitString =
readEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/DistanceUnits" ), QString() );
2195 if ( !distanceUnitString.isEmpty() )
2198 const QString areaUnitString =
readEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/AreaUnits" ), QString() );
2199 if ( !areaUnitString.isEmpty() )
2210 if (
readNumEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectionsEnabled" ), 0 ) )
2213 const QDomNode srsNode = doc->documentElement().namedItem( QStringLiteral(
"projectCrs" ) );
2214 if ( !srsNode.isNull() )
2216 projectCrs.
readXml( srsNode );
2221 const QString projCrsString =
readEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCRSProj4String" ) );
2222 const long currentCRS =
readNumEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCRSID" ), -1 );
2223 const QString authid =
readEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCrs" ) );
2226 const bool isUserAuthId = authid.startsWith( QLatin1String(
"USER:" ), Qt::CaseInsensitive );
2227 if ( !authid.isEmpty() && !isUserAuthId )
2231 if ( !projectCrs.
isValid() && currentCRS >= 0 )
2237 if ( !projCrsString.isEmpty() && ( authid.isEmpty() || isUserAuthId ) && ( !projectCrs.
isValid() || projectCrs.
toProj() != projCrsString ) )
2254 const QDomNode verticalCrsNode = doc->documentElement().namedItem( QStringLiteral(
"verticalCrs" ) );
2255 if ( !verticalCrsNode.isNull() )
2263 QStringList datumErrors;
2264 if ( !mTransformContext.
readXml( doc->documentElement(), context, datumErrors ) && !datumErrors.empty() )
2271 const QDomNode elevationShadingNode = doc->documentElement().namedItem( QStringLiteral(
"elevation-shading-renderer" ) );
2272 if ( !elevationShadingNode.isNull() )
2274 mElevationShadingRenderer.
readXml( elevationShadingNode.toElement(), context );
2281 const QStringList variableNames =
readListEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableNames" ) );
2282 const QStringList variableValues =
readListEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableValues" ) );
2284 mCustomVariables.clear();
2285 if ( variableNames.length() == variableValues.length() )
2287 for (
int i = 0; i < variableNames.length(); ++i )
2289 mCustomVariables.insert( variableNames.at( i ), variableValues.at( i ) );
2294 QgsMessageLog::logMessage( tr(
"Project Variables Invalid" ), tr(
"The project contains invalid variable settings." ) );
2302 QDomElement element = doc->documentElement().firstChildElement( QStringLiteral(
"projectMetadata" ) );
2304 if ( !element.isNull() )
2313 if ( mMetadata.
title().isEmpty() && !oldTitle.isEmpty() )
2321 element = doc->documentElement().firstChildElement( QStringLiteral(
"transaction" ) );
2322 if ( !element.isNull() )
2329 element = doc->documentElement().firstChildElement( QStringLiteral(
"autotransaction" ) );
2330 if ( ! element.isNull() )
2332 mTransactionMode =
static_cast<Qgis::TransactionMode>( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() );
2337 profile.switchTask( tr(
"Loading layer tree" ) );
2338 mRootGroup->setCustomProperty( QStringLiteral(
"loading" ), 1 );
2340 QDomElement layerTreeElem = doc->documentElement().firstChildElement( QStringLiteral(
"layer-tree-group" ) );
2341 if ( !layerTreeElem.isNull() )
2353 mLayerTreeRegistryBridge->setEnabled(
false );
2356 profile.switchTask( tr(
"Reading map layers" ) );
2358 loadProjectFlags( doc.get() );
2360 QList<QDomNode> brokenNodes;
2361 const bool clean = _getMapLayers( *doc, brokenNodes,
flags );
2366 QgsDebugError( QStringLiteral(
"Unable to get map layers from project file." ) );
2368 if ( !brokenNodes.isEmpty() )
2370 QgsDebugError(
"there are " + QString::number( brokenNodes.size() ) +
" broken layers" );
2375 mBadLayerHandler->handleBadLayers( brokenNodes );
2378 mMainAnnotationLayer->
readLayerXml( doc->documentElement().firstChildElement( QStringLiteral(
"main-annotation-layer" ) ), context );
2382 profile.switchTask( tr(
"Loading embedded layers" ) );
2383 loadEmbeddedNodes( mRootGroup.get(),
flags );
2387 profile.switchTask( tr(
"Resolving layer references" ) );
2388 QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
2389 for ( QMap<QString, QgsMapLayer *>::iterator it =
layers.begin(); it !=
layers.end(); ++it )
2391 it.value()->resolveReferences(
this );
2395 mLayerTreeRegistryBridge->setEnabled(
true );
2398 profile.switchTask( tr(
"Resolving references" ) );
2399 mRootGroup->resolveReferences(
this );
2409 if ( !layerTreeElem.isNull() )
2411 mRootGroup->readLayerOrderFromXml( layerTreeElem );
2415 const QDomElement layerTreeCanvasElem = doc->documentElement().firstChildElement( QStringLiteral(
"layer-tree-canvas" ) );
2416 if ( !layerTreeCanvasElem.isNull( ) )
2418 mRootGroup->readLayerOrderFromXml( layerTreeCanvasElem );
2424 const QStringList requiredLayerIds =
readListEntry( QStringLiteral(
"RequiredLayers" ), QStringLiteral(
"Layers" ) );
2425 for (
const QString &layerId : requiredLayerIds )
2432 const QStringList disabledLayerIds =
readListEntry( QStringLiteral(
"Identify" ), QStringLiteral(
"/disabledLayers" ) );
2433 for (
const QString &layerId : disabledLayerIds )
2446 QString styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Marker" ) );
2447 if ( !styleName.isEmpty() )
2452 styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Line" ) );
2453 if ( !styleName.isEmpty() )
2458 styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Fill" ) );
2459 if ( !styleName.isEmpty() )
2464 styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/ColorRamp" ) );
2465 if ( !styleName.isEmpty() )
2475 double opacity = 1.0;
2478 double alpha =
readDoubleEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/AlphaInt" ), 255, &ok );
2480 opacity = alpha / 255.0;
2481 double newOpacity =
readDoubleEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Opacity" ), 1.0, &ok );
2483 opacity = newOpacity;
2487 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Marker" ) );
2488 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Line" ) );
2489 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Fill" ) );
2490 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/ColorRamp" ) );
2491 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/RandomColors" ) );
2492 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/AlphaInt" ) );
2493 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Opacity" ) );
2501 profile.switchTask( tr(
"Storing original layer properties" ) );
2505 mRootGroup->removeCustomProperty( QStringLiteral(
"loading" ) );
2507 profile.switchTask( tr(
"Loading map themes" ) );
2510 mMapThemeCollection->readXml( *doc );
2512 profile.switchTask( tr(
"Loading label settings" ) );
2513 mLabelingEngineSettings->readSettingsFromProject(
this );
2515 const QDomElement labelEngineSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"labelEngineSettings" ) );
2516 mLabelingEngineSettings->readXml( labelEngineSettingsElement, context );
2518 mLabelingEngineSettings->resolveReferences(
this );
2522 profile.switchTask( tr(
"Loading annotations" ) );
2525 mAnnotationManager->readXml( doc->documentElement(), context );
2529 mAnnotationManager->readXmlAndUpgradeToAnnotationLayerItems( doc->documentElement(), context, mMainAnnotationLayer, mTransformContext );
2533 profile.switchTask( tr(
"Loading layouts" ) );
2534 mLayoutManager->readXml( doc->documentElement(), *doc );
2539 profile.switchTask( tr(
"Loading 3D Views" ) );
2540 m3DViewsManager->readXml( doc->documentElement(), *doc );
2543 profile.switchTask( tr(
"Loading bookmarks" ) );
2544 mBookmarkManager->
readXml( doc->documentElement(), *doc );
2546 profile.switchTask( tr(
"Loading sensors" ) );
2547 mSensorManager->
readXml( doc->documentElement(), *doc );
2550 QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
2551 for ( QMap<QString, QgsMapLayer *>::iterator it = existingMaps.begin(); it != existingMaps.end(); ++it )
2553 it.value()->setDependencies( it.value()->dependencies() );
2556 profile.switchTask( tr(
"Loading snapping settings" ) );
2560 profile.switchTask( tr(
"Loading view settings" ) );
2563 const QStringList scales =
readListEntry( QStringLiteral(
"Scales" ), QStringLiteral(
"/ScalesList" ) );
2564 QVector<double> res;
2565 for (
const QString &scale : scales )
2567 const QStringList parts = scale.split(
':' );
2568 if ( parts.size() != 2 )
2572 const double denominator = QLocale().toDouble( parts[1], &ok );
2579 const QDomElement viewSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectViewSettings" ) );
2580 if ( !viewSettingsElement.isNull() )
2581 mViewSettings->
readXml( viewSettingsElement, context );
2584 profile.switchTask( tr(
"Loading style properties" ) );
2585 const QDomElement styleSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectStyleSettings" ) );
2586 if ( !styleSettingsElement.isNull() )
2589 mStyleSettings->
readXml( styleSettingsElement, context,
flags );
2593 profile.switchTask( tr(
"Loading temporal settings" ) );
2594 const QDomElement timeSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectTimeSettings" ) );
2595 if ( !timeSettingsElement.isNull() )
2596 mTimeSettings->
readXml( timeSettingsElement, context );
2599 profile.switchTask( tr(
"Loading elevation properties" ) );
2600 const QDomElement elevationPropertiesElement = doc->documentElement().firstChildElement( QStringLiteral(
"ElevationProperties" ) );
2601 if ( !elevationPropertiesElement.isNull() )
2602 mElevationProperties->
readXml( elevationPropertiesElement, context );
2605 profile.switchTask( tr(
"Loading display settings" ) );
2607 const QDomElement displaySettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectDisplaySettings" ) );
2608 if ( !displaySettingsElement.isNull() )
2609 mDisplaySettings->
readXml( displaySettingsElement, context );
2612 profile.switchTask( tr(
"Loading GPS settings" ) );
2614 const QDomElement gpsSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectGpsSettings" ) );
2615 if ( !gpsSettingsElement.isNull() )
2616 mGpsSettings->
readXml( gpsSettingsElement, context );
2620 profile.switchTask( tr(
"Updating variables" ) );
2622 profile.switchTask( tr(
"Updating CRS" ) );
2626 if ( mCrs3D != oldCrs3D )
2631 profile.switchTask( tr(
"Reading external settings" ) );
2635 profile.switchTask( tr(
"Updating interface" ) );
2637 snapSignalBlock.release();
2638 if ( !mBlockSnappingUpdates )
2649 QgsDebugMsgLevel( QStringLiteral(
"Project save user: %1" ).arg( mSaveUser ), 2 );
2650 QgsDebugMsgLevel( QStringLiteral(
"Project save user: %1" ).arg( mSaveUserFull ), 2 );
2659 const QString newFileName( QStringLiteral(
"%1/%2.qgs" ).arg( QFileInfo( projectFile.fileName() ).absolutePath(), localeFileName ) );
2674 const QMap<QString, QgsMapLayer *> loadedLayers =
mapLayers();
2675 for (
auto it = loadedLayers.constBegin(); it != loadedLayers.constEnd(); ++it )
2677 if ( it.value()->isValid() && it.value()->customProperty( QStringLiteral(
"_layer_was_editable" ) ).toBool() )
2679 if (
QgsVectorLayer *vl = qobject_cast< QgsVectorLayer * >( it.value() ) )
2681 it.value()->removeCustomProperty( QStringLiteral(
"_layer_was_editable" ) );
2693 const auto constChildren = group->
children();
2699 if ( childGroup->
customProperty( QStringLiteral(
"embedded" ) ).toInt() )
2702 const QString projectPath =
readPath( childGroup->
customProperty( QStringLiteral(
"embedded_project" ) ).toString() );
2703 childGroup->
setCustomProperty( QStringLiteral(
"embedded_project" ), projectPath );
2707 QList<QgsLayerTreeNode *> clonedChildren;
2708 const QList<QgsLayerTreeNode *> constChildren = newGroup->
children();
2709 clonedChildren.reserve( constChildren.size() );
2711 clonedChildren << newGroupChild->clone();
2719 loadEmbeddedNodes( childGroup,
flags );
2724 if ( child->customProperty( QStringLiteral(
"embedded" ) ).toInt() )
2726 QList<QDomNode> brokenNodes;
2729 valid = valid &&
false;
2744 return mCustomVariables;
2751 if ( variables == mCustomVariables )
2755 QStringList variableNames;
2756 QStringList variableValues;
2758 QVariantMap::const_iterator it = variables.constBegin();
2759 for ( ; it != variables.constEnd(); ++it )
2761 variableNames << it.key();
2762 variableValues << it.value().toString();
2765 writeEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableNames" ), variableNames );
2766 writeEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableValues" ), variableValues );
2768 mCustomVariables = variables;
2769 mProjectScope.reset();
2778 *mLabelingEngineSettings = settings;
2786 return *mLabelingEngineSettings;
2793 mProjectScope.reset();
2794 return mLayerStore.get();
2801 return mLayerStore.get();
2808 QList<QgsVectorLayer *>
layers;
2809 const QStringList layerIds =
readListEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsList" ), QStringList() );
2810 const auto constLayerIds = layerIds;
2811 for (
const QString &layerId : constLayerIds )
2824 list.reserve(
layers.size() );
2829 list << layer->id();
2832 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsList" ), list );
2854 if ( mProjectScope )
2856 auto projectScope = std::make_unique< QgsExpressionContextScope >( *mProjectScope );
2863 projectScope->addFunction( QStringLiteral(
"sensor_data" ),
new GetSensorData(
sensorManager()->sensorsData() ) );
2865 return projectScope.release();
2868 mProjectScope = std::make_unique< QgsExpressionContextScope >( QObject::tr(
"Project" ) );
2872 QVariantMap::const_iterator it = vars.constBegin();
2874 for ( ; it != vars.constEnd(); ++it )
2876 mProjectScope->setVariable( it.key(), it.value(),
true );
2880 if ( projectPath.isEmpty() )
2881 projectPath = mOriginalPath;
2882 const QString projectFolder = QFileInfo( projectPath ).path();
2883 const QString projectFilename = QFileInfo( projectPath ).fileName();
2884 const QString projectBasename =
baseName();
2921 QVariantMap keywords;
2923 for (
auto it = metadataKeywords.constBegin(); it != metadataKeywords.constEnd(); ++it )
2925 keywords.insert( it.key(), it.value() );
2930 QVariantList layersIds;
2932 const QMap<QString, QgsMapLayer *> layersInProject = mLayerStore->mapLayers();
2933 layersIds.reserve( layersInProject.count() );
2934 layers.reserve( layersInProject.count() );
2935 for (
auto it = layersInProject.constBegin(); it != layersInProject.constEnd(); ++it )
2937 layersIds << it.value()->id();
2943 mProjectScope->addFunction( QStringLiteral(
"project_color" ),
new GetNamedProjectColor(
this ) );
2944 mProjectScope->addFunction( QStringLiteral(
"project_color_object" ),
new GetNamedProjectColorObject(
this ) );
2949void QgsProject::onMapLayersAdded(
const QList<QgsMapLayer *> &layers )
2953 const QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
2955 const auto constLayers =
layers;
2958 if ( ! layer->isValid() )
2961 if (
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer ) )
2964 if ( vlayer->dataProvider() )
2972 for ( QMap<QString, QgsMapLayer *>::const_iterator it = existingMaps.cbegin(); it != existingMaps.cend(); ++it )
2974 const QSet<QgsMapLayerDependency> deps = it.value()->dependencies();
2975 if ( deps.contains( layer->id() ) )
2978 it.value()->setDependencies( deps );
2983 updateTransactionGroups();
2989void QgsProject::onMapLayersRemoved(
const QList<QgsMapLayer *> &layers )
2998 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
3006void QgsProject::cleanTransactionGroups(
bool force )
3010 bool changed =
false;
3011 for ( QMap< QPair< QString, QString>,
QgsTransactionGroup *>::Iterator tg = mTransactionGroups.begin(); tg != mTransactionGroups.end(); )
3013 if ( tg.value()->isEmpty() || force )
3016 tg = mTransactionGroups.erase( tg );
3028void QgsProject::updateTransactionGroups()
3032 mEditBufferGroup.
clear();
3034 switch ( mTransactionMode )
3038 cleanTransactionGroups(
true );
3043 cleanTransactionGroups(
true );
3046 cleanTransactionGroups(
false );
3050 bool tgChanged =
false;
3051 const auto constLayers =
mapLayers().values();
3054 if ( ! layer->isValid() )
3057 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
3061 switch ( mTransactionMode )
3078 mTransactionGroups.insert( qMakePair( key, connString ), tg );
3088 mEditBufferGroup.
addLayer( vlayer );
3104 context.setProjectTranslator(
this );
3106 QList<QDomNode> brokenNodes;
3107 if ( addLayer( layerNode.toElement(), brokenNodes, context ) )
3111 const QVector<QgsVectorLayer *> vectorLayers = layers<QgsVectorLayer *>();
3115 layer->resolveReferences(
this );
3117 if ( layer->isValid() && layer->customProperty( QStringLiteral(
"_layer_was_editable" ) ).toBool() )
3119 layer->startEditing();
3120 layer->removeCustomProperty( QStringLiteral(
"_layer_was_editable" ) );
3132 mFile.setFileName( filename );
3133 mCachedHomePath.clear();
3141 mProjectScope.reset();
3147 const QString storageFilePath { storage->filePath( mFile.fileName() ) };
3148 if ( storageFilePath.isEmpty() )
3154 const QString tempPath = QStandardPaths::standardLocations( QStandardPaths::TempLocation ).at( 0 );
3155 const QString tmpZipFilename( tempPath + QDir::separator() + QUuid::createUuid().toString() );
3157 if ( !zip( tmpZipFilename ) )
3160 QFile tmpZipFile( tmpZipFilename );
3161 if ( !tmpZipFile.open( QIODevice::ReadOnly ) )
3163 setError( tr(
"Unable to read file %1" ).arg( tmpZipFilename ) );
3168 if ( !storage->writeProject( mFile.fileName(), &tmpZipFile, context ) )
3170 QString err = tr(
"Unable to save project to storage %1" ).arg( mFile.fileName() );
3171 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
3172 if ( !messages.isEmpty() )
3173 err += QStringLiteral(
"\n\n" ) + messages.last().message();
3179 QFile::remove( tmpZipFilename );
3186 return zip( mFile.fileName() );
3192 const bool asOk = saveAuxiliaryStorage();
3193 const bool writeOk = writeProjectFile( mFile.fileName() );
3194 bool attachmentsOk =
true;
3195 if ( !mArchive->files().isEmpty() )
3197 const QFileInfo finfo( mFile.fileName() );
3198 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( QStringLiteral(
"%1_attachments.zip" ).arg( finfo.completeBaseName() ) );
3199 attachmentsOk = mArchive->zip( attachmentsZip );
3203 if ( ( !asOk || !attachmentsOk ) && writeOk )
3205 QStringList errorMessage;
3208 const QString err = mAuxiliaryStorage->errorString();
3209 errorMessage.append( tr(
"Unable to save auxiliary storage ('%1')" ).arg( err ) );
3211 if ( !attachmentsOk )
3213 errorMessage.append( tr(
"Unable to save attachments archive" ) );
3215 setError( errorMessage.join(
'\n' ) );
3218 return asOk && writeOk && attachmentsOk;
3222bool QgsProject::writeProjectFile(
const QString &filename )
3226 QFile projectFile( filename );
3232 const QFileInfo myFileInfo( projectFile );
3233 if ( myFileInfo.exists() && !myFileInfo.isWritable() )
3235 setError( tr(
"%1 is not writable. Please adjust permissions (if possible) and try again." )
3236 .arg( projectFile.fileName() ) );
3244 QDomImplementation::setInvalidDataPolicy( QDomImplementation::DropInvalidChars );
3246 const QDomDocumentType documentType =
3247 QDomImplementation().createDocumentType( QStringLiteral(
"qgis" ), QStringLiteral(
"http://mrcc.com/qgis.dtd" ),
3248 QStringLiteral(
"SYSTEM" ) );
3249 auto doc = std::make_unique<QDomDocument>( documentType );
3251 QDomElement qgisNode = doc->createElement( QStringLiteral(
"qgis" ) );
3252 qgisNode.setAttribute( QStringLiteral(
"projectname" ),
title() );
3253 qgisNode.setAttribute( QStringLiteral(
"version" ),
Qgis::version() );
3255 if ( !mSettings.
value( QStringLiteral(
"projects/anonymize_saved_projects" ),
false,
QgsSettings::Core ).toBool() )
3259 qgisNode.setAttribute( QStringLiteral(
"saveUser" ), newSaveUser );
3260 qgisNode.setAttribute( QStringLiteral(
"saveUserFull" ), newSaveUserFull );
3261 mSaveUser = newSaveUser;
3262 mSaveUserFull = newSaveUserFull;
3263 mSaveDateTime = QDateTime::currentDateTime();
3264 qgisNode.setAttribute( QStringLiteral(
"saveDateTime" ), mSaveDateTime.toString( Qt::ISODate ) );
3269 mSaveUserFull.clear();
3270 mSaveDateTime = QDateTime();
3272 doc->appendChild( qgisNode );
3275 QDomElement homePathNode = doc->createElement( QStringLiteral(
"homePath" ) );
3276 homePathNode.setAttribute( QStringLiteral(
"path" ), mHomePath );
3277 qgisNode.appendChild( homePathNode );
3280 QDomElement titleNode = doc->createElement( QStringLiteral(
"title" ) );
3281 qgisNode.appendChild( titleNode );
3283 QDomElement transactionNode = doc->createElement( QStringLiteral(
"transaction" ) );
3284 transactionNode.setAttribute( QStringLiteral(
"mode" ),
qgsEnumValueToKey( mTransactionMode ) );
3285 qgisNode.appendChild( transactionNode );
3287 QDomElement flagsNode = doc->createElement( QStringLiteral(
"projectFlags" ) );
3289 qgisNode.appendChild( flagsNode );
3291 const QDomText titleText = doc->createTextNode(
title() );
3292 titleNode.appendChild( titleText );
3296 QDomElement srsNode = doc->createElement( QStringLiteral(
"projectCrs" ) );
3298 qgisNode.appendChild( srsNode );
3301 QDomElement verticalSrsNode = doc->createElement( QStringLiteral(
"verticalCrs" ) );
3302 mVerticalCrs.
writeXml( verticalSrsNode, *doc );
3303 qgisNode.appendChild( verticalSrsNode );
3306 QDomElement elevationShadingNode = doc->createElement( QStringLiteral(
"elevation-shading-renderer" ) );
3307 mElevationShadingRenderer.
writeXml( elevationShadingNode, context );
3308 qgisNode.appendChild( elevationShadingNode );
3315 clonedRoot->
writeXml( qgisNode, context );
3319 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsMode" ),
static_cast<int>( mAvoidIntersectionsMode ) );
3327 QDomElement annotationLayerNode = doc->createElement( QStringLiteral(
"main-annotation-layer" ) );
3328 mMainAnnotationLayer->
writeLayerXml( annotationLayerNode, *doc, context );
3329 qgisNode.appendChild( annotationLayerNode );
3333 QDomElement projectLayersNode = doc->createElement( QStringLiteral(
"projectlayers" ) );
3335 QMap<QString, QgsMapLayer *>::ConstIterator li =
layers.constBegin();
3336 while ( li !=
layers.end() )
3342 const QHash< QString, QPair< QString, bool> >::const_iterator emIt = mEmbeddedLayers.constFind( ml->
id() );
3343 if ( emIt == mEmbeddedLayers.constEnd() )
3345 QDomElement maplayerElem;
3351 maplayerElem = doc->createElement( QStringLiteral(
"maplayer" ) );
3355 maplayerElem.setAttribute( QStringLiteral(
"editable" ), QStringLiteral(
"1" ) );
3359 QDomDocument document;
3362 maplayerElem = document.firstChildElement();
3366 QgsDebugError( QStringLiteral(
"Could not restore layer properties for layer %1" ).arg( ml->
id() ) );
3372 projectLayersNode.appendChild( maplayerElem );
3378 if ( emIt.value().second )
3380 QDomElement mapLayerElem = doc->createElement( QStringLiteral(
"maplayer" ) );
3381 mapLayerElem.setAttribute( QStringLiteral(
"embedded" ), 1 );
3382 mapLayerElem.setAttribute( QStringLiteral(
"project" ),
writePath( emIt.value().first ) );
3383 mapLayerElem.setAttribute( QStringLiteral(
"id" ), ml->
id() );
3384 projectLayersNode.appendChild( mapLayerElem );
3391 qgisNode.appendChild( projectLayersNode );
3393 QDomElement layerOrderNode = doc->createElement( QStringLiteral(
"layerorder" ) );
3394 const auto constCustomLayerOrder = mRootGroup->customLayerOrder();
3395 for (
QgsMapLayer *layer : constCustomLayerOrder )
3397 QDomElement mapLayerElem = doc->createElement( QStringLiteral(
"layer" ) );
3398 mapLayerElem.setAttribute( QStringLiteral(
"id" ), layer->id() );
3399 layerOrderNode.appendChild( mapLayerElem );
3401 qgisNode.appendChild( layerOrderNode );
3403 mLabelingEngineSettings->writeSettingsToProject(
this );
3405 QDomElement labelEngineSettingsElement = doc->createElement( QStringLiteral(
"labelEngineSettings" ) );
3406 mLabelingEngineSettings->writeXml( *doc, labelEngineSettingsElement, context );
3407 qgisNode.appendChild( labelEngineSettingsElement );
3410 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorRedPart" ), mBackgroundColor.red() );
3411 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorGreenPart" ), mBackgroundColor.green() );
3412 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorBluePart" ), mBackgroundColor.blue() );
3414 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorRedPart" ), mSelectionColor.red() );
3415 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorGreenPart" ), mSelectionColor.green() );
3416 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorBluePart" ), mSelectionColor.blue() );
3417 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorAlphaPart" ), mSelectionColor.alpha() );
3425 dump_( mProperties );
3428 QgsDebugMsgLevel( QStringLiteral(
"there are %1 property scopes" ).arg(
static_cast<int>( mProperties.
count() ) ), 2 );
3433 mProperties.
writeXml( QStringLiteral(
"properties" ), qgisNode, *doc );
3436 QDomElement ddElem = doc->createElement( QStringLiteral(
"dataDefinedServerProperties" ) );
3437 mDataDefinedServerProperties.
writeXml( ddElem, dataDefinedServerPropertyDefinitions() );
3438 qgisNode.appendChild( ddElem );
3440 mMapThemeCollection->writeXml( *doc );
3442 mTransformContext.
writeXml( qgisNode, context );
3444 QDomElement metadataElem = doc->createElement( QStringLiteral(
"projectMetadata" ) );
3446 qgisNode.appendChild( metadataElem );
3449 const QDomElement annotationsElem = mAnnotationManager->writeXml( *doc, context );
3450 qgisNode.appendChild( annotationsElem );
3454 const QDomElement layoutElem = mLayoutManager->writeXml( *doc );
3455 qgisNode.appendChild( layoutElem );
3459 const QDomElement views3DElem = m3DViewsManager->writeXml( *doc );
3460 qgisNode.appendChild( views3DElem );
3464 const QDomElement bookmarkElem = mBookmarkManager->
writeXml( *doc );
3465 qgisNode.appendChild( bookmarkElem );
3469 const QDomElement sensorElem = mSensorManager->
writeXml( *doc );
3470 qgisNode.appendChild( sensorElem );
3474 const QDomElement viewSettingsElem = mViewSettings->
writeXml( *doc, context );
3475 qgisNode.appendChild( viewSettingsElem );
3479 const QDomElement styleSettingsElem = mStyleSettings->
writeXml( *doc, context );
3480 qgisNode.appendChild( styleSettingsElem );
3484 const QDomElement timeSettingsElement = mTimeSettings->
writeXml( *doc, context );
3485 qgisNode.appendChild( timeSettingsElement );
3489 const QDomElement elevationPropertiesElement = mElevationProperties->
writeXml( *doc, context );
3490 qgisNode.appendChild( elevationPropertiesElement );
3494 const QDomElement displaySettingsElem = mDisplaySettings->
writeXml( *doc, context );
3495 qgisNode.appendChild( displaySettingsElem );
3499 const QDomElement gpsSettingsElem = mGpsSettings->
writeXml( *doc, context );
3500 qgisNode.appendChild( gpsSettingsElem );
3509 QFile backupFile( QStringLiteral(
"%1~" ).arg( filename ) );
3511 ok &= backupFile.open( QIODevice::WriteOnly | QIODevice::Truncate );
3512 ok &= projectFile.open( QIODevice::ReadOnly );
3515 while ( ok && !projectFile.atEnd() )
3517 ba = projectFile.read( 10240 );
3518 ok &= backupFile.write( ba ) == ba.size();
3521 projectFile.close();
3526 setError( tr(
"Unable to create backup file %1" ).arg( backupFile.fileName() ) );
3531 struct utimbuf tb = {
static_cast<time_t
>( fi.lastRead().toSecsSinceEpoch() ),
static_cast<time_t
>( fi.lastModified().toSecsSinceEpoch() ) };
3532 utime( backupFile.fileName().toUtf8().constData(), &tb );
3535 if ( !projectFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
3537 projectFile.close();
3540 setError( tr(
"Unable to save to file %1" ).arg( projectFile.fileName() ) );
3544 QTemporaryFile tempFile;
3545 bool ok = tempFile.open();
3548 QTextStream projectFileStream( &tempFile );
3549 doc->save( projectFileStream, 2 );
3550 ok &= projectFileStream.pos() > -1;
3552 ok &= tempFile.seek( 0 );
3555 while ( ok && !tempFile.atEnd() )
3557 ba = tempFile.read( 10240 );
3558 ok &= projectFile.write( ba ) == ba.size();
3561 ok &= projectFile.error() == QFile::NoError;
3563 projectFile.close();
3570 setError( tr(
"Unable to save to file %1. Your project "
3571 "may be corrupted on disk. Try clearing some space on the volume and "
3572 "check file permissions before pressing save again." )
3573 .arg( projectFile.fileName() ) );
3587 bool propertiesModified;
3588 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3590 if ( propertiesModified )
3600 bool propertiesModified;
3601 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3603 if ( propertiesModified )
3613 bool propertiesModified;
3614 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3616 if ( propertiesModified )
3626 bool propertiesModified;
3627 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3629 if ( propertiesModified )
3639 bool propertiesModified;
3640 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3642 if ( propertiesModified )
3650 const QStringList &def,
3662 value =
property->value();
3664 const bool valid = QMetaType::Type::QStringList == value.userType();
3670 return value.toStringList();
3693 value =
property->value();
3695 const bool valid = value.canConvert( QMetaType::Type::QString );
3700 return value.toString();
3719 value =
property->value();
3722 const bool valid = value.canConvert( QMetaType::Type::Int );
3731 return value.toInt();
3746 const QVariant value =
property->value();
3748 const bool valid = value.canConvert( QMetaType::Type::Double );
3753 return value.toDouble();
3770 const QVariant value =
property->value();
3772 const bool valid = value.canConvert( QMetaType::Type::Bool );
3777 return value.toBool();
3789 if (
findKey_( scope, key, mProperties ) )
3795 return !
findKey_( scope, key, mProperties );
3804 QStringList entries;
3806 if ( foundProperty )
3823 QStringList entries;
3825 if ( foundProperty )
3840 dump_( mProperties );
3860 filePath = storage->filePath( mFile.fileName() );
3887void QgsProject::setError(
const QString &errorMessage )
3891 mErrorMessage = errorMessage;
3898 return mErrorMessage;
3901void QgsProject::clearError()
3905 setError( QString() );
3912 mBadLayerHandler.reset( handler );
3919 const QHash< QString, QPair< QString, bool > >::const_iterator it = mEmbeddedLayers.find(
id );
3920 if ( it == mEmbeddedLayers.constEnd() )
3924 return it.value().first;
3934 static QString sPrevProjectFilePath;
3935 static QDateTime sPrevProjectFileTimestamp;
3936 static QDomDocument sProjectDocument;
3938 QString qgsProjectFile = projectFilePath;
3940 if ( projectFilePath.endsWith( QLatin1String(
".qgz" ), Qt::CaseInsensitive ) )
3942 archive.
unzip( projectFilePath );
3946 const QDateTime projectFileTimestamp = QFileInfo( projectFilePath ).lastModified();
3948 if ( projectFilePath != sPrevProjectFilePath || projectFileTimestamp != sPrevProjectFileTimestamp )
3950 sPrevProjectFilePath.clear();
3952 QFile projectFile( qgsProjectFile );
3953 if ( !projectFile.open( QIODevice::ReadOnly ) )
3958 if ( !sProjectDocument.setContent( &projectFile ) )
3963 sPrevProjectFilePath = projectFilePath;
3964 sPrevProjectFileTimestamp = projectFileTimestamp;
3968 bool useAbsolutePaths =
true;
3970 const QDomElement propertiesElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral(
"properties" ) );
3971 if ( !propertiesElem.isNull() )
3973 QDomElement e = propertiesElem.firstChildElement( QStringLiteral(
"Paths" ) );
3976 e = propertiesElem.firstChildElement( QStringLiteral(
"properties" ) );
3977 while ( !e.isNull() && e.attribute( QStringLiteral(
"name" ) ) != QStringLiteral(
"Paths" ) )
3978 e = e.nextSiblingElement( QStringLiteral(
"properties" ) );
3980 e = e.firstChildElement( QStringLiteral(
"properties" ) );
3981 while ( !e.isNull() && e.attribute( QStringLiteral(
"name" ) ) != QStringLiteral(
"Absolute" ) )
3982 e = e.nextSiblingElement( QStringLiteral(
"properties" ) );
3986 e = e.firstChildElement( QStringLiteral(
"Absolute" ) );
3991 useAbsolutePaths = e.text().compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0;
3996 if ( !useAbsolutePaths )
4001 const QDomElement projectLayersElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral(
"projectlayers" ) );
4002 if ( projectLayersElem.isNull() )
4007 QDomElement mapLayerElem = projectLayersElem.firstChildElement( QStringLiteral(
"maplayer" ) );
4008 while ( ! mapLayerElem.isNull() )
4011 const QString
id = mapLayerElem.firstChildElement( QStringLiteral(
"id" ) ).text();
4012 if (
id == layerId )
4015 if ( mapLayerElem.attribute( QStringLiteral(
"embedded" ) ) == QLatin1String(
"1" ) )
4020 mEmbeddedLayers.insert( layerId, qMakePair( projectFilePath, saveFlag ) );
4022 if ( addLayer( mapLayerElem, brokenNodes, embeddedContext,
flags ) )
4028 mEmbeddedLayers.remove( layerId );
4032 mapLayerElem = mapLayerElem.nextSiblingElement( QStringLiteral(
"maplayer" ) );
4042 QString qgsProjectFile = projectFilePath;
4044 if ( projectFilePath.endsWith( QLatin1String(
".qgz" ), Qt::CaseInsensitive ) )
4046 archive.
unzip( projectFilePath );
4051 QFile projectFile( qgsProjectFile );
4052 if ( !projectFile.open( QIODevice::ReadOnly ) )
4057 QDomDocument projectDocument;
4058 if ( !projectDocument.setContent( &projectFile ) )
4070 QDomElement layerTreeElem = projectDocument.documentElement().firstChildElement( QStringLiteral(
"layer-tree-group" ) );
4071 if ( !layerTreeElem.isNull() )
4081 if ( !group || group->
customProperty( QStringLiteral(
"embedded" ) ).toBool() )
4094 newGroup->
setCustomProperty( QStringLiteral(
"embedded_project" ), projectFilePath );
4097 mLayerTreeRegistryBridge->setEnabled(
false );
4098 initializeEmbeddedSubtree( projectFilePath, newGroup,
flags );
4099 mLayerTreeRegistryBridge->setEnabled(
true );
4102 const auto constFindLayerIds = newGroup->
findLayerIds();
4103 for (
const QString &layerId : constFindLayerIds )
4120 const auto constChildren = group->
children();
4124 child->setCustomProperty( QStringLiteral(
"embedded" ), 1 );
4133 QList<QDomNode> brokenNodes;
4157 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/TopologicalEditing" ), ( enabled ? 1 : 0 ) );
4165 return readNumEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/TopologicalEditing" ), 0 );
4172 if ( mDistanceUnits == unit )
4175 mDistanceUnits = unit;
4184 if ( mAreaUnits == unit )
4196 if ( mScaleMethod == method )
4199 mScaleMethod = method;
4209 if ( !mCachedHomePath.isEmpty() )
4210 return mCachedHomePath;
4214 if ( !mHomePath.isEmpty() )
4216 const QFileInfo homeInfo( mHomePath );
4217 if ( !homeInfo.isRelative() )
4219 mCachedHomePath = mHomePath;
4229 const QString storagePath { storage->filePath(
fileName() ) };
4230 if ( ! storagePath.isEmpty() && QFileInfo::exists( storagePath ) )
4232 mCachedHomePath = QFileInfo( storagePath ).path();
4233 return mCachedHomePath;
4237 mCachedHomePath = pfi.path();
4238 return mCachedHomePath;
4241 if ( !pfi.exists() )
4243 mCachedHomePath = mHomePath;
4247 if ( !mHomePath.isEmpty() )
4250 mCachedHomePath = QDir::cleanPath( pfi.path() +
'/' + mHomePath );
4254 mCachedHomePath = pfi.canonicalPath();
4256 return mCachedHomePath;
4271 return mRelationManager.get();
4278 return mLayoutManager.get();
4285 return mLayoutManager.get();
4292 return m3DViewsManager.get();
4299 return m3DViewsManager.get();
4306 return mBookmarkManager;
4313 return mBookmarkManager;
4320 return mSensorManager;
4327 return mSensorManager;
4334 return mViewSettings;
4341 return mViewSettings;
4348 return mStyleSettings;
4356 return mStyleSettings;
4363 return mTimeSettings;
4370 return mTimeSettings;
4377 return mElevationProperties;
4384 return mElevationProperties;
4391 return mDisplaySettings;
4398 return mDisplaySettings;
4405 return mGpsSettings;
4412 return mGpsSettings;
4419 return mRootGroup.get();
4426 return mMapThemeCollection.get();
4433 return mAnnotationManager.get();
4440 return mAnnotationManager.get();
4447 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
4448 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
4453 if (
layers.contains( it.value() ) )
4454 it.value()->setFlags( it.value()->flags() &
~QgsMapLayer::Identifiable );
4470 for (
const QString &layerId : layerIds )
4488 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
4522 updateTransactionGroups();
4529 return mTransactionMode;
4540 const auto constLayers =
mapLayers().values();
4543 if ( layer->isEditable() )
4545 QgsLogger::warning( tr(
"Transaction mode can be changed only if all layers are not editable." ) );
4551 updateTransactionGroups();
4560 return mTransactionGroups;
4573 return mLayerStore->count();
4580 return mLayerStore->validCount();
4588 return mLayerStore->mapLayer( layerId );
4595 return mLayerStore->mapLayersByName( layerName );
4602 QList<QgsMapLayer *>
layers;
4603 const auto constMapLayers { mLayerStore->mapLayers() };
4604 for (
const auto &l : constMapLayers )
4606 if ( ! l->serverProperties()->shortName().isEmpty() )
4608 if ( l->serverProperties()->shortName() == shortName )
4611 else if ( l->name() == shortName )
4624 auto archive = std::make_unique<QgsProjectArchive>();
4627 if ( !archive->unzip( filename ) )
4629 setError( tr(
"Unable to unzip file '%1'" ).arg( filename ) );
4634 if ( archive->projectFile().isEmpty() )
4636 setError( tr(
"Zip archive does not provide a project file" ) );
4641 releaseHandlesToProjectArchive();
4642 mArchive = std::move( archive );
4659 setError( tr(
"Cannot read unzipped qgs project file" ) + QStringLiteral(
": " ) +
error() );
4669bool QgsProject::zip(
const QString &filename )
4676 auto archive = std::make_unique<QgsProjectArchive>();
4677 const QString
baseName = QFileInfo( filename ).baseName();
4678 const QString qgsFileName = QStringLiteral(
"%1.qgs" ).arg(
baseName );
4679 QFile qgsFile( QDir( archive->dir() ).filePath( qgsFileName ) );
4681 bool writeOk =
false;
4682 if ( qgsFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
4684 writeOk = writeProjectFile( qgsFile.fileName() );
4691 setError( tr(
"Unable to write temporary qgs file" ) );
4696 const QFileInfo info( qgsFile );
4698 const QString asFileName = info.path() + QDir::separator() + info.completeBaseName() + asExt;
4700 bool auxiliaryStorageSavedOk =
true;
4701 if ( ! saveAuxiliaryStorage( asFileName ) )
4703 const QString err = mAuxiliaryStorage->errorString();
4704 setError( tr(
"Unable to save auxiliary storage file ('%1'). The project has been saved but the latest changes to auxiliary data cannot be recovered. It is recommended to reload the project." ).arg( err ) );
4705 auxiliaryStorageSavedOk =
false;
4708 if ( !mArchive->exists() )
4710 releaseHandlesToProjectArchive();
4712 mArchive->unzip( mFile.fileName() );
4715 const QString auxiliaryStorageFile =
static_cast<QgsProjectArchive *
>( mArchive.get() )->auxiliaryStorageFile();
4716 if ( ! auxiliaryStorageFile.isEmpty() )
4718 archive->
addFile( auxiliaryStorageFile );
4727 if ( QFile::exists( asFileName ) )
4729 archive->addFile( asFileName );
4734 archive->addFile( qgsFile.fileName() );
4737 const QStringList &files = mArchive->files();
4738 for (
const QString &file : files )
4740 if ( !file.endsWith( QLatin1String(
".qgs" ), Qt::CaseInsensitive ) && !file.endsWith( asExt, Qt::CaseInsensitive ) )
4742 archive->addFile( file );
4748 if ( !archive->zip( filename ) )
4750 setError( tr(
"Unable to perform zip" ) );
4754 return auxiliaryStorageSavedOk && zipOk;
4765 const QList<QgsMapLayer *> &layers,
4767 bool takeOwnership )
4771 const QList<QgsMapLayer *> myResultList { mLayerStore->addMapLayers(
layers, takeOwnership ) };
4772 if ( !myResultList.isEmpty() )
4775 for (
auto &l : myResultList )
4785 if ( mAuxiliaryStorage )
4800 mProjectScope.reset();
4802 return myResultList;
4808 bool takeOwnership )
4812 QList<QgsMapLayer *> addedLayers;
4813 addedLayers =
addMapLayers( QList<QgsMapLayer *>() << layer, addToLegend, takeOwnership );
4814 return addedLayers.isEmpty() ? nullptr : addedLayers[0];
4817void QgsProject::removeAuxiliaryLayer(
const QgsMapLayer *ml )
4824 const QgsVectorLayer *vl = qobject_cast<const QgsVectorLayer *>( ml );
4836 for (
const auto &layerId : layerIds )
4837 removeAuxiliaryLayer( mLayerStore->mapLayer( layerId ) );
4839 mProjectScope.reset();
4840 mLayerStore->removeMapLayers( layerIds );
4847 for (
const auto &layer :
layers )
4848 removeAuxiliaryLayer( layer );
4850 mProjectScope.reset();
4851 mLayerStore->removeMapLayers(
layers );
4858 removeAuxiliaryLayer( mLayerStore->mapLayer( layerId ) );
4859 mProjectScope.reset();
4860 mLayerStore->removeMapLayer( layerId );
4867 removeAuxiliaryLayer( layer );
4868 mProjectScope.reset();
4869 mLayerStore->removeMapLayer( layer );
4876 mProjectScope.reset();
4877 return mLayerStore->takeMapLayer( layer );
4884 return mMainAnnotationLayer;
4891 if ( mLayerStore->count() == 0 )
4894 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
4895 mProjectScope.reset();
4896 mLayerStore->removeAllMapLayers();
4898 snapSingleBlocker.release();
4900 if ( !mBlockSnappingUpdates )
4908 const QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
4909 QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin();
4910 for ( ; it !=
layers.constEnd(); ++it )
4912 it.value()->reload();
4921 return validOnly ? mLayerStore->validMapLayers() : mLayerStore->mapLayers();
4928 return mTransactionGroups.value( qMakePair( providerKey, connString ) );
4935 return &mEditBufferGroup;
4946 if ( mSettings.
value( QStringLiteral(
"/projections/unknownCrsBehavior" ), QStringLiteral(
"NoAction" ),
QgsSettings::App ).toString() == QStringLiteral(
"UseProjectCrs" )
4947 || mSettings.
value( QStringLiteral(
"/projections/unknownCrsBehavior" ), 0,
QgsSettings::App ).toString() == QLatin1String(
"2" ) )
4955 const QString layerDefaultCrs = mSettings.
value( QStringLiteral(
"/Projections/layerDefaultCrs" ), QStringLiteral(
"EPSG:4326" ) ).toString();
4976bool QgsProject::saveAuxiliaryStorage(
const QString &filename )
4982 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
4987 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() );
4995 if ( !mAuxiliaryStorage->exists( *
this ) && empty )
4999 else if ( !filename.isEmpty() )
5001 return mAuxiliaryStorage->saveAs( filename );
5005 return mAuxiliaryStorage->saveAs( *
this );
5018 return sPropertyDefinitions;
5031 return mAuxiliaryStorage.get();
5038 return mAuxiliaryStorage.get();
5045 const QDir archiveDir( mArchive->dir() );
5046 QTemporaryFile tmpFile( archiveDir.filePath(
"XXXXXX_" + nameTemplate ),
this );
5047 tmpFile.setAutoRemove(
false );
5049 mArchive->addFile( tmpFile.fileName() );
5050 return tmpFile.fileName();
5057 QStringList attachments;
5059 const QStringList files = mArchive->files();
5060 attachments.reserve( files.size() );
5061 for (
const QString &file : files )
5063 if ( QFileInfo( file ).baseName() !=
baseName )
5065 attachments.append( file );
5075 return mArchive->removeFile( path );
5082 return QStringLiteral(
"attachment:///%1" ).arg( QFileInfo( attachedFile ).
fileName() );
5089 if ( identifier.startsWith( QLatin1String(
"attachment:///" ) ) )
5091 return QDir( mArchive->dir() ).absoluteFilePath( identifier.mid( 14 ) );
5112 mProjectScope.reset();
5126 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5140 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
5141 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
5146 if (
layers.contains( it.value() ) )
5147 it.value()->setFlags( it.value()->flags() &
~QgsMapLayer::Removable );
5158 QStringList customColors;
5159 QStringList customColorLabels;
5161 QgsNamedColorList::const_iterator colorIt = colors.constBegin();
5162 for ( ; colorIt != colors.constEnd(); ++colorIt )
5165 const QString label = ( *colorIt ).second;
5166 customColors.append( color );
5167 customColorLabels.append( label );
5169 writeEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Colors" ), customColors );
5170 writeEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Labels" ), customColorLabels );
5171 mProjectScope.reset();
5179 if ( mBackgroundColor == color )
5182 mBackgroundColor = color;
5190 return mBackgroundColor;
5197 if ( mSelectionColor == color )
5200 mSelectionColor = color;
5208 return mSelectionColor;
5245 translationContext.setFileName( QStringLiteral(
"%1/%2.ts" ).arg(
absolutePath(),
baseName() ) );
5249 translationContext.writeTsFile( locale );
5252QString
QgsProject::translate(
const QString &context,
const QString &sourceText,
const char *disambiguation,
int n )
const
5261 QString result = mTranslator->translate( context.toUtf8(), sourceText.toUtf8(), disambiguation, n );
5263 if ( result.isEmpty() )
5277 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5282 if ( !( ( *it )->accept( visitor ) ) )
5291 if ( !mLayoutManager->accept( visitor ) )
5294 if ( !mAnnotationManager->accept( visitor ) )
5302 return mElevationShadingRenderer;
5305void QgsProject::loadProjectFlags(
const QDomDocument *doc )
5309 QDomElement element = doc->documentElement().firstChildElement( QStringLiteral(
"projectFlags" ) );
5311 if ( !element.isNull() )
5318 element = doc->documentElement().firstChildElement( QStringLiteral(
"evaluateDefaultValues" ) );
5319 if ( !element.isNull() )
5321 if ( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
5326 element = doc->documentElement().firstChildElement( QStringLiteral(
"trust" ) );
5327 if ( !element.isNull() )
5329 if ( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
5345 const QString projectFunctions =
readEntry( QStringLiteral(
"ExpressionFunctions" ), QStringLiteral(
"/pythonCode" ), QString() );
5346 if ( !projectFunctions.isEmpty() )
5366QHash< QString, QColor > loadColorsFromProject(
const QgsProject *project )
5368 QHash< QString, QColor > colors;
5371 QStringList colorStrings = project->
readListEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Colors" ) );
5372 const QStringList colorLabels = project->
readListEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Labels" ) );
5376 for ( QStringList::iterator it = colorStrings.begin();
5377 it != colorStrings.end(); ++it )
5381 if ( colorLabels.length() > colorIndex )
5383 label = colorLabels.at( colorIndex );
5386 colors.insert( label.toLower(), color );
5394GetNamedProjectColor::GetNamedProjectColor(
const QgsProject *project )
5400 mColors = loadColorsFromProject( project );
5403GetNamedProjectColor::GetNamedProjectColor(
const QHash<QString, QColor> &colors )
5411 const QString colorName = values.at( 0 ).toString().toLower();
5412 if ( mColors.contains( colorName ) )
5414 return QStringLiteral(
"%1,%2,%3" ).arg( mColors.value( colorName ).red() ).arg( mColors.value( colorName ).green() ).arg( mColors.value( colorName ).blue() );
5422 return new GetNamedProjectColor( mColors );
5425GetNamedProjectColorObject::GetNamedProjectColorObject(
const QgsProject *project )
5431 mColors = loadColorsFromProject( project );
5434GetNamedProjectColorObject::GetNamedProjectColorObject(
const QHash<QString, QColor> &colors )
5442 const QString colorName = values.at( 0 ).toString().toLower();
5443 if ( mColors.contains( colorName ) )
5445 return mColors.value( colorName );
5453 return new GetNamedProjectColorObject( mColors );
5458GetSensorData::GetSensorData(
const QMap<QString, QgsAbstractSensor::SensorData> &sensorData )
5461 QStringLiteral(
"Sensors" ) )
5462 , mSensorData( sensorData )
5468 const QString sensorName = values.at( 0 ).toString();
5469 const int expiration = values.at( 1 ).toInt();
5470 const qint64 timestamp = QDateTime::currentMSecsSinceEpoch();
5471 if ( mSensorData.contains( sensorName ) )
5473 if ( expiration <= 0 || ( timestamp - mSensorData[sensorName].lastTimestamp.toMSecsSinceEpoch() ) < expiration )
5475 return mSensorData[sensorName].lastValue;
5484 return new GetSensorData( mSensorData );
@ 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.
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.
PythonEmbeddedMode
Authorisation to run Python Embedded in projects.
@ Always
Python embedded is always run.
@ Ask
User is prompt before running.
@ SessionOnly
Only during this session.
@ Compound
Compound (horizontal + vertical) CRS.
@ Projected
Projected CRS.
@ DerivedProjected
Derived projected CRS.
@ Engineering
Engineering CRS.
@ Geographic3d
3D geopraphic CRS
@ Geographic2d
2D geographic CRS
@ Geocentric
Geocentric CRS.
AvoidIntersectionsMode
Flags which control how intersections of pre-existing feature are handled when digitizing new feature...
@ AvoidIntersectionsLayers
Overlap with features from a specified list of layers when digitizing new features not allowed.
@ AllowIntersections
Overlap with any feature allowed when digitizing new features.
ProjectFlag
Flags which control the behavior of QgsProjects.
@ RememberLayerEditStatusBetweenSessions
If set, then any layers set to be editable will be stored in the project and immediately made editabl...
@ EvaluateDefaultValuesOnProviderSide
If set, default values for fields will be evaluated on the provider side when features from the proje...
@ TrustStoredLayerStatistics
If set, then layer statistics (such as the layer extent) will be read from values stored in the proje...
QFlags< DataProviderReadFlag > DataProviderReadFlags
Flags which control data provider construction.
LayerType
Types of layers that can be added to a map.
@ Group
Composite group layer. Added in QGIS 3.24.
@ Plugin
Plugin based layer.
@ TiledScene
Tiled scene layer. Added in QGIS 3.34.
@ Annotation
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
@ VectorTile
Vector tile layer. Added in QGIS 3.14.
@ Mesh
Mesh layer. Added in QGIS 3.2.
@ PointCloud
Point cloud layer. Added in QGIS 3.18.
ScaleCalculationMethod
Scale calculation logic.
@ HorizontalMiddle
Calculate horizontally, across midle of map.
@ SkipCredentialsRequest
Skip credentials if the provided one are not valid, let the provider be invalid, avoiding to block th...
@ ParallelThreadLoading
Provider is created in a parallel thread than the one where it will live.
QFlags< ProjectFlag > ProjectFlags
static QString geoNone()
Constant that holds the string representation for "No ellipse/No CRS".
@ Preferred
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
virtual bool readXml(const QDomElement &collectionElem, const QgsPropertiesDefinition &definitions)
Reads property collection state from an XML element.
virtual bool writeXml(QDomElement &collectionElem, const QgsPropertiesDefinition &definitions) const
Writes the current state of the property collection into an XML element.
Represents a map layer containing a set of georeferenced annotations, e.g.
void resolveReferences(QgsProject *project) override
Resolve references to other layers (kept as layer IDs after reading XML) into layer objects.
void setTransformContext(const QgsCoordinateTransformContext &context) override
Sets the coordinate transform context to transformContext.
void reset()
Resets the annotation layer to a default state, and clears all items from it.
bool isEmpty() const
Returns true if the annotation layer is empty and contains no annotations.
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.
void addFile(const QString &filename)
Add a new file to this 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.
bool readXml(const QDomElement &element, const QDomDocument &doc)
Reads the manager's state from a DOM element, restoring all bookmarks present in the XML document.
void clear()
Removes and deletes all bookmarks from the manager.
QDomElement writeXml(QDomDocument &doc) const
Returns a DOM element representing the state of the manager.
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.
bool hasVerticalAxis() const
Returns true if the CRS has a vertical axis.
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.
QgsCoordinateReferenceSystem verticalCrs() const
Returns the vertical CRS associated with this CRS object.
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.
bool writeXml(QDomNode &node, QDomDocument &doc) const
Stores state to the given Dom node in the given document.
static QgsCoordinateReferenceSystem fromSrsId(long srsId)
Creates a CRS from a specified QGIS SRS ID.
Qgis::CrsType type() const
Returns the type of the CRS.
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.
void writeXml(QDomElement &element, const QgsReadWriteContext &context) const
Writes the context's state to a DOM element.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context, QStringList &missingTransforms)
Reads the context's state from a DOM element.
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.
Renders elevation shading on an image with different methods (eye dome lighting, hillshading,...
void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const
Writes configuration on a DOM element.
void readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads configuration from a DOM element.
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").
Encapsulate a field in an attribute table or data source.
Container of fields for a vector layer.
Stores global configuration for labeling engine.
Handles sorting of dependencies stored in a XML project or layer definition file.
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.
QStringList findLayerIds() const
Find layer IDs used in all layer nodes.
void insertChildNodes(int index, const QList< QgsLayerTreeNode * > &nodes)
Insert existing nodes at specified position.
QgsLayerTreeGroup * clone() const override
Returns a clone of the group.
QgsLayerTreeLayer * findLayer(QgsMapLayer *layer) const
Find layer node representing the map layer.
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.
virtual void writeXml(QDomElement &parentElement, const QgsReadWriteContext &context)=0
Write layer tree to XML.
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.
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 removeCustomProperty(const QString &key)
Remove a custom property from 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...
QgsCoordinateReferenceSystem crs
QString originalXmlProperties() const
Returns the XML properties of the original layer as they were when the layer was first read from the ...
Q_INVOKABLE void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
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.
bool readLayerXml(const QDomElement &layerElement, QgsReadWriteContext &context, QgsMapLayer::ReadFlags flags=QgsMapLayer::ReadFlags(), QgsDataProvider *preloadedProvider=nullptr)
Sets state from DOM document.
void setCrs(const QgsCoordinateReferenceSystem &srs, bool emitSignal=true)
Sets layer's spatial reference system.
Container class that allows storage of map themes consisting of visible map layers and layer styles.
Manages storage of a set of views.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE())
Adds a message to the log instance (and creates it if necessary).
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.
QString auxiliaryStorageFile() const
Returns the current .qgd auxiliary storage 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...
void reset()
Resets the settings to a default state.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads the settings's state from a DOM element.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Returns a DOM element representing the settings.
Contains elevation properties for a QgsProject.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads the property state from a DOM element.
void reset()
Resets the properties to a default state.
QDomElement writeXml(QDomDocument &document, const QgsReadWriteContext &context) const
Returns a DOM element representing the properties.
void resolveReferences(const QgsProject *project)
Resolves reference to layers from stored layer ID.
Contains settings and properties relating to how a QgsProject should interact with a GPS device.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads the settings's state from a DOM element.
void reset()
Resets the settings to a default state.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Returns a DOM element representing the settings.
void resolveReferences(const QgsProject *project)
Resolves reference to layers from stored layer ID (if it has not been resolved already)
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.
bool isEmpty() const
Returns true if this property contains no sub-keys.
virtual void clearKeys()
Deletes any sub-nodes from the property.
bool writeXml(const QString &nodeName, QDomElement &element, QDomDocument &document) override
Writes the property hierarchy to a specified DOM element.
void subkeyList(QStringList &entries) const
Returns any sub-keys contained by this property which themselves contain other keys.
void setName(const QString &name)
The name of the property is used as identifier.
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.
int count() const
Returns the number of sub-keys contained by this property.
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.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Returns a DOM element representing the settings.
void setDefaultSymbol(Qgis::SymbolType symbolType, QgsSymbol *symbol)
Sets the project default symbol for a given type.
void reset()
Resets the settings to a default state.
void removeProjectStyle()
Removes and deletes the project style database.
void setRandomizeDefaultSymbolColor(bool randomized)
Sets whether the default symbol fill color is randomized.
void setDefaultColorRamp(QgsColorRamp *colorRamp)
Sets the project default color ramp.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context, Qgis::ProjectReadFlags flags=Qgis::ProjectReadFlags())
Reads the settings's state from a DOM element.
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...
bool readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads the settings's state from a DOM element.
void reset()
Resets the settings to a default state.
QDomElement writeXml(QDomDocument &document, const QgsReadWriteContext &context) const
Returns a DOM element representing the settings.
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,...
bool useProjectScales() const
Returns true if project mapScales() are enabled.
void reset()
Resets the settings to a default state.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads the settings's state from a DOM element.
void setMapScales(const QVector< double > &scales)
Sets the list of custom project map scales.
void setUseProjectScales(bool enabled)
Sets whether project mapScales() are enabled.
QVector< double > mapScales() const
Returns the list of custom project map scales.
void mapScalesChanged()
Emitted when the list of custom project map scales changes.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Returns a DOM element representing the settings.
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 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.
QString title() const
Returns the project's title.
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.
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.
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 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...
bool loadFunctionsFromProject(bool force=false)
Loads python expression functions stored in the currrent 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...
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 the specified scope and k...
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.
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.
const QgsProjectViewSettings * viewSettings() const
Returns the project's view settings, which contains settings and properties relating to how a QgsProj...
void cleanFunctionsFromProject()
Unloads python expression functions stored in the current project and reloads local functions from th...
QgsCoordinateReferenceSystem verticalCrs() const
Returns the project's vertical coordinate reference system.
QString readPath(const QString &filename) const
Transforms a filename read from the project file to an absolute path.
void registerTranslatableContainers(QgsTranslationContext *translationContext, QgsAttributeEditorContainer *parent, const QString &layerId)
Registers the containers that require translation into the translationContext.
void setElevationShadingRenderer(const QgsElevationShadingRenderer &elevationShadingRenderer)
Sets the elevation shading renderer used for global map shading.
void setFilePathStorage(Qgis::FilePathType type)
Sets the type of paths used when storing file paths in a QGS/QGZ project file.
Q_DECL_DEPRECATED QSet< QgsMapLayer * > requiredLayers() const
Returns a set of map layers that are required in the project and therefore they should not get remove...
void transformContextChanged()
Emitted when the project transformContext() is changed.
void setTopologicalEditing(bool enabled)
Convenience function to set topological editing.
void legendLayersAdded(const QList< QgsMapLayer * > &layers)
Emitted, when a layer was added to the registry and the legend.
QVariantMap customVariables() const
A map of custom project variables.
void setAvoidIntersectionsLayers(const QList< QgsVectorLayer * > &layers)
Sets the list of layers with which intersections should be avoided.
void homePathChanged()
Emitted when the home path of the project changes.
void dirtySet()
Emitted when setDirty(true) is called.
void setCustomVariables(const QVariantMap &customVariables)
A map of custom project variables.
void writeProject(QDomDocument &document)
Emitted when the project is being written.
QgsCoordinateReferenceSystem defaultCrsForNewLayers() const
Returns the default CRS for new layers based on the settings and the current project CRS.
QString saveUserFullName() const
Returns the full user name that did the last save.
void layersAdded(const QList< QgsMapLayer * > &layers)
Emitted when one or more layers were added to the registry.
QMap< QString, QgsMapLayer * > mapLayers(const bool validOnly=false) const
Returns a map of all registered layers by layer ID.
bool isDirty() const
Returns true if the project has been modified since the last write()
QgsMapLayer * takeMapLayer(QgsMapLayer *layer)
Takes a layer from the registry.
void isDirtyChanged(bool dirty)
Emitted when the project dirty status changes.
void setDistanceUnits(Qgis::DistanceUnit unit)
Sets the default distance measurement units for the project.
Q_DECL_DEPRECATED bool useProjectScales() const
Returns true if project mapScales() are enabled.
Q_DECL_DEPRECATED void setMapScales(const QVector< double > &scales)
Sets the list of custom project map scales.
void setPresetHomePath(const QString &path)
Sets the project's home path.
void setFlags(Qgis::ProjectFlags flags)
Sets the project's flags, which dictate the behavior of the project.
QList< QgsMapLayer * > mapLayersByShortName(const QString &shortName) const
Retrieves a list of matching registered layers by layer shortName.
QgsProjectStorage * projectStorage() const
Returns pointer to project storage implementation that handles read/write of the project file.
QString layerIsEmbedded(const QString &id) const
Returns the source project file path if the layer with matching id is embedded from other project fil...
const QgsProjectTimeSettings * timeSettings() const
Returns the project's time settings, which contains the project's temporal range and other time based...
void verticalCrsChanged()
Emitted when the verticalCrs() of the project has changed.
void topologicalEditingChanged()
Emitted when the topological editing flag has changed.
bool removeEntry(const QString &scope, const QString &key)
Remove the given key from the specified scope.
QgsProjectVersion lastSaveVersion() const
Returns the QGIS version which the project was last saved using.
void avoidIntersectionsModeChanged()
Emitted whenever the avoid intersections mode has changed.
void loadingLayer(const QString &layerName)
Emitted when a layer is loaded.
A grouped map of multiple QgsProperty objects, each referenced by an integer key value.
Definition for a property.
@ 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 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.
Used when reading a project to asynchronously create data providers that support asynchronous creatio...
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.
QDomElement writeXml(QDomDocument &document) const
Returns a DOM element representing the state of the manager.
void clear()
Deregisters and removes all sensors from the manager.
bool readXml(const QDomElement &element, const QDomDocument &document)
Reads the manager's state from a DOM element, restoring all sensors present in the XML document.
T value(const QString &dynamicKeyPart=QString()) const
Returns settings value.
static const QgsSettingsEntryInteger * settingsLayerParallelLoadingMaxCount
Settings entry maximum thread count used to load layer in parallel.
static const QgsSettingsEntryBool * settingsLayerParallelLoading
Settings entry whether layer are loading in parallel.
Stores settings for use within QGIS.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
T enumValue(const QString &key, const T &defaultValue, const Section section=NoSection)
Returns the setting value for a setting based on an enum.
Stores configuration of snapping settings for the project.
bool addLayers(const QList< QgsMapLayer * > &layers)
Adds the specified layers as individual layers to the configuration with standard configuration.
void readProject(const QDomDocument &doc)
Reads the configuration from the specified QGIS project document.
void reset()
reset to default values
void writeProject(QDomDocument &doc)
Writes the configuration to the specified QGIS project document.
void clearIndividualLayerSettings()
Removes all individual layer snapping settings.
bool removeLayers(const QList< QgsMapLayer * > &layers)
Removes the specified layers from the individual layer configuration.
An interface for classes which can visit style entity (e.g.
virtual bool visitExit(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor stops visiting a node.
virtual bool visitEnter(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor starts visiting a node.
void triggerIconRebuild()
Triggers emission of the rebuildIconPreviews() signal.
static QgsStyle * defaultStyle(bool initialize=true)
Returns the default application-wide style.
Represents a transaction group.
bool addLayer(QgsVectorLayer *layer)
Add a layer to this transaction group.
static bool supportsTransaction(const QgsVectorLayer *layer)
Checks if the provider of a given layer supports transactions.
QString connectionString() const
Returns the connection string of the transaction.
Used for the collecting of strings from projects for translation and creation of ts files.
void registerTranslation(const QString &context, const QString &source)
Registers the source to be translated.
void setProject(QgsProject *project)
Sets the project being translated.
static Q_INVOKABLE QString toString(Qgis::DistanceUnit unit)
Returns a translated string representing a distance unit.
static Q_INVOKABLE Qgis::AreaUnit decodeAreaUnit(const QString &string, bool *ok=nullptr)
Decodes an areal unit from a string.
static Q_INVOKABLE QString encodeUnit(Qgis::DistanceUnit unit)
Encodes a distance unit to a string.
static Q_INVOKABLE Qgis::DistanceUnit decodeDistanceUnit(const QString &string, bool *ok=nullptr)
Decodes a distance unit from a string.
The edit buffer group manages a group of edit buffers.
bool commitChanges(QStringList &commitErrors, bool stopEditing=true)
Attempts to commit any changes to disk.
bool startEditing()
Start editing.
void clear()
Remove all layers from this edit buffer group.
bool rollBack(QStringList &rollbackErrors, bool stopEditing=true)
Stop editing and discard the edits.
void removeLayer(QgsVectorLayer *layer)
Remove a layer from this edit buffer group.
void addLayer(QgsVectorLayer *layer)
Add a layer to this edit buffer group.
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...
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...
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.
QStringList makeKeyTokens_(const QString &scope, const QString &key)
Takes the given scope and key and convert them to a string list of key tokens that will be used to na...
void dump_(const QgsProjectPropertyKey &topQgsPropertyKey)
QgsProjectProperty * findKey_(const QString &scope, const QString &key, QgsProjectPropertyKey &rootProperty)
Returns the property that matches the given key sequence, if any.
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
const QgsCoordinateReferenceSystem & crs
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.
Setting options for loading group layers.
Contains information relating to a node (i.e.