73 #include <QApplication>
77 #include <QTextStream>
78 #include <QTemporaryFile>
81 #include <QStandardPaths>
83 #include <QRegularExpression>
86 #include <sys/utime.h>
104 QStringList keyTokens = QStringList( scope );
105 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
106 keyTokens += key.split(
'/', QString::SkipEmptyParts );
108 keyTokens += key.split(
'/', Qt::SkipEmptyParts );
112 keyTokens.push_front( QStringLiteral(
"properties" ) );
115 for (
int i = 0; i < keyTokens.size(); ++i )
117 const QString keyToken = keyTokens.at( i );
121 const thread_local QRegularExpression sInvalidRegexp = QRegularExpression(
"([^: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}])" );
122 if ( keyToken.contains( sInvalidRegexp ) )
124 const QString errorString = QObject::tr(
"Entry token invalid : '%1'. The token will not be saved to file." ).arg( keyToken );
152 while ( !keySequence.isEmpty() )
156 if ( keySequence.first() == currentProperty->
name() )
159 keySequence.pop_front();
161 if ( 1 == keySequence.count() )
164 return currentProperty->
find( keySequence.front() );
166 else if ( keySequence.isEmpty() )
171 return currentProperty;
173 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
175 if ( nextProperty->
isKey() )
179 else if ( nextProperty->
isValue() && 1 == keySequence.count() )
185 return currentProperty;
223 const QVariant &value,
224 bool &propertiesModified )
233 propertiesModified =
false;
234 while ( ! keySequence.isEmpty() )
238 if ( keySequence.first() == currentProperty->
name() )
241 keySequence.pop_front();
245 if ( 1 == keySequence.count() )
248 if ( !property || property->value() != value )
250 currentProperty->
setValue( keySequence.front(), value );
251 propertiesModified =
true;
254 return currentProperty;
258 else if ( keySequence.isEmpty() )
260 if ( currentProperty->
value() != value )
263 propertiesModified =
true;
266 return currentProperty;
268 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
272 if ( currentProperty )
283 if ( ( newPropertyKey = currentProperty->
addKey( keySequence.first() ) ) )
285 currentProperty = newPropertyKey;
317 while ( ! keySequence.isEmpty() )
321 if ( keySequence.first() == currentProperty->
name() )
324 keySequence.pop_front();
328 if ( 1 == keySequence.count() )
330 currentProperty->
removeKey( keySequence.front() );
335 else if ( keySequence.isEmpty() )
337 previousQgsPropertyKey->
removeKey( currentProperty->
name() );
339 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
341 previousQgsPropertyKey = currentProperty;
344 if ( currentProperty )
370 , mSnappingConfig( this )
384 mProperties.
setName( QStringLiteral(
"properties" ) );
387 mMainAnnotationLayer->setParent(
this );
401 this, [ = ](
const QStringList &
layers ) { mProjectScope.reset(); emit layersWillBeRemoved( layers ); } );
403 this, [ = ](
const QList<QgsMapLayer *> &
layers ) { mProjectScope.reset(); emit layersWillBeRemoved( layers ); } );
405 this, [ = ](
const QString & layer ) { mProjectScope.reset(); emit layerWillBeRemoved( layer ); } );
407 this, [ = ](
QgsMapLayer * layer ) { mProjectScope.reset(); emit layerWillBeRemoved( layer ); } );
409 [ = ](
const QStringList &
layers ) { mProjectScope.reset(); emit layersRemoved( layers ); } );
411 [ = ](
const QString & layer ) { mProjectScope.reset(); emit layerRemoved( layer ); } );
413 [ = ]() { mProjectScope.reset(); emit removeAll(); } );
415 [ = ](
const QList< QgsMapLayer * > &
layers ) { mProjectScope.reset(); emit layersAdded( layers ); } );
417 [ = ](
QgsMapLayer * layer ) { mProjectScope.reset(); emit layerWasAdded( layer ); } );
425 [ = ](
const QList<QgsMapLayer *> &
layers )
427 for ( const auto &layer : layers )
429 disconnect( layer, &QgsMapLayer::dataSourceChanged, mRelationManager, &QgsRelationManager::updateRelationsStatus );
434 [ = ](
const QList<QgsMapLayer *> &layers )
436 for ( const auto &layer : layers )
438 connect( layer, &QgsMapLayer::dataSourceChanged, mRelationManager, &QgsRelationManager::updateRelationsStatus );
451 mIsBeingDeleted =
true;
454 delete mBadLayerHandler;
455 delete mRelationManager;
456 delete mLayerTreeRegistryBridge;
458 if (
this == sProject )
485 mProjectScope.reset();
493 return mMetadata.
title();
503 return mSaveUserFull;
508 return mSaveDateTime;
523 if ( dirty && mDirtyBlockCount > 0 )
529 if ( mDirty == dirty )
538 if ( path == mHomePath )
542 mCachedHomePath.clear();
543 mProjectScope.reset();
552 const QList<QgsAttributeEditorElement *> elements = parent->
children();
560 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:formcontainers" ).arg( layerId ), container->
name() );
562 if ( !container->
children().empty() )
575 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1" ).arg( layer->layerId() ), layer->name() );
592 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:fieldaliases" ).arg( vlayer->
id() ), fieldName );
607 const QList<QgsLayerTreeGroup *> groupLayers = mRootGroup->
findGroups();
610 translationContext->
registerTranslation( QStringLiteral(
"project:layergroups" ), groupLayer->name() );
614 const QList<QgsRelation> &relations = mRelationManager->
relations().values();
617 translationContext->
registerTranslation( QStringLiteral(
"project:relations" ), relation.name() );
623 mDataDefinedServerProperties = properties;
628 return mDataDefinedServerProperties;
633 if ( name == mFile.fileName() )
636 const QString oldHomePath =
homePath();
638 mFile.setFileName( name );
639 mCachedHomePath.clear();
640 mProjectScope.reset();
644 const QString newHomePath =
homePath();
645 if ( newHomePath != oldHomePath )
653 return mFile.fileName();
658 mOriginalPath = path;
663 return mOriginalPath;
668 return QFileInfo( mFile );
681 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
686 return QFileInfo( mFile.fileName() ).lastModified();
695 if ( mFile.fileName().isEmpty() )
698 return QFileInfo( mFile.fileName() ).absolutePath();
706 if ( mFile.fileName().isEmpty() )
709 return QFileInfo( mFile.fileName() ).absoluteFilePath();
717 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
722 return QFileInfo( mFile.fileName() ).completeBaseName();
728 const bool absolutePaths =
readBoolEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
false );
737 writeEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
true );
740 writeEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
false );
755 writeEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectionsEnabled" ),
crs.
isValid() ? 1 : 0 );
756 mProjectScope.reset();
767 if ( adjustEllipsoid )
773 if ( !
crs().isValid() )
776 return readEntry( QStringLiteral(
"Measure" ), QStringLiteral(
"/Ellipsoid" ),
geoNone() );
781 if (
ellipsoid ==
readEntry( QStringLiteral(
"Measure" ), QStringLiteral(
"/Ellipsoid" ) ) )
784 mProjectScope.reset();
791 return mTransformContext;
796 if ( context == mTransformContext )
799 mTransformContext = context;
800 mProjectScope.reset();
803 for (
auto &layer : mLayerStore.get()->mapLayers() )
805 layer->setTransformContext( context );
812 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
814 mProjectScope.reset();
815 mFile.setFileName( QString() );
818 mSaveUserFull.clear();
819 mSaveDateTime = QDateTime();
822 mCachedHomePath.clear();
823 mAutoTransaction =
false;
824 mEvaluateDefaultValues =
false;
826 mTrustLayerMetadata =
false;
827 mCustomVariables.clear();
830 if ( !mSettings.
value( QStringLiteral(
"projects/anonymize_new_projects" ),
false,
QgsSettings::Core ).toBool() )
841 mEmbeddedLayers.clear();
842 mRelationManager->
clear();
843 mAnnotationManager->clear();
844 mLayoutManager->clear();
845 m3DViewsManager->clear();
846 mBookmarkManager->
clear();
847 mViewSettings->
reset();
848 mTimeSettings->
reset();
849 mDisplaySettings->
reset();
850 mSnappingConfig.
reset();
858 mLabelingEngineSettings->clear();
865 if ( !mIsBeingDeleted )
873 writeEntry( QStringLiteral(
"PositionPrecision" ), QStringLiteral(
"/Automatic" ),
true );
874 writeEntry( QStringLiteral(
"PositionPrecision" ), QStringLiteral(
"/DecimalPlaces" ), 2 );
876 const bool defaultRelativePaths = mSettings.
value( QStringLiteral(
"/qgis/defaultProjectPathsRelative" ),
true ).toBool();
880 writeEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/DistanceUnits" ), mSettings.
value( QStringLiteral(
"/qgis/measure/displayunits" ) ).toString() );
881 writeEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/AreaUnits" ), mSettings.
value( QStringLiteral(
"/qgis/measure/areaunits" ) ).toString() );
883 int red = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_red" ), 255 ).toInt();
884 int green = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_green" ), 255 ).toInt();
885 int blue = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_blue" ), 255 ).toInt();
888 red = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_red" ), 255 ).toInt();
889 green = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_green" ), 255 ).toInt();
890 blue = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_blue" ), 0 ).toInt();
891 const int alpha = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_alpha" ), 255 ).toInt();
898 if ( mMainAnnotationLayer )
899 mMainAnnotationLayer->
reset();
901 snapSingleBlocker.release();
903 if ( !mBlockSnappingUpdates )
915 topQgsPropertyKey.
dump();
948 const QDomElement propertiesElem = doc.documentElement().firstChildElement( QStringLiteral(
"properties" ) );
950 if ( propertiesElem.isNull() )
955 const QDomNodeList scopes = propertiesElem.childNodes();
957 if ( propertiesElem.firstChild().isNull() )
959 QgsDebugMsg( QStringLiteral(
"empty ``properties'' XML tag ... bailing" ) );
963 if ( ! project_properties.
readXml( propertiesElem ) )
965 QgsDebugMsg( QStringLiteral(
"Project_properties.readXml() failed" ) );
979 const QDomElement ddElem = doc.documentElement().firstChildElement( QStringLiteral(
"dataDefinedServerProperties" ) );
980 if ( !ddElem.isNull() )
982 if ( !ddServerProperties.
readXml( ddElem, dataDefinedServerPropertyDefinitions ) )
984 QgsDebugMsg( QStringLiteral(
"dataDefinedServerProperties.readXml() failed" ) );
987 return ddServerProperties;
994 static void _getTitle(
const QDomDocument &doc, QString &title )
996 const QDomElement titleNode = doc.documentElement().firstChildElement( QStringLiteral(
"title" ) );
1000 if ( titleNode.isNull() )
1006 if ( !titleNode.hasChildNodes() )
1012 const QDomNode titleTextNode = titleNode.firstChild();
1014 if ( !titleTextNode.isText() )
1020 const QDomText titleText = titleTextNode.toText();
1022 title = titleText.data();
1026 static void readProjectFileMetadata(
const QDomDocument &doc, QString &lastUser, QString &lastUserFull, QDateTime &lastSaveDateTime )
1028 const QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"qgis" ) );
1036 const QDomNode qgisNode = nl.item( 0 );
1038 const QDomElement qgisElement = qgisNode.toElement();
1039 lastUser = qgisElement.attribute( QStringLiteral(
"saveUser" ), QString() );
1040 lastUserFull = qgisElement.attribute( QStringLiteral(
"saveUserFull" ), QString() );
1041 lastSaveDateTime = QDateTime::fromString( qgisElement.attribute( QStringLiteral(
"saveDateTime" ), QString() ), Qt::ISODate );
1047 const QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"qgis" ) );
1051 QgsDebugMsg( QStringLiteral(
" unable to find qgis element in project file" ) );
1055 const QDomNode qgisNode = nl.item( 0 );
1057 const QDomElement qgisElement = qgisNode.toElement();
1058 QgsProjectVersion projectVersion( qgisElement.attribute( QStringLiteral(
"version" ) ) );
1059 return projectVersion;
1065 return mSnappingConfig;
1080 if ( mAvoidIntersectionsMode == mode )
1083 mAvoidIntersectionsMode = mode;
1087 bool QgsProject::_getMapLayers(
const QDomDocument &doc, QList<QDomNode> &brokenNodes, QgsProject::ReadFlags flags )
1092 QDomElement layerElement = doc.documentElement().firstChildElement( QStringLiteral(
"projectlayers" ) ).firstChildElement( QStringLiteral(
"maplayer" ) );
1096 if ( layerElement.isNull() )
1106 bool returnStatus =
true;
1109 while ( ! layerElement.isNull() )
1112 layerElement = layerElement.nextSiblingElement( QStringLiteral(
"maplayer" ) );
1118 if ( depSorter.hasCycle() )
1122 if ( depSorter.hasMissingDependency() )
1123 returnStatus =
false;
1127 const QVector<QDomNode> sortedLayerNodes = depSorter.sortedLayerNodes();
1128 const int totalLayerCount = sortedLayerNodes.count();
1131 for (
const QDomNode &node : sortedLayerNodes )
1133 const QDomElement element = node.toElement();
1135 const QString name =
translate( QStringLiteral(
"project:layers:%1" ).arg( node.namedItem( QStringLiteral(
"id" ) ).toElement().text() ), node.namedItem( QStringLiteral(
"layername" ) ).toElement().text() );
1136 if ( !name.isNull() )
1137 emit
loadingLayer( tr(
"Loading layer %1" ).arg( name ) );
1139 profile.switchTask( name );
1141 if ( element.attribute( QStringLiteral(
"embedded" ) ) == QLatin1String(
"1" ) )
1143 createEmbeddedLayer( element.attribute( QStringLiteral(
"id" ) ),
readPath( element.attribute( QStringLiteral(
"project" ) ) ), brokenNodes,
true, flags );
1152 if ( !addLayer( element, brokenNodes, context, flags ) )
1154 returnStatus =
false;
1157 if ( !messages.isEmpty() )
1166 return returnStatus;
1169 bool QgsProject::addLayer(
const QDomElement &layerElem, QList<QDomNode> &brokenNodes,
QgsReadWriteContext &context, QgsProject::ReadFlags flags )
1171 const QString type = layerElem.attribute( QStringLiteral(
"type" ) );
1173 std::unique_ptr<QgsMapLayer>
mapLayer;
1181 QgsDebugMsg( QStringLiteral(
"Unknown layer type \"%1\"" ).arg( type ) );
1185 switch ( layerType )
1189 mapLayer = std::make_unique<QgsVectorLayer>();
1199 mapLayer = std::make_unique<QgsRasterLayer>();
1203 mapLayer = std::make_unique<QgsMeshLayer>();
1207 mapLayer = std::make_unique<QgsVectorTileLayer>();
1211 mapLayer = std::make_unique<QgsPointCloudLayer>();
1216 const QString
typeName = layerElem.attribute( QStringLiteral(
"name" ) );
1224 mapLayer = std::make_unique<QgsAnnotationLayer>( QString(), options );
1231 mapLayer = std::make_unique<QgsGroupLayer>( QString(), options );
1238 QgsDebugMsg( QStringLiteral(
"Unable to create layer" ) );
1246 const QString layerId { layerElem.namedItem( QStringLiteral(
"id" ) ).toElement().text() };
1247 Q_ASSERT( ! layerId.isEmpty() );
1251 QgsMapLayer::ReadFlags layerFlags = QgsMapLayer::ReadFlags();
1258 profile.switchTask( tr(
"Load layer source" ) );
1261 profile.switchTask( tr(
"Add layer to project" ) );
1262 QList<QgsMapLayer *> newLayers;
1274 vLayer->joinBuffer()->resolveReferences(
this );
1282 QgsDebugMsg(
"Unable to load " + type +
" layer" );
1283 brokenNodes.push_back( layerElem );
1288 if ( ! layerWasStored )
1293 return layerIsValid;
1298 mFile.setFileName( filename );
1299 mCachedHomePath.clear();
1300 mProjectScope.reset();
1302 return read( flags );
1307 const QString filename = mFile.fileName();
1312 QTemporaryFile inDevice;
1313 if ( !inDevice.open() )
1315 setError( tr(
"Unable to open %1" ).arg( inDevice.fileName() ) );
1321 if ( !storage->readProject( filename, &inDevice, context ) )
1323 QString err = tr(
"Unable to open %1" ).arg( filename );
1324 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
1325 if ( !messages.isEmpty() )
1326 err += QStringLiteral(
"\n\n" ) + messages.last().message();
1330 returnValue = unzip( inDevice.fileName(), flags );
1336 returnValue = unzip( mFile.fileName(), flags );
1341 const QFileInfo finfo( mFile.fileName() );
1342 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( QStringLiteral(
"%1_attachments.zip" ).arg( finfo.completeBaseName() ) );
1343 if ( QFile( attachmentsZip ).exists() )
1345 std::unique_ptr<QgsArchive> archive(
new QgsArchive() );
1346 if ( archive->unzip( attachmentsZip ) )
1348 mArchive = std::move( archive );
1351 returnValue = readProjectFile( mFile.fileName(), flags );
1357 mFile.setFileName( filename );
1358 mCachedHomePath.clear();
1359 mProjectScope.reset();
1364 mTranslator.reset(
nullptr );
1371 bool QgsProject::readProjectFile(
const QString &filename, QgsProject::ReadFlags flags )
1374 ScopedIntIncrementor snapSignalBlock( &mBlockSnappingUpdates );
1376 QFile projectFile( filename );
1384 if ( QFile( QStringLiteral(
"%1/%2.qm" ).arg( QFileInfo( projectFile.fileName() ).absolutePath(), localeFileName ) ).exists() )
1386 mTranslator.reset(
new QTranslator() );
1387 ( void )mTranslator->load( localeFileName, QFileInfo( projectFile.fileName() ).absolutePath() );
1390 profile.switchTask( tr(
"Reading project file" ) );
1391 std::unique_ptr<QDomDocument> doc(
new QDomDocument( QStringLiteral(
"qgis" ) ) );
1393 if ( !projectFile.open( QIODevice::ReadOnly | QIODevice::Text ) )
1395 projectFile.close();
1397 setError( tr(
"Unable to open %1" ).arg( projectFile.fileName() ) );
1406 if ( !doc->setContent( &projectFile, &errorMsg, &line, &column ) )
1408 const QString errorString = tr(
"Project file read error in file %1: %2 at line %3 column %4" )
1409 .arg( projectFile.fileName(), errorMsg ).arg( line ).arg( column );
1413 projectFile.close();
1415 setError( tr(
"%1 for file %2" ).arg( errorString, projectFile.fileName() ) );
1420 projectFile.close();
1428 profile.switchTask( tr(
"Updating project file" ) );
1429 if ( thisVersion > fileVersion )
1431 const bool isOlderMajorVersion = fileVersion.
majorVersion() < thisVersion.majorVersion();
1433 if ( isOlderMajorVersion )
1436 "version of qgis (saved in " + fileVersion.
text() +
1438 "). Problems may occur." );
1449 projectFile.updateRevision( thisVersion );
1451 else if ( fileVersion > thisVersion )
1454 "version of qgis (saved in " + fileVersion.
text() +
1456 "). Problems may occur." );
1462 profile.switchTask( tr(
"Creating auxiliary storage" ) );
1463 const QString
fileName = mFile.fileName();
1464 std::unique_ptr<QgsAuxiliaryStorage> aStorage = std::move( mAuxiliaryStorage );
1465 std::unique_ptr<QgsArchive> archive = std::move( mArchive );
1467 mAuxiliaryStorage = std::move( aStorage );
1468 mArchive = std::move( archive );
1470 mCachedHomePath.clear();
1471 mProjectScope.reset();
1472 mSaveVersion = fileVersion;
1475 profile.switchTask( tr(
"Reading properties" ) );
1484 dump_( mProperties );
1489 _getTitle( *doc, oldTitle );
1491 readProjectFileMetadata( *doc, mSaveUser, mSaveUserFull, mSaveDateTime );
1493 const QDomNodeList homePathNl = doc->elementsByTagName( QStringLiteral(
"homePath" ) );
1494 if ( homePathNl.count() > 0 )
1496 const QDomElement homePathElement = homePathNl.at( 0 ).toElement();
1497 const QString
homePath = homePathElement.attribute( QStringLiteral(
"path" ) );
1507 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorGreenPart" ), 255 ),
1508 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorBluePart" ), 255 ) );
1511 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorGreenPart" ), 255 ),
1512 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorBluePart" ), 255 ),
1513 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorAlphaPart" ), 255 ) );
1522 if (
readNumEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectionsEnabled" ), 0 ) )
1525 const QDomNode srsNode = doc->documentElement().namedItem( QStringLiteral(
"projectCrs" ) );
1526 if ( !srsNode.isNull() )
1528 projectCrs.
readXml( srsNode );
1533 const QString projCrsString =
readEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCRSProj4String" ) );
1534 const long currentCRS =
readNumEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCRSID" ), -1 );
1535 const QString authid =
readEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCrs" ) );
1538 const bool isUserAuthId = authid.startsWith( QLatin1String(
"USER:" ), Qt::CaseInsensitive );
1539 if ( !authid.isEmpty() && !isUserAuthId )
1543 if ( !projectCrs.
isValid() && currentCRS >= 0 )
1549 if ( !projCrsString.isEmpty() && ( authid.isEmpty() || isUserAuthId ) && ( !projectCrs.
isValid() || projectCrs.
toProj() != projCrsString ) )
1563 QStringList datumErrors;
1564 if ( !mTransformContext.
readXml( doc->documentElement(), context, datumErrors ) && !datumErrors.empty() )
1572 const QStringList variableNames =
readListEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableNames" ) );
1573 const QStringList variableValues =
readListEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableValues" ) );
1575 mCustomVariables.clear();
1576 if ( variableNames.length() == variableValues.length() )
1578 for (
int i = 0; i < variableNames.length(); ++i )
1580 mCustomVariables.insert( variableNames.at( i ), variableValues.at( i ) );
1585 QgsMessageLog::logMessage( tr(
"Project Variables Invalid" ), tr(
"The project contains invalid variable settings." ) );
1588 QDomElement element = doc->documentElement().firstChildElement( QStringLiteral(
"projectMetadata" ) );
1590 if ( !element.isNull() )
1599 if ( mMetadata.
title().isEmpty() && !oldTitle.isEmpty() )
1606 element = doc->documentElement().firstChildElement( QStringLiteral(
"autotransaction" ) );
1607 if ( ! element.isNull() )
1609 if ( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
1610 mAutoTransaction =
true;
1613 element = doc->documentElement().firstChildElement( QStringLiteral(
"evaluateDefaultValues" ) );
1614 if ( !element.isNull() )
1616 if ( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
1617 mEvaluateDefaultValues =
true;
1621 element = doc->documentElement().firstChildElement( QStringLiteral(
"trust" ) );
1622 if ( !element.isNull() )
1624 if ( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
1625 mTrustLayerMetadata =
true;
1629 profile.switchTask( tr(
"Loading layer tree" ) );
1632 QDomElement layerTreeElem = doc->documentElement().firstChildElement( QStringLiteral(
"layer-tree-group" ) );
1633 if ( !layerTreeElem.isNull() )
1645 mLayerTreeRegistryBridge->
setEnabled(
false );
1648 profile.switchTask( tr(
"Reading map layers" ) );
1650 QList<QDomNode> brokenNodes;
1651 const bool clean = _getMapLayers( *doc, brokenNodes, flags );
1656 QgsDebugMsg( QStringLiteral(
"Unable to get map layers from project file." ) );
1658 if ( !brokenNodes.isEmpty() )
1660 QgsDebugMsg(
"there are " + QString::number( brokenNodes.size() ) +
" broken layers" );
1668 mMainAnnotationLayer->
readLayerXml( doc->documentElement().firstChildElement( QStringLiteral(
"main-annotation-layer" ) ), context );
1672 profile.switchTask( tr(
"Loading embedded layers" ) );
1673 loadEmbeddedNodes( mRootGroup, flags );
1677 profile.switchTask( tr(
"Resolving layer references" ) );
1678 QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
1679 for ( QMap<QString, QgsMapLayer *>::iterator it =
layers.begin(); it !=
layers.end(); ++it )
1681 it.value()->resolveReferences(
this );
1684 mLayerTreeRegistryBridge->
setEnabled(
true );
1687 profile.switchTask( tr(
"Resolving references" ) );
1690 if ( !layerTreeElem.isNull() )
1696 const QDomElement layerTreeCanvasElem = doc->documentElement().firstChildElement( QStringLiteral(
"layer-tree-canvas" ) );
1697 if ( !layerTreeCanvasElem.isNull( ) )
1705 const QStringList requiredLayerIds =
readListEntry( QStringLiteral(
"RequiredLayers" ), QStringLiteral(
"Layers" ) );
1706 for (
const QString &layerId : requiredLayerIds )
1713 const QStringList disabledLayerIds =
readListEntry( QStringLiteral(
"Identify" ), QStringLiteral(
"/disabledLayers" ) );
1714 for (
const QString &layerId : disabledLayerIds )
1728 profile.switchTask( tr(
"Storing original layer properties" ) );
1734 profile.switchTask( tr(
"Loading map themes" ) );
1737 mMapThemeCollection->readXml( *doc );
1739 profile.switchTask( tr(
"Loading label settings" ) );
1740 mLabelingEngineSettings->readSettingsFromProject(
this );
1743 profile.switchTask( tr(
"Loading annotations" ) );
1744 mAnnotationManager->readXml( doc->documentElement(), context );
1747 profile.switchTask( tr(
"Loading layouts" ) );
1748 mLayoutManager->readXml( doc->documentElement(), *doc );
1753 profile.switchTask( tr(
"Loading 3D Views" ) );
1754 m3DViewsManager->readXml( doc->documentElement(), *doc );
1757 profile.switchTask( tr(
"Loading bookmarks" ) );
1758 mBookmarkManager->
readXml( doc->documentElement(), *doc );
1761 QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
1762 for ( QMap<QString, QgsMapLayer *>::iterator it = existingMaps.begin(); it != existingMaps.end(); ++it )
1764 it.value()->setDependencies( it.value()->dependencies() );
1767 profile.switchTask( tr(
"Loading snapping settings" ) );
1771 profile.switchTask( tr(
"Loading view settings" ) );
1774 const QStringList scales =
readListEntry( QStringLiteral(
"Scales" ), QStringLiteral(
"/ScalesList" ) );
1775 QVector<double> res;
1776 for (
const QString &scale : scales )
1778 const QStringList parts = scale.split(
':' );
1779 if ( parts.size() != 2 )
1783 const double denominator = QLocale().toDouble( parts[1], &ok );
1790 const QDomElement viewSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectViewSettings" ) );
1791 if ( !viewSettingsElement.isNull() )
1792 mViewSettings->
readXml( viewSettingsElement, context );
1795 profile.switchTask( tr(
"Loading temporal settings" ) );
1796 const QDomElement timeSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectTimeSettings" ) );
1797 if ( !timeSettingsElement.isNull() )
1798 mTimeSettings->
readXml( timeSettingsElement, context );
1800 profile.switchTask( tr(
"Loading display settings" ) );
1801 const QDomElement displaySettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectDisplaySettings" ) );
1802 if ( !displaySettingsElement.isNull() )
1803 mDisplaySettings->
readXml( displaySettingsElement, context );
1805 profile.switchTask( tr(
"Updating variables" ) );
1807 profile.switchTask( tr(
"Updating CRS" ) );
1812 profile.switchTask( tr(
"Reading external settings" ) );
1816 profile.switchTask( tr(
"Updating interface" ) );
1818 snapSignalBlock.release();
1819 if ( !mBlockSnappingUpdates )
1830 QgsDebugMsgLevel( QString(
"Project save user: %1" ).arg( mSaveUser ), 2 );
1831 QgsDebugMsgLevel( QString(
"Project save user: %1" ).arg( mSaveUserFull ), 2 );
1840 const QString newFileName( QStringLiteral(
"%1/%2.qgs" ).arg( QFileInfo( projectFile.fileName() ).absolutePath(), localeFileName ) );
1846 QgsMessageLog::logMessage( tr(
"Translated project saved with locale prefix %1" ).arg( newFileName ), QObject::tr(
"Project translation" ), Qgis::MessageLevel::Success );
1850 QgsMessageLog::logMessage( tr(
"Error saving translated project with locale prefix %1" ).arg( newFileName ), QObject::tr(
"Project translation" ), Qgis::MessageLevel::Critical );
1857 bool QgsProject::loadEmbeddedNodes(
QgsLayerTreeGroup *group, QgsProject::ReadFlags flags )
1860 const auto constChildren = group->
children();
1866 if ( childGroup->
customProperty( QStringLiteral(
"embedded" ) ).toInt() )
1869 const QString projectPath =
readPath( childGroup->
customProperty( QStringLiteral(
"embedded_project" ) ).toString() );
1870 childGroup->
setCustomProperty( QStringLiteral(
"embedded_project" ), projectPath );
1874 QList<QgsLayerTreeNode *> clonedChildren;
1875 const auto constChildren = newGroup->
children();
1877 clonedChildren << newGroupChild->clone();
1885 loadEmbeddedNodes( childGroup, flags );
1890 if ( child->customProperty( QStringLiteral(
"embedded" ) ).toInt() )
1892 QList<QDomNode> brokenNodes;
1895 valid = valid &&
false;
1907 return mCustomVariables;
1912 if ( variables == mCustomVariables )
1916 QStringList variableNames;
1917 QStringList variableValues;
1919 QVariantMap::const_iterator it = variables.constBegin();
1920 for ( ; it != variables.constEnd(); ++it )
1922 variableNames << it.key();
1923 variableValues << it.value().toString();
1926 writeEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableNames" ), variableNames );
1927 writeEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableValues" ), variableValues );
1929 mCustomVariables = variables;
1930 mProjectScope.reset();
1937 *mLabelingEngineSettings = settings;
1943 return *mLabelingEngineSettings;
1948 mProjectScope.reset();
1949 return mLayerStore.get();
1954 return mLayerStore.get();
1959 QList<QgsVectorLayer *>
layers;
1960 const QStringList layerIds =
readListEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsList" ), QStringList() );
1961 const auto constLayerIds = layerIds;
1962 for (
const QString &layerId : constLayerIds )
1973 const auto constLayers =
layers;
1975 list << layer->id();
1976 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsList" ), list );
1993 if ( mProjectScope )
1995 std::unique_ptr< QgsExpressionContextScope > projectScope = std::make_unique< QgsExpressionContextScope >( *mProjectScope );
1999 return projectScope.release();
2002 mProjectScope = std::make_unique< QgsExpressionContextScope >( QObject::tr(
"Project" ) );
2006 QVariantMap::const_iterator it = vars.constBegin();
2008 for ( ; it != vars.constEnd(); ++it )
2010 mProjectScope->setVariable( it.key(), it.value(),
true );
2014 if ( projectPath.isEmpty() )
2015 projectPath = mOriginalPath;
2016 const QString projectFolder = QFileInfo( projectPath ).path();
2017 const QString projectFilename = QFileInfo( projectPath ).fileName();
2018 const QString projectBasename =
baseName();
2047 QVariantMap keywords;
2049 for (
auto it = metadataKeywords.constBegin(); it != metadataKeywords.constEnd(); ++it )
2051 keywords.insert( it.key(), it.value() );
2056 QVariantList layersIds;
2058 const QMap<QString, QgsMapLayer *> layersInProject = mLayerStore->mapLayers();
2059 layersIds.reserve( layersInProject.count() );
2060 layers.reserve( layersInProject.count() );
2061 for (
auto it = layersInProject.constBegin(); it != layersInProject.constEnd(); ++it )
2063 layersIds << it.value()->id();
2069 mProjectScope->addFunction( QStringLiteral(
"project_color" ),
new GetNamedProjectColor(
this ) );
2074 void QgsProject::onMapLayersAdded(
const QList<QgsMapLayer *> &layers )
2076 const QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
2078 bool tgChanged =
false;
2080 const auto constLayers =
layers;
2083 if ( layer->isValid() )
2085 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
2092 const QString connString = QgsTransaction::connectionString( vlayer->
source() );
2100 mTransactionGroups.insert( qMakePair( key, connString ), tg );
2115 for ( QMap<QString, QgsMapLayer *>::const_iterator it = existingMaps.cbegin(); it != existingMaps.cend(); ++it )
2117 const QSet<QgsMapLayerDependency> deps = it.value()->dependencies();
2118 if ( deps.contains( layer->id() ) )
2121 it.value()->setDependencies( deps );
2131 void QgsProject::onMapLayersRemoved(
const QList<QgsMapLayer *> &layers )
2137 void QgsProject::cleanTransactionGroups(
bool force )
2139 bool changed =
false;
2140 for ( QMap< QPair< QString, QString>,
QgsTransactionGroup *>::Iterator tg = mTransactionGroups.begin(); tg != mTransactionGroups.end(); )
2142 if ( tg.value()->
isEmpty() || force )
2145 tg = mTransactionGroups.erase( tg );
2163 QList<QDomNode> brokenNodes;
2164 if ( addLayer( layerNode.toElement(), brokenNodes, context ) )
2168 const QVector<QgsVectorLayer *> vectorLayers = layers<QgsVectorLayer *>();
2169 const auto constVectorLayers = vectorLayers;
2173 layer->resolveReferences(
this );
2183 mFile.setFileName( filename );
2184 mCachedHomePath.clear();
2190 mProjectScope.reset();
2196 const QString storageFilePath { storage->filePath( mFile.fileName() ) };
2197 if ( storageFilePath.isEmpty() )
2203 const QString tempPath = QStandardPaths::standardLocations( QStandardPaths::TempLocation ).at( 0 );
2204 const QString tmpZipFilename( tempPath + QDir::separator() + QUuid::createUuid().toString() );
2206 if ( !zip( tmpZipFilename ) )
2209 QFile tmpZipFile( tmpZipFilename );
2210 if ( !tmpZipFile.open( QIODevice::ReadOnly ) )
2212 setError( tr(
"Unable to read file %1" ).arg( tmpZipFilename ) );
2217 if ( !storage->writeProject( mFile.fileName(), &tmpZipFile, context ) )
2219 QString err = tr(
"Unable to save project to storage %1" ).arg( mFile.fileName() );
2220 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
2221 if ( !messages.isEmpty() )
2222 err += QStringLiteral(
"\n\n" ) + messages.last().message();
2228 QFile::remove( tmpZipFilename );
2235 return zip( mFile.fileName() );
2241 const bool asOk = saveAuxiliaryStorage();
2242 const bool writeOk = writeProjectFile( mFile.fileName() );
2243 bool attachmentsOk =
true;
2244 if ( !mArchive->files().isEmpty() )
2246 const QFileInfo finfo( mFile.fileName() );
2247 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( QStringLiteral(
"%1_attachments.zip" ).arg( finfo.completeBaseName() ) );
2248 attachmentsOk = mArchive->zip( attachmentsZip );
2252 if ( ( !asOk || !attachmentsOk ) && writeOk )
2254 QStringList errorMessage;
2257 const QString err = mAuxiliaryStorage->errorString();
2258 errorMessage.append( tr(
"Unable to save auxiliary storage ('%1')" ).arg( err ) );
2260 if ( !attachmentsOk )
2262 errorMessage.append( tr(
"Unable to save attachments archive" ) );
2264 setError( errorMessage.join(
"\n" ) );
2267 return asOk && writeOk && attachmentsOk;
2271 bool QgsProject::writeProjectFile(
const QString &filename )
2273 QFile projectFile( filename );
2279 const QFileInfo myFileInfo( projectFile );
2280 if ( myFileInfo.exists() && !myFileInfo.isWritable() )
2282 setError( tr(
"%1 is not writable. Please adjust permissions (if possible) and try again." )
2283 .arg( projectFile.fileName() ) );
2291 QDomImplementation::setInvalidDataPolicy( QDomImplementation::DropInvalidChars );
2293 const QDomDocumentType documentType =
2294 QDomImplementation().createDocumentType( QStringLiteral(
"qgis" ), QStringLiteral(
"http://mrcc.com/qgis.dtd" ),
2295 QStringLiteral(
"SYSTEM" ) );
2296 std::unique_ptr<QDomDocument> doc(
new QDomDocument( documentType ) );
2298 QDomElement qgisNode = doc->createElement( QStringLiteral(
"qgis" ) );
2299 qgisNode.setAttribute( QStringLiteral(
"projectname" ),
title() );
2300 qgisNode.setAttribute( QStringLiteral(
"version" ),
Qgis::version() );
2302 if ( !mSettings.
value( QStringLiteral(
"projects/anonymize_saved_projects" ),
false,
QgsSettings::Core ).toBool() )
2306 qgisNode.setAttribute( QStringLiteral(
"saveUser" ), newSaveUser );
2307 qgisNode.setAttribute( QStringLiteral(
"saveUserFull" ), newSaveUserFull );
2308 mSaveUser = newSaveUser;
2309 mSaveUserFull = newSaveUserFull;
2310 mSaveDateTime = QDateTime::currentDateTime();
2311 qgisNode.setAttribute( QStringLiteral(
"saveDateTime" ), mSaveDateTime.toString( Qt::ISODate ) );
2316 mSaveUserFull.clear();
2317 mSaveDateTime = QDateTime();
2319 doc->appendChild( qgisNode );
2322 QDomElement homePathNode = doc->createElement( QStringLiteral(
"homePath" ) );
2323 homePathNode.setAttribute( QStringLiteral(
"path" ), mHomePath );
2324 qgisNode.appendChild( homePathNode );
2327 QDomElement titleNode = doc->createElement( QStringLiteral(
"title" ) );
2328 qgisNode.appendChild( titleNode );
2330 QDomElement transactionNode = doc->createElement( QStringLiteral(
"autotransaction" ) );
2331 transactionNode.setAttribute( QStringLiteral(
"active" ), mAutoTransaction ? 1 : 0 );
2332 qgisNode.appendChild( transactionNode );
2334 QDomElement evaluateDefaultValuesNode = doc->createElement( QStringLiteral(
"evaluateDefaultValues" ) );
2335 evaluateDefaultValuesNode.setAttribute( QStringLiteral(
"active" ), mEvaluateDefaultValues ? 1 : 0 );
2336 qgisNode.appendChild( evaluateDefaultValuesNode );
2338 QDomElement trustNode = doc->createElement( QStringLiteral(
"trust" ) );
2339 trustNode.setAttribute( QStringLiteral(
"active" ), mTrustLayerMetadata ? 1 : 0 );
2340 qgisNode.appendChild( trustNode );
2342 const QDomText titleText = doc->createTextNode(
title() );
2343 titleNode.appendChild( titleText );
2346 QDomElement srsNode = doc->createElement( QStringLiteral(
"projectCrs" ) );
2348 qgisNode.appendChild( srsNode );
2355 clonedRoot->
writeXml( qgisNode, context );
2359 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsMode" ),
static_cast<int>( mAvoidIntersectionsMode ) );
2367 QDomElement annotationLayerNode = doc->createElement( QStringLiteral(
"main-annotation-layer" ) );
2368 mMainAnnotationLayer->
writeLayerXml( annotationLayerNode, *doc, context );
2369 qgisNode.appendChild( annotationLayerNode );
2373 QDomElement projectLayersNode = doc->createElement( QStringLiteral(
"projectlayers" ) );
2375 QMap<QString, QgsMapLayer *>::ConstIterator li =
layers.constBegin();
2376 while ( li !=
layers.end() )
2382 const QHash< QString, QPair< QString, bool> >::const_iterator emIt = mEmbeddedLayers.constFind( ml->
id() );
2383 if ( emIt == mEmbeddedLayers.constEnd() )
2385 QDomElement maplayerElem;
2391 maplayerElem = doc->createElement( QStringLiteral(
"maplayer" ) );
2396 QDomDocument document;
2399 maplayerElem = document.firstChildElement();
2403 QgsDebugMsg( QStringLiteral(
"Could not restore layer properties for layer %1" ).arg( ml->
id() ) );
2409 projectLayersNode.appendChild( maplayerElem );
2415 if ( emIt.value().second )
2417 QDomElement mapLayerElem = doc->createElement( QStringLiteral(
"maplayer" ) );
2418 mapLayerElem.setAttribute( QStringLiteral(
"embedded" ), 1 );
2419 mapLayerElem.setAttribute( QStringLiteral(
"project" ),
writePath( emIt.value().first ) );
2420 mapLayerElem.setAttribute( QStringLiteral(
"id" ), ml->
id() );
2421 projectLayersNode.appendChild( mapLayerElem );
2428 qgisNode.appendChild( projectLayersNode );
2430 QDomElement layerOrderNode = doc->createElement( QStringLiteral(
"layerorder" ) );
2432 for (
QgsMapLayer *layer : constCustomLayerOrder )
2434 QDomElement mapLayerElem = doc->createElement( QStringLiteral(
"layer" ) );
2435 mapLayerElem.setAttribute( QStringLiteral(
"id" ), layer->id() );
2436 layerOrderNode.appendChild( mapLayerElem );
2438 qgisNode.appendChild( layerOrderNode );
2440 mLabelingEngineSettings->writeSettingsToProject(
this );
2442 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorRedPart" ), mBackgroundColor.red() );
2443 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorGreenPart" ), mBackgroundColor.green() );
2444 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorBluePart" ), mBackgroundColor.blue() );
2446 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorRedPart" ), mSelectionColor.red() );
2447 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorGreenPart" ), mSelectionColor.green() );
2448 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorBluePart" ), mSelectionColor.blue() );
2449 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorAlphaPart" ), mSelectionColor.alpha() );
2453 dump_( mProperties );
2456 QgsDebugMsgLevel( QStringLiteral(
"there are %1 property scopes" ).arg(
static_cast<int>( mProperties.
count() ) ), 2 );
2461 mProperties.
writeXml( QStringLiteral(
"properties" ), qgisNode, *doc );
2464 QDomElement ddElem = doc->createElement( QStringLiteral(
"dataDefinedServerProperties" ) );
2465 mDataDefinedServerProperties.
writeXml( ddElem, dataDefinedServerPropertyDefinitions() );
2466 qgisNode.appendChild( ddElem );
2468 mMapThemeCollection->writeXml( *doc );
2470 mTransformContext.
writeXml( qgisNode, context );
2472 QDomElement metadataElem = doc->createElement( QStringLiteral(
"projectMetadata" ) );
2474 qgisNode.appendChild( metadataElem );
2476 const QDomElement annotationsElem = mAnnotationManager->writeXml( *doc, context );
2477 qgisNode.appendChild( annotationsElem );
2479 const QDomElement layoutElem = mLayoutManager->writeXml( *doc );
2480 qgisNode.appendChild( layoutElem );
2482 const QDomElement views3DElem = m3DViewsManager->writeXml( *doc );
2483 qgisNode.appendChild( views3DElem );
2485 const QDomElement bookmarkElem = mBookmarkManager->
writeXml( *doc );
2486 qgisNode.appendChild( bookmarkElem );
2488 const QDomElement viewSettingsElem = mViewSettings->
writeXml( *doc, context );
2489 qgisNode.appendChild( viewSettingsElem );
2491 const QDomElement timeSettingsElement = mTimeSettings->
writeXml( *doc, context );
2492 qgisNode.appendChild( timeSettingsElement );
2494 const QDomElement displaySettingsElem = mDisplaySettings->
writeXml( *doc, context );
2495 qgisNode.appendChild( displaySettingsElem );
2503 QFile backupFile( QStringLiteral(
"%1~" ).arg( filename ) );
2505 ok &= backupFile.open( QIODevice::WriteOnly | QIODevice::Truncate );
2506 ok &= projectFile.open( QIODevice::ReadOnly );
2509 while ( ok && !projectFile.atEnd() )
2511 ba = projectFile.read( 10240 );
2512 ok &= backupFile.write( ba ) == ba.size();
2515 projectFile.close();
2520 setError( tr(
"Unable to create backup file %1" ).arg( backupFile.fileName() ) );
2525 struct utimbuf tb = {
static_cast<time_t
>( fi.lastRead().toSecsSinceEpoch() ),
static_cast<time_t
>( fi.lastModified().toSecsSinceEpoch() ) };
2526 utime( backupFile.fileName().toUtf8().constData(), &tb );
2529 if ( !projectFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
2531 projectFile.close();
2534 setError( tr(
"Unable to save to file %1" ).arg( projectFile.fileName() ) );
2538 QTemporaryFile tempFile;
2539 bool ok = tempFile.open();
2542 QTextStream projectFileStream( &tempFile );
2543 doc->save( projectFileStream, 2 );
2544 ok &= projectFileStream.pos() > -1;
2546 ok &= tempFile.seek( 0 );
2549 while ( ok && !tempFile.atEnd() )
2551 ba = tempFile.read( 10240 );
2552 ok &= projectFile.write( ba ) == ba.size();
2555 ok &= projectFile.error() == QFile::NoError;
2557 projectFile.close();
2564 setError( tr(
"Unable to save to file %1. Your project "
2565 "may be corrupted on disk. Try clearing some space on the volume and "
2566 "check file permissions before pressing save again." )
2567 .arg( projectFile.fileName() ) );
2579 bool propertiesModified;
2580 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
2582 if ( propertiesModified )
2590 bool propertiesModified;
2591 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
2593 if ( propertiesModified )
2601 bool propertiesModified;
2602 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
2604 if ( propertiesModified )
2612 bool propertiesModified;
2613 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
2615 if ( propertiesModified )
2623 bool propertiesModified;
2624 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
2626 if ( propertiesModified )
2634 const QStringList &def,
2643 value =
property->value();
2645 const bool valid = QVariant::StringList == value.type();
2651 return value.toStringList();
2673 value =
property->value();
2675 const bool valid = value.canConvert( QVariant::String );
2680 return value.toString();
2697 value =
property->value();
2700 const bool valid = value.canConvert( QVariant::Int );
2709 return value.toInt();
2722 const QVariant value =
property->value();
2724 const bool valid = value.canConvert( QVariant::Double );
2729 return value.toDouble();
2744 const QVariant value =
property->value();
2746 const bool valid = value.canConvert( QVariant::Bool );
2751 return value.toBool();
2761 if (
findKey_( scope, key, mProperties ) )
2767 return !
findKey_( scope, key, mProperties );
2775 QStringList entries;
2777 if ( foundProperty )
2792 QStringList entries;
2794 if ( foundProperty )
2807 dump_( mProperties );
2825 filePath = storage->filePath( mFile.fileName() );
2848 void QgsProject::setError(
const QString &errorMessage )
2850 mErrorMessage = errorMessage;
2855 return mErrorMessage;
2858 void QgsProject::clearError()
2860 setError( QString() );
2865 delete mBadLayerHandler;
2866 mBadLayerHandler = handler;
2871 const QHash< QString, QPair< QString, bool > >::const_iterator it = mEmbeddedLayers.find(
id );
2872 if ( it == mEmbeddedLayers.constEnd() )
2876 return it.value().first;
2880 bool saveFlag, QgsProject::ReadFlags flags )
2884 static QString sPrevProjectFilePath;
2885 static QDateTime sPrevProjectFileTimestamp;
2886 static QDomDocument sProjectDocument;
2888 QString qgsProjectFile = projectFilePath;
2890 if ( projectFilePath.endsWith( QLatin1String(
".qgz" ), Qt::CaseInsensitive ) )
2892 archive.
unzip( projectFilePath );
2896 const QDateTime projectFileTimestamp = QFileInfo( projectFilePath ).lastModified();
2898 if ( projectFilePath != sPrevProjectFilePath || projectFileTimestamp != sPrevProjectFileTimestamp )
2900 sPrevProjectFilePath.clear();
2902 QFile projectFile( qgsProjectFile );
2903 if ( !projectFile.open( QIODevice::ReadOnly ) )
2908 if ( !sProjectDocument.setContent( &projectFile ) )
2913 sPrevProjectFilePath = projectFilePath;
2914 sPrevProjectFileTimestamp = projectFileTimestamp;
2918 bool useAbsolutePaths =
true;
2920 const QDomElement propertiesElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral(
"properties" ) );
2921 if ( !propertiesElem.isNull() )
2923 const QDomElement absElem = propertiesElem.firstChildElement( QStringLiteral(
"Paths" ) ).firstChildElement( QStringLiteral(
"Absolute" ) );
2924 if ( !absElem.isNull() )
2926 useAbsolutePaths = absElem.text().compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0;
2931 if ( !useAbsolutePaths )
2936 const QDomElement projectLayersElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral(
"projectlayers" ) );
2937 if ( projectLayersElem.isNull() )
2942 QDomElement mapLayerElem = projectLayersElem.firstChildElement( QStringLiteral(
"maplayer" ) );
2943 while ( ! mapLayerElem.isNull() )
2946 const QString
id = mapLayerElem.firstChildElement( QStringLiteral(
"id" ) ).text();
2947 if (
id == layerId )
2950 if ( mapLayerElem.attribute( QStringLiteral(
"embedded" ) ) == QLatin1String(
"1" ) )
2955 mEmbeddedLayers.insert( layerId, qMakePair( projectFilePath, saveFlag ) );
2957 if ( addLayer( mapLayerElem, brokenNodes, embeddedContext, flags ) )
2963 mEmbeddedLayers.remove( layerId );
2967 mapLayerElem = mapLayerElem.nextSiblingElement( QStringLiteral(
"maplayer" ) );
2976 QString qgsProjectFile = projectFilePath;
2978 if ( projectFilePath.endsWith( QLatin1String(
".qgz" ), Qt::CaseInsensitive ) )
2980 archive.
unzip( projectFilePath );
2985 QFile projectFile( qgsProjectFile );
2986 if ( !projectFile.open( QIODevice::ReadOnly ) )
2991 QDomDocument projectDocument;
2992 if ( !projectDocument.setContent( &projectFile ) )
3004 QDomElement layerTreeElem = projectDocument.documentElement().firstChildElement( QStringLiteral(
"layer-tree-group" ) );
3005 if ( !layerTreeElem.isNull() )
3015 if ( !group || group->
customProperty( QStringLiteral(
"embedded" ) ).toBool() )
3028 newGroup->
setCustomProperty( QStringLiteral(
"embedded_project" ), projectFilePath );
3031 mLayerTreeRegistryBridge->
setEnabled(
false );
3032 initializeEmbeddedSubtree( projectFilePath, newGroup, flags );
3033 mLayerTreeRegistryBridge->
setEnabled(
true );
3036 const auto constFindLayerIds = newGroup->
findLayerIds();
3037 for (
const QString &layerId : constFindLayerIds )
3050 void QgsProject::initializeEmbeddedSubtree(
const QString &projectFilePath,
QgsLayerTreeGroup *group, QgsProject::ReadFlags flags )
3052 const auto constChildren = group->
children();
3056 child->setCustomProperty( QStringLiteral(
"embedded" ), 1 );
3065 QList<QDomNode> brokenNodes;
3073 return mEvaluateDefaultValues;
3082 QMap<QString, QgsMapLayer *>::const_iterator layerIt =
layers.constBegin();
3083 for ( ; layerIt !=
layers.constEnd(); ++layerIt )
3085 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layerIt.value() );
3097 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/TopologicalEditing" ), ( enabled ? 1 : 0 ) );
3103 return readNumEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/TopologicalEditing" ), 0 );
3108 const QString distanceUnitString =
readEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/DistanceUnits" ), QString() );
3109 if ( !distanceUnitString.isEmpty() )
3125 const QString areaUnitString =
readEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/AreaUnits" ), QString() );
3126 if ( !areaUnitString.isEmpty() )
3142 if ( !mCachedHomePath.isEmpty() )
3143 return mCachedHomePath;
3147 if ( !mHomePath.isEmpty() )
3149 const QFileInfo homeInfo( mHomePath );
3150 if ( !homeInfo.isRelative() )
3152 mCachedHomePath = mHomePath;
3158 mCachedHomePath = pfi.path();
3160 return mCachedHomePath;
3163 if ( !pfi.exists() )
3165 mCachedHomePath = mHomePath;
3169 if ( !mHomePath.isEmpty() )
3172 mCachedHomePath = QDir::cleanPath( pfi.path() +
'/' + mHomePath );
3176 mCachedHomePath = pfi.canonicalPath();
3178 return mCachedHomePath;
3188 return mRelationManager;
3193 return mLayoutManager.get();
3198 return mLayoutManager.get();
3203 return m3DViewsManager.get();
3208 return m3DViewsManager.get();
3213 return mBookmarkManager;
3218 return mBookmarkManager;
3223 return mViewSettings;
3228 return mViewSettings;
3233 return mTimeSettings;
3238 return mTimeSettings;
3243 return mDisplaySettings;
3248 return mDisplaySettings;
3258 return mMapThemeCollection.get();
3263 return mAnnotationManager.get();
3268 return mAnnotationManager.get();
3273 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
3274 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
3279 if (
layers.contains( it.value() ) )
3294 for (
const QString &layerId : layerIds )
3310 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
3322 return mAutoTransaction;
3332 onMapLayersAdded(
mapLayers().values() );
3334 cleanTransactionGroups(
true );
3340 return mTransactionGroups;
3351 return mLayerStore->count();
3356 return mLayerStore->validCount();
3361 return mLayerStore->mapLayer( layerId );
3366 return mLayerStore->mapLayersByName( layerName );
3371 QList<QgsMapLayer *>
layers;
3372 const auto constMapLayers { mLayerStore->mapLayers() };
3373 for (
const auto &l : constMapLayers )
3375 if ( ! l->shortName().isEmpty() )
3377 if ( l->shortName() == shortName )
3380 else if ( l->name() == shortName )
3388 bool QgsProject::unzip(
const QString &filename, QgsProject::ReadFlags flags )
3394 if ( !archive->unzip( filename ) )
3396 setError( tr(
"Unable to unzip file '%1'" ).arg( filename ) );
3401 if ( archive->projectFile().isEmpty() )
3403 setError( tr(
"Zip archive does not provide a project file" ) );
3408 mArchive = std::move( archive );
3425 setError( tr(
"Cannot read unzipped qgs project file" ) );
3435 bool QgsProject::zip(
const QString &filename )
3441 const QString
baseName = QFileInfo( filename ).baseName();
3442 const QString qgsFileName = QStringLiteral(
"%1.qgs" ).arg(
baseName );
3443 QFile qgsFile( QDir( archive->dir() ).filePath( qgsFileName ) );
3445 bool writeOk =
false;
3446 if ( qgsFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
3448 writeOk = writeProjectFile( qgsFile.fileName() );
3455 setError( tr(
"Unable to write temporary qgs file" ) );
3460 const QFileInfo info( qgsFile );
3462 const QString asFileName = info.path() + QDir::separator() + info.completeBaseName() + asExt;
3464 bool auxiliaryStorageSavedOk =
true;
3465 if ( ! saveAuxiliaryStorage( asFileName ) )
3467 const QString err = mAuxiliaryStorage->errorString();
3468 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 ) );
3469 auxiliaryStorageSavedOk =
false;
3472 if ( !mArchive->exists() )
3475 mArchive->unzip( mFile.fileName() );
3478 const QString auxiliaryStorageFile =
static_cast<QgsProjectArchive *
>( mArchive.get() )->auxiliaryStorageFile();
3479 if ( ! auxiliaryStorageFile.isEmpty() )
3481 archive->
addFile( auxiliaryStorageFile );
3490 if ( QFile::exists( asFileName ) )
3492 archive->addFile( asFileName );
3497 archive->addFile( qgsFile.fileName() );
3500 const QStringList &files = mArchive->files();
3501 for (
const QString &file : files )
3503 if ( !file.endsWith(
".qgs", Qt::CaseInsensitive ) && !file.endsWith( asExt, Qt::CaseInsensitive ) )
3505 archive->addFile( file );
3511 if ( !archive->zip( filename ) )
3513 setError( tr(
"Unable to perform zip" ) );
3517 return auxiliaryStorageSavedOk && zipOk;
3526 const QList<QgsMapLayer *> &layers,
3528 bool takeOwnership )
3530 const QList<QgsMapLayer *> myResultList { mLayerStore->addMapLayers(
layers, takeOwnership ) };
3531 if ( !myResultList.isEmpty() )
3534 for (
auto &l : myResultList )
3544 if ( mAuxiliaryStorage )
3559 mProjectScope.reset();
3561 return myResultList;
3567 bool takeOwnership )
3569 QList<QgsMapLayer *> addedLayers;
3570 addedLayers =
addMapLayers( QList<QgsMapLayer *>() << layer, addToLegend, takeOwnership );
3571 return addedLayers.isEmpty() ? nullptr : addedLayers[0];
3576 mProjectScope.reset();
3577 mLayerStore->removeMapLayers( layerIds );
3582 mProjectScope.reset();
3583 mLayerStore->removeMapLayers(
layers );
3588 mProjectScope.reset();
3589 mLayerStore->removeMapLayer( layerId );
3594 mProjectScope.reset();
3595 mLayerStore->removeMapLayer( layer );
3600 mProjectScope.reset();
3601 return mLayerStore->takeMapLayer( layer );
3606 return mMainAnnotationLayer;
3611 if ( mLayerStore->count() == 0 )
3614 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
3615 mProjectScope.reset();
3616 mLayerStore->removeAllMapLayers();
3618 snapSingleBlocker.release();
3620 if ( !mBlockSnappingUpdates )
3626 const QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
3627 QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin();
3628 for ( ; it !=
layers.constEnd(); ++it )
3630 it.value()->reload();
3636 return validOnly ? mLayerStore->validMapLayers() : mLayerStore->mapLayers();
3641 return mTransactionGroups.value( qMakePair( providerKey, connString ) );
3650 if ( mSettings.
value( QStringLiteral(
"/projections/unknownCrsBehavior" ), QStringLiteral(
"NoAction" ),
QgsSettings::App ).toString() == QStringLiteral(
"UseProjectCrs" )
3651 || mSettings.
value( QStringLiteral(
"/projections/unknownCrsBehavior" ), 0,
QgsSettings::App ).toString() == QLatin1String(
"2" ) )
3659 const QString layerDefaultCrs = mSettings.
value( QStringLiteral(
"/Projections/layerDefaultCrs" ),
geoEpsgCrsAuthId() ).toString();
3668 mTrustLayerMetadata = trust;
3671 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
3673 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() );
3681 bool QgsProject::saveAuxiliaryStorage(
const QString &filename )
3685 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
3690 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() );
3698 if ( !mAuxiliaryStorage->exists( *
this ) && empty )
3702 else if ( !filename.isEmpty() )
3704 return mAuxiliaryStorage->saveAs( filename );
3708 return mAuxiliaryStorage->saveAs( *
this );
3717 QgsProject::DataDefinedServerProperty::WMSOnlineResource,
3721 return sPropertyDefinitions;
3726 return mAuxiliaryStorage.get();
3731 return mAuxiliaryStorage.get();
3736 const QDir archiveDir( mArchive->dir() );
3737 QTemporaryFile tmpFile( archiveDir.filePath(
"XXXXXX_" + nameTemplate ),
this );
3738 tmpFile.setAutoRemove(
false );
3740 mArchive->addFile( tmpFile.fileName() );
3741 return tmpFile.fileName();
3746 QStringList attachments;
3748 for (
const QString &file : mArchive->files() )
3752 attachments.append( file );
3760 return mArchive->removeFile( path );
3765 return QStringLiteral(
"attachment:///%1" ).arg( QFileInfo( attachedFile ).
fileName() );
3770 if ( identifier.startsWith(
"attachment:///" ) )
3772 return QDir( mArchive->dir() ).absoluteFilePath( identifier.mid( 14 ) );
3788 mProjectScope.reset();
3800 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
3812 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
3813 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
3818 if (
layers.contains( it.value() ) )
3828 QStringList customColors;
3829 QStringList customColorLabels;
3831 QgsNamedColorList::const_iterator colorIt = colors.constBegin();
3832 for ( ; colorIt != colors.constEnd(); ++colorIt )
3835 const QString label = ( *colorIt ).second;
3836 customColors.append( color );
3837 customColorLabels.append( label );
3839 writeEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Colors" ), customColors );
3840 writeEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Labels" ), customColorLabels );
3841 mProjectScope.reset();
3847 if ( mBackgroundColor == color )
3850 mBackgroundColor = color;
3856 return mBackgroundColor;
3861 if ( mSelectionColor == color )
3864 mSelectionColor = color;
3870 return mSelectionColor;
3904 QString
QgsProject::translate(
const QString &context,
const QString &sourceText,
const char *disambiguation,
int n )
const
3911 QString result = mTranslator->translate( context.toUtf8(), sourceText.toUtf8(), disambiguation, n );
3913 if ( result.isEmpty() )
3925 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
3930 if ( !( ( *it )->accept( visitor ) ) )
3939 if ( !mLayoutManager->accept( visitor ) )
3942 if ( !mAnnotationManager->accept( visitor ) )
3949 GetNamedProjectColor::GetNamedProjectColor(
const QgsProject *project )
3956 QStringList colorStrings = project->
readListEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Colors" ) );
3957 const QStringList colorLabels = project->
readListEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Labels" ) );
3961 for ( QStringList::iterator it = colorStrings.begin();
3962 it != colorStrings.end(); ++it )
3966 if ( colorLabels.length() > colorIndex )
3968 label = colorLabels.at( colorIndex );
3971 mColors.insert( label.toLower(), color );
3976 GetNamedProjectColor::GetNamedProjectColor(
const QHash<QString, QColor> &colors )
3984 const QString colorName = values.at( 0 ).toString().toLower();
3985 if ( mColors.contains( colorName ) )
3987 return QStringLiteral(
"%1,%2,%3" ).arg( mColors.value( colorName ).red() ).arg( mColors.value( colorName ).green() ).arg( mColors.value( colorName ).blue() );
3995 return new GetNamedProjectColor( mColors );
static QString version()
Version string.
FilePathType
File path types.
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 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.
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 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.
static const QgsSettingsEntryString settingsLocaleUserLocale
Settings entry locale user locale.
Class allowing to manage the zip/unzip actions.
void addFile(const QString &filename)
Add a new file to this archive.
This is a container for attribute editors, used to group them visually in the attribute form if it is...
QList< QgsAttributeEditorElement * > children() const
Gets a list of the children elements of this container.
This is an abstract base class for any elements of a drag and drop form.
QString name() const
Returns the name of this element.
@ AeTypeContainer
A container.
QgsFields auxiliaryFields() const
Returns a list of all auxiliary fields currently managed by the layer.
bool save()
Commits changes and starts editing then.
Class providing some utility methods to manage auxiliary storage.
static QString extension()
Returns the extension used for auxiliary databases.
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.
This class represents a coordinate reference system (CRS).
static QgsCoordinateReferenceSystem fromOgcWmsCrs(const QString &ogcCrs)
Creates a CRS from a given OGC WMS-format Coordinate Reference System string.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
QString toProj() const
Returns a Proj string representation of this CRS.
bool readXml(const QDomNode &node)
Restores state from the given DOM node.
QString ellipsoidAcronym() const
Returns the ellipsoid acronym for the ellipsoid used by the CRS.
QString projectionAcronym() const
Returns the projection acronym for the projection used by the CRS.
static QgsCoordinateReferenceSystem fromProj(const QString &proj)
Creates a CRS from a proj style formatted string.
@ WKT_PREFERRED
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
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.
QString toWkt(WktVariant variant=WKT1_GDAL, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
Q_GADGET QgsUnitTypes::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.
void setProviderProperty(ProviderProperty property, const QVariant &value)
Allows setting arbitrary properties on the provider.
@ EvaluateDefaultValues
Evaluate default values on provider side when calling QgsVectorDataProvider::defaultValue( int index ...
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 expression node for expression functions.
Class for parsing and evaluation of expressions (formerly called "search strings").
Encapsulate a field in an attribute table or data source.
QgsEditorWidgetSetup editorWidgetSetup() const
Gets the editor widget setup for the field.
Container of fields for a vector layer.
bool isEmpty() const
Checks whether the container is empty.
Stores global configuration for labeling engine.
Class used to work with layer dependencies stored in a XML project or layer definition file.
Layer tree group node serves as a container for layers and further groups.
void resolveReferences(const QgsProject *project, bool looseMatching=false) override
Calls resolveReferences() on child tree nodes.
QgsLayerTreeGroup * findGroup(const QString &name)
Find group node with specified name.
QList< QgsLayerTreeGroup * > findGroups(bool recursive=false) const
Find group layer nodes.
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.
void readChildrenFromXml(QDomElement &element, const QgsReadWriteContext &context)
Read children from XML and append them to the group.
QgsLayerTreeGroup * clone() const override
Returns a clone of the group.
QList< QgsLayerTreeLayer * > findLayers() const
Find all layer nodes.
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)
This class is a base class for nodes in a layer tree.
QList< QgsLayerTreeNode * > abandonChildren()
Removes the childrens, disconnect all the forwarded and external signals and sets their parent to nul...
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.
void removeCustomProperty(const QString &key)
Remove a custom property from layer. Properties are stored in a map and saved in project file.
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.
QList< QgsLayerTreeNode * > children()
Gets list of children of the node. Children are owned by the parent.
void setItemVisibilityChecked(bool checked)
Check or uncheck a node (independently of its ancestors or children)
Listens to the updates in map layer registry and does changes in layer tree.
void setEnabled(bool enabled)
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.
void readLayerOrderFromXml(const QDomElement &doc)
Load the layer order from an XML element.
void clear()
Clear any information from this layer tree.
static bool isLayer(const QgsLayerTreeNode *node)
Check whether the node is a valid layer node.
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
static bool isGroup(QgsLayerTreeNode *node)
Check whether the node is a valid group node.
QList< QgsMapLayer * > customLayerOrder() const
The order in which layers will be rendered on the canvas.
static QgsLayerTreeGroup * toGroup(QgsLayerTreeNode *node)
Cast node to a group.
QgsLayerTree * clone() const override
Create a copy of the node. Returns new instance.
Manages storage of a set of layouts.
static void warning(const QString &msg)
Goes to qWarning.
static QgsMapLayerType 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.
QString source() const
Returns the source for the layer.
QString providerType() const
Returns the provider type (provider key) for this layer.
void configChanged()
Emitted whenever the configuration is changed.
QgsCoordinateReferenceSystem crs
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
QString originalXmlProperties() const
Returns the XML properties of the original layer as they were when the layer was first read from the ...
bool writeLayerXml(QDomElement &layerElement, QDomDocument &document, const QgsReadWriteContext &context) const
Stores state in DOM node.
bool readLayerXml(const QDomElement &layerElement, QgsReadWriteContext &context, QgsMapLayer::ReadFlags flags=QgsMapLayer::ReadFlags())
Sets state from DOM document.
@ 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...
@ FlagTrustLayerMetadata
Trust layer metadata. Improves layer load time by skipping expensive checks like primary key unicity,...
@ FlagDontResolveLayers
Don't resolve layer paths or create data providers for layers.
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)
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.
Class allowing to manage the zip/unzip actions on project file.
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 file.
virtual void handleBadLayers(const QList< QDomNode > &layers)
This method will be called whenever the project tries to load layers which cannot be accessed.
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.
Project property key node.
QString name() const
The name of the property is used as identifier.
QgsProjectPropertyKey * addKey(const QString &keyName)
Adds the specified property key as a sub-key.
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.
QgsProjectProperty * find(const QString &propertyName) const
Attempts to find a property with a matching sub-key name.
void setName(const QString &name)
The name of the property is used as identifier.
QVariant value() const override
If this key has a value, it will be stored by its name in its properties.
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.
QgsProjectPropertyValue * setValue(const QString &name, const QVariant &value)
Sets the value associated with this key.
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 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.
A class to describe 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.
QgsProject(QObject *parent=nullptr)
Create a new QgsProject.
bool removeAttachedFile(const QString &path)
Removes the attached file.
void setAvoidIntersectionsMode(const AvoidIntersectionsMode mode)
Sets the avoid intersections mode.
QgsRelationManager * relationManager
bool write()
Writes the project to its current associated file (see fileName() ).
void removeMapLayer(const QString &layerId)
Remove a layer from the registry by layer ID.
bool evaluateDefaultValues() const
Should default values be evaluated on provider side when requested and not when committed.
void setAreaUnits(QgsUnitTypes::AreaUnit unit)
Sets the default area measurement units for the project.
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.
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.
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.
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.
void setSnappingConfig(const QgsSnappingConfig &snappingConfig)
The snapping configuration for this project.
void setDistanceUnits(QgsUnitTypes::DistanceUnit unit)
Sets the default distance measurement units for the project.
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 setSelectionColor(const QColor &color)
Sets the color used to highlight selected features.
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.
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 the project with QTranslator and qm file.
QgsSnappingConfig snappingConfig
void setFileName(const QString &name)
Sets the file name associated with the project.
QgsUnitTypes::AreaUnit areaUnits() const
Convenience function to query default area measurement units for 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.
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.
void setAutoTransaction(bool autoTransaction)
Transactional editing means that on supported datasources (postgres databases) the edit state of all ...
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...
Q_DECL_DEPRECATED void oldProjectVersionWarning(const QString &)
Emitted when an old project file is read.
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.
QVector< T > layers() const
Returns a list of registered map layers with a specified layer type.
QString resolveAttachmentIdentifier(const QString &identifier) const
Resolves an attachment identifier to a attachment file path.
QString absolutePath() const
Returns full absolute path to the project folder if the project is stored in a file system - derived ...
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...
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.
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.
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.
QgsAnnotationManager * annotationManager()
Returns pointer to the project's annotation manager.
QgsProjectMetadata metadata
void projectColorsChanged()
Emitted whenever the project's color scheme has been changed.
QgsUnitTypes::DistanceUnit distanceUnits() const
Convenience function to query default distance measurement units for project.
QString saveUser() const
Returns the user name that did the last save.
void setProjectColors(const QgsNamedColorList &colors)
Sets the colors for the project's color scheme (see QgsProjectColorScheme).
QgsCoordinateTransformContext transformContext
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.
void readProject(const QDomDocument &)
Emitted when a project is being read.
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.
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...
QList< QgsMapLayer * > mapLayersByName(const QString &layerName) const
Retrieve a list of matching registered layers by layer name.
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
void readProjectWithContext(const QDomDocument &, QgsReadWriteContext &context)
Emitted when a project is being read.
QgsMapLayer * addMapLayer(QgsMapLayer *mapLayer, bool addToLegend=true, bool takeOwnership=true)
Add a layer to the map of loaded layers.
QStringList nonIdentifiableLayers
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 setTitle(const QString &title)
Sets the project's title.
QMap< QPair< QString, QString >, QgsTransactionGroup * > transactionGroups()
Map of transaction groups.
void writeProject(QDomDocument &)
Emitted when the project is being written.
QDateTime lastModified() const
Returns last modified time of the project file as returned by the file system (or other project stora...
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.
QgsLayerTreeGroup * createEmbeddedGroup(const QString &groupName, const QString &projectFilePath, const QStringList &invisibleLayers, QgsProject::ReadFlags flags=QgsProject::ReadFlags())
Create layer group instance defined in an arbitrary 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.
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".
bool read(const QString &filename, QgsProject::ReadFlags flags=QgsProject::ReadFlags())
Reads given project file from the given file.
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...
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.
bool createEmbeddedLayer(const QString &layerId, const QString &projectFilePath, QList< QDomNode > &brokenNodes, bool saveFlag=true, QgsProject::ReadFlags flags=QgsProject::ReadFlags())
Creates a maplayer instance defined in an arbitrary project file.
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.
@ FlagTrustLayerMetadata
Trust layer metadata. Improves project read time. Do not use it if layers' extent is not fixed during...
@ FlagDontStoreOriginalStyles
Skip the initial XML style storage for layers. Useful for minimising project load times in non-intera...
@ FlagDontLoadLayouts
Don't load print layouts. Improves project read time if layouts are not required, and allows projects...
@ FlagDontResolveLayers
Don't resolve layer paths (i.e. don't load any layer content). Dramatically improves project read tim...
const QgsProjectViewSettings * viewSettings() const
Returns the project's view settings, which contains settings and properties relating to how a QgsProj...
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 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.
QgsCoordinateReferenceSystem defaultCrsForNewLayers() const
Returns the default CRS for new layers based on the settings and the current project CRS.
const QgsProjectDisplaySettings * displaySettings() const
Returns the project's display settings, which settings and properties relating to how a QgsProject sh...
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.
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.
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 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 a integer key value.
Definition for a property.
@ String
Any string value.
The class is used as a container of context for various read/write operations on other objects.
void setTransformContext(const QgsCoordinateTransformContext &transformContext)
Sets data coordinate transform context to transformContext.
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.
This class manages a set of relations between layers.
void clear()
Remove any relation managed by this class.
QMap< QString, QgsRelation > relations() const
Gets access to the relations managed by this class.
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.
QString value(const QString &dynamicKeyPart=QString(), bool useDefaultValueOverride=false, const QString &defaultValueOverride=QString()) const
Returns settings value.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
This is a container for configuration of the snapping of 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.
static QColor decodeColor(const QString &str)
static QString encodeColor(const QColor &color)
bool isEmpty() const
Returns true if there are no layers in this 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.
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 writeTsFile(const QString &locale)
Writes the Ts-file.
void setFileName(const QString &fileName)
Sets the fileName of the TS file.
void setProject(QgsProject *project)
Sets the project being translated.
DistanceUnit
Units of distance.
static Q_INVOKABLE QString encodeUnit(QgsUnitTypes::DistanceUnit unit)
Encodes a distance unit to a string.
static Q_INVOKABLE QgsUnitTypes::DistanceUnit decodeDistanceUnit(const QString &string, bool *ok=nullptr)
Decodes a distance unit from a string.
static Q_INVOKABLE QString toString(QgsUnitTypes::DistanceUnit unit)
Returns a translated string representing a distance unit.
static Q_INVOKABLE QgsUnitTypes::AreaUnit decodeAreaUnit(const QString &string, bool *ok=nullptr)
Decodes an areal unit from a string.
@ AreaSquareMeters
Square meters.
Represents a vector layer which manages a vector based data sets.
bool loadAuxiliaryLayer(const QgsAuxiliaryStorage &storage, const QString &key=QString())
Loads the auxiliary layer for this vector layer.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
QgsAuxiliaryLayer * auxiliaryLayer()
Returns the current auxiliary layer.
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
void setReadExtentFromXml(bool readExtentFromXml)
Flag allowing to indicate if the extent has to be read from the XML document when data source has no ...
QgsEditFormConfig editFormConfig
QList< QPair< QColor, QString > > QgsNamedColorList
List of colors paired with a friendly display name identifying the color.
QgsMapLayerType
Types of layers that can be added to a map.
@ PointCloudLayer
Point cloud layer. Added in QGIS 3.18.
@ MeshLayer
Mesh layer. Added in QGIS 3.2.
@ VectorLayer
Vector layer.
@ RasterLayer
Raster layer.
@ GroupLayer
Composite group layer. Added in QGIS 3.24.
@ VectorTileLayer
Vector tile layer. Added in QGIS 3.14.
@ AnnotationLayer
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
@ PluginLayer
Plugin based layer.
CORE_EXPORT bool isZipFile(const QString &filename)
Returns true if the file name is a zipped file ( i.e with a '.qgz' extension, false otherwise.
CONSTLATIN1STRING geoNone()
Constant that holds the string representation for "No ellips/No CRS".
#define Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_PUSH
CONSTLATIN1STRING geoEpsgCrsAuthId()
Geographic coord sys from EPSG authority.
#define QgsDebugMsgLevel(str, level)
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"...
QgsProjectProperty * findKey_(const QString &scope, const QString &key, QgsProjectPropertyKey &rootProperty)
Returns the property that matches the given key sequence, if any.
void removeKey_(const QString &scope, const QString &key, QgsProjectPropertyKey &rootProperty)
Removes a given key.
QgsProjectProperty * addKey_(const QString &scope, const QString &key, QgsProjectPropertyKey *rootProperty, const QVariant &value, bool &propertiesModified)
Adds the given key and value.
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)
QMap< int, QgsPropertyDefinition > QgsPropertiesDefinition
Definition of available properties.
const QgsCoordinateReferenceSystem & crs
Setting options for loading annotation layers.
Single variable definition for use within a QgsExpressionContextScope.
Setting options for loading group layers.
Contains information relating to a node (i.e.