71 #include <QApplication>
75 #include <QTextStream>
76 #include <QTemporaryFile>
79 #include <QStandardPaths>
81 #include <QRegularExpression>
84 #include <sys/utime.h>
102 QStringList keyTokens = QStringList( scope );
103 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
104 keyTokens += key.split(
'/', QString::SkipEmptyParts );
106 keyTokens += key.split(
'/', Qt::SkipEmptyParts );
110 keyTokens.push_front( QStringLiteral(
"properties" ) );
113 for (
int i = 0; i < keyTokens.size(); ++i )
115 const QString keyToken = keyTokens.at( i );
119 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}])" );
120 if ( keyToken.contains( sInvalidRegexp ) )
122 const QString errorString = QObject::tr(
"Entry token invalid : '%1'. The token will not be saved to file." ).arg( keyToken );
150 while ( !keySequence.isEmpty() )
154 if ( keySequence.first() == currentProperty->
name() )
157 keySequence.pop_front();
159 if ( 1 == keySequence.count() )
162 return currentProperty->
find( keySequence.front() );
164 else if ( keySequence.isEmpty() )
169 return currentProperty;
171 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
173 if ( nextProperty->
isKey() )
177 else if ( nextProperty->
isValue() && 1 == keySequence.count() )
183 return currentProperty;
221 const QVariant &value,
222 bool &propertiesModified )
231 propertiesModified =
false;
232 while ( ! keySequence.isEmpty() )
236 if ( keySequence.first() == currentProperty->
name() )
239 keySequence.pop_front();
243 if ( 1 == keySequence.count() )
246 if ( !property || property->value() != value )
248 currentProperty->
setValue( keySequence.front(), value );
249 propertiesModified =
true;
252 return currentProperty;
256 else if ( keySequence.isEmpty() )
258 if ( currentProperty->
value() != value )
261 propertiesModified =
true;
264 return currentProperty;
266 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
270 if ( currentProperty )
281 if ( ( newPropertyKey = currentProperty->
addKey( keySequence.first() ) ) )
283 currentProperty = newPropertyKey;
315 while ( ! keySequence.isEmpty() )
319 if ( keySequence.first() == currentProperty->
name() )
322 keySequence.pop_front();
326 if ( 1 == keySequence.count() )
328 currentProperty->
removeKey( keySequence.front() );
333 else if ( keySequence.isEmpty() )
335 previousQgsPropertyKey->
removeKey( currentProperty->
name() );
337 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
339 previousQgsPropertyKey = currentProperty;
342 if ( currentProperty )
368 , mSnappingConfig( this )
381 mProperties.
setName( QStringLiteral(
"properties" ) );
384 mMainAnnotationLayer->setParent(
this );
398 this, [ = ](
const QStringList &
layers ) { mProjectScope.reset(); emit layersWillBeRemoved( layers ); } );
400 this, [ = ](
const QList<QgsMapLayer *> &
layers ) { mProjectScope.reset(); emit layersWillBeRemoved( layers ); } );
402 this, [ = ](
const QString & layer ) { mProjectScope.reset(); emit layerWillBeRemoved( layer ); } );
404 this, [ = ](
QgsMapLayer * layer ) { mProjectScope.reset(); emit layerWillBeRemoved( layer ); } );
406 [ = ](
const QStringList &
layers ) { mProjectScope.reset(); emit layersRemoved( layers ); } );
408 [ = ](
const QString & layer ) { mProjectScope.reset(); emit layerRemoved( layer ); } );
410 [ = ]() { mProjectScope.reset(); emit removeAll(); } );
412 [ = ](
const QList< QgsMapLayer * > &
layers ) { mProjectScope.reset(); emit layersAdded( layers ); } );
414 [ = ](
QgsMapLayer * layer ) { mProjectScope.reset(); emit layerWasAdded( layer ); } );
422 [ = ](
const QList<QgsMapLayer *> &
layers )
424 for ( const auto &layer : layers )
426 disconnect( layer, &QgsMapLayer::dataSourceChanged, mRelationManager, &QgsRelationManager::updateRelationsStatus );
431 [ = ](
const QList<QgsMapLayer *> &layers )
433 for ( const auto &layer : layers )
435 connect( layer, &QgsMapLayer::dataSourceChanged, mRelationManager, &QgsRelationManager::updateRelationsStatus );
448 mIsBeingDeleted =
true;
451 delete mBadLayerHandler;
452 delete mRelationManager;
453 delete mLayerTreeRegistryBridge;
455 if (
this == sProject )
482 mProjectScope.reset();
490 return mMetadata.
title();
500 return mSaveUserFull;
505 return mSaveDateTime;
520 if ( dirty && mDirtyBlockCount > 0 )
526 if ( mDirty == dirty )
535 if ( path == mHomePath )
539 mCachedHomePath.clear();
540 mProjectScope.reset();
549 const QList<QgsAttributeEditorElement *> elements = parent->
children();
557 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:formcontainers" ).arg( layerId ), container->
name() );
559 if ( !container->
children().empty() )
572 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1" ).arg( layer->layerId() ), layer->name() );
589 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:fieldaliases" ).arg( vlayer->
id() ), fieldName );
604 const QList<QgsLayerTreeGroup *> groupLayers = mRootGroup->
findGroups();
607 translationContext->
registerTranslation( QStringLiteral(
"project:layergroups" ), groupLayer->name() );
611 const QList<QgsRelation> &relations = mRelationManager->
relations().values();
614 translationContext->
registerTranslation( QStringLiteral(
"project:relations" ), relation.name() );
620 mDataDefinedServerProperties = properties;
625 return mDataDefinedServerProperties;
630 if ( name == mFile.fileName() )
633 const QString oldHomePath =
homePath();
635 mFile.setFileName( name );
636 mCachedHomePath.clear();
637 mProjectScope.reset();
641 const QString newHomePath =
homePath();
642 if ( newHomePath != oldHomePath )
650 return mFile.fileName();
655 mOriginalPath = path;
660 return mOriginalPath;
665 return QFileInfo( mFile );
678 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
683 return QFileInfo( mFile.fileName() ).lastModified();
692 if ( mFile.fileName().isEmpty() )
695 return QFileInfo( mFile.fileName() ).absolutePath();
703 if ( mFile.fileName().isEmpty() )
706 return QFileInfo( mFile.fileName() ).absoluteFilePath();
714 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
719 return QFileInfo( mFile.fileName() ).completeBaseName();
725 const bool absolutePaths =
readBoolEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
false );
734 writeEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
true );
737 writeEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
false );
752 writeEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectionsEnabled" ),
crs.
isValid() ? 1 : 0 );
753 mProjectScope.reset();
764 if ( adjustEllipsoid )
770 if ( !
crs().isValid() )
773 return readEntry( QStringLiteral(
"Measure" ), QStringLiteral(
"/Ellipsoid" ),
geoNone() );
778 if (
ellipsoid ==
readEntry( QStringLiteral(
"Measure" ), QStringLiteral(
"/Ellipsoid" ) ) )
781 mProjectScope.reset();
788 return mTransformContext;
793 if ( context == mTransformContext )
796 mTransformContext = context;
797 mProjectScope.reset();
800 for (
auto &layer : mLayerStore.get()->mapLayers() )
802 layer->setTransformContext( context );
809 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
811 mProjectScope.reset();
812 mFile.setFileName( QString() );
815 mSaveUserFull.clear();
816 mSaveDateTime = QDateTime();
819 mCachedHomePath.clear();
820 mAutoTransaction =
false;
821 mEvaluateDefaultValues =
false;
823 mTrustLayerMetadata =
false;
824 mCustomVariables.clear();
827 if ( !mSettings.
value( QStringLiteral(
"projects/anonymize_new_projects" ),
false,
QgsSettings::Core ).toBool() )
838 mEmbeddedLayers.clear();
839 mRelationManager->
clear();
840 mAnnotationManager->clear();
841 mLayoutManager->clear();
842 mBookmarkManager->
clear();
843 mViewSettings->
reset();
844 mTimeSettings->
reset();
845 mDisplaySettings->
reset();
846 mSnappingConfig.
reset();
854 mLabelingEngineSettings->clear();
861 if ( !mIsBeingDeleted )
869 writeEntry( QStringLiteral(
"PositionPrecision" ), QStringLiteral(
"/Automatic" ),
true );
870 writeEntry( QStringLiteral(
"PositionPrecision" ), QStringLiteral(
"/DecimalPlaces" ), 2 );
872 const bool defaultRelativePaths = mSettings.
value( QStringLiteral(
"/qgis/defaultProjectPathsRelative" ),
true ).toBool();
876 writeEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/DistanceUnits" ), mSettings.
value( QStringLiteral(
"/qgis/measure/displayunits" ) ).toString() );
877 writeEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/AreaUnits" ), mSettings.
value( QStringLiteral(
"/qgis/measure/areaunits" ) ).toString() );
879 int red = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_red" ), 255 ).toInt();
880 int green = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_green" ), 255 ).toInt();
881 int blue = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_blue" ), 255 ).toInt();
884 red = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_red" ), 255 ).toInt();
885 green = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_green" ), 255 ).toInt();
886 blue = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_blue" ), 0 ).toInt();
887 const int alpha = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_alpha" ), 255 ).toInt();
894 if ( mMainAnnotationLayer )
895 mMainAnnotationLayer->
reset();
897 snapSingleBlocker.release();
899 if ( !mBlockSnappingUpdates )
911 topQgsPropertyKey.
dump();
944 const QDomElement propertiesElem = doc.documentElement().firstChildElement( QStringLiteral(
"properties" ) );
946 if ( propertiesElem.isNull() )
951 const QDomNodeList scopes = propertiesElem.childNodes();
953 if ( propertiesElem.firstChild().isNull() )
955 QgsDebugMsg( QStringLiteral(
"empty ``properties'' XML tag ... bailing" ) );
959 if ( ! project_properties.
readXml( propertiesElem ) )
961 QgsDebugMsg( QStringLiteral(
"Project_properties.readXml() failed" ) );
975 const QDomElement ddElem = doc.documentElement().firstChildElement( QStringLiteral(
"dataDefinedServerProperties" ) );
976 if ( !ddElem.isNull() )
978 if ( !ddServerProperties.
readXml( ddElem, dataDefinedServerPropertyDefinitions ) )
980 QgsDebugMsg( QStringLiteral(
"dataDefinedServerProperties.readXml() failed" ) );
983 return ddServerProperties;
990 static void _getTitle(
const QDomDocument &doc, QString &title )
992 const QDomElement titleNode = doc.documentElement().firstChildElement( QStringLiteral(
"title" ) );
996 if ( titleNode.isNull() )
1002 if ( !titleNode.hasChildNodes() )
1008 const QDomNode titleTextNode = titleNode.firstChild();
1010 if ( !titleTextNode.isText() )
1016 const QDomText titleText = titleTextNode.toText();
1018 title = titleText.data();
1022 static void readProjectFileMetadata(
const QDomDocument &doc, QString &lastUser, QString &lastUserFull, QDateTime &lastSaveDateTime )
1024 const QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"qgis" ) );
1032 const QDomNode qgisNode = nl.item( 0 );
1034 const QDomElement qgisElement = qgisNode.toElement();
1035 lastUser = qgisElement.attribute( QStringLiteral(
"saveUser" ), QString() );
1036 lastUserFull = qgisElement.attribute( QStringLiteral(
"saveUserFull" ), QString() );
1037 lastSaveDateTime = QDateTime::fromString( qgisElement.attribute( QStringLiteral(
"saveDateTime" ), QString() ), Qt::ISODate );
1043 const QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"qgis" ) );
1047 QgsDebugMsg( QStringLiteral(
" unable to find qgis element in project file" ) );
1051 const QDomNode qgisNode = nl.item( 0 );
1053 const QDomElement qgisElement = qgisNode.toElement();
1054 QgsProjectVersion projectVersion( qgisElement.attribute( QStringLiteral(
"version" ) ) );
1055 return projectVersion;
1061 return mSnappingConfig;
1076 if ( mAvoidIntersectionsMode == mode )
1079 mAvoidIntersectionsMode = mode;
1083 bool QgsProject::_getMapLayers(
const QDomDocument &doc, QList<QDomNode> &brokenNodes, QgsProject::ReadFlags flags )
1088 QDomElement layerElement = doc.documentElement().firstChildElement( QStringLiteral(
"projectlayers" ) ).firstChildElement( QStringLiteral(
"maplayer" ) );
1092 if ( layerElement.isNull() )
1102 bool returnStatus =
true;
1105 while ( ! layerElement.isNull() )
1108 layerElement = layerElement.nextSiblingElement( QStringLiteral(
"maplayer" ) );
1114 if ( depSorter.hasCycle() )
1118 if ( depSorter.hasMissingDependency() )
1119 returnStatus =
false;
1123 const QVector<QDomNode> sortedLayerNodes = depSorter.sortedLayerNodes();
1124 const int totalLayerCount = sortedLayerNodes.count();
1127 for (
const QDomNode &node : sortedLayerNodes )
1129 const QDomElement element = node.toElement();
1131 const QString name =
translate( QStringLiteral(
"project:layers:%1" ).arg( node.namedItem( QStringLiteral(
"id" ) ).toElement().text() ), node.namedItem( QStringLiteral(
"layername" ) ).toElement().text() );
1132 if ( !name.isNull() )
1133 emit
loadingLayer( tr(
"Loading layer %1" ).arg( name ) );
1135 profile.switchTask( name );
1137 if ( element.attribute( QStringLiteral(
"embedded" ) ) == QLatin1String(
"1" ) )
1139 createEmbeddedLayer( element.attribute( QStringLiteral(
"id" ) ),
readPath( element.attribute( QStringLiteral(
"project" ) ) ), brokenNodes,
true, flags );
1148 if ( !addLayer( element, brokenNodes, context, flags ) )
1150 returnStatus =
false;
1153 if ( !messages.isEmpty() )
1162 return returnStatus;
1165 bool QgsProject::addLayer(
const QDomElement &layerElem, QList<QDomNode> &brokenNodes,
QgsReadWriteContext &context, QgsProject::ReadFlags flags )
1167 const QString type = layerElem.attribute( QStringLiteral(
"type" ) );
1169 std::unique_ptr<QgsMapLayer>
mapLayer;
1177 QgsDebugMsg( QStringLiteral(
"Unknown layer type \"%1\"" ).arg( type ) );
1181 switch ( layerType )
1185 mapLayer = std::make_unique<QgsVectorLayer>();
1195 mapLayer = std::make_unique<QgsRasterLayer>();
1199 mapLayer = std::make_unique<QgsMeshLayer>();
1203 mapLayer = std::make_unique<QgsVectorTileLayer>();
1207 mapLayer = std::make_unique<QgsPointCloudLayer>();
1212 const QString
typeName = layerElem.attribute( QStringLiteral(
"name" ) );
1220 mapLayer = std::make_unique<QgsAnnotationLayer>( QString(), options );
1227 QgsDebugMsg( QStringLiteral(
"Unable to create layer" ) );
1235 const QString layerId { layerElem.namedItem( QStringLiteral(
"id" ) ).toElement().text() };
1236 Q_ASSERT( ! layerId.isEmpty() );
1240 QgsMapLayer::ReadFlags layerFlags = QgsMapLayer::ReadFlags();
1247 profile.switchTask( tr(
"Load layer source" ) );
1250 profile.switchTask( tr(
"Add layer to project" ) );
1251 QList<QgsMapLayer *> newLayers;
1263 QgsDebugMsg(
"Unable to load " + type +
" layer" );
1264 brokenNodes.push_back( layerElem );
1269 if ( ! layerWasStored )
1274 return layerIsValid;
1279 mFile.setFileName( filename );
1280 mCachedHomePath.clear();
1281 mProjectScope.reset();
1283 return read( flags );
1288 const QString filename = mFile.fileName();
1293 QTemporaryFile inDevice;
1294 if ( !inDevice.open() )
1296 setError( tr(
"Unable to open %1" ).arg( inDevice.fileName() ) );
1302 if ( !storage->readProject( filename, &inDevice, context ) )
1304 QString err = tr(
"Unable to open %1" ).arg( filename );
1305 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
1306 if ( !messages.isEmpty() )
1307 err += QStringLiteral(
"\n\n" ) + messages.last().message();
1311 returnValue = unzip( inDevice.fileName(), flags );
1317 returnValue = unzip( mFile.fileName(), flags );
1322 const QFileInfo finfo( mFile.fileName() );
1323 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( QStringLiteral(
"%1_attachments.zip" ).arg( finfo.completeBaseName() ) );
1324 if ( QFile( attachmentsZip ).exists() )
1326 std::unique_ptr<QgsArchive> archive(
new QgsArchive() );
1327 if ( archive->unzip( attachmentsZip ) )
1329 mArchive = std::move( archive );
1332 returnValue = readProjectFile( mFile.fileName(), flags );
1338 mFile.setFileName( filename );
1339 mCachedHomePath.clear();
1340 mProjectScope.reset();
1345 mTranslator.reset(
nullptr );
1352 bool QgsProject::readProjectFile(
const QString &filename, QgsProject::ReadFlags flags )
1355 ScopedIntIncrementor snapSignalBlock( &mBlockSnappingUpdates );
1357 QFile projectFile( filename );
1365 if ( QFile( QStringLiteral(
"%1/%2.qm" ).arg( QFileInfo( projectFile.fileName() ).absolutePath(), localeFileName ) ).exists() )
1367 mTranslator.reset(
new QTranslator() );
1368 ( void )mTranslator->load( localeFileName, QFileInfo( projectFile.fileName() ).absolutePath() );
1371 profile.switchTask( tr(
"Reading project file" ) );
1372 std::unique_ptr<QDomDocument> doc(
new QDomDocument( QStringLiteral(
"qgis" ) ) );
1374 if ( !projectFile.open( QIODevice::ReadOnly | QIODevice::Text ) )
1376 projectFile.close();
1378 setError( tr(
"Unable to open %1" ).arg( projectFile.fileName() ) );
1387 if ( !doc->setContent( &projectFile, &errorMsg, &line, &column ) )
1389 const QString errorString = tr(
"Project file read error in file %1: %2 at line %3 column %4" )
1390 .arg( projectFile.fileName(), errorMsg ).arg( line ).arg( column );
1394 projectFile.close();
1396 setError( tr(
"%1 for file %2" ).arg( errorString, projectFile.fileName() ) );
1401 projectFile.close();
1409 profile.switchTask( tr(
"Updating project file" ) );
1410 if ( thisVersion > fileVersion )
1413 "version of qgis (saved in " + fileVersion.
text() +
1415 "). Problems may occur." );
1422 projectFile.updateRevision( thisVersion );
1426 profile.switchTask( tr(
"Creating auxiliary storage" ) );
1427 const QString
fileName = mFile.fileName();
1428 std::unique_ptr<QgsAuxiliaryStorage> aStorage = std::move( mAuxiliaryStorage );
1429 std::unique_ptr<QgsArchive> archive = std::move( mArchive );
1431 mAuxiliaryStorage = std::move( aStorage );
1432 mArchive = std::move( archive );
1434 mCachedHomePath.clear();
1435 mProjectScope.reset();
1436 mSaveVersion = fileVersion;
1439 profile.switchTask( tr(
"Reading properties" ) );
1448 dump_( mProperties );
1453 _getTitle( *doc, oldTitle );
1455 readProjectFileMetadata( *doc, mSaveUser, mSaveUserFull, mSaveDateTime );
1457 const QDomNodeList homePathNl = doc->elementsByTagName( QStringLiteral(
"homePath" ) );
1458 if ( homePathNl.count() > 0 )
1460 const QDomElement homePathElement = homePathNl.at( 0 ).toElement();
1461 const QString
homePath = homePathElement.attribute( QStringLiteral(
"path" ) );
1471 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorGreenPart" ), 255 ),
1472 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorBluePart" ), 255 ) );
1475 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorGreenPart" ), 255 ),
1476 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorBluePart" ), 255 ),
1477 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorAlphaPart" ), 255 ) );
1486 if (
readNumEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectionsEnabled" ), 0 ) )
1489 const QDomNode srsNode = doc->documentElement().namedItem( QStringLiteral(
"projectCrs" ) );
1490 if ( !srsNode.isNull() )
1492 projectCrs.
readXml( srsNode );
1497 const QString projCrsString =
readEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCRSProj4String" ) );
1498 const long currentCRS =
readNumEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCRSID" ), -1 );
1499 const QString authid =
readEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCrs" ) );
1502 const bool isUserAuthId = authid.startsWith( QLatin1String(
"USER:" ), Qt::CaseInsensitive );
1503 if ( !authid.isEmpty() && !isUserAuthId )
1507 if ( !projectCrs.
isValid() && currentCRS >= 0 )
1513 if ( !projCrsString.isEmpty() && ( authid.isEmpty() || isUserAuthId ) && ( !projectCrs.
isValid() || projectCrs.
toProj() != projCrsString ) )
1527 QStringList datumErrors;
1528 if ( !mTransformContext.
readXml( doc->documentElement(), context, datumErrors ) && !datumErrors.empty() )
1536 const QStringList variableNames =
readListEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableNames" ) );
1537 const QStringList variableValues =
readListEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableValues" ) );
1539 mCustomVariables.clear();
1540 if ( variableNames.length() == variableValues.length() )
1542 for (
int i = 0; i < variableNames.length(); ++i )
1544 mCustomVariables.insert( variableNames.at( i ), variableValues.at( i ) );
1549 QgsMessageLog::logMessage( tr(
"Project Variables Invalid" ), tr(
"The project contains invalid variable settings." ) );
1552 QDomElement element = doc->documentElement().firstChildElement( QStringLiteral(
"projectMetadata" ) );
1554 if ( !element.isNull() )
1563 if ( mMetadata.
title().isEmpty() && !oldTitle.isEmpty() )
1570 element = doc->documentElement().firstChildElement( QStringLiteral(
"autotransaction" ) );
1571 if ( ! element.isNull() )
1573 if ( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
1574 mAutoTransaction =
true;
1577 element = doc->documentElement().firstChildElement( QStringLiteral(
"evaluateDefaultValues" ) );
1578 if ( !element.isNull() )
1580 if ( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
1581 mEvaluateDefaultValues =
true;
1585 element = doc->documentElement().firstChildElement( QStringLiteral(
"trust" ) );
1586 if ( !element.isNull() )
1588 if ( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
1589 mTrustLayerMetadata =
true;
1593 profile.switchTask( tr(
"Loading layer tree" ) );
1596 QDomElement layerTreeElem = doc->documentElement().firstChildElement( QStringLiteral(
"layer-tree-group" ) );
1597 if ( !layerTreeElem.isNull() )
1609 mLayerTreeRegistryBridge->
setEnabled(
false );
1612 profile.switchTask( tr(
"Reading map layers" ) );
1614 QList<QDomNode> brokenNodes;
1615 const bool clean = _getMapLayers( *doc, brokenNodes, flags );
1620 QgsDebugMsg( QStringLiteral(
"Unable to get map layers from project file." ) );
1622 if ( !brokenNodes.isEmpty() )
1624 QgsDebugMsg(
"there are " + QString::number( brokenNodes.size() ) +
" broken layers" );
1632 mMainAnnotationLayer->
readLayerXml( doc->documentElement().firstChildElement( QStringLiteral(
"main-annotation-layer" ) ), context );
1636 profile.switchTask( tr(
"Loading embedded layers" ) );
1637 loadEmbeddedNodes( mRootGroup, flags );
1641 profile.switchTask( tr(
"Resolving layer references" ) );
1642 QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
1643 for ( QMap<QString, QgsMapLayer *>::iterator it =
layers.begin(); it !=
layers.end(); ++it )
1645 it.value()->resolveReferences(
this );
1648 mLayerTreeRegistryBridge->
setEnabled(
true );
1651 profile.switchTask( tr(
"Resolving references" ) );
1654 if ( !layerTreeElem.isNull() )
1660 const QDomElement layerTreeCanvasElem = doc->documentElement().firstChildElement( QStringLiteral(
"layer-tree-canvas" ) );
1661 if ( !layerTreeCanvasElem.isNull( ) )
1669 const QStringList requiredLayerIds =
readListEntry( QStringLiteral(
"RequiredLayers" ), QStringLiteral(
"Layers" ) );
1670 for (
const QString &layerId : requiredLayerIds )
1677 const QStringList disabledLayerIds =
readListEntry( QStringLiteral(
"Identify" ), QStringLiteral(
"/disabledLayers" ) );
1678 for (
const QString &layerId : disabledLayerIds )
1692 profile.switchTask( tr(
"Storing original layer properties" ) );
1698 profile.switchTask( tr(
"Loading map themes" ) );
1701 mMapThemeCollection->readXml( *doc );
1703 profile.switchTask( tr(
"Loading label settings" ) );
1704 mLabelingEngineSettings->readSettingsFromProject(
this );
1707 profile.switchTask( tr(
"Loading annotations" ) );
1708 mAnnotationManager->readXml( doc->documentElement(), context );
1711 profile.switchTask( tr(
"Loading layouts" ) );
1712 mLayoutManager->readXml( doc->documentElement(), *doc );
1714 profile.switchTask( tr(
"Loading bookmarks" ) );
1715 mBookmarkManager->
readXml( doc->documentElement(), *doc );
1718 QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
1719 for ( QMap<QString, QgsMapLayer *>::iterator it = existingMaps.begin(); it != existingMaps.end(); ++it )
1721 it.value()->setDependencies( it.value()->dependencies() );
1724 profile.switchTask( tr(
"Loading snapping settings" ) );
1728 profile.switchTask( tr(
"Loading view settings" ) );
1731 const QStringList scales =
readListEntry( QStringLiteral(
"Scales" ), QStringLiteral(
"/ScalesList" ) );
1732 QVector<double> res;
1733 for (
const QString &scale : scales )
1735 const QStringList parts = scale.split(
':' );
1736 if ( parts.size() != 2 )
1740 const double denominator = QLocale().toDouble( parts[1], &ok );
1747 const QDomElement viewSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectViewSettings" ) );
1748 if ( !viewSettingsElement.isNull() )
1749 mViewSettings->
readXml( viewSettingsElement, context );
1752 profile.switchTask( tr(
"Loading temporal settings" ) );
1753 const QDomElement timeSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectTimeSettings" ) );
1754 if ( !timeSettingsElement.isNull() )
1755 mTimeSettings->
readXml( timeSettingsElement, context );
1757 profile.switchTask( tr(
"Loading display settings" ) );
1758 const QDomElement displaySettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectDisplaySettings" ) );
1759 if ( !displaySettingsElement.isNull() )
1760 mDisplaySettings->
readXml( displaySettingsElement, context );
1762 profile.switchTask( tr(
"Updating variables" ) );
1764 profile.switchTask( tr(
"Updating CRS" ) );
1769 profile.switchTask( tr(
"Reading external settings" ) );
1773 profile.switchTask( tr(
"Updating interface" ) );
1775 snapSignalBlock.release();
1776 if ( !mBlockSnappingUpdates )
1787 QgsDebugMsgLevel( QString(
"Project save user: %1" ).arg( mSaveUser ), 2 );
1788 QgsDebugMsgLevel( QString(
"Project save user: %1" ).arg( mSaveUserFull ), 2 );
1797 const QString newFileName( QStringLiteral(
"%1/%2.qgs" ).arg( QFileInfo( projectFile.fileName() ).absolutePath(), localeFileName ) );
1803 QgsMessageLog::logMessage( tr(
"Translated project saved with locale prefix %1" ).arg( newFileName ), QObject::tr(
"Project translation" ), Qgis::MessageLevel::Success );
1807 QgsMessageLog::logMessage( tr(
"Error saving translated project with locale prefix %1" ).arg( newFileName ), QObject::tr(
"Project translation" ), Qgis::MessageLevel::Critical );
1814 bool QgsProject::loadEmbeddedNodes(
QgsLayerTreeGroup *group, QgsProject::ReadFlags flags )
1817 const auto constChildren = group->
children();
1823 if ( childGroup->
customProperty( QStringLiteral(
"embedded" ) ).toInt() )
1826 const QString projectPath =
readPath( childGroup->
customProperty( QStringLiteral(
"embedded_project" ) ).toString() );
1827 childGroup->
setCustomProperty( QStringLiteral(
"embedded_project" ), projectPath );
1831 QList<QgsLayerTreeNode *> clonedChildren;
1832 const auto constChildren = newGroup->
children();
1834 clonedChildren << newGroupChild->clone();
1842 loadEmbeddedNodes( childGroup, flags );
1847 if ( child->customProperty( QStringLiteral(
"embedded" ) ).toInt() )
1849 QList<QDomNode> brokenNodes;
1852 valid = valid &&
false;
1864 return mCustomVariables;
1869 if ( variables == mCustomVariables )
1873 QStringList variableNames;
1874 QStringList variableValues;
1876 QVariantMap::const_iterator it = variables.constBegin();
1877 for ( ; it != variables.constEnd(); ++it )
1879 variableNames << it.key();
1880 variableValues << it.value().toString();
1883 writeEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableNames" ), variableNames );
1884 writeEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableValues" ), variableValues );
1886 mCustomVariables = variables;
1887 mProjectScope.reset();
1894 *mLabelingEngineSettings = settings;
1900 return *mLabelingEngineSettings;
1905 mProjectScope.reset();
1906 return mLayerStore.get();
1911 return mLayerStore.get();
1916 QList<QgsVectorLayer *>
layers;
1917 const QStringList layerIds =
readListEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsList" ), QStringList() );
1918 const auto constLayerIds = layerIds;
1919 for (
const QString &layerId : constLayerIds )
1930 const auto constLayers =
layers;
1932 list << layer->id();
1933 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsList" ), list );
1950 if ( mProjectScope )
1952 std::unique_ptr< QgsExpressionContextScope > projectScope = std::make_unique< QgsExpressionContextScope >( *mProjectScope );
1956 return projectScope.release();
1959 mProjectScope = std::make_unique< QgsExpressionContextScope >( QObject::tr(
"Project" ) );
1963 QVariantMap::const_iterator it = vars.constBegin();
1965 for ( ; it != vars.constEnd(); ++it )
1967 mProjectScope->setVariable( it.key(), it.value(),
true );
1971 if ( projectPath.isEmpty() )
1972 projectPath = mOriginalPath;
1973 const QString projectFolder = QFileInfo( projectPath ).path();
1974 const QString projectFilename = QFileInfo( projectPath ).fileName();
1975 const QString projectBasename =
baseName();
2004 QVariantMap keywords;
2006 for (
auto it = metadataKeywords.constBegin(); it != metadataKeywords.constEnd(); ++it )
2008 keywords.insert( it.key(), it.value() );
2013 QVariantList layersIds;
2015 const QMap<QString, QgsMapLayer *> layersInProject = mLayerStore->mapLayers();
2016 layersIds.reserve( layersInProject.count() );
2017 layers.reserve( layersInProject.count() );
2018 for (
auto it = layersInProject.constBegin(); it != layersInProject.constEnd(); ++it )
2020 layersIds << it.value()->id();
2026 mProjectScope->addFunction( QStringLiteral(
"project_color" ),
new GetNamedProjectColor(
this ) );
2031 void QgsProject::onMapLayersAdded(
const QList<QgsMapLayer *> &layers )
2033 const QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
2035 bool tgChanged =
false;
2037 const auto constLayers =
layers;
2040 if ( layer->isValid() )
2042 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
2049 const QString connString = QgsTransaction::connectionString( vlayer->
source() );
2057 mTransactionGroups.insert( qMakePair( key, connString ), tg );
2072 for ( QMap<QString, QgsMapLayer *>::const_iterator it = existingMaps.cbegin(); it != existingMaps.cend(); ++it )
2074 const QSet<QgsMapLayerDependency> deps = it.value()->dependencies();
2075 if ( deps.contains( layer->id() ) )
2078 it.value()->setDependencies( deps );
2088 void QgsProject::onMapLayersRemoved(
const QList<QgsMapLayer *> &layers )
2094 void QgsProject::cleanTransactionGroups(
bool force )
2096 bool changed =
false;
2097 for ( QMap< QPair< QString, QString>,
QgsTransactionGroup *>::Iterator tg = mTransactionGroups.begin(); tg != mTransactionGroups.end(); )
2099 if ( tg.value()->
isEmpty() || force )
2102 tg = mTransactionGroups.erase( tg );
2120 QList<QDomNode> brokenNodes;
2121 if ( addLayer( layerNode.toElement(), brokenNodes, context ) )
2125 const QVector<QgsVectorLayer *> vectorLayers = layers<QgsVectorLayer *>();
2126 const auto constVectorLayers = vectorLayers;
2130 layer->resolveReferences(
this );
2140 mFile.setFileName( filename );
2141 mCachedHomePath.clear();
2147 mProjectScope.reset();
2153 const QString storageFilePath { storage->filePath( mFile.fileName() ) };
2154 if ( storageFilePath.isEmpty() )
2160 const QString tempPath = QStandardPaths::standardLocations( QStandardPaths::TempLocation ).at( 0 );
2161 const QString tmpZipFilename( tempPath + QDir::separator() + QUuid::createUuid().toString() );
2163 if ( !zip( tmpZipFilename ) )
2166 QFile tmpZipFile( tmpZipFilename );
2167 if ( !tmpZipFile.open( QIODevice::ReadOnly ) )
2169 setError( tr(
"Unable to read file %1" ).arg( tmpZipFilename ) );
2174 if ( !storage->writeProject( mFile.fileName(), &tmpZipFile, context ) )
2176 QString err = tr(
"Unable to save project to storage %1" ).arg( mFile.fileName() );
2177 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
2178 if ( !messages.isEmpty() )
2179 err += QStringLiteral(
"\n\n" ) + messages.last().message();
2185 QFile::remove( tmpZipFilename );
2192 return zip( mFile.fileName() );
2198 const bool asOk = saveAuxiliaryStorage();
2199 const bool writeOk = writeProjectFile( mFile.fileName() );
2200 bool attachmentsOk =
true;
2201 if ( !mArchive->files().isEmpty() )
2203 const QFileInfo finfo( mFile.fileName() );
2204 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( QStringLiteral(
"%1_attachments.zip" ).arg( finfo.completeBaseName() ) );
2205 attachmentsOk = mArchive->zip( attachmentsZip );
2209 if ( ( !asOk || !attachmentsOk ) && writeOk )
2211 QStringList errorMessage;
2214 const QString err = mAuxiliaryStorage->errorString();
2215 errorMessage.append( tr(
"Unable to save auxiliary storage ('%1')" ).arg( err ) );
2217 if ( !attachmentsOk )
2219 errorMessage.append( tr(
"Unable to save attachments archive" ) );
2221 setError( errorMessage.join(
"\n" ) );
2224 return asOk && writeOk && attachmentsOk;
2228 bool QgsProject::writeProjectFile(
const QString &filename )
2230 QFile projectFile( filename );
2236 const QFileInfo myFileInfo( projectFile );
2237 if ( myFileInfo.exists() && !myFileInfo.isWritable() )
2239 setError( tr(
"%1 is not writable. Please adjust permissions (if possible) and try again." )
2240 .arg( projectFile.fileName() ) );
2248 QDomImplementation DomImplementation;
2249 DomImplementation.setInvalidDataPolicy( QDomImplementation::DropInvalidChars );
2251 const QDomDocumentType documentType =
2252 DomImplementation.createDocumentType( QStringLiteral(
"qgis" ), QStringLiteral(
"http://mrcc.com/qgis.dtd" ),
2253 QStringLiteral(
"SYSTEM" ) );
2254 std::unique_ptr<QDomDocument> doc(
new QDomDocument( documentType ) );
2256 QDomElement qgisNode = doc->createElement( QStringLiteral(
"qgis" ) );
2257 qgisNode.setAttribute( QStringLiteral(
"projectname" ),
title() );
2258 qgisNode.setAttribute( QStringLiteral(
"version" ),
Qgis::version() );
2260 if ( !mSettings.
value( QStringLiteral(
"projects/anonymize_saved_projects" ),
false,
QgsSettings::Core ).toBool() )
2264 qgisNode.setAttribute( QStringLiteral(
"saveUser" ), newSaveUser );
2265 qgisNode.setAttribute( QStringLiteral(
"saveUserFull" ), newSaveUserFull );
2266 mSaveUser = newSaveUser;
2267 mSaveUserFull = newSaveUserFull;
2268 mSaveDateTime = QDateTime::currentDateTime();
2269 qgisNode.setAttribute( QStringLiteral(
"saveDateTime" ), mSaveDateTime.toString( Qt::ISODate ) );
2274 mSaveUserFull.clear();
2275 mSaveDateTime = QDateTime();
2277 doc->appendChild( qgisNode );
2280 QDomElement homePathNode = doc->createElement( QStringLiteral(
"homePath" ) );
2281 homePathNode.setAttribute( QStringLiteral(
"path" ), mHomePath );
2282 qgisNode.appendChild( homePathNode );
2285 QDomElement titleNode = doc->createElement( QStringLiteral(
"title" ) );
2286 qgisNode.appendChild( titleNode );
2288 QDomElement transactionNode = doc->createElement( QStringLiteral(
"autotransaction" ) );
2289 transactionNode.setAttribute( QStringLiteral(
"active" ), mAutoTransaction ? 1 : 0 );
2290 qgisNode.appendChild( transactionNode );
2292 QDomElement evaluateDefaultValuesNode = doc->createElement( QStringLiteral(
"evaluateDefaultValues" ) );
2293 evaluateDefaultValuesNode.setAttribute( QStringLiteral(
"active" ), mEvaluateDefaultValues ? 1 : 0 );
2294 qgisNode.appendChild( evaluateDefaultValuesNode );
2296 QDomElement trustNode = doc->createElement( QStringLiteral(
"trust" ) );
2297 trustNode.setAttribute( QStringLiteral(
"active" ), mTrustLayerMetadata ? 1 : 0 );
2298 qgisNode.appendChild( trustNode );
2300 const QDomText titleText = doc->createTextNode(
title() );
2301 titleNode.appendChild( titleText );
2304 QDomElement srsNode = doc->createElement( QStringLiteral(
"projectCrs" ) );
2306 qgisNode.appendChild( srsNode );
2313 clonedRoot->
writeXml( qgisNode, context );
2317 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsMode" ),
static_cast<int>( mAvoidIntersectionsMode ) );
2325 QDomElement annotationLayerNode = doc->createElement( QStringLiteral(
"main-annotation-layer" ) );
2326 mMainAnnotationLayer->
writeLayerXml( annotationLayerNode, *doc, context );
2327 qgisNode.appendChild( annotationLayerNode );
2331 QDomElement projectLayersNode = doc->createElement( QStringLiteral(
"projectlayers" ) );
2333 QMap<QString, QgsMapLayer *>::ConstIterator li =
layers.constBegin();
2334 while ( li !=
layers.end() )
2340 const QHash< QString, QPair< QString, bool> >::const_iterator emIt = mEmbeddedLayers.constFind( ml->
id() );
2341 if ( emIt == mEmbeddedLayers.constEnd() )
2343 QDomElement maplayerElem;
2349 maplayerElem = doc->createElement( QStringLiteral(
"maplayer" ) );
2354 QDomDocument document;
2357 maplayerElem = document.firstChildElement();
2361 QgsDebugMsg( QStringLiteral(
"Could not restore layer properties for layer %1" ).arg( ml->
id() ) );
2367 projectLayersNode.appendChild( maplayerElem );
2373 if ( emIt.value().second )
2375 QDomElement mapLayerElem = doc->createElement( QStringLiteral(
"maplayer" ) );
2376 mapLayerElem.setAttribute( QStringLiteral(
"embedded" ), 1 );
2377 mapLayerElem.setAttribute( QStringLiteral(
"project" ),
writePath( emIt.value().first ) );
2378 mapLayerElem.setAttribute( QStringLiteral(
"id" ), ml->
id() );
2379 projectLayersNode.appendChild( mapLayerElem );
2386 qgisNode.appendChild( projectLayersNode );
2388 QDomElement layerOrderNode = doc->createElement( QStringLiteral(
"layerorder" ) );
2390 for (
QgsMapLayer *layer : constCustomLayerOrder )
2392 QDomElement mapLayerElem = doc->createElement( QStringLiteral(
"layer" ) );
2393 mapLayerElem.setAttribute( QStringLiteral(
"id" ), layer->id() );
2394 layerOrderNode.appendChild( mapLayerElem );
2396 qgisNode.appendChild( layerOrderNode );
2398 mLabelingEngineSettings->writeSettingsToProject(
this );
2400 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorRedPart" ), mBackgroundColor.red() );
2401 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorGreenPart" ), mBackgroundColor.green() );
2402 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorBluePart" ), mBackgroundColor.blue() );
2404 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorRedPart" ), mSelectionColor.red() );
2405 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorGreenPart" ), mSelectionColor.green() );
2406 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorBluePart" ), mSelectionColor.blue() );
2407 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorAlphaPart" ), mSelectionColor.alpha() );
2411 dump_( mProperties );
2414 QgsDebugMsgLevel( QStringLiteral(
"there are %1 property scopes" ).arg(
static_cast<int>( mProperties.
count() ) ), 2 );
2419 mProperties.
writeXml( QStringLiteral(
"properties" ), qgisNode, *doc );
2422 QDomElement ddElem = doc->createElement( QStringLiteral(
"dataDefinedServerProperties" ) );
2423 mDataDefinedServerProperties.
writeXml( ddElem, dataDefinedServerPropertyDefinitions() );
2424 qgisNode.appendChild( ddElem );
2426 mMapThemeCollection->writeXml( *doc );
2428 mTransformContext.
writeXml( qgisNode, context );
2430 QDomElement metadataElem = doc->createElement( QStringLiteral(
"projectMetadata" ) );
2432 qgisNode.appendChild( metadataElem );
2434 const QDomElement annotationsElem = mAnnotationManager->writeXml( *doc, context );
2435 qgisNode.appendChild( annotationsElem );
2437 const QDomElement layoutElem = mLayoutManager->writeXml( *doc );
2438 qgisNode.appendChild( layoutElem );
2440 const QDomElement bookmarkElem = mBookmarkManager->
writeXml( *doc );
2441 qgisNode.appendChild( bookmarkElem );
2443 const QDomElement viewSettingsElem = mViewSettings->
writeXml( *doc, context );
2444 qgisNode.appendChild( viewSettingsElem );
2446 const QDomElement timeSettingsElement = mTimeSettings->
writeXml( *doc, context );
2447 qgisNode.appendChild( timeSettingsElement );
2449 const QDomElement displaySettingsElem = mDisplaySettings->
writeXml( *doc, context );
2450 qgisNode.appendChild( displaySettingsElem );
2458 QFile backupFile( QStringLiteral(
"%1~" ).arg( filename ) );
2460 ok &= backupFile.open( QIODevice::WriteOnly | QIODevice::Truncate );
2461 ok &= projectFile.open( QIODevice::ReadOnly );
2464 while ( ok && !projectFile.atEnd() )
2466 ba = projectFile.read( 10240 );
2467 ok &= backupFile.write( ba ) == ba.size();
2470 projectFile.close();
2475 setError( tr(
"Unable to create backup file %1" ).arg( backupFile.fileName() ) );
2480 struct utimbuf tb = {
static_cast<time_t
>( fi.lastRead().toSecsSinceEpoch() ),
static_cast<time_t
>( fi.lastModified().toSecsSinceEpoch() ) };
2481 utime( backupFile.fileName().toUtf8().constData(), &tb );
2484 if ( !projectFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
2486 projectFile.close();
2489 setError( tr(
"Unable to save to file %1" ).arg( projectFile.fileName() ) );
2493 QTemporaryFile tempFile;
2494 bool ok = tempFile.open();
2497 QTextStream projectFileStream( &tempFile );
2498 doc->save( projectFileStream, 2 );
2499 ok &= projectFileStream.pos() > -1;
2501 ok &= tempFile.seek( 0 );
2504 while ( ok && !tempFile.atEnd() )
2506 ba = tempFile.read( 10240 );
2507 ok &= projectFile.write( ba ) == ba.size();
2510 ok &= projectFile.error() == QFile::NoError;
2512 projectFile.close();
2519 setError( tr(
"Unable to save to file %1. Your project "
2520 "may be corrupted on disk. Try clearing some space on the volume and "
2521 "check file permissions before pressing save again." )
2522 .arg( projectFile.fileName() ) );
2534 bool propertiesModified;
2535 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
2537 if ( propertiesModified )
2545 bool propertiesModified;
2546 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
2548 if ( propertiesModified )
2556 bool propertiesModified;
2557 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
2559 if ( propertiesModified )
2567 bool propertiesModified;
2568 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
2570 if ( propertiesModified )
2578 bool propertiesModified;
2579 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
2581 if ( propertiesModified )
2589 const QStringList &def,
2598 value =
property->value();
2600 const bool valid = QVariant::StringList == value.type();
2606 return value.toStringList();
2628 value =
property->value();
2630 const bool valid = value.canConvert( QVariant::String );
2635 return value.toString();
2652 value =
property->value();
2655 const bool valid = value.canConvert( QVariant::Int );
2664 return value.toInt();
2677 const QVariant value =
property->value();
2679 const bool valid = value.canConvert( QVariant::Double );
2684 return value.toDouble();
2699 const QVariant value =
property->value();
2701 const bool valid = value.canConvert( QVariant::Bool );
2706 return value.toBool();
2716 if (
findKey_( scope, key, mProperties ) )
2722 return !
findKey_( scope, key, mProperties );
2730 QStringList entries;
2732 if ( foundProperty )
2747 QStringList entries;
2749 if ( foundProperty )
2762 dump_( mProperties );
2780 filePath = storage->filePath( mFile.fileName() );
2803 void QgsProject::setError(
const QString &errorMessage )
2805 mErrorMessage = errorMessage;
2810 return mErrorMessage;
2813 void QgsProject::clearError()
2815 setError( QString() );
2820 delete mBadLayerHandler;
2821 mBadLayerHandler = handler;
2826 const QHash< QString, QPair< QString, bool > >::const_iterator it = mEmbeddedLayers.find(
id );
2827 if ( it == mEmbeddedLayers.constEnd() )
2831 return it.value().first;
2835 bool saveFlag, QgsProject::ReadFlags flags )
2839 static QString sPrevProjectFilePath;
2840 static QDateTime sPrevProjectFileTimestamp;
2841 static QDomDocument sProjectDocument;
2843 QString qgsProjectFile = projectFilePath;
2845 if ( projectFilePath.endsWith( QLatin1String(
".qgz" ), Qt::CaseInsensitive ) )
2847 archive.
unzip( projectFilePath );
2851 const QDateTime projectFileTimestamp = QFileInfo( projectFilePath ).lastModified();
2853 if ( projectFilePath != sPrevProjectFilePath || projectFileTimestamp != sPrevProjectFileTimestamp )
2855 sPrevProjectFilePath.clear();
2857 QFile projectFile( qgsProjectFile );
2858 if ( !projectFile.open( QIODevice::ReadOnly ) )
2863 if ( !sProjectDocument.setContent( &projectFile ) )
2868 sPrevProjectFilePath = projectFilePath;
2869 sPrevProjectFileTimestamp = projectFileTimestamp;
2873 bool useAbsolutePaths =
true;
2875 const QDomElement propertiesElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral(
"properties" ) );
2876 if ( !propertiesElem.isNull() )
2878 const QDomElement absElem = propertiesElem.firstChildElement( QStringLiteral(
"Paths" ) ).firstChildElement( QStringLiteral(
"Absolute" ) );
2879 if ( !absElem.isNull() )
2881 useAbsolutePaths = absElem.text().compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0;
2886 if ( !useAbsolutePaths )
2891 const QDomElement projectLayersElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral(
"projectlayers" ) );
2892 if ( projectLayersElem.isNull() )
2897 QDomElement mapLayerElem = projectLayersElem.firstChildElement( QStringLiteral(
"maplayer" ) );
2898 while ( ! mapLayerElem.isNull() )
2901 const QString
id = mapLayerElem.firstChildElement( QStringLiteral(
"id" ) ).text();
2902 if (
id == layerId )
2905 if ( mapLayerElem.attribute( QStringLiteral(
"embedded" ) ) == QLatin1String(
"1" ) )
2910 mEmbeddedLayers.insert( layerId, qMakePair( projectFilePath, saveFlag ) );
2912 if ( addLayer( mapLayerElem, brokenNodes, embeddedContext, flags ) )
2918 mEmbeddedLayers.remove( layerId );
2922 mapLayerElem = mapLayerElem.nextSiblingElement( QStringLiteral(
"maplayer" ) );
2931 QString qgsProjectFile = projectFilePath;
2933 if ( projectFilePath.endsWith( QLatin1String(
".qgz" ), Qt::CaseInsensitive ) )
2935 archive.
unzip( projectFilePath );
2940 QFile projectFile( qgsProjectFile );
2941 if ( !projectFile.open( QIODevice::ReadOnly ) )
2946 QDomDocument projectDocument;
2947 if ( !projectDocument.setContent( &projectFile ) )
2959 QDomElement layerTreeElem = projectDocument.documentElement().firstChildElement( QStringLiteral(
"layer-tree-group" ) );
2960 if ( !layerTreeElem.isNull() )
2970 if ( !group || group->
customProperty( QStringLiteral(
"embedded" ) ).toBool() )
2983 newGroup->
setCustomProperty( QStringLiteral(
"embedded_project" ), projectFilePath );
2986 mLayerTreeRegistryBridge->
setEnabled(
false );
2987 initializeEmbeddedSubtree( projectFilePath, newGroup, flags );
2988 mLayerTreeRegistryBridge->
setEnabled(
true );
2991 const auto constFindLayerIds = newGroup->
findLayerIds();
2992 for (
const QString &layerId : constFindLayerIds )
3005 void QgsProject::initializeEmbeddedSubtree(
const QString &projectFilePath,
QgsLayerTreeGroup *group, QgsProject::ReadFlags flags )
3007 const auto constChildren = group->
children();
3011 child->setCustomProperty( QStringLiteral(
"embedded" ), 1 );
3020 QList<QDomNode> brokenNodes;
3028 return mEvaluateDefaultValues;
3037 QMap<QString, QgsMapLayer *>::const_iterator layerIt =
layers.constBegin();
3038 for ( ; layerIt !=
layers.constEnd(); ++layerIt )
3040 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layerIt.value() );
3052 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/TopologicalEditing" ), ( enabled ? 1 : 0 ) );
3058 return readNumEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/TopologicalEditing" ), 0 );
3063 const QString distanceUnitString =
readEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/DistanceUnits" ), QString() );
3064 if ( !distanceUnitString.isEmpty() )
3080 const QString areaUnitString =
readEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/AreaUnits" ), QString() );
3081 if ( !areaUnitString.isEmpty() )
3097 if ( !mCachedHomePath.isEmpty() )
3098 return mCachedHomePath;
3102 if ( !mHomePath.isEmpty() )
3104 const QFileInfo homeInfo( mHomePath );
3105 if ( !homeInfo.isRelative() )
3107 mCachedHomePath = mHomePath;
3113 mCachedHomePath = pfi.path();
3115 return mCachedHomePath;
3118 if ( !pfi.exists() )
3120 mCachedHomePath = mHomePath;
3124 if ( !mHomePath.isEmpty() )
3127 mCachedHomePath = QDir::cleanPath( pfi.path() +
'/' + mHomePath );
3131 mCachedHomePath = pfi.canonicalPath();
3133 return mCachedHomePath;
3143 return mRelationManager;
3148 return mLayoutManager.get();
3153 return mLayoutManager.get();
3158 return mBookmarkManager;
3163 return mBookmarkManager;
3168 return mViewSettings;
3173 return mViewSettings;
3178 return mTimeSettings;
3183 return mTimeSettings;
3188 return mDisplaySettings;
3193 return mDisplaySettings;
3203 return mMapThemeCollection.get();
3208 return mAnnotationManager.get();
3213 return mAnnotationManager.get();
3218 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
3219 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
3224 if (
layers.contains( it.value() ) )
3239 for (
const QString &layerId : layerIds )
3255 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
3267 return mAutoTransaction;
3277 onMapLayersAdded(
mapLayers().values() );
3279 cleanTransactionGroups(
true );
3285 return mTransactionGroups;
3296 return mLayerStore->count();
3301 return mLayerStore->validCount();
3306 return mLayerStore->mapLayer( layerId );
3311 return mLayerStore->mapLayersByName( layerName );
3316 QList<QgsMapLayer *>
layers;
3317 const auto constMapLayers { mLayerStore->mapLayers() };
3318 for (
const auto &l : constMapLayers )
3320 if ( ! l->shortName().isEmpty() )
3322 if ( l->shortName() == shortName )
3325 else if ( l->name() == shortName )
3333 bool QgsProject::unzip(
const QString &filename, QgsProject::ReadFlags flags )
3339 if ( !archive->unzip( filename ) )
3341 setError( tr(
"Unable to unzip file '%1'" ).arg( filename ) );
3346 if ( archive->projectFile().isEmpty() )
3348 setError( tr(
"Zip archive does not provide a project file" ) );
3353 mArchive = std::move( archive );
3370 setError( tr(
"Cannot read unzipped qgs project file" ) );
3380 bool QgsProject::zip(
const QString &filename )
3386 const QString
baseName = QFileInfo( filename ).baseName();
3387 const QString qgsFileName = QStringLiteral(
"%1.qgs" ).arg(
baseName );
3388 QFile qgsFile( QDir( archive->dir() ).filePath( qgsFileName ) );
3390 bool writeOk =
false;
3391 if ( qgsFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
3393 writeOk = writeProjectFile( qgsFile.fileName() );
3400 setError( tr(
"Unable to write temporary qgs file" ) );
3405 const QFileInfo info( qgsFile );
3407 const QString asFileName = info.path() + QDir::separator() + info.completeBaseName() + asExt;
3409 bool auxiliaryStorageSavedOk =
true;
3410 if ( ! saveAuxiliaryStorage( asFileName ) )
3412 const QString err = mAuxiliaryStorage->errorString();
3413 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 ) );
3414 auxiliaryStorageSavedOk =
false;
3417 if ( !mArchive->exists() )
3420 mArchive->unzip( mFile.fileName() );
3423 const QString auxiliaryStorageFile =
static_cast<QgsProjectArchive *
>( mArchive.get() )->auxiliaryStorageFile();
3424 if ( ! auxiliaryStorageFile.isEmpty() )
3426 archive->
addFile( auxiliaryStorageFile );
3435 if ( QFile::exists( asFileName ) )
3437 archive->addFile( asFileName );
3442 archive->addFile( qgsFile.fileName() );
3445 const QStringList &files = mArchive->files();
3446 for (
const QString &file : files )
3448 if ( !file.endsWith(
".qgs", Qt::CaseInsensitive ) && !file.endsWith( asExt, Qt::CaseInsensitive ) )
3450 archive->addFile( file );
3456 if ( !archive->zip( filename ) )
3458 setError( tr(
"Unable to perform zip" ) );
3462 return auxiliaryStorageSavedOk && zipOk;
3471 const QList<QgsMapLayer *> &layers,
3473 bool takeOwnership )
3475 const QList<QgsMapLayer *> myResultList { mLayerStore->addMapLayers(
layers, takeOwnership ) };
3476 if ( !myResultList.isEmpty() )
3479 for (
auto &l : myResultList )
3489 if ( mAuxiliaryStorage )
3504 mProjectScope.reset();
3506 return myResultList;
3512 bool takeOwnership )
3514 QList<QgsMapLayer *> addedLayers;
3515 addedLayers =
addMapLayers( QList<QgsMapLayer *>() << layer, addToLegend, takeOwnership );
3516 return addedLayers.isEmpty() ? nullptr : addedLayers[0];
3521 mProjectScope.reset();
3522 mLayerStore->removeMapLayers( layerIds );
3527 mProjectScope.reset();
3528 mLayerStore->removeMapLayers(
layers );
3533 mProjectScope.reset();
3534 mLayerStore->removeMapLayer( layerId );
3539 mProjectScope.reset();
3540 mLayerStore->removeMapLayer( layer );
3545 mProjectScope.reset();
3546 return mLayerStore->takeMapLayer( layer );
3551 return mMainAnnotationLayer;
3556 if ( mLayerStore->count() == 0 )
3559 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
3560 mProjectScope.reset();
3561 mLayerStore->removeAllMapLayers();
3563 snapSingleBlocker.release();
3565 if ( !mBlockSnappingUpdates )
3571 const QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
3572 QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin();
3573 for ( ; it !=
layers.constEnd(); ++it )
3575 it.value()->reload();
3581 return validOnly ? mLayerStore->validMapLayers() : mLayerStore->mapLayers();
3586 return mTransactionGroups.value( qMakePair( providerKey, connString ) );
3595 if ( mSettings.
value( QStringLiteral(
"/projections/unknownCrsBehavior" ), QStringLiteral(
"NoAction" ),
QgsSettings::App ).toString() == QStringLiteral(
"UseProjectCrs" )
3596 || mSettings.
value( QStringLiteral(
"/projections/unknownCrsBehavior" ), 0,
QgsSettings::App ).toString() == QLatin1String(
"2" ) )
3604 const QString layerDefaultCrs = mSettings.
value( QStringLiteral(
"/Projections/layerDefaultCrs" ),
geoEpsgCrsAuthId() ).toString();
3613 mTrustLayerMetadata = trust;
3616 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
3618 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() );
3626 bool QgsProject::saveAuxiliaryStorage(
const QString &filename )
3630 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
3635 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() );
3643 if ( !mAuxiliaryStorage->exists( *
this ) && empty )
3647 else if ( !filename.isEmpty() )
3649 return mAuxiliaryStorage->saveAs( filename );
3653 return mAuxiliaryStorage->saveAs( *
this );
3662 QgsProject::DataDefinedServerProperty::WMSOnlineResource,
3666 return sPropertyDefinitions;
3671 return mAuxiliaryStorage.get();
3676 return mAuxiliaryStorage.get();
3681 const QString
fileName = nameTemplate;
3682 const QDir archiveDir( mArchive->dir() );
3683 QTemporaryFile tmpFile( archiveDir.filePath(
"XXXXXX_" + nameTemplate ),
this );
3684 tmpFile.setAutoRemove(
false );
3686 mArchive->addFile( tmpFile.fileName() );
3687 return tmpFile.fileName();
3692 QStringList attachments;
3694 for (
const QString &file : mArchive->files() )
3698 attachments.append( file );
3706 return mArchive->removeFile( path );
3711 return QStringLiteral(
"attachment:///%1" ).arg( QFileInfo( attachedFile ).
fileName() );
3716 if ( identifier.startsWith(
"attachment:///" ) )
3718 return QDir( mArchive->dir() ).absoluteFilePath( identifier.mid( 14 ) );
3734 mProjectScope.reset();
3746 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
3758 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
3759 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
3764 if (
layers.contains( it.value() ) )
3774 QStringList customColors;
3775 QStringList customColorLabels;
3777 QgsNamedColorList::const_iterator colorIt = colors.constBegin();
3778 for ( ; colorIt != colors.constEnd(); ++colorIt )
3781 const QString label = ( *colorIt ).second;
3782 customColors.append( color );
3783 customColorLabels.append( label );
3785 writeEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Colors" ), customColors );
3786 writeEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Labels" ), customColorLabels );
3787 mProjectScope.reset();
3793 if ( mBackgroundColor == color )
3796 mBackgroundColor = color;
3802 return mBackgroundColor;
3807 if ( mSelectionColor == color )
3810 mSelectionColor = color;
3816 return mSelectionColor;
3850 QString
QgsProject::translate(
const QString &context,
const QString &sourceText,
const char *disambiguation,
int n )
const
3857 QString result = mTranslator->translate( context.toUtf8(), sourceText.toUtf8(), disambiguation, n );
3859 if ( result.isEmpty() )
3871 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
3876 if ( !( ( *it )->accept( visitor ) ) )
3885 if ( !mLayoutManager->accept( visitor ) )
3888 if ( !mAnnotationManager->accept( visitor ) )
3895 GetNamedProjectColor::GetNamedProjectColor(
const QgsProject *project )
3902 QStringList colorStrings = project->
readListEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Colors" ) );
3903 const QStringList colorLabels = project->
readListEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Labels" ) );
3907 for ( QStringList::iterator it = colorStrings.begin();
3908 it != colorStrings.end(); ++it )
3912 if ( colorLabels.length() > colorIndex )
3914 label = colorLabels.at( colorIndex );
3917 mColors.insert( label.toLower(), color );
3922 GetNamedProjectColor::GetNamedProjectColor(
const QHash<QString, QColor> &colors )
3930 const QString colorName = values.at( 0 ).toString().toLower();
3931 if ( mColors.contains( colorName ) )
3933 return QStringLiteral(
"%1,%2,%3" ).arg( mColors.value( colorName ).red() ).arg( mColors.value( colorName ).green() ).arg( mColors.value( colorName ).blue() );
3941 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 description() const
Returns the descriptive name of the CRS, e.g., "WGS 84" or "GDA 94 / Vicgrid94".
QString projectionAcronym() const
Returns the projection acronym for the projection used by the CRS.
static QgsCoordinateReferenceSystem fromProj(const QString &proj)
Creates a CRS from a proj style formatted string.
QString authid() const
Returns the authority identifier for the CRS.
@ 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.
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.
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 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...
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.
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 oldProjectVersionWarning(const QString &)
Emitted when an old project file is read.
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
Added in 3.18.
@ VectorTileLayer
Added in 3.14.
@ AnnotationLayer
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
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.
Contains information relating to a node (i.e.