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" ) );
120 for (
int i = 0; i < keyTokens.size(); ++i )
122 const QString keyToken = keyTokens.at( i );
126 const thread_local QRegularExpression sInvalidRegexp = QRegularExpression( QStringLiteral(
"([^:A-Z_a-z\\x{C0}-\\x{D6}\\x{D8}-\\x{F6}\\x{F8}-\\x{2FF}\\x{370}-\\x{37D}\\x{37F}-\\x{1FFF}\\x{200C}-\\x{200D}\\x{2070}-\\x{218F}\\x{2C00}-\\x{2FEF}\\x{3001}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFFD}\\-\\.0-9\\x{B7}\\x{0300}-\\x{036F}\\x{203F}-\\x{2040}]|^[^:A-Z_a-z\\x{C0}-\\x{D6}\\x{D8}-\\x{F6}\\x{F8}-\\x{2FF}\\x{370}-\\x{37D}\\x{37F}-\\x{1FFF}\\x{200C}-\\x{200D}\\x{2070}-\\x{218F}\\x{2C00}-\\x{2FEF}\\x{3001}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFFD}])" ) );
127 if ( keyToken.contains( sInvalidRegexp ) )
129 const QString errorString = QObject::tr(
"Entry token invalid : '%1'. The token will not be saved to file." ).arg( keyToken );
157 while ( !keySequence.isEmpty() )
161 if ( keySequence.first() == currentProperty->
name() )
164 keySequence.pop_front();
166 if ( 1 == keySequence.count() )
169 return currentProperty->
find( keySequence.front() );
171 else if ( keySequence.isEmpty() )
176 return currentProperty;
178 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
180 if ( nextProperty->
isKey() )
184 else if ( nextProperty->
isValue() && 1 == keySequence.count() )
190 return currentProperty;
228 const QVariant &value,
229 bool &propertiesModified )
238 propertiesModified =
false;
239 while ( ! keySequence.isEmpty() )
243 if ( keySequence.first() == currentProperty->
name() )
246 keySequence.pop_front();
250 if ( 1 == keySequence.count() )
253 if ( !property || property->value() != value )
255 currentProperty->
setValue( keySequence.front(), value );
256 propertiesModified =
true;
259 return currentProperty;
263 else if ( keySequence.isEmpty() )
265 if ( currentProperty->
value() != value )
268 propertiesModified =
true;
271 return currentProperty;
273 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
277 if ( currentProperty )
288 if ( ( newPropertyKey = currentProperty->
addKey( keySequence.first() ) ) )
290 currentProperty = newPropertyKey;
322 while ( ! keySequence.isEmpty() )
326 if ( keySequence.first() == currentProperty->
name() )
329 keySequence.pop_front();
333 if ( 1 == keySequence.count() )
335 currentProperty->
removeKey( keySequence.front() );
340 else if ( keySequence.isEmpty() )
342 previousQgsPropertyKey->
removeKey( currentProperty->
name() );
344 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
346 previousQgsPropertyKey = currentProperty;
349 if ( currentProperty )
373 , mCapabilities( capabilities )
376 , mSnappingConfig( this )
394 mProperties.
setName( QStringLiteral(
"properties" ) );
397 mMainAnnotationLayer->setParent(
this );
404 mLayerTreeRegistryBridge = std::make_unique<QgsLayerTreeRegistryBridge>( mRootGroup.get(),
this,
this );
411 this, [
this](
const QStringList &
layers ) { mProjectScope.reset(); emit layersWillBeRemoved( layers ); } );
413 this, [
this](
const QList<QgsMapLayer *> &
layers ) { mProjectScope.reset(); emit layersWillBeRemoved( layers ); } );
415 this, [
this](
const QString & layer ) { mProjectScope.reset(); emit layerWillBeRemoved( layer ); } );
417 this, [
this](
QgsMapLayer * layer ) { mProjectScope.reset(); emit layerWillBeRemoved( layer ); } );
419 [
this](
const QStringList &
layers ) { mProjectScope.reset(); emit layersRemoved( layers ); } );
421 [
this](
const QString & layer ) { mProjectScope.reset(); emit layerRemoved( layer ); } );
423 [
this]() { mProjectScope.reset(); emit removeAll(); } );
425 [
this](
const QList< QgsMapLayer * > &
layers ) { mProjectScope.reset(); emit layersAdded( layers ); } );
427 [
this](
QgsMapLayer * layer ) { mProjectScope.reset(); emit layerWasAdded( layer ); } );
435 [
this](
const QList<QgsMapLayer *> &
layers )
437 for ( const auto &layer : layers )
439 disconnect( layer, &QgsMapLayer::dataSourceChanged, mRelationManager.get(), &QgsRelationManager::updateRelationsStatus );
444 [
this](
const QList<QgsMapLayer *> &layers )
446 for ( const auto &layer : layers )
448 connect( layer, &QgsMapLayer::dataSourceChanged, mRelationManager.get(), &QgsRelationManager::updateRelationsStatus );
457 mStyleSettings->combinedStyleModel()->addDefaultStyle();
463 mIsBeingDeleted =
true;
466 releaseHandlesToProjectArchive();
468 if (
this == sProject )
499 mProjectScope.reset();
510 return mMetadata.
title();
519 if ( oldEvaluateDefaultValues != newEvaluateDefaultValues )
522 for (
auto layerIt =
layers.constBegin(); layerIt !=
layers.constEnd(); ++layerIt )
524 if (
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layerIt.value() ) )
525 if ( vl->dataProvider() )
532 if ( oldTrustLayerMetadata != newTrustLayerMetadata )
535 for (
auto layerIt =
layers.constBegin(); layerIt !=
layers.constEnd(); ++layerIt )
537 if (
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layerIt.value() ) )
539 vl->setReadExtentFromXml( newTrustLayerMetadata );
544 if ( mFlags !=
flags )
559 newFlags &= ~(
static_cast< int >( flag ) );
574 return mSaveUserFull;
581 return mSaveDateTime;
602 if ( dirty && mDirtyBlockCount > 0 )
608 if ( mDirty == dirty )
619 if ( path == mHomePath )
623 mCachedHomePath.clear();
624 mProjectScope.reset();
635 const QList<QgsAttributeEditorElement *> elements = parent->
children();
643 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:formcontainers" ).arg( layerId ), container->
name() );
645 if ( !container->
children().empty() )
656 const QList<QgsLayerTreeLayer *>
layers = mRootGroup->findLayers();
660 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1" ).arg( layer->layerId() ), layer->name() );
669 for (
const QgsField &field : fields )
672 if ( field.alias().isEmpty() )
673 fieldName = field.name();
675 fieldName = field.alias();
677 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:fieldaliases" ).arg( vlayer->
id() ), fieldName );
679 if ( field.editorWidgetSetup().type() == QStringLiteral(
"ValueRelation" ) )
681 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:fields:%2:valuerelationvalue" ).arg( vlayer->
id(), field.name() ), field.editorWidgetSetup().config().value( QStringLiteral(
"Value" ) ).toString() );
683 if ( field.editorWidgetSetup().type() == QStringLiteral(
"ValueMap" ) )
685 if ( field.editorWidgetSetup().config().value( QStringLiteral(
"map" ) ).canConvert<QList<QVariant>>() )
687 const QList<QVariant> valueList = field.editorWidgetSetup().config().value( QStringLiteral(
"map" ) ).toList();
689 for (
int i = 0, row = 0; i < valueList.count(); i++, row++ )
691 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:fields:%2:valuemapdescriptions" ).arg( vlayer->
id(), field.name() ), valueList[i].toMap().constBegin().key() );
704 const QList<QgsLayerTreeGroup *> groupLayers = mRootGroup->findGroups();
707 translationContext->
registerTranslation( QStringLiteral(
"project:layergroups" ), groupLayer->name() );
711 const QList<QgsRelation> &relations = mRelationManager->relations().values();
714 translationContext->
registerTranslation( QStringLiteral(
"project:relations" ), relation.name() );
722 mDataDefinedServerProperties = properties;
729 return mDataDefinedServerProperties;
736 switch ( mTransactionMode )
757 switch ( mTransactionMode )
764 commitErrors.append( tr(
"Trying to commit changes without a layer specified. This only works if the transaction mode is buffered" ) );
773 return mEditBufferGroup.
commitChanges( commitErrors, stopEditing );
783 switch ( mTransactionMode )
790 rollbackErrors.append( tr(
"Trying to roll back changes without a layer specified. This only works if the transaction mode is buffered" ) );
793 bool success = vectorLayer->
rollBack( stopEditing );
799 return mEditBufferGroup.
rollBack( rollbackErrors, stopEditing );
809 if ( name == mFile.fileName() )
812 const QString oldHomePath =
homePath();
814 mFile.setFileName( name );
815 mCachedHomePath.clear();
816 mProjectScope.reset();
820 const QString newHomePath =
homePath();
821 if ( newHomePath != oldHomePath )
832 return mFile.fileName();
839 mOriginalPath = path;
846 return mOriginalPath;
853 return QFileInfo( mFile );
871 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
876 return QFileInfo( mFile.fileName() ).lastModified();
887 if ( mFile.fileName().isEmpty() )
890 return QFileInfo( mFile.fileName() ).absolutePath();
901 if ( mFile.fileName().isEmpty() )
904 return QFileInfo( mFile.fileName() ).absoluteFilePath();
915 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
920 return QFileInfo( mFile.fileName() ).completeBaseName();
928 const bool absolutePaths =
readBoolEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
false );
939 writeEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
true );
942 writeEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
false );
959 return mCrs3D.
isValid() ? mCrs3D : mCrs;
971 writeEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectionsEnabled" ),
crs.
isValid() ? 1 : 0 );
972 mProjectScope.reset();
986 if ( oldCrs3D != mCrs3D )
990 if ( adjustEllipsoid )
999 if ( !
crs().isValid() )
1009 if (
ellipsoid ==
readEntry( QStringLiteral(
"Measure" ), QStringLiteral(
"/Ellipsoid" ) ) )
1012 mProjectScope.reset();
1022 switch ( mCrs.
type() )
1025 QgsDebugError( QStringLiteral(
"Project has a vertical CRS set as the horizontal CRS!" ) );
1044 return mVerticalCrs;
1072 *errorMessage = QObject::tr(
"Specified CRS is a %1 CRS, not a Vertical CRS" ).arg(
qgsEnumValueToKey(
crs.
type() ) );
1077 if (
crs != mVerticalCrs )
1082 switch ( mCrs.
type() )
1085 if (
crs != oldVerticalCrs )
1088 *errorMessage = QObject::tr(
"Project CRS is a Compound CRS, specified Vertical CRS will be ignored" );
1094 if (
crs != oldVerticalCrs )
1097 *errorMessage = QObject::tr(
"Project CRS is a Geographic 3D CRS, specified Vertical CRS will be ignored" );
1103 if (
crs != oldVerticalCrs )
1106 *errorMessage = QObject::tr(
"Project CRS is a Geocentric CRS, specified Vertical CRS will be ignored" );
1115 *errorMessage = QObject::tr(
"Project CRS is a Projected 3D CRS, specified Vertical CRS will be ignored" );
1133 res = rebuildCrs3D( errorMessage );
1134 mProjectScope.reset();
1141 if ( mCrs3D != oldCrs3D )
1152 return mTransformContext;
1159 if ( context == mTransformContext )
1162 mTransformContext = context;
1163 mProjectScope.reset();
1166 for (
auto &layer : mLayerStore.get()->mapLayers() )
1168 layer->setTransformContext( context );
1177 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
1181 if ( !mIsBeingDeleted )
1190 mProjectScope.reset();
1191 mFile.setFileName( QString() );
1194 mSaveUserFull.clear();
1195 mSaveDateTime = QDateTime();
1198 mCachedHomePath.clear();
1202 mCustomVariables.clear();
1208 if ( !mSettings.
value( QStringLiteral(
"projects/anonymize_new_projects" ),
false,
QgsSettings::Core ).toBool() )
1229 mEmbeddedLayers.clear();
1230 mRelationManager->clear();
1231 mAnnotationManager->clear();
1232 mLayoutManager->clear();
1233 m3DViewsManager->clear();
1234 mBookmarkManager->
clear();
1235 mSensorManager->
clear();
1236 mViewSettings->
reset();
1237 mTimeSettings->
reset();
1238 mElevationProperties->
reset();
1239 mDisplaySettings->
reset();
1240 mGpsSettings->
reset();
1241 mSnappingConfig.
reset();
1249 mLabelingEngineSettings->clear();
1253 releaseHandlesToProjectArchive();
1259 mStyleSettings->
reset();
1263 if ( !mIsBeingDeleted )
1271 writeEntry( QStringLiteral(
"PositionPrecision" ), QStringLiteral(
"/Automatic" ),
true );
1272 writeEntry( QStringLiteral(
"PositionPrecision" ), QStringLiteral(
"/DecimalPlaces" ), 2 );
1274 const bool defaultRelativePaths = mSettings.
value( QStringLiteral(
"/qgis/defaultProjectPathsRelative" ),
true ).toBool();
1277 int red = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_red" ), 255 ).toInt();
1278 int green = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_green" ), 255 ).toInt();
1279 int blue = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_blue" ), 255 ).toInt();
1282 red = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_red" ), 255 ).toInt();
1283 green = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_green" ), 255 ).toInt();
1284 blue = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_blue" ), 0 ).toInt();
1285 const int alpha = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_alpha" ), 255 ).toInt();
1291 mRootGroup->clear();
1292 if ( mMainAnnotationLayer )
1293 mMainAnnotationLayer->
reset();
1295 snapSingleBlocker.release();
1297 if ( !mBlockSnappingUpdates )
1302 if ( !mBlockChangeSignalsDuringClear )
1314 topQgsPropertyKey.
dump();
1347 const QDomElement propertiesElem = doc.documentElement().firstChildElement( QStringLiteral(
"properties" ) );
1349 if ( propertiesElem.isNull() )
1354 const QDomNodeList scopes = propertiesElem.childNodes();
1356 if ( propertiesElem.firstChild().isNull() )
1358 QgsDebugError( QStringLiteral(
"empty ``properties'' XML tag ... bailing" ) );
1362 if ( ! project_properties.
readXml( propertiesElem ) )
1364 QgsDebugError( QStringLiteral(
"Project_properties.readXml() failed" ) );
1378 const QDomElement ddElem = doc.documentElement().firstChildElement( QStringLiteral(
"dataDefinedServerProperties" ) );
1379 if ( !ddElem.isNull() )
1381 if ( !ddServerProperties.
readXml( ddElem, dataDefinedServerPropertyDefinitions ) )
1383 QgsDebugError( QStringLiteral(
"dataDefinedServerProperties.readXml() failed" ) );
1386 return ddServerProperties;
1393static void _getTitle(
const QDomDocument &doc, QString &title )
1395 const QDomElement titleNode = doc.documentElement().firstChildElement( QStringLiteral(
"title" ) );
1399 if ( titleNode.isNull() )
1405 if ( !titleNode.hasChildNodes() )
1411 const QDomNode titleTextNode = titleNode.firstChild();
1413 if ( !titleTextNode.isText() )
1419 const QDomText titleText = titleTextNode.toText();
1421 title = titleText.data();
1425static void readProjectFileMetadata(
const QDomDocument &doc, QString &lastUser, QString &lastUserFull, QDateTime &lastSaveDateTime )
1427 const QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"qgis" ) );
1431 QgsDebugError( QStringLiteral(
"unable to find qgis element" ) );
1435 const QDomNode qgisNode = nl.item( 0 );
1437 const QDomElement qgisElement = qgisNode.toElement();
1438 lastUser = qgisElement.attribute( QStringLiteral(
"saveUser" ), QString() );
1439 lastUserFull = qgisElement.attribute( QStringLiteral(
"saveUserFull" ), QString() );
1440 lastSaveDateTime = QDateTime::fromString( qgisElement.attribute( QStringLiteral(
"saveDateTime" ), QString() ), Qt::ISODate );
1445 const QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"qgis" ) );
1449 QgsDebugError( QStringLiteral(
" unable to find qgis element in project file" ) );
1453 const QDomNode qgisNode = nl.item( 0 );
1455 const QDomElement qgisElement = qgisNode.toElement();
1456 QgsProjectVersion projectVersion( qgisElement.attribute( QStringLiteral(
"version" ) ) );
1457 return projectVersion;
1464 return mSnappingConfig;
1483 if ( mAvoidIntersectionsMode == mode )
1486 mAvoidIntersectionsMode = mode;
1520void QgsProject::preloadProviders(
const QVector<QDomNode> ¶llelLayerNodes,
1522 QMap<QString, QgsDataProvider *> &loadedProviders,
1524 int totalProviderCount )
1529 QMap<QString, LayerToLoad> layersToLoad;
1531 for (
const QDomNode &node : parallelLayerNodes )
1535 const QDomElement layerElement = node.toElement();
1537 layerToLoad.
layerId = layerElement.namedItem( QStringLiteral(
"id" ) ).toElement().text();
1538 layerToLoad.
provider = layerElement.namedItem( QStringLiteral(
"provider" ) ).toElement().text();
1539 layerToLoad.
dataSource = layerElement.namedItem( QStringLiteral(
"datasource" ) ).toElement().text();
1550 layersToLoad.insert( layerToLoad.
layerId, layerToLoad );
1553 while ( !layersToLoad.isEmpty() )
1555 const QList<LayerToLoad> layersToAttemptInParallel = layersToLoad.values();
1556 QString layerToAttemptInMainThread;
1558 QHash<QString, QgsRunnableProviderCreator *> runnables;
1559 QThreadPool threadPool;
1562 for (
const LayerToLoad &lay : layersToAttemptInParallel )
1565 runnables.insert( lay.layerId, run );
1571 layersToLoad.remove( layId );
1574 Q_ASSERT( finishedRun );
1576 std::unique_ptr<QgsDataProvider> provider( finishedRun->
dataProvider() );
1577 Q_ASSERT( provider && provider->isValid() );
1579 loadedProviders.insert( layId, provider.release() );
1584 if ( layerToAttemptInMainThread.isEmpty() )
1585 layerToAttemptInMainThread = layId;
1589 if ( i == parallelLayerNodes.count() || !isValid )
1592 threadPool.start( run );
1596 threadPool.waitForDone();
1598 qDeleteAll( runnables );
1601 auto it = layersToLoad.find( layerToAttemptInMainThread );
1602 if ( it != layersToLoad.end() )
1604 std::unique_ptr<QgsDataProvider> provider;
1614 if ( provider && provider->isValid() )
1619 layersToLoad.erase( it );
1622 loadedProviders.insert( layerId, provider.release() );
1630void QgsProject::releaseHandlesToProjectArchive()
1635bool QgsProject::rebuildCrs3D( QString *error )
1642 else if ( !mVerticalCrs.
isValid() )
1648 switch ( mCrs.
type() )
1689bool QgsProject::_getMapLayers(
const QDomDocument &doc, QList<QDomNode> &brokenNodes,
Qgis::ProjectReadFlags flags )
1696 QDomElement layerElement = doc.documentElement().firstChildElement( QStringLiteral(
"projectlayers" ) ).firstChildElement( QStringLiteral(
"maplayer" ) );
1700 if ( layerElement.isNull() )
1710 bool returnStatus =
true;
1713 while ( ! layerElement.isNull() )
1716 layerElement = layerElement.nextSiblingElement( QStringLiteral(
"maplayer" ) );
1722 if ( depSorter.hasCycle() )
1726 if ( depSorter.hasMissingDependency() )
1727 returnStatus =
false;
1731 const QVector<QDomNode> sortedLayerNodes = depSorter.sortedLayerNodes();
1732 const int totalLayerCount = sortedLayerNodes.count();
1734 QVector<QDomNode> parallelLoading;
1735 QMap<QString, QgsDataProvider *> loadedProviders;
1740 profile.switchTask( tr(
"Load providers in parallel" ) );
1741 for (
const QDomNode &node : sortedLayerNodes )
1743 const QDomElement element = node.toElement();
1744 if ( element.attribute( QStringLiteral(
"embedded" ) ) != QLatin1String(
"1" ) )
1746 const QString layerId = node.namedItem( QStringLiteral(
"id" ) ).toElement().text();
1747 if ( !depSorter.isLayerDependent( layerId ) )
1749 const QDomNode mnl = element.namedItem( QStringLiteral(
"provider" ) );
1750 const QDomElement mne = mnl.toElement();
1751 const QString provider = mne.text();
1755 parallelLoading.append( node );
1764 if ( !parallelLoading.isEmpty() )
1765 preloadProviders( parallelLoading, context, loadedProviders, projectFlagsToLayerReadFlags(
flags, mFlags ), sortedLayerNodes.count() );
1768 int i = loadedProviders.count();
1769 for (
const QDomNode &node : std::as_const( sortedLayerNodes ) )
1771 const QDomElement element = node.toElement();
1772 const QString name =
translate( QStringLiteral(
"project:layers:%1" ).arg( node.namedItem( QStringLiteral(
"id" ) ).toElement().text() ), node.namedItem( QStringLiteral(
"layername" ) ).toElement().text() );
1773 if ( !name.isNull() )
1774 emit
loadingLayer( tr(
"Loading layer %1" ).arg( name ) );
1776 profile.switchTask( name );
1777 if ( element.attribute( QStringLiteral(
"embedded" ) ) == QLatin1String(
"1" ) )
1779 createEmbeddedLayer( element.attribute( QStringLiteral(
"id" ) ),
readPath( element.attribute( QStringLiteral(
"project" ) ) ), brokenNodes,
true,
flags );
1787 QString layerId = element.namedItem( QStringLiteral(
"id" ) ).toElement().text();
1789 if ( !addLayer( element, brokenNodes, context,
flags, loadedProviders.take( layerId ) ) )
1791 returnStatus =
false;
1794 if ( !messages.isEmpty() )
1803 return returnStatus;
1806bool QgsProject::addLayer(
const QDomElement &layerElem,
1807 QList<QDomNode> &brokenNodes,
1814 const QString type = layerElem.attribute( QStringLiteral(
"type" ) );
1816 std::unique_ptr<QgsMapLayer>
mapLayer;
1824 QgsDebugError( QStringLiteral(
"Unknown layer type \"%1\"" ).arg( type ) );
1828 switch ( layerType )
1831 mapLayer = std::make_unique<QgsVectorLayer>();
1835 mapLayer = std::make_unique<QgsRasterLayer>();
1839 mapLayer = std::make_unique<QgsMeshLayer>();
1843 mapLayer = std::make_unique<QgsVectorTileLayer>();
1847 mapLayer = std::make_unique<QgsPointCloudLayer>();
1851 mapLayer = std::make_unique<QgsTiledSceneLayer>();
1856 const QString
typeName = layerElem.attribute( QStringLiteral(
"name" ) );
1864 mapLayer = std::make_unique<QgsAnnotationLayer>( QString(), options );
1871 mapLayer = std::make_unique<QgsGroupLayer>( QString(), options );
1878 QgsDebugError( QStringLiteral(
"Unable to create layer" ) );
1886 const QString layerId { layerElem.namedItem( QStringLiteral(
"id" ) ).toElement().text() };
1887 Q_ASSERT( ! layerId.isEmpty() );
1893 profile.switchTask( tr(
"Load layer source" ) );
1900 if ( vl->dataProvider() )
1907 profile.switchTask( tr(
"Add layer to project" ) );
1908 QList<QgsMapLayer *> newLayers;
1920 vLayer->joinBuffer()->resolveReferences(
this );
1929 brokenNodes.push_back( layerElem );
1932 const bool wasEditable = layerElem.attribute( QStringLiteral(
"editable" ), QStringLiteral(
"0" ) ).toInt();
1944 if ( ! layerWasStored )
1949 return layerIsValid;
1956 mFile.setFileName( filename );
1957 mCachedHomePath.clear();
1958 mProjectScope.reset();
1967 const QString filename = mFile.fileName();
1972 QTemporaryFile inDevice;
1973 if ( !inDevice.open() )
1975 setError( tr(
"Unable to open %1" ).arg( inDevice.fileName() ) );
1981 if ( !storage->readProject( filename, &inDevice, context ) )
1983 QString err = tr(
"Unable to open %1" ).arg( filename );
1984 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
1985 if ( !messages.isEmpty() )
1986 err += QStringLiteral(
"\n\n" ) + messages.last().message();
1990 returnValue = unzip( inDevice.fileName(),
flags );
1996 returnValue = unzip( mFile.fileName(),
flags );
2001 const QFileInfo finfo( mFile.fileName() );
2002 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( QStringLiteral(
"%1_attachments.zip" ).arg( finfo.completeBaseName() ) );
2003 if ( QFile( attachmentsZip ).exists() )
2005 auto archive = std::make_unique<QgsArchive>();
2006 if ( archive->unzip( attachmentsZip ) )
2008 releaseHandlesToProjectArchive();
2009 mArchive = std::move( archive );
2012 returnValue = readProjectFile( mFile.fileName(),
flags );
2018 mFile.setFileName( filename );
2019 mCachedHomePath.clear();
2020 mProjectScope.reset();
2025 mTranslator.reset(
nullptr );
2037 ScopedIntIncrementor snapSignalBlock( &mBlockSnappingUpdates );
2039 QFile projectFile( filename );
2047 if ( QFile( QStringLiteral(
"%1/%2.qm" ).arg( QFileInfo( mFile ).
absolutePath(), localeFileName ) ).exists() )
2049 mTranslator.reset(
new QTranslator() );
2050 ( void )mTranslator->load( localeFileName, QFileInfo( mFile ).absolutePath() );
2053 profile.switchTask( tr(
"Reading project file" ) );
2054 auto doc = std::make_unique<QDomDocument>( QStringLiteral(
"qgis" ) );
2056 if ( !projectFile.open( QIODevice::ReadOnly | QIODevice::Text ) )
2058 projectFile.close();
2060 setError( tr(
"Unable to open %1" ).arg( projectFile.fileName() ) );
2065 QTextStream textStream( &projectFile );
2066#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
2067 textStream.setCodec(
"UTF-8" );
2069 QString projectString = textStream.readAll();
2070 projectFile.close();
2072 for (
int i = 0; i < 32; i++ )
2074 if ( i == 9 || i == 10 || i == 13 )
2078 projectString.replace( QChar( i ), QStringLiteral(
"%1%2%1" ).arg(
FONTMARKER_CHR_FIX, QString::number( i ) ) );
2084 if ( !doc->setContent( projectString, &errorMsg, &line, &column ) )
2086 const QString errorString = tr(
"Project file read error in file %1: %2 at line %3 column %4" )
2087 .arg( projectFile.fileName(), errorMsg ).arg( line ).arg( column );
2089 setError( errorString );
2094 projectFile.close();
2102 profile.switchTask( tr(
"Updating project file" ) );
2103 if ( thisVersion > fileVersion )
2105 const bool isOlderMajorVersion = fileVersion.
majorVersion() < thisVersion.majorVersion();
2107 if ( isOlderMajorVersion )
2110 "version of qgis (saved in " + fileVersion.
text() +
2112 "). Problems may occur." );
2123 projectFile.updateRevision( thisVersion );
2125 else if ( fileVersion > thisVersion )
2128 "version of qgis (saved in " + fileVersion.
text() +
2130 "). Problems may occur." );
2136 profile.switchTask( tr(
"Creating auxiliary storage" ) );
2137 const QString
fileName = mFile.fileName();
2144 std::unique_ptr<QgsAuxiliaryStorage> aStorage = std::move( mAuxiliaryStorage );
2145 std::unique_ptr<QgsArchive> archive = std::move( mArchive );
2149 mBlockChangeSignalsDuringClear =
true;
2151 mBlockChangeSignalsDuringClear =
false;
2156 releaseHandlesToProjectArchive();
2158 mAuxiliaryStorage = std::move( aStorage );
2159 mArchive = std::move( archive );
2162 mCachedHomePath.clear();
2163 mProjectScope.reset();
2164 mSaveVersion = fileVersion;
2167 profile.switchTask( tr(
"Reading properties" ) );
2176 dump_( mProperties );
2181 _getTitle( *doc, oldTitle );
2183 readProjectFileMetadata( *doc, mSaveUser, mSaveUserFull, mSaveDateTime );
2185 const QDomNodeList homePathNl = doc->elementsByTagName( QStringLiteral(
"homePath" ) );
2186 if ( homePathNl.count() > 0 )
2188 const QDomElement homePathElement = homePathNl.at( 0 ).toElement();
2189 const QString
homePath = homePathElement.attribute( QStringLiteral(
"path" ) );
2199 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorGreenPart" ), 255 ),
2200 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorBluePart" ), 255 ) );
2203 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorGreenPart" ), 255 ),
2204 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorBluePart" ), 255 ),
2205 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorAlphaPart" ), 255 ) );
2209 const QString distanceUnitString =
readEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/DistanceUnits" ), QString() );
2210 if ( !distanceUnitString.isEmpty() )
2213 const QString areaUnitString =
readEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/AreaUnits" ), QString() );
2214 if ( !areaUnitString.isEmpty() )
2225 if (
readNumEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectionsEnabled" ), 0 ) )
2228 const QDomNode srsNode = doc->documentElement().namedItem( QStringLiteral(
"projectCrs" ) );
2229 if ( !srsNode.isNull() )
2231 projectCrs.
readXml( srsNode );
2236 const QString projCrsString =
readEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCRSProj4String" ) );
2237 const long currentCRS =
readNumEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCRSID" ), -1 );
2238 const QString authid =
readEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCrs" ) );
2241 const bool isUserAuthId = authid.startsWith( QLatin1String(
"USER:" ), Qt::CaseInsensitive );
2242 if ( !authid.isEmpty() && !isUserAuthId )
2246 if ( !projectCrs.
isValid() && currentCRS >= 0 )
2252 if ( !projCrsString.isEmpty() && ( authid.isEmpty() || isUserAuthId ) && ( !projectCrs.
isValid() || projectCrs.
toProj() != projCrsString ) )
2269 const QDomNode verticalCrsNode = doc->documentElement().namedItem( QStringLiteral(
"verticalCrs" ) );
2270 if ( !verticalCrsNode.isNull() )
2278 QStringList datumErrors;
2279 if ( !mTransformContext.
readXml( doc->documentElement(), context, datumErrors ) && !datumErrors.empty() )
2286 const QDomNode elevationShadingNode = doc->documentElement().namedItem( QStringLiteral(
"elevation-shading-renderer" ) );
2287 if ( !elevationShadingNode.isNull() )
2289 mElevationShadingRenderer.
readXml( elevationShadingNode.toElement(), context );
2296 const QStringList variableNames =
readListEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableNames" ) );
2297 const QStringList variableValues =
readListEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableValues" ) );
2299 mCustomVariables.clear();
2300 if ( variableNames.length() == variableValues.length() )
2302 for (
int i = 0; i < variableNames.length(); ++i )
2304 mCustomVariables.insert( variableNames.at( i ), variableValues.at( i ) );
2309 QgsMessageLog::logMessage( tr(
"Project Variables Invalid" ), tr(
"The project contains invalid variable settings." ) );
2317 QDomElement element = doc->documentElement().firstChildElement( QStringLiteral(
"projectMetadata" ) );
2319 if ( !element.isNull() )
2328 if ( mMetadata.
title().isEmpty() && !oldTitle.isEmpty() )
2336 element = doc->documentElement().firstChildElement( QStringLiteral(
"transaction" ) );
2337 if ( !element.isNull() )
2344 element = doc->documentElement().firstChildElement( QStringLiteral(
"autotransaction" ) );
2345 if ( ! element.isNull() )
2347 mTransactionMode =
static_cast<Qgis::TransactionMode>( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() );
2352 profile.switchTask( tr(
"Loading layer tree" ) );
2353 mRootGroup->setCustomProperty( QStringLiteral(
"loading" ), 1 );
2355 QDomElement layerTreeElem = doc->documentElement().firstChildElement( QStringLiteral(
"layer-tree-group" ) );
2356 if ( !layerTreeElem.isNull() )
2368 mLayerTreeRegistryBridge->setEnabled(
false );
2371 profile.switchTask( tr(
"Reading map layers" ) );
2373 loadProjectFlags( doc.get() );
2375 QList<QDomNode> brokenNodes;
2376 const bool clean = _getMapLayers( *doc, brokenNodes,
flags );
2381 QgsDebugError( QStringLiteral(
"Unable to get map layers from project file." ) );
2383 if ( !brokenNodes.isEmpty() )
2385 QgsDebugError(
"there are " + QString::number( brokenNodes.size() ) +
" broken layers" );
2390 mBadLayerHandler->handleBadLayers( brokenNodes );
2393 mMainAnnotationLayer->
readLayerXml( doc->documentElement().firstChildElement( QStringLiteral(
"main-annotation-layer" ) ), context );
2397 profile.switchTask( tr(
"Loading embedded layers" ) );
2398 loadEmbeddedNodes( mRootGroup.get(),
flags );
2402 profile.switchTask( tr(
"Resolving layer references" ) );
2403 QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
2404 for ( QMap<QString, QgsMapLayer *>::iterator it =
layers.begin(); it !=
layers.end(); ++it )
2406 it.value()->resolveReferences(
this );
2410 mLayerTreeRegistryBridge->setEnabled(
true );
2413 profile.switchTask( tr(
"Resolving references" ) );
2414 mRootGroup->resolveReferences(
this );
2424 if ( !layerTreeElem.isNull() )
2426 mRootGroup->readLayerOrderFromXml( layerTreeElem );
2430 const QDomElement layerTreeCanvasElem = doc->documentElement().firstChildElement( QStringLiteral(
"layer-tree-canvas" ) );
2431 if ( !layerTreeCanvasElem.isNull( ) )
2433 mRootGroup->readLayerOrderFromXml( layerTreeCanvasElem );
2439 const QStringList requiredLayerIds =
readListEntry( QStringLiteral(
"RequiredLayers" ), QStringLiteral(
"Layers" ) );
2440 for (
const QString &layerId : requiredLayerIds )
2447 const QStringList disabledLayerIds =
readListEntry( QStringLiteral(
"Identify" ), QStringLiteral(
"/disabledLayers" ) );
2448 for (
const QString &layerId : disabledLayerIds )
2461 QString styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Marker" ) );
2462 if ( !styleName.isEmpty() )
2467 styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Line" ) );
2468 if ( !styleName.isEmpty() )
2473 styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Fill" ) );
2474 if ( !styleName.isEmpty() )
2479 styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/ColorRamp" ) );
2480 if ( !styleName.isEmpty() )
2490 double opacity = 1.0;
2493 double alpha =
readDoubleEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/AlphaInt" ), 255, &ok );
2495 opacity = alpha / 255.0;
2496 double newOpacity =
readDoubleEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Opacity" ), 1.0, &ok );
2498 opacity = newOpacity;
2502 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Marker" ) );
2503 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Line" ) );
2504 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Fill" ) );
2505 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/ColorRamp" ) );
2506 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/RandomColors" ) );
2507 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/AlphaInt" ) );
2508 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Opacity" ) );
2516 profile.switchTask( tr(
"Storing original layer properties" ) );
2520 mRootGroup->removeCustomProperty( QStringLiteral(
"loading" ) );
2522 profile.switchTask( tr(
"Loading map themes" ) );
2525 mMapThemeCollection->readXml( *doc );
2527 profile.switchTask( tr(
"Loading label settings" ) );
2528 mLabelingEngineSettings->readSettingsFromProject(
this );
2530 const QDomElement labelEngineSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"labelEngineSettings" ) );
2531 mLabelingEngineSettings->readXml( labelEngineSettingsElement, context );
2533 mLabelingEngineSettings->resolveReferences(
this );
2537 profile.switchTask( tr(
"Loading annotations" ) );
2540 mAnnotationManager->readXml( doc->documentElement(), context );
2544 mAnnotationManager->readXmlAndUpgradeToAnnotationLayerItems( doc->documentElement(), context, mMainAnnotationLayer, mTransformContext );
2548 profile.switchTask( tr(
"Loading layouts" ) );
2549 mLayoutManager->readXml( doc->documentElement(), *doc );
2554 profile.switchTask( tr(
"Loading 3D Views" ) );
2555 m3DViewsManager->readXml( doc->documentElement(), *doc );
2558 profile.switchTask( tr(
"Loading bookmarks" ) );
2559 mBookmarkManager->
readXml( doc->documentElement(), *doc );
2561 profile.switchTask( tr(
"Loading sensors" ) );
2562 mSensorManager->
readXml( doc->documentElement(), *doc );
2565 QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
2566 for ( QMap<QString, QgsMapLayer *>::iterator it = existingMaps.begin(); it != existingMaps.end(); ++it )
2568 it.value()->setDependencies( it.value()->dependencies() );
2571 profile.switchTask( tr(
"Loading snapping settings" ) );
2575 profile.switchTask( tr(
"Loading view settings" ) );
2578 const QStringList scales =
readListEntry( QStringLiteral(
"Scales" ), QStringLiteral(
"/ScalesList" ) );
2579 QVector<double> res;
2580 for (
const QString &scale : scales )
2582 const QStringList parts = scale.split(
':' );
2583 if ( parts.size() != 2 )
2587 const double denominator = QLocale().toDouble( parts[1], &ok );
2594 const QDomElement viewSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectViewSettings" ) );
2595 if ( !viewSettingsElement.isNull() )
2596 mViewSettings->
readXml( viewSettingsElement, context );
2599 profile.switchTask( tr(
"Loading style properties" ) );
2600 const QDomElement styleSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectStyleSettings" ) );
2601 if ( !styleSettingsElement.isNull() )
2604 mStyleSettings->
readXml( styleSettingsElement, context,
flags );
2608 profile.switchTask( tr(
"Loading temporal settings" ) );
2609 const QDomElement timeSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectTimeSettings" ) );
2610 if ( !timeSettingsElement.isNull() )
2611 mTimeSettings->
readXml( timeSettingsElement, context );
2614 profile.switchTask( tr(
"Loading elevation properties" ) );
2615 const QDomElement elevationPropertiesElement = doc->documentElement().firstChildElement( QStringLiteral(
"ElevationProperties" ) );
2616 if ( !elevationPropertiesElement.isNull() )
2617 mElevationProperties->
readXml( elevationPropertiesElement, context );
2620 profile.switchTask( tr(
"Loading display settings" ) );
2622 const QDomElement displaySettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectDisplaySettings" ) );
2623 if ( !displaySettingsElement.isNull() )
2624 mDisplaySettings->
readXml( displaySettingsElement, context );
2627 profile.switchTask( tr(
"Loading GPS settings" ) );
2629 const QDomElement gpsSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectGpsSettings" ) );
2630 if ( !gpsSettingsElement.isNull() )
2631 mGpsSettings->
readXml( gpsSettingsElement, context );
2635 profile.switchTask( tr(
"Updating variables" ) );
2637 profile.switchTask( tr(
"Updating CRS" ) );
2641 if ( mCrs3D != oldCrs3D )
2646 profile.switchTask( tr(
"Reading external settings" ) );
2650 profile.switchTask( tr(
"Updating interface" ) );
2652 snapSignalBlock.release();
2653 if ( !mBlockSnappingUpdates )
2664 QgsDebugMsgLevel( QStringLiteral(
"Project save user: %1" ).arg( mSaveUser ), 2 );
2665 QgsDebugMsgLevel( QStringLiteral(
"Project save user: %1" ).arg( mSaveUserFull ), 2 );
2674 const QString newFileName( QStringLiteral(
"%1/%2.qgs" ).arg( QFileInfo( mFile ).
absolutePath(), localeFileName ) );
2689 const QMap<QString, QgsMapLayer *> loadedLayers =
mapLayers();
2690 for (
auto it = loadedLayers.constBegin(); it != loadedLayers.constEnd(); ++it )
2692 if ( it.value()->isValid() && it.value()->customProperty( QStringLiteral(
"_layer_was_editable" ) ).toBool() )
2694 if (
QgsVectorLayer *vl = qobject_cast< QgsVectorLayer * >( it.value() ) )
2696 it.value()->removeCustomProperty( QStringLiteral(
"_layer_was_editable" ) );
2708 const auto constChildren = group->
children();
2714 if ( childGroup->
customProperty( QStringLiteral(
"embedded" ) ).toInt() )
2717 const QString projectPath =
readPath( childGroup->
customProperty( QStringLiteral(
"embedded_project" ) ).toString() );
2718 childGroup->
setCustomProperty( QStringLiteral(
"embedded_project" ), projectPath );
2722 QList<QgsLayerTreeNode *> clonedChildren;
2723 const QList<QgsLayerTreeNode *> constChildren = newGroup->
children();
2724 clonedChildren.reserve( constChildren.size() );
2726 clonedChildren << newGroupChild->clone();
2734 loadEmbeddedNodes( childGroup,
flags );
2739 if ( child->customProperty( QStringLiteral(
"embedded" ) ).toInt() )
2741 QList<QDomNode> brokenNodes;
2744 valid = valid &&
false;
2759 return mCustomVariables;
2766 if ( variables == mCustomVariables )
2770 QStringList variableNames;
2771 QStringList variableValues;
2773 QVariantMap::const_iterator it = variables.constBegin();
2774 for ( ; it != variables.constEnd(); ++it )
2776 variableNames << it.key();
2777 variableValues << it.value().toString();
2780 writeEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableNames" ), variableNames );
2781 writeEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableValues" ), variableValues );
2783 mCustomVariables = variables;
2784 mProjectScope.reset();
2793 *mLabelingEngineSettings = settings;
2801 return *mLabelingEngineSettings;
2808 mProjectScope.reset();
2809 return mLayerStore.get();
2816 return mLayerStore.get();
2823 QList<QgsVectorLayer *>
layers;
2824 const QStringList layerIds =
readListEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsList" ), QStringList() );
2825 const auto constLayerIds = layerIds;
2826 for (
const QString &layerId : constLayerIds )
2839 list.reserve(
layers.size() );
2844 list << layer->id();
2847 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsList" ), list );
2869 if ( mProjectScope )
2871 auto projectScope = std::make_unique< QgsExpressionContextScope >( *mProjectScope );
2878 projectScope->addFunction( QStringLiteral(
"sensor_data" ),
new GetSensorData(
sensorManager()->sensorsData() ) );
2880 return projectScope.release();
2883 mProjectScope = std::make_unique< QgsExpressionContextScope >( QObject::tr(
"Project" ) );
2887 QVariantMap::const_iterator it = vars.constBegin();
2889 for ( ; it != vars.constEnd(); ++it )
2891 mProjectScope->setVariable( it.key(), it.value(),
true );
2895 if ( projectPath.isEmpty() )
2896 projectPath = mOriginalPath;
2897 const QString projectFolder = QFileInfo( projectPath ).path();
2898 const QString projectFilename = QFileInfo( projectPath ).fileName();
2899 const QString projectBasename =
baseName();
2936 QVariantMap keywords;
2938 for (
auto it = metadataKeywords.constBegin(); it != metadataKeywords.constEnd(); ++it )
2940 keywords.insert( it.key(), it.value() );
2945 QVariantList layersIds;
2947 const QMap<QString, QgsMapLayer *> layersInProject = mLayerStore->mapLayers();
2948 layersIds.reserve( layersInProject.count() );
2949 layers.reserve( layersInProject.count() );
2950 for (
auto it = layersInProject.constBegin(); it != layersInProject.constEnd(); ++it )
2952 layersIds << it.value()->id();
2958 mProjectScope->addFunction( QStringLiteral(
"project_color" ),
new GetNamedProjectColor(
this ) );
2959 mProjectScope->addFunction( QStringLiteral(
"project_color_object" ),
new GetNamedProjectColorObject(
this ) );
2964void QgsProject::onMapLayersAdded(
const QList<QgsMapLayer *> &layers )
2968 const QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
2970 const auto constLayers =
layers;
2973 if ( ! layer->isValid() )
2976 if (
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer ) )
2979 if ( vlayer->dataProvider() )
2987 for ( QMap<QString, QgsMapLayer *>::const_iterator it = existingMaps.cbegin(); it != existingMaps.cend(); ++it )
2989 const QSet<QgsMapLayerDependency> deps = it.value()->dependencies();
2990 if ( deps.contains( layer->id() ) )
2993 it.value()->setDependencies( deps );
2998 updateTransactionGroups();
3004void QgsProject::onMapLayersRemoved(
const QList<QgsMapLayer *> &layers )
3013 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
3021void QgsProject::cleanTransactionGroups(
bool force )
3025 bool changed =
false;
3026 for ( QMap< QPair< QString, QString>,
QgsTransactionGroup *>::Iterator tg = mTransactionGroups.begin(); tg != mTransactionGroups.end(); )
3028 if ( tg.value()->isEmpty() || force )
3031 tg = mTransactionGroups.erase( tg );
3043void QgsProject::updateTransactionGroups()
3047 mEditBufferGroup.
clear();
3049 switch ( mTransactionMode )
3053 cleanTransactionGroups(
true );
3058 cleanTransactionGroups(
true );
3061 cleanTransactionGroups(
false );
3065 bool tgChanged =
false;
3066 const auto constLayers =
mapLayers().values();
3069 if ( ! layer->isValid() )
3072 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
3076 switch ( mTransactionMode )
3093 mTransactionGroups.insert( qMakePair( key, connString ), tg );
3103 mEditBufferGroup.
addLayer( vlayer );
3119 context.setProjectTranslator(
this );
3121 QList<QDomNode> brokenNodes;
3122 if ( addLayer( layerNode.toElement(), brokenNodes, context ) )
3126 const QVector<QgsVectorLayer *> vectorLayers = layers<QgsVectorLayer *>();
3130 layer->resolveReferences(
this );
3132 if ( layer->isValid() && layer->customProperty( QStringLiteral(
"_layer_was_editable" ) ).toBool() )
3134 layer->startEditing();
3135 layer->removeCustomProperty( QStringLiteral(
"_layer_was_editable" ) );
3147 mFile.setFileName( filename );
3148 mCachedHomePath.clear();
3156 mProjectScope.reset();
3162 const QString storageFilePath { storage->filePath( mFile.fileName() ) };
3163 if ( storageFilePath.isEmpty() )
3169 const QString tempPath = QStandardPaths::standardLocations( QStandardPaths::TempLocation ).at( 0 );
3170 const QString tmpZipFilename( tempPath + QDir::separator() + QUuid::createUuid().toString() );
3172 if ( !zip( tmpZipFilename ) )
3175 QFile tmpZipFile( tmpZipFilename );
3176 if ( !tmpZipFile.open( QIODevice::ReadOnly ) )
3178 setError( tr(
"Unable to read file %1" ).arg( tmpZipFilename ) );
3183 if ( !storage->writeProject( mFile.fileName(), &tmpZipFile, context ) )
3185 QString err = tr(
"Unable to save project to storage %1" ).arg( mFile.fileName() );
3186 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
3187 if ( !messages.isEmpty() )
3188 err += QStringLiteral(
"\n\n" ) + messages.last().message();
3194 QFile::remove( tmpZipFilename );
3201 return zip( mFile.fileName() );
3207 const bool asOk = saveAuxiliaryStorage();
3208 const bool writeOk = writeProjectFile( mFile.fileName() );
3209 bool attachmentsOk =
true;
3210 if ( !mArchive->files().isEmpty() )
3212 const QFileInfo finfo( mFile.fileName() );
3213 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( QStringLiteral(
"%1_attachments.zip" ).arg( finfo.completeBaseName() ) );
3214 attachmentsOk = mArchive->zip( attachmentsZip );
3218 if ( ( !asOk || !attachmentsOk ) && writeOk )
3220 QStringList errorMessage;
3223 const QString err = mAuxiliaryStorage->errorString();
3224 errorMessage.append( tr(
"Unable to save auxiliary storage ('%1')" ).arg( err ) );
3226 if ( !attachmentsOk )
3228 errorMessage.append( tr(
"Unable to save attachments archive" ) );
3230 setError( errorMessage.join(
'\n' ) );
3233 return asOk && writeOk && attachmentsOk;
3237bool QgsProject::writeProjectFile(
const QString &filename )
3241 QFile projectFile( filename );
3247 const QFileInfo myFileInfo( projectFile );
3248 if ( myFileInfo.exists() && !myFileInfo.isWritable() )
3250 setError( tr(
"%1 is not writable. Please adjust permissions (if possible) and try again." )
3251 .arg( projectFile.fileName() ) );
3259 QDomImplementation::setInvalidDataPolicy( QDomImplementation::DropInvalidChars );
3261 const QDomDocumentType documentType =
3262 QDomImplementation().createDocumentType( QStringLiteral(
"qgis" ), QStringLiteral(
"http://mrcc.com/qgis.dtd" ),
3263 QStringLiteral(
"SYSTEM" ) );
3264 auto doc = std::make_unique<QDomDocument>( documentType );
3266 QDomElement qgisNode = doc->createElement( QStringLiteral(
"qgis" ) );
3267 qgisNode.setAttribute( QStringLiteral(
"projectname" ),
title() );
3268 qgisNode.setAttribute( QStringLiteral(
"version" ),
Qgis::version() );
3270 if ( !mSettings.
value( QStringLiteral(
"projects/anonymize_saved_projects" ),
false,
QgsSettings::Core ).toBool() )
3274 qgisNode.setAttribute( QStringLiteral(
"saveUser" ), newSaveUser );
3275 qgisNode.setAttribute( QStringLiteral(
"saveUserFull" ), newSaveUserFull );
3276 mSaveUser = newSaveUser;
3277 mSaveUserFull = newSaveUserFull;
3283 mSaveDateTime = QDateTime::currentDateTime();
3284 qgisNode.setAttribute( QStringLiteral(
"saveDateTime" ), mSaveDateTime.toString( Qt::ISODate ) );
3289 mSaveUserFull.clear();
3292 mSaveDateTime = QDateTime();
3294 doc->appendChild( qgisNode );
3297 QDomElement homePathNode = doc->createElement( QStringLiteral(
"homePath" ) );
3298 homePathNode.setAttribute( QStringLiteral(
"path" ), mHomePath );
3299 qgisNode.appendChild( homePathNode );
3302 QDomElement titleNode = doc->createElement( QStringLiteral(
"title" ) );
3303 qgisNode.appendChild( titleNode );
3305 QDomElement transactionNode = doc->createElement( QStringLiteral(
"transaction" ) );
3306 transactionNode.setAttribute( QStringLiteral(
"mode" ),
qgsEnumValueToKey( mTransactionMode ) );
3307 qgisNode.appendChild( transactionNode );
3309 QDomElement flagsNode = doc->createElement( QStringLiteral(
"projectFlags" ) );
3311 qgisNode.appendChild( flagsNode );
3313 const QDomText titleText = doc->createTextNode(
title() );
3314 titleNode.appendChild( titleText );
3318 QDomElement srsNode = doc->createElement( QStringLiteral(
"projectCrs" ) );
3320 qgisNode.appendChild( srsNode );
3323 QDomElement verticalSrsNode = doc->createElement( QStringLiteral(
"verticalCrs" ) );
3324 mVerticalCrs.
writeXml( verticalSrsNode, *doc );
3325 qgisNode.appendChild( verticalSrsNode );
3328 QDomElement elevationShadingNode = doc->createElement( QStringLiteral(
"elevation-shading-renderer" ) );
3329 mElevationShadingRenderer.
writeXml( elevationShadingNode, context );
3330 qgisNode.appendChild( elevationShadingNode );
3337 clonedRoot->
writeXml( qgisNode, context );
3341 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsMode" ),
static_cast<int>( mAvoidIntersectionsMode ) );
3349 QDomElement annotationLayerNode = doc->createElement( QStringLiteral(
"main-annotation-layer" ) );
3350 mMainAnnotationLayer->
writeLayerXml( annotationLayerNode, *doc, context );
3351 qgisNode.appendChild( annotationLayerNode );
3355 QDomElement projectLayersNode = doc->createElement( QStringLiteral(
"projectlayers" ) );
3357 QMap<QString, QgsMapLayer *>::ConstIterator li =
layers.constBegin();
3358 while ( li !=
layers.end() )
3364 const QHash< QString, QPair< QString, bool> >::const_iterator emIt = mEmbeddedLayers.constFind( ml->
id() );
3365 if ( emIt == mEmbeddedLayers.constEnd() )
3367 QDomElement maplayerElem;
3373 maplayerElem = doc->createElement( QStringLiteral(
"maplayer" ) );
3377 maplayerElem.setAttribute( QStringLiteral(
"editable" ), QStringLiteral(
"1" ) );
3381 QDomDocument document;
3384 maplayerElem = document.firstChildElement();
3388 QgsDebugError( QStringLiteral(
"Could not restore layer properties for layer %1" ).arg( ml->
id() ) );
3394 projectLayersNode.appendChild( maplayerElem );
3400 if ( emIt.value().second )
3402 QDomElement mapLayerElem = doc->createElement( QStringLiteral(
"maplayer" ) );
3403 mapLayerElem.setAttribute( QStringLiteral(
"embedded" ), 1 );
3404 mapLayerElem.setAttribute( QStringLiteral(
"project" ),
writePath( emIt.value().first ) );
3405 mapLayerElem.setAttribute( QStringLiteral(
"id" ), ml->
id() );
3406 projectLayersNode.appendChild( mapLayerElem );
3413 qgisNode.appendChild( projectLayersNode );
3415 QDomElement layerOrderNode = doc->createElement( QStringLiteral(
"layerorder" ) );
3416 const auto constCustomLayerOrder = mRootGroup->customLayerOrder();
3417 for (
QgsMapLayer *layer : constCustomLayerOrder )
3419 QDomElement mapLayerElem = doc->createElement( QStringLiteral(
"layer" ) );
3420 mapLayerElem.setAttribute( QStringLiteral(
"id" ), layer->id() );
3421 layerOrderNode.appendChild( mapLayerElem );
3423 qgisNode.appendChild( layerOrderNode );
3425 mLabelingEngineSettings->writeSettingsToProject(
this );
3427 QDomElement labelEngineSettingsElement = doc->createElement( QStringLiteral(
"labelEngineSettings" ) );
3428 mLabelingEngineSettings->writeXml( *doc, labelEngineSettingsElement, context );
3429 qgisNode.appendChild( labelEngineSettingsElement );
3432 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorRedPart" ), mBackgroundColor.red() );
3433 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorGreenPart" ), mBackgroundColor.green() );
3434 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorBluePart" ), mBackgroundColor.blue() );
3436 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorRedPart" ), mSelectionColor.red() );
3437 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorGreenPart" ), mSelectionColor.green() );
3438 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorBluePart" ), mSelectionColor.blue() );
3439 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorAlphaPart" ), mSelectionColor.alpha() );
3447 dump_( mProperties );
3450 QgsDebugMsgLevel( QStringLiteral(
"there are %1 property scopes" ).arg(
static_cast<int>( mProperties.
count() ) ), 2 );
3455 mProperties.
writeXml( QStringLiteral(
"properties" ), qgisNode, *doc );
3458 QDomElement ddElem = doc->createElement( QStringLiteral(
"dataDefinedServerProperties" ) );
3459 mDataDefinedServerProperties.
writeXml( ddElem, dataDefinedServerPropertyDefinitions() );
3460 qgisNode.appendChild( ddElem );
3462 mMapThemeCollection->writeXml( *doc );
3464 mTransformContext.
writeXml( qgisNode, context );
3466 QDomElement metadataElem = doc->createElement( QStringLiteral(
"projectMetadata" ) );
3468 qgisNode.appendChild( metadataElem );
3471 const QDomElement annotationsElem = mAnnotationManager->writeXml( *doc, context );
3472 qgisNode.appendChild( annotationsElem );
3476 const QDomElement layoutElem = mLayoutManager->writeXml( *doc );
3477 qgisNode.appendChild( layoutElem );
3481 const QDomElement views3DElem = m3DViewsManager->writeXml( *doc );
3482 qgisNode.appendChild( views3DElem );
3486 const QDomElement bookmarkElem = mBookmarkManager->
writeXml( *doc );
3487 qgisNode.appendChild( bookmarkElem );
3491 const QDomElement sensorElem = mSensorManager->
writeXml( *doc );
3492 qgisNode.appendChild( sensorElem );
3496 const QDomElement viewSettingsElem = mViewSettings->
writeXml( *doc, context );
3497 qgisNode.appendChild( viewSettingsElem );
3501 const QDomElement styleSettingsElem = mStyleSettings->
writeXml( *doc, context );
3502 qgisNode.appendChild( styleSettingsElem );
3506 const QDomElement timeSettingsElement = mTimeSettings->
writeXml( *doc, context );
3507 qgisNode.appendChild( timeSettingsElement );
3511 const QDomElement elevationPropertiesElement = mElevationProperties->
writeXml( *doc, context );
3512 qgisNode.appendChild( elevationPropertiesElement );
3516 const QDomElement displaySettingsElem = mDisplaySettings->
writeXml( *doc, context );
3517 qgisNode.appendChild( displaySettingsElem );
3521 const QDomElement gpsSettingsElem = mGpsSettings->
writeXml( *doc, context );
3522 qgisNode.appendChild( gpsSettingsElem );
3531 QFile backupFile( QStringLiteral(
"%1~" ).arg( filename ) );
3533 ok &= backupFile.open( QIODevice::WriteOnly | QIODevice::Truncate );
3534 ok &= projectFile.open( QIODevice::ReadOnly );
3537 while ( ok && !projectFile.atEnd() )
3539 ba = projectFile.read( 10240 );
3540 ok &= backupFile.write( ba ) == ba.size();
3543 projectFile.close();
3548 setError( tr(
"Unable to create backup file %1" ).arg( backupFile.fileName() ) );
3553 struct utimbuf tb = {
static_cast<time_t
>( fi.lastRead().toSecsSinceEpoch() ),
static_cast<time_t
>( fi.lastModified().toSecsSinceEpoch() ) };
3554 utime( backupFile.fileName().toUtf8().constData(), &tb );
3557 if ( !projectFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
3559 projectFile.close();
3562 setError( tr(
"Unable to save to file %1" ).arg( projectFile.fileName() ) );
3566 QTemporaryFile tempFile;
3567 bool ok = tempFile.open();
3570 QTextStream projectFileStream( &tempFile );
3571 doc->save( projectFileStream, 2 );
3572 ok &= projectFileStream.pos() > -1;
3574 ok &= tempFile.seek( 0 );
3577 while ( ok && !tempFile.atEnd() )
3579 ba = tempFile.read( 10240 );
3580 ok &= projectFile.write( ba ) == ba.size();
3583 ok &= projectFile.error() == QFile::NoError;
3585 projectFile.close();
3592 setError( tr(
"Unable to save to file %1. Your project "
3593 "may be corrupted on disk. Try clearing some space on the volume and "
3594 "check file permissions before pressing save again." )
3595 .arg( projectFile.fileName() ) );
3609 bool propertiesModified;
3610 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3612 if ( propertiesModified )
3622 bool propertiesModified;
3623 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3625 if ( propertiesModified )
3635 bool propertiesModified;
3636 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3638 if ( propertiesModified )
3648 bool propertiesModified;
3649 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3651 if ( propertiesModified )
3661 bool propertiesModified;
3662 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3664 if ( propertiesModified )
3672 const QStringList &def,
3684 value =
property->value();
3686 const bool valid = QMetaType::Type::QStringList == value.userType();
3692 return value.toStringList();
3715 value =
property->value();
3717 const bool valid = value.canConvert( QMetaType::Type::QString );
3722 return value.toString();
3741 value =
property->value();
3744 const bool valid = value.canConvert( QMetaType::Type::Int );
3753 return value.toInt();
3768 const QVariant value =
property->value();
3770 const bool valid = value.canConvert( QMetaType::Type::Double );
3775 return value.toDouble();
3792 const QVariant value =
property->value();
3794 const bool valid = value.canConvert( QMetaType::Type::Bool );
3799 return value.toBool();
3811 if (
findKey_( scope, key, mProperties ) )
3817 return !
findKey_( scope, key, mProperties );
3826 QStringList entries;
3828 if ( foundProperty )
3845 QStringList entries;
3847 if ( foundProperty )
3862 dump_( mProperties );
3882 filePath = storage->filePath( mFile.fileName() );
3909void QgsProject::setError(
const QString &errorMessage )
3913 mErrorMessage = errorMessage;
3920 return mErrorMessage;
3923void QgsProject::clearError()
3927 setError( QString() );
3934 mBadLayerHandler.reset( handler );
3941 const QHash< QString, QPair< QString, bool > >::const_iterator it = mEmbeddedLayers.find(
id );
3942 if ( it == mEmbeddedLayers.constEnd() )
3946 return it.value().first;
3956 static QString sPrevProjectFilePath;
3957 static QDateTime sPrevProjectFileTimestamp;
3958 static QDomDocument sProjectDocument;
3960 QString qgsProjectFile = projectFilePath;
3962 if ( projectFilePath.endsWith( QLatin1String(
".qgz" ), Qt::CaseInsensitive ) )
3964 archive.
unzip( projectFilePath );
3968 const QDateTime projectFileTimestamp = QFileInfo( projectFilePath ).lastModified();
3970 if ( projectFilePath != sPrevProjectFilePath || projectFileTimestamp != sPrevProjectFileTimestamp )
3972 sPrevProjectFilePath.clear();
3974 QFile projectFile( qgsProjectFile );
3975 if ( !projectFile.open( QIODevice::ReadOnly ) )
3980 if ( !sProjectDocument.setContent( &projectFile ) )
3985 sPrevProjectFilePath = projectFilePath;
3986 sPrevProjectFileTimestamp = projectFileTimestamp;
3990 bool useAbsolutePaths =
true;
3992 const QDomElement propertiesElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral(
"properties" ) );
3993 if ( !propertiesElem.isNull() )
3995 const QDomElement absElem = propertiesElem.firstChildElement( QStringLiteral(
"Paths" ) ).firstChildElement( QStringLiteral(
"Absolute" ) );
3996 if ( !absElem.isNull() )
3998 useAbsolutePaths = absElem.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.
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.