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;
3268 mSaveDateTime = QDateTime::currentDateTime();
3269 qgisNode.setAttribute( QStringLiteral(
"saveDateTime" ), mSaveDateTime.toString( Qt::ISODate ) );
3274 mSaveUserFull.clear();
3277 mSaveDateTime = QDateTime();
3279 doc->appendChild( qgisNode );
3282 QDomElement homePathNode = doc->createElement( QStringLiteral(
"homePath" ) );
3283 homePathNode.setAttribute( QStringLiteral(
"path" ), mHomePath );
3284 qgisNode.appendChild( homePathNode );
3287 QDomElement titleNode = doc->createElement( QStringLiteral(
"title" ) );
3288 qgisNode.appendChild( titleNode );
3290 QDomElement transactionNode = doc->createElement( QStringLiteral(
"transaction" ) );
3291 transactionNode.setAttribute( QStringLiteral(
"mode" ),
qgsEnumValueToKey( mTransactionMode ) );
3292 qgisNode.appendChild( transactionNode );
3294 QDomElement flagsNode = doc->createElement( QStringLiteral(
"projectFlags" ) );
3296 qgisNode.appendChild( flagsNode );
3298 const QDomText titleText = doc->createTextNode(
title() );
3299 titleNode.appendChild( titleText );
3303 QDomElement srsNode = doc->createElement( QStringLiteral(
"projectCrs" ) );
3305 qgisNode.appendChild( srsNode );
3308 QDomElement verticalSrsNode = doc->createElement( QStringLiteral(
"verticalCrs" ) );
3309 mVerticalCrs.
writeXml( verticalSrsNode, *doc );
3310 qgisNode.appendChild( verticalSrsNode );
3313 QDomElement elevationShadingNode = doc->createElement( QStringLiteral(
"elevation-shading-renderer" ) );
3314 mElevationShadingRenderer.
writeXml( elevationShadingNode, context );
3315 qgisNode.appendChild( elevationShadingNode );
3322 clonedRoot->
writeXml( qgisNode, context );
3326 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsMode" ),
static_cast<int>( mAvoidIntersectionsMode ) );
3334 QDomElement annotationLayerNode = doc->createElement( QStringLiteral(
"main-annotation-layer" ) );
3335 mMainAnnotationLayer->
writeLayerXml( annotationLayerNode, *doc, context );
3336 qgisNode.appendChild( annotationLayerNode );
3340 QDomElement projectLayersNode = doc->createElement( QStringLiteral(
"projectlayers" ) );
3342 QMap<QString, QgsMapLayer *>::ConstIterator li =
layers.constBegin();
3343 while ( li !=
layers.end() )
3349 const QHash< QString, QPair< QString, bool> >::const_iterator emIt = mEmbeddedLayers.constFind( ml->
id() );
3350 if ( emIt == mEmbeddedLayers.constEnd() )
3352 QDomElement maplayerElem;
3358 maplayerElem = doc->createElement( QStringLiteral(
"maplayer" ) );
3362 maplayerElem.setAttribute( QStringLiteral(
"editable" ), QStringLiteral(
"1" ) );
3366 QDomDocument document;
3369 maplayerElem = document.firstChildElement();
3373 QgsDebugError( QStringLiteral(
"Could not restore layer properties for layer %1" ).arg( ml->
id() ) );
3379 projectLayersNode.appendChild( maplayerElem );
3385 if ( emIt.value().second )
3387 QDomElement mapLayerElem = doc->createElement( QStringLiteral(
"maplayer" ) );
3388 mapLayerElem.setAttribute( QStringLiteral(
"embedded" ), 1 );
3389 mapLayerElem.setAttribute( QStringLiteral(
"project" ),
writePath( emIt.value().first ) );
3390 mapLayerElem.setAttribute( QStringLiteral(
"id" ), ml->
id() );
3391 projectLayersNode.appendChild( mapLayerElem );
3398 qgisNode.appendChild( projectLayersNode );
3400 QDomElement layerOrderNode = doc->createElement( QStringLiteral(
"layerorder" ) );
3401 const auto constCustomLayerOrder = mRootGroup->customLayerOrder();
3402 for (
QgsMapLayer *layer : constCustomLayerOrder )
3404 QDomElement mapLayerElem = doc->createElement( QStringLiteral(
"layer" ) );
3405 mapLayerElem.setAttribute( QStringLiteral(
"id" ), layer->id() );
3406 layerOrderNode.appendChild( mapLayerElem );
3408 qgisNode.appendChild( layerOrderNode );
3410 mLabelingEngineSettings->writeSettingsToProject(
this );
3412 QDomElement labelEngineSettingsElement = doc->createElement( QStringLiteral(
"labelEngineSettings" ) );
3413 mLabelingEngineSettings->writeXml( *doc, labelEngineSettingsElement, context );
3414 qgisNode.appendChild( labelEngineSettingsElement );
3417 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorRedPart" ), mBackgroundColor.red() );
3418 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorGreenPart" ), mBackgroundColor.green() );
3419 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorBluePart" ), mBackgroundColor.blue() );
3421 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorRedPart" ), mSelectionColor.red() );
3422 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorGreenPart" ), mSelectionColor.green() );
3423 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorBluePart" ), mSelectionColor.blue() );
3424 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorAlphaPart" ), mSelectionColor.alpha() );
3432 dump_( mProperties );
3435 QgsDebugMsgLevel( QStringLiteral(
"there are %1 property scopes" ).arg(
static_cast<int>( mProperties.
count() ) ), 2 );
3440 mProperties.
writeXml( QStringLiteral(
"properties" ), qgisNode, *doc );
3443 QDomElement ddElem = doc->createElement( QStringLiteral(
"dataDefinedServerProperties" ) );
3444 mDataDefinedServerProperties.
writeXml( ddElem, dataDefinedServerPropertyDefinitions() );
3445 qgisNode.appendChild( ddElem );
3447 mMapThemeCollection->writeXml( *doc );
3449 mTransformContext.
writeXml( qgisNode, context );
3451 QDomElement metadataElem = doc->createElement( QStringLiteral(
"projectMetadata" ) );
3453 qgisNode.appendChild( metadataElem );
3456 const QDomElement annotationsElem = mAnnotationManager->writeXml( *doc, context );
3457 qgisNode.appendChild( annotationsElem );
3461 const QDomElement layoutElem = mLayoutManager->writeXml( *doc );
3462 qgisNode.appendChild( layoutElem );
3466 const QDomElement views3DElem = m3DViewsManager->writeXml( *doc );
3467 qgisNode.appendChild( views3DElem );
3471 const QDomElement bookmarkElem = mBookmarkManager->
writeXml( *doc );
3472 qgisNode.appendChild( bookmarkElem );
3476 const QDomElement sensorElem = mSensorManager->
writeXml( *doc );
3477 qgisNode.appendChild( sensorElem );
3481 const QDomElement viewSettingsElem = mViewSettings->
writeXml( *doc, context );
3482 qgisNode.appendChild( viewSettingsElem );
3486 const QDomElement styleSettingsElem = mStyleSettings->
writeXml( *doc, context );
3487 qgisNode.appendChild( styleSettingsElem );
3491 const QDomElement timeSettingsElement = mTimeSettings->
writeXml( *doc, context );
3492 qgisNode.appendChild( timeSettingsElement );
3496 const QDomElement elevationPropertiesElement = mElevationProperties->
writeXml( *doc, context );
3497 qgisNode.appendChild( elevationPropertiesElement );
3501 const QDomElement displaySettingsElem = mDisplaySettings->
writeXml( *doc, context );
3502 qgisNode.appendChild( displaySettingsElem );
3506 const QDomElement gpsSettingsElem = mGpsSettings->
writeXml( *doc, context );
3507 qgisNode.appendChild( gpsSettingsElem );
3516 QFile backupFile( QStringLiteral(
"%1~" ).arg( filename ) );
3518 ok &= backupFile.open( QIODevice::WriteOnly | QIODevice::Truncate );
3519 ok &= projectFile.open( QIODevice::ReadOnly );
3522 while ( ok && !projectFile.atEnd() )
3524 ba = projectFile.read( 10240 );
3525 ok &= backupFile.write( ba ) == ba.size();
3528 projectFile.close();
3533 setError( tr(
"Unable to create backup file %1" ).arg( backupFile.fileName() ) );
3538 struct utimbuf tb = {
static_cast<time_t
>( fi.lastRead().toSecsSinceEpoch() ),
static_cast<time_t
>( fi.lastModified().toSecsSinceEpoch() ) };
3539 utime( backupFile.fileName().toUtf8().constData(), &tb );
3542 if ( !projectFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
3544 projectFile.close();
3547 setError( tr(
"Unable to save to file %1" ).arg( projectFile.fileName() ) );
3551 QTemporaryFile tempFile;
3552 bool ok = tempFile.open();
3555 QTextStream projectFileStream( &tempFile );
3556 doc->save( projectFileStream, 2 );
3557 ok &= projectFileStream.pos() > -1;
3559 ok &= tempFile.seek( 0 );
3562 while ( ok && !tempFile.atEnd() )
3564 ba = tempFile.read( 10240 );
3565 ok &= projectFile.write( ba ) == ba.size();
3568 ok &= projectFile.error() == QFile::NoError;
3570 projectFile.close();
3577 setError( tr(
"Unable to save to file %1. Your project "
3578 "may be corrupted on disk. Try clearing some space on the volume and "
3579 "check file permissions before pressing save again." )
3580 .arg( projectFile.fileName() ) );
3594 bool propertiesModified;
3595 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3597 if ( propertiesModified )
3607 bool propertiesModified;
3608 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3610 if ( propertiesModified )
3620 bool propertiesModified;
3621 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3623 if ( propertiesModified )
3633 bool propertiesModified;
3634 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3636 if ( propertiesModified )
3646 bool propertiesModified;
3647 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3649 if ( propertiesModified )
3657 const QStringList &def,
3669 value =
property->value();
3671 const bool valid = QMetaType::Type::QStringList == value.userType();
3677 return value.toStringList();
3700 value =
property->value();
3702 const bool valid = value.canConvert( QMetaType::Type::QString );
3707 return value.toString();
3726 value =
property->value();
3729 const bool valid = value.canConvert( QMetaType::Type::Int );
3738 return value.toInt();
3753 const QVariant value =
property->value();
3755 const bool valid = value.canConvert( QMetaType::Type::Double );
3760 return value.toDouble();
3777 const QVariant value =
property->value();
3779 const bool valid = value.canConvert( QMetaType::Type::Bool );
3784 return value.toBool();
3796 if (
findKey_( scope, key, mProperties ) )
3802 return !
findKey_( scope, key, mProperties );
3811 QStringList entries;
3813 if ( foundProperty )
3830 QStringList entries;
3832 if ( foundProperty )
3847 dump_( mProperties );
3867 filePath = storage->filePath( mFile.fileName() );
3894void QgsProject::setError(
const QString &errorMessage )
3898 mErrorMessage = errorMessage;
3905 return mErrorMessage;
3908void QgsProject::clearError()
3912 setError( QString() );
3919 mBadLayerHandler.reset( handler );
3926 const QHash< QString, QPair< QString, bool > >::const_iterator it = mEmbeddedLayers.find(
id );
3927 if ( it == mEmbeddedLayers.constEnd() )
3931 return it.value().first;
3941 static QString sPrevProjectFilePath;
3942 static QDateTime sPrevProjectFileTimestamp;
3943 static QDomDocument sProjectDocument;
3945 QString qgsProjectFile = projectFilePath;
3947 if ( projectFilePath.endsWith( QLatin1String(
".qgz" ), Qt::CaseInsensitive ) )
3949 archive.
unzip( projectFilePath );
3953 const QDateTime projectFileTimestamp = QFileInfo( projectFilePath ).lastModified();
3955 if ( projectFilePath != sPrevProjectFilePath || projectFileTimestamp != sPrevProjectFileTimestamp )
3957 sPrevProjectFilePath.clear();
3959 QFile projectFile( qgsProjectFile );
3960 if ( !projectFile.open( QIODevice::ReadOnly ) )
3965 if ( !sProjectDocument.setContent( &projectFile ) )
3970 sPrevProjectFilePath = projectFilePath;
3971 sPrevProjectFileTimestamp = projectFileTimestamp;
3975 bool useAbsolutePaths =
true;
3977 const QDomElement propertiesElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral(
"properties" ) );
3978 if ( !propertiesElem.isNull() )
3980 QDomElement e = propertiesElem.firstChildElement( QStringLiteral(
"Paths" ) );
3983 e = propertiesElem.firstChildElement( QStringLiteral(
"properties" ) );
3984 while ( !e.isNull() && e.attribute( QStringLiteral(
"name" ) ) != QStringLiteral(
"Paths" ) )
3985 e = e.nextSiblingElement( QStringLiteral(
"properties" ) );
3987 e = e.firstChildElement( QStringLiteral(
"properties" ) );
3988 while ( !e.isNull() && e.attribute( QStringLiteral(
"name" ) ) != QStringLiteral(
"Absolute" ) )
3989 e = e.nextSiblingElement( QStringLiteral(
"properties" ) );
3993 e = e.firstChildElement( QStringLiteral(
"Absolute" ) );
3998 useAbsolutePaths = e.text().compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0;
4003 if ( !useAbsolutePaths )
4008 const QDomElement projectLayersElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral(
"projectlayers" ) );
4009 if ( projectLayersElem.isNull() )
4014 QDomElement mapLayerElem = projectLayersElem.firstChildElement( QStringLiteral(
"maplayer" ) );
4015 while ( ! mapLayerElem.isNull() )
4018 const QString
id = mapLayerElem.firstChildElement( QStringLiteral(
"id" ) ).text();
4019 if (
id == layerId )
4022 if ( mapLayerElem.attribute( QStringLiteral(
"embedded" ) ) == QLatin1String(
"1" ) )
4027 mEmbeddedLayers.insert( layerId, qMakePair( projectFilePath, saveFlag ) );
4029 if ( addLayer( mapLayerElem, brokenNodes, embeddedContext,
flags ) )
4035 mEmbeddedLayers.remove( layerId );
4039 mapLayerElem = mapLayerElem.nextSiblingElement( QStringLiteral(
"maplayer" ) );
4049 QString qgsProjectFile = projectFilePath;
4051 if ( projectFilePath.endsWith( QLatin1String(
".qgz" ), Qt::CaseInsensitive ) )
4053 archive.
unzip( projectFilePath );
4058 QFile projectFile( qgsProjectFile );
4059 if ( !projectFile.open( QIODevice::ReadOnly ) )
4064 QDomDocument projectDocument;
4065 if ( !projectDocument.setContent( &projectFile ) )
4077 QDomElement layerTreeElem = projectDocument.documentElement().firstChildElement( QStringLiteral(
"layer-tree-group" ) );
4078 if ( !layerTreeElem.isNull() )
4088 if ( !group || group->
customProperty( QStringLiteral(
"embedded" ) ).toBool() )
4101 newGroup->
setCustomProperty( QStringLiteral(
"embedded_project" ), projectFilePath );
4104 mLayerTreeRegistryBridge->setEnabled(
false );
4105 initializeEmbeddedSubtree( projectFilePath, newGroup,
flags );
4106 mLayerTreeRegistryBridge->setEnabled(
true );
4109 const auto constFindLayerIds = newGroup->
findLayerIds();
4110 for (
const QString &layerId : constFindLayerIds )
4127 const auto constChildren = group->
children();
4131 child->setCustomProperty( QStringLiteral(
"embedded" ), 1 );
4140 QList<QDomNode> brokenNodes;
4164 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/TopologicalEditing" ), ( enabled ? 1 : 0 ) );
4172 return readNumEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/TopologicalEditing" ), 0 );
4179 if ( mDistanceUnits == unit )
4182 mDistanceUnits = unit;
4191 if ( mAreaUnits == unit )
4203 if ( mScaleMethod == method )
4206 mScaleMethod = method;
4216 if ( !mCachedHomePath.isEmpty() )
4217 return mCachedHomePath;
4221 if ( !mHomePath.isEmpty() )
4223 const QFileInfo homeInfo( mHomePath );
4224 if ( !homeInfo.isRelative() )
4226 mCachedHomePath = mHomePath;
4236 const QString storagePath { storage->filePath(
fileName() ) };
4237 if ( ! storagePath.isEmpty() && QFileInfo::exists( storagePath ) )
4239 mCachedHomePath = QFileInfo( storagePath ).path();
4240 return mCachedHomePath;
4244 mCachedHomePath = pfi.path();
4245 return mCachedHomePath;
4248 if ( !pfi.exists() )
4250 mCachedHomePath = mHomePath;
4254 if ( !mHomePath.isEmpty() )
4257 mCachedHomePath = QDir::cleanPath( pfi.path() +
'/' + mHomePath );
4261 mCachedHomePath = pfi.canonicalPath();
4263 return mCachedHomePath;
4278 return mRelationManager.get();
4285 return mLayoutManager.get();
4292 return mLayoutManager.get();
4299 return m3DViewsManager.get();
4306 return m3DViewsManager.get();
4313 return mBookmarkManager;
4320 return mBookmarkManager;
4327 return mSensorManager;
4334 return mSensorManager;
4341 return mViewSettings;
4348 return mViewSettings;
4355 return mStyleSettings;
4363 return mStyleSettings;
4370 return mTimeSettings;
4377 return mTimeSettings;
4384 return mElevationProperties;
4391 return mElevationProperties;
4398 return mDisplaySettings;
4405 return mDisplaySettings;
4412 return mGpsSettings;
4419 return mGpsSettings;
4426 return mRootGroup.get();
4433 return mMapThemeCollection.get();
4440 return mAnnotationManager.get();
4447 return mAnnotationManager.get();
4454 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
4455 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
4460 if (
layers.contains( it.value() ) )
4461 it.value()->setFlags( it.value()->flags() &
~QgsMapLayer::Identifiable );
4477 for (
const QString &layerId : layerIds )
4495 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
4529 updateTransactionGroups();
4536 return mTransactionMode;
4547 const auto constLayers =
mapLayers().values();
4550 if ( layer->isEditable() )
4552 QgsLogger::warning( tr(
"Transaction mode can be changed only if all layers are not editable." ) );
4558 updateTransactionGroups();
4567 return mTransactionGroups;
4580 return mLayerStore->count();
4587 return mLayerStore->validCount();
4595 return mLayerStore->mapLayer( layerId );
4602 return mLayerStore->mapLayersByName( layerName );
4609 QList<QgsMapLayer *>
layers;
4610 const auto constMapLayers { mLayerStore->mapLayers() };
4611 for (
const auto &l : constMapLayers )
4613 if ( ! l->serverProperties()->shortName().isEmpty() )
4615 if ( l->serverProperties()->shortName() == shortName )
4618 else if ( l->name() == shortName )
4631 auto archive = std::make_unique<QgsProjectArchive>();
4634 if ( !archive->unzip( filename ) )
4636 setError( tr(
"Unable to unzip file '%1'" ).arg( filename ) );
4641 if ( archive->projectFile().isEmpty() )
4643 setError( tr(
"Zip archive does not provide a project file" ) );
4648 releaseHandlesToProjectArchive();
4649 mArchive = std::move( archive );
4666 setError( tr(
"Cannot read unzipped qgs project file" ) + QStringLiteral(
": " ) +
error() );
4676bool QgsProject::zip(
const QString &filename )
4683 auto archive = std::make_unique<QgsProjectArchive>();
4684 const QString
baseName = QFileInfo( filename ).baseName();
4685 const QString qgsFileName = QStringLiteral(
"%1.qgs" ).arg(
baseName );
4686 QFile qgsFile( QDir( archive->dir() ).filePath( qgsFileName ) );
4688 bool writeOk =
false;
4689 if ( qgsFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
4691 writeOk = writeProjectFile( qgsFile.fileName() );
4698 setError( tr(
"Unable to write temporary qgs file" ) );
4703 const QFileInfo info( qgsFile );
4705 const QString asFileName = info.path() + QDir::separator() + info.completeBaseName() + asExt;
4707 bool auxiliaryStorageSavedOk =
true;
4708 if ( ! saveAuxiliaryStorage( asFileName ) )
4710 const QString err = mAuxiliaryStorage->errorString();
4711 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 ) );
4712 auxiliaryStorageSavedOk =
false;
4715 if ( !mArchive->exists() )
4717 releaseHandlesToProjectArchive();
4719 mArchive->unzip( mFile.fileName() );
4722 const QString auxiliaryStorageFile =
static_cast<QgsProjectArchive *
>( mArchive.get() )->auxiliaryStorageFile();
4723 if ( ! auxiliaryStorageFile.isEmpty() )
4725 archive->
addFile( auxiliaryStorageFile );
4734 if ( QFile::exists( asFileName ) )
4736 archive->addFile( asFileName );
4741 archive->addFile( qgsFile.fileName() );
4744 const QStringList &files = mArchive->files();
4745 for (
const QString &file : files )
4747 if ( !file.endsWith( QLatin1String(
".qgs" ), Qt::CaseInsensitive ) && !file.endsWith( asExt, Qt::CaseInsensitive ) )
4749 archive->addFile( file );
4755 if ( !archive->zip( filename ) )
4757 setError( tr(
"Unable to perform zip" ) );
4761 return auxiliaryStorageSavedOk && zipOk;
4772 const QList<QgsMapLayer *> &layers,
4774 bool takeOwnership )
4778 const QList<QgsMapLayer *> myResultList { mLayerStore->addMapLayers(
layers, takeOwnership ) };
4779 if ( !myResultList.isEmpty() )
4782 for (
auto &l : myResultList )
4792 if ( mAuxiliaryStorage )
4807 mProjectScope.reset();
4809 return myResultList;
4815 bool takeOwnership )
4819 QList<QgsMapLayer *> addedLayers;
4820 addedLayers =
addMapLayers( QList<QgsMapLayer *>() << layer, addToLegend, takeOwnership );
4821 return addedLayers.isEmpty() ? nullptr : addedLayers[0];
4824void QgsProject::removeAuxiliaryLayer(
const QgsMapLayer *ml )
4831 const QgsVectorLayer *vl = qobject_cast<const QgsVectorLayer *>( ml );
4843 for (
const auto &layerId : layerIds )
4844 removeAuxiliaryLayer( mLayerStore->mapLayer( layerId ) );
4846 mProjectScope.reset();
4847 mLayerStore->removeMapLayers( layerIds );
4854 for (
const auto &layer :
layers )
4855 removeAuxiliaryLayer( layer );
4857 mProjectScope.reset();
4858 mLayerStore->removeMapLayers(
layers );
4865 removeAuxiliaryLayer( mLayerStore->mapLayer( layerId ) );
4866 mProjectScope.reset();
4867 mLayerStore->removeMapLayer( layerId );
4874 removeAuxiliaryLayer( layer );
4875 mProjectScope.reset();
4876 mLayerStore->removeMapLayer( layer );
4883 mProjectScope.reset();
4884 return mLayerStore->takeMapLayer( layer );
4891 return mMainAnnotationLayer;
4898 if ( mLayerStore->count() == 0 )
4901 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
4902 mProjectScope.reset();
4903 mLayerStore->removeAllMapLayers();
4905 snapSingleBlocker.release();
4907 if ( !mBlockSnappingUpdates )
4915 const QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
4916 QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin();
4917 for ( ; it !=
layers.constEnd(); ++it )
4919 it.value()->reload();
4928 return validOnly ? mLayerStore->validMapLayers() : mLayerStore->mapLayers();
4935 return mTransactionGroups.value( qMakePair( providerKey, connString ) );
4942 return &mEditBufferGroup;
4953 if ( mSettings.
value( QStringLiteral(
"/projections/unknownCrsBehavior" ), QStringLiteral(
"NoAction" ),
QgsSettings::App ).toString() == QStringLiteral(
"UseProjectCrs" )
4954 || mSettings.
value( QStringLiteral(
"/projections/unknownCrsBehavior" ), 0,
QgsSettings::App ).toString() == QLatin1String(
"2" ) )
4962 const QString layerDefaultCrs = mSettings.
value( QStringLiteral(
"/Projections/layerDefaultCrs" ), QStringLiteral(
"EPSG:4326" ) ).toString();
4983bool QgsProject::saveAuxiliaryStorage(
const QString &filename )
4989 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
4994 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() );
5002 if ( !mAuxiliaryStorage->exists( *
this ) && empty )
5006 else if ( !filename.isEmpty() )
5008 return mAuxiliaryStorage->saveAs( filename );
5012 return mAuxiliaryStorage->saveAs( *
this );
5025 return sPropertyDefinitions;
5038 return mAuxiliaryStorage.get();
5045 return mAuxiliaryStorage.get();
5052 const QDir archiveDir( mArchive->dir() );
5053 QTemporaryFile tmpFile( archiveDir.filePath(
"XXXXXX_" + nameTemplate ),
this );
5054 tmpFile.setAutoRemove(
false );
5056 mArchive->addFile( tmpFile.fileName() );
5057 return tmpFile.fileName();
5064 QStringList attachments;
5066 const QStringList files = mArchive->files();
5067 attachments.reserve( files.size() );
5068 for (
const QString &file : files )
5070 if ( QFileInfo( file ).baseName() !=
baseName )
5072 attachments.append( file );
5082 return mArchive->removeFile( path );
5089 return QStringLiteral(
"attachment:///%1" ).arg( QFileInfo( attachedFile ).
fileName() );
5096 if ( identifier.startsWith( QLatin1String(
"attachment:///" ) ) )
5098 return QDir( mArchive->dir() ).absoluteFilePath( identifier.mid( 14 ) );
5119 mProjectScope.reset();
5133 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5147 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
5148 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
5153 if (
layers.contains( it.value() ) )
5154 it.value()->setFlags( it.value()->flags() &
~QgsMapLayer::Removable );
5165 QStringList customColors;
5166 QStringList customColorLabels;
5168 QgsNamedColorList::const_iterator colorIt = colors.constBegin();
5169 for ( ; colorIt != colors.constEnd(); ++colorIt )
5172 const QString label = ( *colorIt ).second;
5173 customColors.append( color );
5174 customColorLabels.append( label );
5176 writeEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Colors" ), customColors );
5177 writeEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Labels" ), customColorLabels );
5178 mProjectScope.reset();
5186 if ( mBackgroundColor == color )
5189 mBackgroundColor = color;
5197 return mBackgroundColor;
5204 if ( mSelectionColor == color )
5207 mSelectionColor = color;
5215 return mSelectionColor;
5252 translationContext.setFileName( QStringLiteral(
"%1/%2.ts" ).arg(
absolutePath(),
baseName() ) );
5256 translationContext.writeTsFile( locale );
5259QString
QgsProject::translate(
const QString &context,
const QString &sourceText,
const char *disambiguation,
int n )
const
5268 QString result = mTranslator->translate( context.toUtf8(), sourceText.toUtf8(), disambiguation, n );
5270 if ( result.isEmpty() )
5284 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5289 if ( !( ( *it )->accept( visitor ) ) )
5298 if ( !mLayoutManager->accept( visitor ) )
5301 if ( !mAnnotationManager->accept( visitor ) )
5309 return mElevationShadingRenderer;
5312void QgsProject::loadProjectFlags(
const QDomDocument *doc )
5316 QDomElement element = doc->documentElement().firstChildElement( QStringLiteral(
"projectFlags" ) );
5318 if ( !element.isNull() )
5325 element = doc->documentElement().firstChildElement( QStringLiteral(
"evaluateDefaultValues" ) );
5326 if ( !element.isNull() )
5328 if ( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
5333 element = doc->documentElement().firstChildElement( QStringLiteral(
"trust" ) );
5334 if ( !element.isNull() )
5336 if ( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
5352 const QString projectFunctions =
readEntry( QStringLiteral(
"ExpressionFunctions" ), QStringLiteral(
"/pythonCode" ), QString() );
5353 if ( !projectFunctions.isEmpty() )
5373QHash< QString, QColor > loadColorsFromProject(
const QgsProject *project )
5375 QHash< QString, QColor > colors;
5378 QStringList colorStrings = project->
readListEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Colors" ) );
5379 const QStringList colorLabels = project->
readListEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Labels" ) );
5383 for ( QStringList::iterator it = colorStrings.begin();
5384 it != colorStrings.end(); ++it )
5388 if ( colorLabels.length() > colorIndex )
5390 label = colorLabels.at( colorIndex );
5393 colors.insert( label.toLower(), color );
5401GetNamedProjectColor::GetNamedProjectColor(
const QgsProject *project )
5407 mColors = loadColorsFromProject( project );
5410GetNamedProjectColor::GetNamedProjectColor(
const QHash<QString, QColor> &colors )
5418 const QString colorName = values.at( 0 ).toString().toLower();
5419 if ( mColors.contains( colorName ) )
5421 return QStringLiteral(
"%1,%2,%3" ).arg( mColors.value( colorName ).red() ).arg( mColors.value( colorName ).green() ).arg( mColors.value( colorName ).blue() );
5429 return new GetNamedProjectColor( mColors );
5432GetNamedProjectColorObject::GetNamedProjectColorObject(
const QgsProject *project )
5438 mColors = loadColorsFromProject( project );
5441GetNamedProjectColorObject::GetNamedProjectColorObject(
const QHash<QString, QColor> &colors )
5449 const QString colorName = values.at( 0 ).toString().toLower();
5450 if ( mColors.contains( colorName ) )
5452 return mColors.value( colorName );
5460 return new GetNamedProjectColorObject( mColors );
5465GetSensorData::GetSensorData(
const QMap<QString, QgsAbstractSensor::SensorData> &sensorData )
5468 QStringLiteral(
"Sensors" ) )
5469 , mSensorData( sensorData )
5475 const QString sensorName = values.at( 0 ).toString();
5476 const int expiration = values.at( 1 ).toInt();
5477 const qint64 timestamp = QDateTime::currentMSecsSinceEpoch();
5478 if ( mSensorData.contains( sensorName ) )
5480 if ( expiration <= 0 || ( timestamp - mSensorData[sensorName].lastTimestamp.toMSecsSinceEpoch() ) < expiration )
5482 return mSensorData[sensorName].lastValue;
5491 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.