64 #include <QApplication> 68 #include <QTextStream> 69 #include <QTemporaryFile> 75 #include <sys/utime.h> 93 QStringList keyTokens = QStringList( scope );
94 keyTokens += key.split(
'/', QString::SkipEmptyParts );
97 keyTokens.push_front( QStringLiteral(
"properties" ) );
100 for (
int i = 0; i < keyTokens.size(); ++i )
102 QString keyToken = keyTokens.at( i );
106 QString nameCharRegexp = QStringLiteral(
"[^:A-Z_a-z\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\x2FF\\x370-\\x37D\\x37F-\\x1FFF\\x200C-\\x200D\\x2070-\\x218F\\x2C00-\\x2FEF\\x3001-\\xD7FF\\xF900-\\xFDCF\\xFDF0-\\xFFFD\\-\\.0-9\\xB7\\x0300-\\x036F\\x203F-\\x2040]" );
107 QString nameStartCharRegexp = QStringLiteral(
"^[^:A-Z_a-z\\xC0-\\xD6\\xD8-\\xF6\\xF8-\\x2FF\\x370-\\x37D\\x37F-\\x1FFF\\x200C-\\x200D\\x2070-\\x218F\\x2C00-\\x2FEF\\x3001-\\xD7FF\\xF900-\\xFDCF\\xFDF0-\\xFFFD]" );
109 if ( keyToken.contains( QRegExp( nameCharRegexp ) ) || keyToken.contains( QRegExp( nameStartCharRegexp ) ) )
112 QString errorString = QObject::tr(
"Entry token invalid : '%1'. The token will not be saved to file." ).arg( keyToken );
142 while ( !keySequence.isEmpty() )
146 if ( keySequence.first() == currentProperty->
name() )
149 keySequence.pop_front();
151 if ( 1 == keySequence.count() )
154 return currentProperty->
find( keySequence.front() );
156 else if ( keySequence.isEmpty() )
161 return currentProperty;
163 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
165 if ( nextProperty->
isKey() )
169 else if ( nextProperty->
isValue() && 1 == keySequence.count() )
175 return currentProperty;
213 const QVariant &value,
214 bool &propertiesModified )
223 propertiesModified =
false;
224 while ( ! keySequence.isEmpty() )
228 if ( keySequence.first() == currentProperty->
name() )
231 keySequence.pop_front();
235 if ( 1 == keySequence.count() )
238 if ( !property || property->value() != value )
240 currentProperty->
setValue( keySequence.front(), value );
241 propertiesModified =
true;
244 return currentProperty;
248 else if ( keySequence.isEmpty() )
250 if ( currentProperty->
value() != value )
253 propertiesModified =
true;
256 return currentProperty;
258 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
262 if ( currentProperty )
273 if ( ( newPropertyKey = currentProperty->
addKey( keySequence.first() ) ) )
275 currentProperty = newPropertyKey;
308 while ( ! keySequence.isEmpty() )
312 if ( keySequence.first() == currentProperty->
name() )
315 keySequence.pop_front();
319 if ( 1 == keySequence.count() )
321 currentProperty->
removeKey( keySequence.front() );
326 else if ( keySequence.isEmpty() )
328 previousQgsPropertyKey->
removeKey( currentProperty->
name() );
330 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
332 previousQgsPropertyKey = currentProperty;
335 if ( currentProperty )
361 , mSnappingConfig( this )
373 mProperties.
setName( QStringLiteral(
"properties" ) );
405 [ = ](
const QList<QgsMapLayer *> &
layers )
407 for (
const auto &layer :
layers )
414 [ = ](
const QList<QgsMapLayer *> &
layers )
416 for (
const auto &layer :
layers )
431 mIsBeingDeleted =
true;
434 delete mBadLayerHandler;
435 delete mRelationManager;
436 delete mLayerTreeRegistryBridge;
438 if (
this == sProject )
444 void QgsProject::setInstance(
QgsProject *project )
461 if ( title == mMetadata.
title() )
465 mProjectScope.reset();
473 return mMetadata.
title();
483 return mSaveUserFull;
493 if ( dirty && mDirtyBlockCount > 0 )
496 if ( mDirty == dirty )
505 if ( path == mHomePath )
509 mCachedHomePath.clear();
510 mProjectScope.reset();
519 const QList<QgsAttributeEditorElement *> elements = parent->
children();
527 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:formcontainers" ).arg( layerId ), container->
name() );
529 if ( !container->
children().empty() )
542 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1" ).arg( layer->layerId() ), layer->name() );
551 for (
const QgsField &field : fields )
554 if ( field.alias().isEmpty() )
555 fieldName = field.name();
557 fieldName = field.alias();
559 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:fieldaliases" ).arg( vlayer->
id() ), fieldName );
561 if ( field.editorWidgetSetup().type() == QStringLiteral(
"ValueRelation" ) )
563 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:fields:%2:valuerelationvalue" ).arg( vlayer->
id(), field.name() ), field.editorWidgetSetup().config().value( QStringLiteral(
"Value" ) ).toString() );
574 const QList<QgsLayerTreeGroup *> groupLayers = mRootGroup->
findGroups();
577 translationContext->
registerTranslation( QStringLiteral(
"project:layergroups" ), groupLayer->name() );
581 const QList<QgsRelation> &relations = mRelationManager->
relations().values();
584 translationContext->
registerTranslation( QStringLiteral(
"project:relations" ), relation.name() );
590 if ( name == mFile.fileName() )
595 mFile.setFileName( name );
596 mCachedHomePath.clear();
597 mProjectScope.reset();
602 if ( newHomePath != oldHomePath )
610 return mFile.fileName();
615 return QFileInfo( mFile );
628 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
642 if ( mFile.fileName().isEmpty() )
653 if ( mFile.fileName().isEmpty() )
664 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
665 return metadata.
name;
669 return QFileInfo( mFile.fileName() ).completeBaseName();
683 writeEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectionsEnabled" ), crs.
isValid() ? 1 : 0 );
684 mProjectScope.reset();
689 if ( adjustEllipsoid )
695 if ( !
crs().isValid() )
698 return readEntry( QStringLiteral(
"Measure" ), QStringLiteral(
"/Ellipsoid" ),
geoNone() );
703 if ( ellipsoid ==
readEntry( QStringLiteral(
"Measure" ), QStringLiteral(
"/Ellipsoid" ) ) )
706 mProjectScope.reset();
707 writeEntry( QStringLiteral(
"Measure" ), QStringLiteral(
"/Ellipsoid" ), ellipsoid );
713 return mTransformContext;
718 if ( context == mTransformContext )
721 mTransformContext = context;
722 mProjectScope.reset();
724 for (
auto &layer : mLayerStore.get()->mapLayers() )
726 layer->setTransformContext( context );
735 mProjectScope.reset();
736 mFile.setFileName( QString() );
739 mSaveUserFull.clear();
741 mCachedHomePath.clear();
742 mAutoTransaction =
false;
743 mEvaluateDefaultValues =
false;
745 mTrustLayerMetadata =
false;
746 mCustomVariables.clear();
748 if ( !settings.
value( QStringLiteral(
"projects/anonymize_new_projects" ),
false,
QgsSettings::Core ).toBool() )
759 mEmbeddedLayers.clear();
760 mRelationManager->
clear();
761 mAnnotationManager->clear();
762 mLayoutManager->clear();
763 mBookmarkManager->
clear();
764 mViewSettings->
reset();
765 mDisplaySettings->
reset();
766 mSnappingConfig.
reset();
773 mLabelingEngineSettings->clear();
780 if ( !mIsBeingDeleted )
788 writeEntry( QStringLiteral(
"PositionPrecision" ), QStringLiteral(
"/Automatic" ),
true );
789 writeEntry( QStringLiteral(
"PositionPrecision" ), QStringLiteral(
"/DecimalPlaces" ), 2 );
790 writeEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
false );
793 writeEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/DistanceUnits" ), settings.
value( QStringLiteral(
"/qgis/measure/displayunits" ) ).toString() );
794 writeEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/AreaUnits" ), settings.
value( QStringLiteral(
"/qgis/measure/areaunits" ) ).toString() );
796 int red = settings.
value( QStringLiteral(
"qgis/default_canvas_color_red" ), 255 ).toInt();
797 int green = settings.
value( QStringLiteral(
"qgis/default_canvas_color_green" ), 255 ).toInt();
798 int blue = settings.
value( QStringLiteral(
"qgis/default_canvas_color_blue" ), 255 ).toInt();
801 red = settings.
value( QStringLiteral(
"qgis/default_selection_color_red" ), 255 ).toInt();
802 green = settings.
value( QStringLiteral(
"qgis/default_selection_color_green" ), 255 ).toInt();
803 blue = settings.
value( QStringLiteral(
"qgis/default_selection_color_blue" ), 0 ).toInt();
804 int alpha = settings.
value( QStringLiteral(
"qgis/default_selection_color_alpha" ), 255 ).toInt();
819 topQgsPropertyKey.
dump();
855 QDomElement propertiesElem = doc.documentElement().firstChildElement( QStringLiteral(
"properties" ) );
857 if ( propertiesElem.isNull() )
862 QDomNodeList scopes = propertiesElem.childNodes();
864 if ( scopes.count() < 1 )
866 QgsDebugMsg( QStringLiteral(
"empty ``properties'' XML tag ... bailing" ) );
870 if ( ! project_properties.
readXml( propertiesElem ) )
872 QgsDebugMsg( QStringLiteral(
"Project_properties.readXml() failed" ) );
881 static void _getTitle(
const QDomDocument &doc, QString &
title )
883 QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"title" ) );
889 QgsDebugMsg( QStringLiteral(
"unable to find title element" ) );
893 QDomNode titleNode = nl.item( 0 );
895 if ( !titleNode.hasChildNodes() )
897 QgsDebugMsg( QStringLiteral(
"unable to find title element" ) );
901 QDomNode titleTextNode = titleNode.firstChild();
903 if ( !titleTextNode.isText() )
905 QgsDebugMsg( QStringLiteral(
"unable to find title element" ) );
909 QDomText titleText = titleTextNode.toText();
911 title = titleText.data();
915 static void readProjectFileMetadata(
const QDomDocument &doc, QString &lastUser, QString &lastUserFull )
917 QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"qgis" ) );
925 QDomNode qgisNode = nl.item( 0 );
927 QDomElement qgisElement = qgisNode.toElement();
928 lastUser = qgisElement.attribute( QStringLiteral(
"saveUser" ), QString() );
929 lastUserFull = qgisElement.attribute( QStringLiteral(
"saveUserFull" ), QString() );
935 QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"qgis" ) );
939 QgsDebugMsg( QStringLiteral(
" unable to find qgis element in project file" ) );
943 QDomNode qgisNode = nl.item( 0 );
945 QDomElement qgisElement = qgisNode.toElement();
946 QgsProjectVersion projectVersion( qgisElement.attribute( QStringLiteral(
"version" ) ) );
947 return projectVersion;
953 return mSnappingConfig;
958 if ( mSnappingConfig == snappingConfig )
966 bool QgsProject::_getMapLayers(
const QDomDocument &doc, QList<QDomNode> &brokenNodes, QgsProject::ReadFlags flags )
971 QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"maplayer" ) );
975 if ( 0 == nl.count() )
985 bool returnStatus =
true;
991 if ( depSorter.hasCycle() || depSorter.hasMissingDependency() )
994 const QVector<QDomNode> sortedLayerNodes = depSorter.sortedLayerNodes();
995 const int totalLayerCount = sortedLayerNodes.count();
998 for (
const QDomNode &node : sortedLayerNodes )
1000 const QDomElement element = node.toElement();
1002 const QString name =
translate( QStringLiteral(
"project:layers:%1" ).arg( node.namedItem( QStringLiteral(
"id" ) ).toElement().text() ), node.namedItem( QStringLiteral(
"layername" ) ).toElement().text() );
1003 if ( !name.isNull() )
1004 emit
loadingLayer( tr(
"Loading layer %1" ).arg( name ) );
1006 if ( element.attribute( QStringLiteral(
"embedded" ) ) == QLatin1String(
"1" ) )
1008 createEmbeddedLayer( element.attribute( QStringLiteral(
"id" ) ),
readPath( element.attribute( QStringLiteral(
"project" ) ) ), brokenNodes,
true, flags );
1017 if ( !addLayer( element, brokenNodes, context, flags ) )
1019 returnStatus =
false;
1022 if ( !messages.isEmpty() )
1031 return returnStatus;
1034 bool QgsProject::addLayer(
const QDomElement &layerElem, QList<QDomNode> &brokenNodes,
QgsReadWriteContext &context, QgsProject::ReadFlags flags )
1036 QString type = layerElem.attribute( QStringLiteral(
"type" ) );
1038 std::unique_ptr<QgsMapLayer>
mapLayer;
1040 if ( type == QLatin1String(
"vector" ) )
1042 mapLayer = qgis::make_unique<QgsVectorLayer>();
1044 if (
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( mapLayer.get() ) )
1046 vl->setReadExtentFromXml( mTrustLayerMetadata );
1049 else if ( type == QLatin1String(
"raster" ) )
1051 mapLayer = qgis::make_unique<QgsRasterLayer>();
1053 else if ( type == QLatin1String(
"mesh" ) )
1055 mapLayer = qgis::make_unique<QgsMeshLayer>();
1057 else if ( type == QLatin1String(
"plugin" ) )
1059 QString
typeName = layerElem.attribute( QStringLiteral(
"name" ) );
1065 QgsDebugMsg( QStringLiteral(
"Unable to create layer" ) );
1069 Q_CHECK_PTR( mapLayer );
1073 const QString layerId { layerElem.namedItem( QStringLiteral(
"id" ) ).toElement().text() };
1074 Q_ASSERT( ! layerId.isEmpty() );
1078 QgsMapLayer::ReadFlags layerFlags =
nullptr;
1081 bool layerIsValid = mapLayer->readLayerXml( layerElem, context, layerFlags ) && mapLayer->isValid();
1082 QList<QgsMapLayer *> newLayers;
1083 newLayers << mapLayer.get();
1084 if ( layerIsValid || flags & QgsProject::ReadFlag::FlagDontResolveLayers )
1094 QgsDebugMsg(
"Unable to load " + type +
" layer" );
1095 brokenNodes.push_back( layerElem );
1100 if ( ! layerWasStored )
1105 return layerIsValid;
1110 mFile.setFileName( filename );
1111 mCachedHomePath.clear();
1112 mProjectScope.reset();
1114 return read( flags );
1119 QString filename = mFile.fileName();
1124 QTemporaryFile inDevice;
1125 if ( !inDevice.open() )
1127 setError( tr(
"Unable to open %1" ).arg( inDevice.fileName() ) );
1133 if ( !storage->readProject( filename, &inDevice, context ) )
1135 QString err = tr(
"Unable to open %1" ).arg( filename );
1136 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
1137 if ( !messages.isEmpty() )
1138 err += QStringLiteral(
"\n\n" ) + messages.last().message();
1142 returnValue = unzip( inDevice.fileName(), flags );
1148 returnValue = unzip( mFile.fileName(), flags );
1153 returnValue = readProjectFile( mFile.fileName(), flags );
1159 mFile.setFileName( filename );
1160 mCachedHomePath.clear();
1161 mProjectScope.reset();
1166 mTranslator.reset(
nullptr );
1173 bool QgsProject::readProjectFile(
const QString &filename, QgsProject::ReadFlags flags )
1175 QFile projectFile( filename );
1180 QString localeFileName = QStringLiteral(
"%1_%2" ).arg( QFileInfo( projectFile.fileName() ).
baseName(), settings.
value( QStringLiteral(
"locale/userLocale" ), QString() ).toString() );
1182 if ( QFile( QStringLiteral(
"%1/%2.qm" ).arg( QFileInfo( projectFile.fileName() ).
absolutePath(), localeFileName ) ).exists() )
1184 mTranslator.reset(
new QTranslator() );
1185 mTranslator->load( localeFileName, QFileInfo( projectFile.fileName() ).
absolutePath() );
1188 std::unique_ptr<QDomDocument> doc(
new QDomDocument( QStringLiteral(
"qgis" ) ) );
1190 if ( !projectFile.open( QIODevice::ReadOnly | QIODevice::Text ) )
1192 projectFile.close();
1194 setError( tr(
"Unable to open %1" ).arg( projectFile.fileName() ) );
1203 if ( !doc->setContent( &projectFile, &errorMsg, &line, &column ) )
1207 QMessageBox::critical( 0, tr(
"Read Project File" ),
1208 tr(
"%1 at line %2 column %3" ).arg( errorMsg ).arg( line ).arg( column ) );
1211 QString errorString = tr(
"Project file read error in file %1: %2 at line %3 column %4" )
1212 .arg( projectFile.fileName(), errorMsg ).arg( line ).arg( column );
1216 projectFile.close();
1218 setError( tr(
"%1 for file %2" ).arg( errorString, projectFile.fileName() ) );
1223 projectFile.close();
1231 if ( thisVersion > fileVersion )
1234 "version of qgis (saved in " + fileVersion.text() +
1236 "). Problems may occur." );
1243 projectFile.updateRevision( thisVersion );
1247 QString
fileName = mFile.fileName();
1248 std::unique_ptr<QgsAuxiliaryStorage> aStorage = std::move( mAuxiliaryStorage );
1250 mAuxiliaryStorage = std::move( aStorage );
1251 mFile.setFileName( fileName );
1252 mCachedHomePath.clear();
1253 mProjectScope.reset();
1261 dump_( mProperties );
1266 _getTitle( *doc, oldTitle );
1268 readProjectFileMetadata( *doc, mSaveUser, mSaveUserFull );
1270 QDomNodeList homePathNl = doc->elementsByTagName( QStringLiteral(
"homePath" ) );
1271 if ( homePathNl.count() > 0 )
1273 QDomElement homePathElement = homePathNl.at( 0 ).toElement();
1274 QString
homePath = homePathElement.attribute( QStringLiteral(
"path" ) );
1275 if ( !homePath.isEmpty() )
1284 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorGreenPart" ), 255 ),
1285 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorBluePart" ), 255 ) );
1288 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorGreenPart" ), 255 ),
1289 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorBluePart" ), 255 ),
1290 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorAlphaPart" ), 255 ) );
1299 if (
readNumEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectionsEnabled" ), 0 ) )
1302 QDomNode srsNode = doc->documentElement().namedItem( QStringLiteral(
"projectCrs" ) );
1303 if ( !srsNode.isNull() )
1305 projectCrs.
readXml( srsNode );
1310 QString projCrsString =
readEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCRSProj4String" ) );
1311 long currentCRS =
readNumEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCRSID" ), -1 );
1312 const QString authid =
readEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCrs" ) );
1315 bool isUserAuthId = authid.startsWith( QLatin1String(
"USER:" ), Qt::CaseInsensitive );
1316 if ( !authid.isEmpty() && !isUserAuthId )
1320 if ( !projectCrs.
isValid() && currentCRS >= 0 )
1326 if ( !projCrsString.isEmpty() && ( authid.isEmpty() || isUserAuthId ) && ( !projectCrs.
isValid() || projectCrs.
toProj() != projCrsString ) )
1340 QStringList datumErrors;
1341 if ( !mTransformContext.
readXml( doc->documentElement(), context, datumErrors ) && !datumErrors.empty() )
1349 QStringList variableNames =
readListEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableNames" ) );
1350 QStringList variableValues =
readListEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableValues" ) );
1352 mCustomVariables.clear();
1353 if ( variableNames.length() == variableValues.length() )
1355 for (
int i = 0; i < variableNames.length(); ++i )
1357 mCustomVariables.insert( variableNames.at( i ), variableValues.at( i ) );
1362 QgsMessageLog::logMessage( tr(
"Project Variables Invalid" ), tr(
"The project contains invalid variable settings." ) );
1365 QDomNodeList nl = doc->elementsByTagName( QStringLiteral(
"projectMetadata" ) );
1366 if ( !nl.isEmpty() )
1368 QDomElement metadataElement = nl.at( 0 ).toElement();
1376 if ( mMetadata.
title().isEmpty() && !oldTitle.isEmpty() )
1383 nl = doc->elementsByTagName( QStringLiteral(
"autotransaction" ) );
1386 QDomElement transactionElement = nl.at( 0 ).toElement();
1387 if ( transactionElement.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
1388 mAutoTransaction =
true;
1391 nl = doc->elementsByTagName( QStringLiteral(
"evaluateDefaultValues" ) );
1394 QDomElement evaluateDefaultValuesElement = nl.at( 0 ).toElement();
1395 if ( evaluateDefaultValuesElement.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
1396 mEvaluateDefaultValues =
true;
1399 nl = doc->elementsByTagName( QStringLiteral(
"trust" ) );
1402 QDomElement trustElement = nl.at( 0 ).toElement();
1403 if ( trustElement.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
1404 mTrustLayerMetadata =
true;
1411 QDomElement layerTreeElem = doc->documentElement().firstChildElement( QStringLiteral(
"layer-tree-group" ) );
1412 if ( !layerTreeElem.isNull() )
1421 mLayerTreeRegistryBridge->
setEnabled(
false );
1424 QList<QDomNode> brokenNodes;
1425 bool clean = _getMapLayers( *doc, brokenNodes, flags );
1430 QgsDebugMsg( QStringLiteral(
"Unable to get map layers from project file." ) );
1432 if ( !brokenNodes.isEmpty() )
1434 QgsDebugMsg(
"there are " + QString::number( brokenNodes.size() ) +
" broken layers" );
1444 QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
1445 for ( QMap<QString, QgsMapLayer *>::iterator it = layers.begin(); it != layers.end(); it++ )
1447 it.value()->resolveReferences(
this );
1450 mLayerTreeRegistryBridge->
setEnabled(
true );
1453 loadEmbeddedNodes( mRootGroup, flags );
1459 if ( !layerTreeElem.isNull() )
1465 QDomElement layerTreeCanvasElem = doc->documentElement().firstChildElement( QStringLiteral(
"layer-tree-canvas" ) );
1466 if ( !layerTreeCanvasElem.isNull( ) )
1474 const QStringList requiredLayerIds =
readListEntry( QStringLiteral(
"RequiredLayers" ), QStringLiteral(
"Layers" ) );
1475 for (
const QString &layerId : requiredLayerIds )
1479 layer->setFlags( layer->flags() & ~
QgsMapLayer::Removable );
1482 const QStringList disabledLayerIds =
readListEntry( QStringLiteral(
"Identify" ), QStringLiteral(
"/disabledLayers" ) );
1483 for (
const QString &layerId : disabledLayerIds )
1487 layer->setFlags( layer->flags() & ~
QgsMapLayer::Identifiable );
1501 mMapThemeCollection->readXml( *doc );
1503 mLabelingEngineSettings->readSettingsFromProject(
this );
1506 mAnnotationManager->readXml( doc->documentElement(), context );
1508 mLayoutManager->readXml( doc->documentElement(), *doc );
1509 mBookmarkManager->
readXml( doc->documentElement(), *doc );
1512 QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
1513 for ( QMap<QString, QgsMapLayer *>::iterator it = existingMaps.begin(); it != existingMaps.end(); it++ )
1515 it.value()->setDependencies( it.value()->dependencies() );
1522 const QStringList scales =
readListEntry( QStringLiteral(
"Scales" ), QStringLiteral(
"/ScalesList" ) );
1523 QVector<double> res;
1524 for (
const QString &scale : scales )
1526 const QStringList parts = scale.split(
':' );
1527 if ( parts.size() != 2 )
1531 const double denominator = QLocale().toDouble( parts[1], &ok );
1538 QDomElement viewSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectViewSettings" ) );
1539 if ( !viewSettingsElement.isNull() )
1540 mViewSettings->
readXml( viewSettingsElement, context );
1542 QDomElement displaySettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectDisplaySettings" ) );
1543 if ( !displaySettingsElement.isNull() )
1544 mDisplaySettings->
readXml( displaySettingsElement, context );
1561 QgsDebugMsg( QString(
"Project save user: %1" ).arg( mSaveUser ) );
1562 QgsDebugMsg( QString(
"Project save user: %1" ).arg( mSaveUserFull ) );
1571 QString newFileName( QStringLiteral(
"%1/%2.qgs" ).arg( QFileInfo( projectFile.fileName() ).
absolutePath(), localeFileName ) );
1588 bool QgsProject::loadEmbeddedNodes(
QgsLayerTreeGroup *group, QgsProject::ReadFlags flags )
1591 const auto constChildren = group->
children();
1597 if ( childGroup->
customProperty( QStringLiteral(
"embedded" ) ).toInt() )
1600 QString projectPath =
readPath( childGroup->
customProperty( QStringLiteral(
"embedded_project" ) ).toString() );
1601 childGroup->
setCustomProperty( QStringLiteral(
"embedded_project" ), projectPath );
1605 QList<QgsLayerTreeNode *> clonedChildren;
1606 const auto constChildren = newGroup->
children();
1608 clonedChildren << newGroupChild->clone();
1616 loadEmbeddedNodes( childGroup, flags );
1621 if ( child->customProperty( QStringLiteral(
"embedded" ) ).toInt() )
1623 QList<QDomNode> brokenNodes;
1626 valid = valid &&
false;
1638 return mCustomVariables;
1643 if ( variables == mCustomVariables )
1647 QStringList variableNames;
1648 QStringList variableValues;
1650 QVariantMap::const_iterator it = variables.constBegin();
1651 for ( ; it != variables.constEnd(); ++it )
1653 variableNames << it.key();
1654 variableValues << it.value().toString();
1657 writeEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableNames" ), variableNames );
1658 writeEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableValues" ), variableValues );
1660 mCustomVariables = variables;
1661 mProjectScope.reset();
1668 *mLabelingEngineSettings = settings;
1674 return *mLabelingEngineSettings;
1679 return mLayerStore.get();
1684 return mLayerStore.get();
1689 QList<QgsVectorLayer *>
layers;
1690 QStringList layerIds =
readListEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsList" ), QStringList() );
1691 const auto constLayerIds = layerIds;
1692 for (
const QString &layerId : constLayerIds )
1703 const auto constLayers =
layers;
1705 list << layer->id();
1706 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsList" ), list );
1723 if ( mProjectScope )
1725 std::unique_ptr< QgsExpressionContextScope > projectScope = qgis::make_unique< QgsExpressionContextScope >( *mProjectScope );
1729 return projectScope.release();
1732 mProjectScope = qgis::make_unique< QgsExpressionContextScope >( QObject::tr(
"Project" ) );
1736 QVariantMap::const_iterator it = vars.constBegin();
1738 for ( ; it != vars.constEnd(); ++it )
1740 mProjectScope->setVariable( it.key(), it.value(), true );
1744 QString projectFolder = QFileInfo( projectPath ).path();
1745 QString projectFilename = QFileInfo( projectPath ).fileName();
1746 QString projectBasename =
baseName();
1768 QVariantMap keywords;
1770 for (
auto it = metadataKeywords.constBegin(); it != metadataKeywords.constEnd(); ++it )
1772 keywords.insert( it.key(), it.value() );
1776 mProjectScope->addFunction( QStringLiteral(
"project_color" ),
new GetNamedProjectColor(
this ) );
1781 void QgsProject::onMapLayersAdded(
const QList<QgsMapLayer *> &
layers )
1783 QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
1785 bool tgChanged =
false;
1787 const auto constLayers =
layers;
1790 if ( layer->isValid() )
1807 mTransactionGroups.insert( qMakePair( key, connString ), tg );
1822 for ( QMap<QString, QgsMapLayer *>::iterator it = existingMaps.begin(); it != existingMaps.end(); it++ )
1824 QSet<QgsMapLayerDependency> deps = it.value()->dependencies();
1825 if ( deps.contains( layer->id() ) )
1828 it.value()->setDependencies( deps );
1834 if ( mSnappingConfig.
addLayers( layers ) )
1838 void QgsProject::onMapLayersRemoved(
const QList<QgsMapLayer *> &
layers )
1844 void QgsProject::cleanTransactionGroups(
bool force )
1846 bool changed =
false;
1847 for ( QMap< QPair< QString, QString>,
QgsTransactionGroup *>::Iterator tg = mTransactionGroups.begin(); tg != mTransactionGroups.end(); )
1849 if ( tg.value()->isEmpty() || force )
1852 tg = mTransactionGroups.erase( tg );
1870 QList<QDomNode> brokenNodes;
1871 if ( addLayer( layerNode.toElement(), brokenNodes, context ) )
1875 QVector<QgsVectorLayer *> vectorLayers = layers<QgsVectorLayer *>();
1876 const auto constVectorLayers = vectorLayers;
1880 layer->resolveReferences(
this );
1890 mFile.setFileName( filename );
1891 mCachedHomePath.clear();
1892 mProjectScope.reset();
1904 QString storageFilePath { storage->filePath( mFile.fileName() ) };
1905 if ( storageFilePath.isEmpty() )
1907 writeEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
true );
1911 QString tempPath = QStandardPaths::standardLocations( QStandardPaths::TempLocation ).at( 0 );
1912 QString tmpZipFilename( tempPath + QDir::separator() + QUuid::createUuid().toString() );
1914 if ( !zip( tmpZipFilename ) )
1917 QFile tmpZipFile( tmpZipFilename );
1918 if ( !tmpZipFile.open( QIODevice::ReadOnly ) )
1920 setError( tr(
"Unable to read file %1" ).arg( tmpZipFilename ) );
1925 if ( !storage->writeProject( mFile.fileName(), &tmpZipFile, context ) )
1927 QString err = tr(
"Unable to save project to storage %1" ).arg( mFile.fileName() );
1928 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
1929 if ( !messages.isEmpty() )
1930 err += QStringLiteral(
"\n\n" ) + messages.last().message();
1936 QFile::remove( tmpZipFilename );
1943 return zip( mFile.fileName() );
1949 const bool asOk = saveAuxiliaryStorage();
1950 const bool writeOk = writeProjectFile( mFile.fileName() );
1953 if ( !asOk && writeOk )
1955 const QString err = mAuxiliaryStorage->errorString();
1956 setError( tr(
"Unable to save auxiliary storage ('%1')" ).arg( err ) );
1959 return asOk && writeOk;
1963 bool QgsProject::writeProjectFile(
const QString &filename )
1965 QFile projectFile( filename );
1971 QFileInfo myFileInfo( projectFile );
1972 if ( myFileInfo.exists() && !myFileInfo.isWritable() )
1974 setError( tr(
"%1 is not writable. Please adjust permissions (if possible) and try again." )
1975 .arg( projectFile.fileName() ) );
1983 QDomImplementation DomImplementation;
1984 DomImplementation.setInvalidDataPolicy( QDomImplementation::DropInvalidChars );
1986 QDomDocumentType documentType =
1987 DomImplementation.createDocumentType( QStringLiteral(
"qgis" ), QStringLiteral(
"http://mrcc.com/qgis.dtd" ),
1988 QStringLiteral(
"SYSTEM" ) );
1989 std::unique_ptr<QDomDocument> doc(
new QDomDocument( documentType ) );
1991 QDomElement qgisNode = doc->createElement( QStringLiteral(
"qgis" ) );
1992 qgisNode.setAttribute( QStringLiteral(
"projectname" ),
title() );
1993 qgisNode.setAttribute( QStringLiteral(
"version" ), QStringLiteral(
"%1" ).arg(
Qgis::version() ) );
1996 if ( !settings.
value( QStringLiteral(
"projects/anonymize_saved_projects" ),
false,
QgsSettings::Core ).toBool() )
2000 qgisNode.setAttribute( QStringLiteral(
"saveUser" ), newSaveUser );
2001 qgisNode.setAttribute( QStringLiteral(
"saveUserFull" ), newSaveUserFull );
2002 mSaveUser = newSaveUser;
2003 mSaveUserFull = newSaveUserFull;
2008 mSaveUserFull.clear();
2010 doc->appendChild( qgisNode );
2012 QDomElement homePathNode = doc->createElement( QStringLiteral(
"homePath" ) );
2013 homePathNode.setAttribute( QStringLiteral(
"path" ), mHomePath );
2014 qgisNode.appendChild( homePathNode );
2017 QDomElement titleNode = doc->createElement( QStringLiteral(
"title" ) );
2018 qgisNode.appendChild( titleNode );
2020 QDomElement transactionNode = doc->createElement( QStringLiteral(
"autotransaction" ) );
2021 transactionNode.setAttribute( QStringLiteral(
"active" ), mAutoTransaction ? 1 : 0 );
2022 qgisNode.appendChild( transactionNode );
2024 QDomElement evaluateDefaultValuesNode = doc->createElement( QStringLiteral(
"evaluateDefaultValues" ) );
2025 evaluateDefaultValuesNode.setAttribute( QStringLiteral(
"active" ), mEvaluateDefaultValues ? 1 : 0 );
2026 qgisNode.appendChild( evaluateDefaultValuesNode );
2028 QDomElement trustNode = doc->createElement( QStringLiteral(
"trust" ) );
2029 trustNode.setAttribute( QStringLiteral(
"active" ), mTrustLayerMetadata ? 1 : 0 );
2030 qgisNode.appendChild( trustNode );
2032 QDomText titleText = doc->createTextNode(
title() );
2033 titleNode.appendChild( titleText );
2036 QDomElement srsNode = doc->createElement( QStringLiteral(
"projectCrs" ) );
2038 qgisNode.appendChild( srsNode );
2045 clonedRoot->
writeXml( qgisNode, context );
2058 QDomElement projectLayersNode = doc->createElement( QStringLiteral(
"projectlayers" ) );
2060 QMap<QString, QgsMapLayer *>::ConstIterator li = layers.constBegin();
2061 while ( li != layers.end() )
2067 QHash< QString, QPair< QString, bool> >::const_iterator emIt = mEmbeddedLayers.constFind( ml->
id() );
2068 if ( emIt == mEmbeddedLayers.constEnd() )
2070 QDomElement maplayerElem;
2076 maplayerElem = doc->createElement( QStringLiteral(
"maplayer" ) );
2081 QDomDocument document;
2084 maplayerElem = document.firstChildElement();
2088 QgsDebugMsg( QStringLiteral(
"Could not restore layer properties for layer %1" ).arg( ml->
id() ) );
2094 projectLayersNode.appendChild( maplayerElem );
2100 if ( emIt.value().second )
2102 QDomElement mapLayerElem = doc->createElement( QStringLiteral(
"maplayer" ) );
2103 mapLayerElem.setAttribute( QStringLiteral(
"embedded" ), 1 );
2104 mapLayerElem.setAttribute( QStringLiteral(
"project" ),
writePath( emIt.value().first ) );
2105 mapLayerElem.setAttribute( QStringLiteral(
"id" ), ml->
id() );
2106 projectLayersNode.appendChild( mapLayerElem );
2113 qgisNode.appendChild( projectLayersNode );
2115 QDomElement layerOrderNode = doc->createElement( QStringLiteral(
"layerorder" ) );
2117 for (
QgsMapLayer *layer : constCustomLayerOrder )
2119 QDomElement mapLayerElem = doc->createElement( QStringLiteral(
"layer" ) );
2120 mapLayerElem.setAttribute( QStringLiteral(
"id" ), layer->id() );
2121 layerOrderNode.appendChild( mapLayerElem );
2123 qgisNode.appendChild( layerOrderNode );
2125 mLabelingEngineSettings->writeSettingsToProject(
this );
2127 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorRedPart" ), mBackgroundColor.red() );
2128 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorGreenPart" ), mBackgroundColor.green() );
2129 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorBluePart" ), mBackgroundColor.blue() );
2131 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorRedPart" ), mSelectionColor.red() );
2132 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorGreenPart" ), mSelectionColor.green() );
2133 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorBluePart" ), mSelectionColor.blue() );
2134 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorAlphaPart" ), mSelectionColor.alpha() );
2138 dump_( mProperties );
2141 QgsDebugMsgLevel( QStringLiteral(
"there are %1 property scopes" ).arg( static_cast<int>( mProperties.
count() ) ), 1 );
2146 mProperties.
writeXml( QStringLiteral(
"properties" ), qgisNode, *doc );
2149 mMapThemeCollection->writeXml( *doc );
2151 mTransformContext.
writeXml( qgisNode, context );
2153 QDomElement metadataElem = doc->createElement( QStringLiteral(
"projectMetadata" ) );
2155 qgisNode.appendChild( metadataElem );
2157 QDomElement annotationsElem = mAnnotationManager->writeXml( *doc, context );
2158 qgisNode.appendChild( annotationsElem );
2160 QDomElement layoutElem = mLayoutManager->writeXml( *doc );
2161 qgisNode.appendChild( layoutElem );
2163 QDomElement bookmarkElem = mBookmarkManager->
writeXml( *doc );
2164 qgisNode.appendChild( bookmarkElem );
2166 QDomElement viewSettingsElem = mViewSettings->
writeXml( *doc, context );
2167 qgisNode.appendChild( viewSettingsElem );
2169 QDomElement displaySettingsElem = mDisplaySettings->
writeXml( *doc, context );
2170 qgisNode.appendChild( displaySettingsElem );
2178 QFile backupFile( QStringLiteral(
"%1~" ).arg( filename ) );
2180 ok &= backupFile.open( QIODevice::WriteOnly | QIODevice::Truncate );
2181 ok &= projectFile.open( QIODevice::ReadOnly );
2184 while ( ok && !projectFile.atEnd() )
2186 ba = projectFile.read( 10240 );
2187 ok &= backupFile.write( ba ) == ba.size();
2190 projectFile.close();
2195 setError( tr(
"Unable to create backup file %1" ).arg( backupFile.fileName() ) );
2200 struct utimbuf tb = {
static_cast<time_t
>( fi.lastRead().toSecsSinceEpoch() ), static_cast<time_t>( fi.lastModified().toSecsSinceEpoch() ) };
2201 utime( backupFile.fileName().toUtf8().constData(), &tb );
2204 if ( !projectFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
2206 projectFile.close();
2209 setError( tr(
"Unable to save to file %1" ).arg( projectFile.fileName() ) );
2213 QTemporaryFile tempFile;
2214 bool ok = tempFile.open();
2217 QTextStream projectFileStream( &tempFile );
2218 doc->save( projectFileStream, 2 );
2219 ok &= projectFileStream.pos() > -1;
2221 ok &= tempFile.seek( 0 );
2224 while ( ok && !tempFile.atEnd() )
2226 ba = tempFile.read( 10240 );
2227 ok &= projectFile.write( ba ) == ba.size();
2230 ok &= projectFile.error() == QFile::NoError;
2232 projectFile.close();
2239 setError( tr(
"Unable to save to file %1. Your project " 2240 "may be corrupted on disk. Try clearing some space on the volume and " 2241 "check file permissions before pressing save again." )
2242 .arg( projectFile.fileName() ) );
2254 bool propertiesModified;
2255 bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
2257 if ( propertiesModified )
2265 bool propertiesModified;
2266 bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
2268 if ( propertiesModified )
2276 bool propertiesModified;
2277 bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
2279 if ( propertiesModified )
2287 bool propertiesModified;
2288 bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
2290 if ( propertiesModified )
2298 bool propertiesModified;
2299 bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
2301 if ( propertiesModified )
2309 const QStringList &def,
2318 value =
property->value();
2320 bool valid = QVariant::StringList == value.type();
2326 return value.toStringList();
2345 value =
property->value();
2347 bool valid = value.canConvert( QVariant::String );
2352 return value.toString();
2367 value =
property->value();
2370 bool valid = value.canConvert( QVariant::Int );
2379 return value.toInt();
2392 QVariant value =
property->value();
2394 bool valid = value.canConvert( QVariant::Double );
2399 return value.toDouble();
2412 QVariant value =
property->value();
2414 bool valid = value.canConvert( QVariant::Bool );
2419 return value.toBool();
2428 if (
findKey_( scope, key, mProperties ) )
2434 return !
findKey_( scope, key, mProperties );
2442 QStringList entries;
2444 if ( foundProperty )
2459 QStringList entries;
2461 if ( foundProperty )
2474 dump_( mProperties );
2479 bool absolutePaths =
readBoolEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
false );
2481 if ( ! absolutePaths )
2488 filePath = storage->filePath( mFile.fileName() );
2508 void QgsProject::setError(
const QString &errorMessage )
2510 mErrorMessage = errorMessage;
2515 return mErrorMessage;
2518 void QgsProject::clearError()
2520 setError( QString() );
2525 delete mBadLayerHandler;
2526 mBadLayerHandler = handler;
2531 QHash< QString, QPair< QString, bool > >::const_iterator it = mEmbeddedLayers.find(
id );
2532 if ( it == mEmbeddedLayers.constEnd() )
2536 return it.value().first;
2540 bool saveFlag, QgsProject::ReadFlags flags )
2544 static QString sPrevProjectFilePath;
2545 static QDateTime sPrevProjectFileTimestamp;
2546 static QDomDocument sProjectDocument;
2548 QString qgsProjectFile = projectFilePath;
2550 if ( projectFilePath.endsWith( QLatin1String(
".qgz" ), Qt::CaseInsensitive ) )
2552 archive.
unzip( projectFilePath );
2556 QDateTime projectFileTimestamp = QFileInfo( projectFilePath ).lastModified();
2558 if ( projectFilePath != sPrevProjectFilePath || projectFileTimestamp != sPrevProjectFileTimestamp )
2560 sPrevProjectFilePath.clear();
2562 QFile projectFile( qgsProjectFile );
2563 if ( !projectFile.open( QIODevice::ReadOnly ) )
2568 if ( !sProjectDocument.setContent( &projectFile ) )
2573 sPrevProjectFilePath = projectFilePath;
2574 sPrevProjectFileTimestamp = projectFileTimestamp;
2578 bool useAbsolutePaths =
true;
2580 QDomElement propertiesElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral(
"properties" ) );
2581 if ( !propertiesElem.isNull() )
2583 QDomElement absElem = propertiesElem.firstChildElement( QStringLiteral(
"Paths" ) ).firstChildElement( QStringLiteral(
"Absolute" ) );
2584 if ( !absElem.isNull() )
2586 useAbsolutePaths = absElem.text().compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0;
2591 if ( !useAbsolutePaths )
2596 QDomElement projectLayersElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral(
"projectlayers" ) );
2597 if ( projectLayersElem.isNull() )
2602 QDomNodeList mapLayerNodes = projectLayersElem.elementsByTagName( QStringLiteral(
"maplayer" ) );
2603 for (
int i = 0; i < mapLayerNodes.size(); ++i )
2606 QDomElement mapLayerElem = mapLayerNodes.at( i ).toElement();
2607 QString
id = mapLayerElem.firstChildElement( QStringLiteral(
"id" ) ).text();
2608 if (
id == layerId )
2611 if ( mapLayerElem.attribute( QStringLiteral(
"embedded" ) ) == QLatin1String(
"1" ) )
2616 mEmbeddedLayers.insert( layerId, qMakePair( projectFilePath, saveFlag ) );
2618 if ( addLayer( mapLayerElem, brokenNodes, embeddedContext, flags ) )
2624 mEmbeddedLayers.remove( layerId );
2636 QString qgsProjectFile = projectFilePath;
2638 if ( projectFilePath.endsWith( QLatin1String(
".qgz" ), Qt::CaseInsensitive ) )
2640 archive.
unzip( projectFilePath );
2645 QFile projectFile( qgsProjectFile );
2646 if ( !projectFile.open( QIODevice::ReadOnly ) )
2651 QDomDocument projectDocument;
2652 if ( !projectDocument.setContent( &projectFile ) )
2664 QDomElement layerTreeElem = projectDocument.documentElement().firstChildElement( QStringLiteral(
"layer-tree-group" ) );
2665 if ( !layerTreeElem.isNull() )
2675 if ( !group || group->customProperty( QStringLiteral(
"embedded" ) ).toBool() )
2688 newGroup->
setCustomProperty( QStringLiteral(
"embedded_project" ), projectFilePath );
2691 mLayerTreeRegistryBridge->
setEnabled(
false );
2692 initializeEmbeddedSubtree( projectFilePath, newGroup, flags );
2693 mLayerTreeRegistryBridge->
setEnabled(
true );
2696 const auto constFindLayerIds = newGroup->
findLayerIds();
2697 for (
const QString &layerId : constFindLayerIds )
2710 void QgsProject::initializeEmbeddedSubtree(
const QString &projectFilePath,
QgsLayerTreeGroup *group, QgsProject::ReadFlags flags )
2712 const auto constChildren = group->
children();
2716 child->setCustomProperty( QStringLiteral(
"embedded" ), 1 );
2725 QList<QDomNode> brokenNodes;
2733 return mEvaluateDefaultValues;
2738 if ( evaluateDefaultValues == mEvaluateDefaultValues )
2742 QMap<QString, QgsMapLayer *>::const_iterator layerIt = layers.constBegin();
2743 for ( ; layerIt != layers.constEnd(); ++layerIt )
2757 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/TopologicalEditing" ), ( enabled ? 1 : 0 ) );
2763 return readNumEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/TopologicalEditing" ), 0 );
2768 QString distanceUnitString =
readEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/DistanceUnits" ), QString() );
2769 if ( !distanceUnitString.isEmpty() )
2786 QString areaUnitString =
readEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/AreaUnits" ), QString() );
2787 if ( !areaUnitString.isEmpty() )
2804 if ( !mCachedHomePath.isEmpty() )
2805 return mCachedHomePath;
2809 if ( !mHomePath.isEmpty() )
2811 QFileInfo homeInfo( mHomePath );
2812 if ( !homeInfo.isRelative() )
2814 mCachedHomePath = mHomePath;
2820 mCachedHomePath = pfi.path();
2822 return mCachedHomePath;
2825 if ( !pfi.exists() )
2827 mCachedHomePath = mHomePath;
2831 if ( !mHomePath.isEmpty() )
2834 mCachedHomePath = QDir::cleanPath( pfi.path() +
'/' + mHomePath );
2838 mCachedHomePath = pfi.canonicalPath();
2840 return mCachedHomePath;
2850 return mRelationManager;
2855 return mLayoutManager.get();
2860 return mLayoutManager.get();
2865 return mBookmarkManager;
2870 return mBookmarkManager;
2875 return mViewSettings;
2880 return mViewSettings;
2885 return mDisplaySettings;
2890 return mDisplaySettings;
2900 return mMapThemeCollection.get();
2905 return mAnnotationManager.get();
2910 return mAnnotationManager.get();
2915 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
2916 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
2921 if ( layers.contains( it.value() ) )
2922 it.value()->setFlags( it.value()->flags() & ~
QgsMapLayer::Identifiable );
2935 nonIdentifiableLayers.reserve( layerIds.count() );
2936 for (
const QString &layerId : layerIds )
2940 nonIdentifiableLayers << layer;
2952 for ( QMap<QString, QgsMapLayer *>::const_iterator it = layers.constBegin(); it != layers.constEnd(); ++it )
2956 nonIdentifiableLayers.append( it.value()->id() );
2964 return mAutoTransaction;
2969 if ( autoTransaction != mAutoTransaction )
2973 if ( autoTransaction )
2974 onMapLayersAdded(
mapLayers().values() );
2976 cleanTransactionGroups(
true );
2982 return mTransactionGroups;
2993 return mLayerStore->count();
2998 return mLayerStore->validCount();
3003 return mLayerStore->mapLayer( layerId );
3008 return mLayerStore->mapLayersByName( layerName );
3013 QList<QgsMapLayer *>
layers;
3014 const auto constMapLayers { mLayerStore->mapLayers() };
3015 for (
const auto &l : constMapLayers )
3017 if ( ! l->shortName().isEmpty() )
3019 if ( l->shortName() == shortName )
3022 else if ( l->name() == shortName )
3030 bool QgsProject::unzip(
const QString &filename, QgsProject::ReadFlags flags )
3036 if ( !archive->unzip( filename ) )
3038 setError( tr(
"Unable to unzip file '%1'" ).arg( filename ) );
3043 if ( archive->projectFile().isEmpty() )
3045 setError( tr(
"Zip archive does not provide a project file" ) );
3050 if ( !archive->auxiliaryStorageFile().isEmpty() )
3054 mAuxiliaryStorage.reset(
new QgsAuxiliaryStorage( archive->auxiliaryStorageFile(), false ) );
3062 if ( ! readProjectFile( archive->projectFile(), flags ) )
3064 setError( tr(
"Cannot read unzipped qgs project file" ) );
3069 mArchive = std::move( archive );
3070 mArchive->clearProjectFile();
3075 bool QgsProject::zip(
const QString &filename )
3081 const QString
baseName = QFileInfo( filename ).baseName();
3082 const QString qgsFileName = QStringLiteral(
"%1.qgs" ).arg( baseName );
3083 QFile qgsFile( QDir( archive->dir() ).filePath( qgsFileName ) );
3085 bool writeOk =
false;
3086 if ( qgsFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
3088 writeOk = writeProjectFile( qgsFile.fileName() );
3095 setError( tr(
"Unable to write temporary qgs file" ) );
3100 const QFileInfo info( qgsFile );
3103 if ( ! saveAuxiliaryStorage( asFileName ) )
3105 const QString err = mAuxiliaryStorage->errorString();
3106 setError( tr(
"Unable to save auxiliary storage ('%1')" ).arg( err ) );
3111 archive->addFile( qgsFile.fileName() );
3112 archive->addFile( asFileName );
3115 if ( !archive->zip( filename ) )
3117 setError( tr(
"Unable to perform zip" ) );
3130 const QList<QgsMapLayer *> &
layers,
3132 bool takeOwnership )
3134 const QList<QgsMapLayer *> myResultList { mLayerStore->addMapLayers( layers, takeOwnership ) };
3135 if ( !myResultList.isEmpty() )
3138 for (
auto &l : myResultList )
3148 if ( mAuxiliaryStorage )
3163 return myResultList;
3169 bool takeOwnership )
3171 QList<QgsMapLayer *> addedLayers;
3172 addedLayers =
addMapLayers( QList<QgsMapLayer *>() << layer, addToLegend, takeOwnership );
3173 return addedLayers.isEmpty() ? nullptr : addedLayers[0];
3178 mLayerStore->removeMapLayers( layerIds );
3183 mLayerStore->removeMapLayers( layers );
3188 mLayerStore->removeMapLayer( layerId );
3193 mLayerStore->removeMapLayer( layer );
3198 return mLayerStore->takeMapLayer( layer );
3203 mLayerStore->removeAllMapLayers();
3208 QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
3209 QMap<QString, QgsMapLayer *>::const_iterator it = layers.constBegin();
3210 for ( ; it != layers.constEnd(); ++it )
3212 it.value()->reload();
3218 return validOnly ? mLayerStore->validMapLayers() : mLayerStore->mapLayers();
3223 return mTransactionGroups.value( qMakePair( providerKey, connString ) );
3233 if ( settings.
value( QStringLiteral(
"/projections/unknownCrsBehavior" ), QStringLiteral(
"NoAction" ),
QgsSettings::App ).toString() == QStringLiteral(
"UseProjectCrs" )
3234 || settings.
value( QStringLiteral(
"/projections/unknownCrsBehavior" ), 0,
QgsSettings::App ).toString() == 2 )
3242 QString layerDefaultCrs = settings.
value( QStringLiteral(
"/Projections/layerDefaultCrs" ),
geoEpsgCrsAuthId() ).toString();
3251 mTrustLayerMetadata = trust;
3254 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
3264 bool QgsProject::saveAuxiliaryStorage(
const QString &filename )
3268 for (
auto it = layers.constBegin(); it != layers.constEnd(); ++it )
3281 if ( !mAuxiliaryStorage->exists( *
this ) && filename.isEmpty() && empty )
3285 else if ( !filename.isEmpty() )
3287 return mAuxiliaryStorage->saveAs( filename );
3291 return mAuxiliaryStorage->saveAs( *
this );
3297 return mAuxiliaryStorage.get();
3302 return mAuxiliaryStorage.get();
3312 if ( metadata == mMetadata )
3316 mProjectScope.reset();
3328 for ( QMap<QString, QgsMapLayer *>::const_iterator it = layers.constBegin(); it != layers.constEnd(); ++it )
3332 requiredLayers.insert( it.value() );
3340 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
3341 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
3346 if ( layers.contains( it.value() ) )
3347 it.value()->setFlags( it.value()->flags() & ~
QgsMapLayer::Removable );
3356 QStringList customColors;
3357 QStringList customColorLabels;
3359 QgsNamedColorList::const_iterator colorIt = colors.constBegin();
3360 for ( ; colorIt != colors.constEnd(); ++colorIt )
3363 QString label = ( *colorIt ).second;
3364 customColors.append( color );
3365 customColorLabels.append( label );
3367 writeEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Colors" ), customColors );
3368 writeEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Labels" ), customColorLabels );
3369 mProjectScope.reset();
3375 if ( mBackgroundColor == color )
3378 mBackgroundColor = color;
3384 return mBackgroundColor;
3389 if ( mSelectionColor == color )
3392 mSelectionColor = color;
3398 return mSelectionColor;
3432 QString
QgsProject::translate(
const QString &context,
const QString &sourceText,
const char *disambiguation,
int n )
const 3439 QString result = mTranslator->translate( context.toUtf8(), sourceText.toUtf8(), disambiguation, n );
3441 if ( result.isEmpty() )
3451 if ( !layers.empty() )
3453 for (
auto it = layers.constBegin(); it != layers.constEnd(); ++it )
3458 if ( !( ( *it )->accept( visitor ) ) )
3467 if ( !mLayoutManager->accept( visitor ) )
3470 if ( !mAnnotationManager->accept( visitor ) )
3477 GetNamedProjectColor::GetNamedProjectColor(
const QgsProject *project )
3484 QStringList colorStrings = project->
readListEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Colors" ) );
3485 QStringList colorLabels = project->
readListEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Labels" ) );
3489 for ( QStringList::iterator it = colorStrings.begin();
3490 it != colorStrings.end(); ++it )
3494 if ( colorLabels.length() > colorIndex )
3496 label = colorLabels.at( colorIndex );
3499 mColors.insert( label.toLower(), color );
3504 GetNamedProjectColor::GetNamedProjectColor(
const QHash<QString, QColor> &colors )
3512 QString colorName = values.at( 0 ).toString().toLower();
3513 if ( mColors.contains( colorName ) )
3515 return QStringLiteral(
"%1,%2,%3" ).arg( mColors.value( colorName ).red() ).arg( mColors.value( colorName ).green() ).arg( mColors.value( colorName ).blue() );
3523 return new GetNamedProjectColor( mColors );
Q_DECL_DEPRECATED QStringList nonIdentifiableLayers() const
Gets the list of layers which currently should not be taken into account on map identification.
Class for parsing and evaluation of expressions (formerly called "search strings").
Layer tree group node serves as a container for layers and further groups.
void setDirty(bool b=true)
Flag the project as dirty (modified).
void setTrustLayerMetadata(bool trust)
Sets the trust option allowing to indicate if the extent has to be read from the XML document when da...
The class is used as a container of context for various read/write operations on other objects...
void readChildrenFromXml(QDomElement &element, const QgsReadWriteContext &context)
Read children from XML and append them to the group.
QString error() const
Returns error message from previous read/write.
Single variable definition for use within a QgsExpressionContextScope.
bool isDirty() const
Returns true if the project has been modified since the last write()
static Q_INVOKABLE QgsUnitTypes::AreaUnit decodeAreaUnit(const QString &string, bool *ok=nullptr)
Decodes an areal unit from a string.
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
QList< QgsMapLayer * > addMapLayers(const QList< QgsMapLayer *> &mapLayers, bool addToLegend=true, bool takeOwnership=true)
Add a list of layers to the map of loaded layers.
Base class for all map layer types.
void layersAdded(const QList< QgsMapLayer *> &layers)
Emitted when one or more layers were added to the registry.
bool unzip(const QString &zipFilename) override
Clear the current content of this archive and unzip.
QDateTime lastModified() const
Returns last modified time of the project file as returned by the file system (or other project stora...
bool readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads the settings's state from a DOM element.
void setPathResolver(const QgsPathResolver &resolver)
Sets up path resolver for conversion between relative and absolute paths.
void snappingConfigChanged(const QgsSnappingConfig &config)
Emitted whenever the configuration for snapping has changed.
QgsRelationManager * relationManager() const
const QgsAuxiliaryStorage * auxiliaryStorage() const
Returns the current const auxiliary storage.
This is an abstract base class for any elements of a drag and drop form.
static bool isGroup(QgsLayerTreeNode *node)
Check whether the node is a valid group node.
void selectionColorChanged()
Emitted whenever the project's selection color has been changed.
QgsMapLayerType type() const
Returns the type of the layer.
static Q_INVOKABLE QString toString(QgsUnitTypes::DistanceUnit unit)
Returns a translated string representing a distance unit.
void setAvoidIntersectionsLayers(const QList< QgsVectorLayer *> &layers)
A list of layers with which intersections should be avoided.
void isDirtyChanged(bool dirty)
Emitted when the project dirty status changes.
QgsTransactionGroup * transactionGroup(const QString &providerKey, const QString &connString)
Returns the matching transaction group from a provider key and connection string. ...
static QgsApplication * instance()
Returns the singleton instance of the QgsApplication.
QString readEntry(const QString &scope, const QString &key, const QString &def=QString(), bool *ok=nullptr) const
void layerWasAdded(QgsMapLayer *layer)
Emitted when a layer was added to the store.
bool save()
Commits changes and starts editing then.
Manages storage of a set of QgsAnnotation annotation objects.
void dump_(const QgsProjectPropertyKey &topQgsPropertyKey)
void setTopologicalEditing(bool enabled)
Convenience function to set topological editing.
bool readBoolEntry(const QString &scope, const QString &key, bool def=false, bool *ok=nullptr) const
const QgsProjectMetadata & metadata() const
Returns a reference to the project's metadata store.
void setProjectTranslator(QgsProjectTranslator *projectTranslator)
Sets the project translator.
This class is a composition of two QSettings instances:
const QgsProjectDisplaySettings * displaySettings() const
Returns the project's display settings, which settings and properties relating to how a QgsProject sh...
void requestForTranslatableObjects(QgsTranslationContext *translationContext)
Emitted when project strings which require translation are being collected for inclusion in a ...
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
void backgroundColorChanged()
Emitted whenever the project's canvas background color has been changed.
void setSnappingConfig(const QgsSnappingConfig &snappingConfig)
The snapping configuration for this project.
QString toProj() const
Returns a Proj string representation of this CRS.
virtual void writeXml(QDomElement &parentElement, const QgsReadWriteContext &context)=0
Write layer tree to XML.
void writeProject(QDomDocument &doc)
Writes the configuration to the specified QGIS project document.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
static QgsLayerTreeGroup * toGroup(QgsLayerTreeNode *node)
Cast node to a group.
static void warning(const QString &msg)
Goes to qWarning.
Class used to work with layer dependencies stored in a XML project or layer definition file...
void layersRemoved(const QStringList &layerIds)
Emitted after one or more layers were removed from the registry.
QString providerType() const
Returns the provider type (provider key) for this layer.
QgsProjectPropertyKey * addKey(const QString &keyName)
Adds the specified property key as a sub-key.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
QList< QgsMapLayer * > mapLayersByShortName(const QString &shortName) const
Retrieves a list of matching registered layers by layer shortName.
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
CONSTLATIN1STRING geoNone()
Constant that holds the string representation for "No ellips/No CRS".
#define Q_NOWARN_DEPRECATED_PUSH
static bool readOldLegend(QgsLayerTreeGroup *root, const QDomElement &legendElem)
Try to load layer tree from.
void setFileName(const QString &name)
Sets the file name associated with the project.
Class providing some utility methods to manage auxiliary storage.
void crsChanged()
Emitted when the CRS of the project has changed.
void layersAdded(const QList< QgsMapLayer *> &layers)
Emitted when one or more layers were added to the store.
Q_DECL_DEPRECATED void mapScalesChanged()
Emitted when the list of custom project map scales changes.
void generateTsFile(const QString &locale)
Triggers the collection strings of .qgs to be included in ts file and calls writeTsFile() ...
void layersWillBeRemoved(const QStringList &layerIds)
Emitted when one or more layers are about to be removed from the store.
void entryList(QStringList &entries) const
Returns any sub-keys contained by this property that do not contain other keys.
void configChanged()
Emitted whenever the configuration is changed.
Container of fields for a vector layer.
void labelingEngineSettingsChanged()
Emitted when global configuration of the labeling engine changes.
void projectColorsChanged()
Emitted whenever the project's color scheme has been changed.
static QgsPluginLayerRegistry * pluginLayerRegistry()
Returns the application's plugin layer registry, used for managing plugin layer types.
void topologicalEditingChanged()
Emitted when the topological editing flag has changed.
int count() const
Returns the number of registered layers.
void metadataChanged()
Emitted when the project's metadata is changed.
Manages storage of a set of bookmarks.
bool useProjectScales() const
Returns true if project mapScales() are enabled.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
void updateRelationsStatus()
Updates relations status.
static Q_INVOKABLE QgsUnitTypes::DistanceUnit decodeDistanceUnit(const QString &string, bool *ok=nullptr)
Decodes a distance unit from a string.
void reloadAllLayers()
Reload all registered layer's provider data caches, synchronising the layer with any changes in the d...
void resolveReferences(const QgsProject *project, bool looseMatching=false) override
Calls resolveReferences() on child tree nodes.
void legendLayersAdded(const QList< QgsMapLayer *> &layers)
Emitted, when a layer was added to the registry and the legend.
bool isValid() const
Returns the status of the layer.
An interface for classes which can visit style entity (e.g.
void removeKey(const QString &keyName)
Removes the specified key.
void projectSaved()
Emitted when the project file has been written and closed.
void layerWillBeRemoved(const QString &layerId)
Emitted when a layer is about to be removed from the store.
void reset()
reset to default values
void allLayersRemoved()
Emitted when all layers are removed, before layersWillBeRemoved() and layerWillBeRemoved() signals ar...
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Returns a DOM element representing the settings.
QgsMapLayerStore * layerStore()
Returns a pointer to the project's internal layer store.
const QgsBookmarkManager * bookmarkManager() const
Returns the project's bookmark manager, which manages bookmarks within the project.
QgsCoordinateTransformContext transformContext() const
Returns a copy of the project's coordinate transform context, which stores various information regard...
QList< QgsMapLayer * > customLayerOrder() const
The order in which layers will be rendered on the canvas.
void clear()
Remove any relation managed by this class.
QgsProject(QObject *parent=nullptr)
Create a new QgsProject.
static QString extension()
Returns the extension used for auxiliary databases.
static QString userFullName()
Returns the user's operating system login account full display name.
int readNumEntry(const QString &scope, const QString &key, int def=0, bool *ok=nullptr) const
QgsProjectVersion getVersion(const QDomDocument &doc)
Returns the version string found in the given DOM document.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Returns a DOM element representing the settings.
void fileNameChanged()
Emitted when the file name of the project changes.
void readProject(const QDomDocument &doc)
Reads the configuration from the specified QGIS project document.
static QString encodeColor(const QColor &color)
Class allowing to manage the zip/unzip actions on project file.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context, QStringList &missingTransforms)
Reads the context's state from a DOM element.
QgsProjectProperty * find(const QString &propertyName) const
Attempts to find a property with a matching sub-key name.
Q_DECL_DEPRECATED void setNonIdentifiableLayers(const QList< QgsMapLayer *> &layers)
Set a list of layers which should not be taken into account on map identification.
virtual bool isKey() const =0
Returns true if the property is a QgsProjectPropertyKey.
QString presetHomePath() const
Returns any manual project home path setting, or an empty string if not set.
bool writeEntry(const QString &scope, const QString &key, bool value)
Write a boolean entry to the project file.
QgsProjectPropertyValue * setValue(const QString &name, const QVariant &value)
Sets the value associated with this key.
void readSettings()
Reads the context's state from application settings.
void missingDatumTransforms(const QStringList &missingTransforms)
Emitted when datum transforms stored in the project are not available locally.
QString ellipsoidAcronym() const
Returns the ellipsoid acronym for the ellipsoid used by the CRS.
void readProjectWithContext(const QDomDocument &, QgsReadWriteContext &context)
Emitted when a project is being read.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context...
static QString version()
Version string.
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
QList< QgsLayerTreeNode * > children()
Gets list of children of the node. Children are owned by the parent.
bool evaluateDefaultValues() const
Should default values be evaluated on provider side when requested and not when committed.
void setMapScales(const QVector< double > &scales)
Sets the list of custom project map scales.
QgsMapLayer * takeMapLayer(QgsMapLayer *layer)
Takes a layer from the registry.
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...
QgsFields fields() const FINAL
Returns the list of fields of this layer.
QString name() const
The name of the property is used as identifier.
Namespace with helper functions for layer tree operations.
QVariant value() const override
If this key has a value, it will be stored by its name in its properties.
QColor selectionColor() const
Returns the color used to highlight selected features.
QString projectFile() const
Returns the current .qgs project file or an empty string if there's none.
QgsPathResolver pathResolver() const
Returns path resolver object with considering whether the project uses absolute or relative paths and...
#define QgsDebugMsgLevel(str, level)
QgsUnitTypes::AreaUnit areaUnits() const
Convenience function to query default area measurement units for project.
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 setAreaUnits(QgsUnitTypes::AreaUnit unit)
Sets the default area measurement units for the project.
virtual bool visitExit(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor stops visiting a node.
Don't load print layouts. Improves project read time if layouts are not required, and allows projects...
void setTransformContext(const QgsCoordinateTransformContext &transformContext)
Sets data coordinate transform context to transformContext.
A class to describe the version of a project.
QString saveUser() const
Returns the user name that did the last save.
QString layerIsEmbedded(const QString &id) const
Returns project file path if layer is embedded from other project file. Returns empty string if layer...
int count() const
Returns the number of sub-keys contained by this property.
virtual void clearKeys()
Deletes any sub-nodes from the property.
void layerRemoved(const QString &layerId)
Emitted after a layer was removed from the store.
QVector< double > mapScales() const
Returns the list of custom project map scales.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QgsCoordinateReferenceSystem defaultCrsForNewLayers() const
Returns the default CRS for new layers based on the settings and the current project CRS...
void setBadLayerHandler(QgsProjectBadLayerHandler *handler)
Change handler for missing layers.
void dumpProperties() const
Dump out current project properties to stderr.
void reset()
Resets the settings to a default state.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
QMap< QString, QgsRelation > relations() const
Gets access to the relations managed by this class.
void readProject(const QDomDocument &)
Emitted when a project is being read.
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.
Listens to the updates in map layer registry and does changes in layer tree.
bool addLayer(QgsVectorLayer *layer)
Add a layer to this transaction group.
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...
QStringList subkeyList(const QString &scope, const QString &key) const
Returns keys with keys – do not return keys that contain only values.
void clear()
Clear any information from this layer tree.
Don't resolve layer paths or create data providers for layers.
QList< QPair< QColor, QString > > QgsNamedColorList
List of colors paired with a friendly display name identifying the color.
void setCrs(const QgsCoordinateReferenceSystem &crs, bool adjustEllipsoid=false)
Sets the project's native coordinate reference system.
QList< QgsLayerTreeGroup * > findGroups() const
Find all group layer nodes.
static void replaceChildrenOfEmbeddedGroups(QgsLayerTreeGroup *group)
Remove subtree of embedded groups and replaces it with a custom property embedded-visible-layers.
void layerLoaded(int i, int n)
Emitted when a layer from a projects was read.
void setUseProjectScales(bool enabled)
Sets whether project mapScales() are enabled.
Contains information relating to a node (i.e.
void dump(int tabs=0) const override
Dumps out the keys and values.
QStringList readListEntry(const QString &scope, const QString &key, const QStringList &def=QStringList(), bool *ok=nullptr) const
Key value accessors.
void setDistanceUnits(QgsUnitTypes::DistanceUnit unit)
Sets the default distance measurement units for the project.
static bool isLayer(const QgsLayerTreeNode *node)
Check whether the node is a valid layer node.
This class is a base class for nodes in a layer tree.
void dataSourceChanged()
Emitted whenever the layer's data source has been changed.
bool removeEntry(const QString &scope, const QString &key)
Remove the given key.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts, annotations, canvases, etc.
QgsExpressionContextScope * createExpressionContextScope() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
void setEllipsoid(const QString &ellipsoid)
Sets the project's ellipsoid from a proj string representation, e.g., "WGS84".
void setProjectColors(const QgsNamedColorList &colors)
Sets the colors for the project's color scheme (see QgsProjectColorScheme).
void insertChildNodes(int index, const QList< QgsLayerTreeNode *> &nodes)
Insert existing nodes at specified position.
static bool supportsTransaction(const QgsVectorLayer *layer)
Checks if the provider of a given layer supports transactions.
bool createEmbeddedLayer(const QString &layerId, const QString &projectFilePath, QList< QDomNode > &brokenNodes, bool saveFlag=true, QgsProject::ReadFlags flags=nullptr)
Creates a maplayer instance defined in an arbitrary project file.
QList< QgsReadWriteContext::ReadWriteMessage > takeMessages()
Returns the stored messages and remove them.
void writeMapLayer(QgsMapLayer *mapLayer, QDomElement &layerElem, QDomDocument &doc)
Emitted when a layer is being saved.
Encapsulate a field in an attribute table or data source.
void removeAllMapLayers()
Removes all registered layers.
Single scope for storing variables and functions for use within a QgsExpressionContext.
void clear()
Removes and deletes all bookmarks from the manager.
void removeCustomProperty(const QString &key)
Remove a custom property from layer. Properties are stored in a map and saved in project file...
An expression node for expression functions.
virtual bool isValue() const =0
Returns true if the property is a QgsProjectPropertyValue.
Contains information about the context in which a coordinate transform is executed.
const QgsProjectViewSettings * viewSettings() const
Returns the project's view settings, which contains settings and properties relating to how a QgsProj...
void removeKey_(const QString &scope, const QString &key, QgsProjectPropertyKey &rootProperty)
Remove a given key.
QgsEditFormConfig editFormConfig
void setCustomVariables(const QVariantMap &customVariables)
A map of custom project variables.
Manages storage of a set of layouts.
void layersRemoved(const QStringList &layerIds)
Emitted after one or more layers were removed from the store.
QList< QgsMapLayer * > mapLayersByName(const QString &layerName) const
Retrieve a list of matching registered layers by layer name.
QgsAuxiliaryLayer * auxiliaryLayer()
Returns the current auxiliary layer.
QMap< QString, QgsMapLayer * > mapLayers(const bool validOnly=false) const
Returns a map of all registered layers by layer ID.
QList< QgsAttributeEditorElement * > children() const
Gets a list of the children elements of this container.
static QgsProjectStorageRegistry * projectStorageRegistry()
Returns registry of available project storage implementations.
void setProviderProperty(ProviderProperty property, const QVariant &value)
Allows setting arbitrary properties on the provider.
QgsProjectStorage * projectStorage() const
Returns pointer to project storage implementation that handles read/write of the project file...
bool write()
Writes the project to its current associated file (see fileName() ).
Used for the collecting of strings from projects for translation and creation of ts files...
Q_DECL_DEPRECATED void setMapScales(const QVector< double > &scales)
Sets the list of custom project map scales.
QgsAnnotationManager * annotationManager()
Returns pointer to the project's annotation manager.
static QString userLoginName()
Returns the user's operating system login account name.
void readLayerOrderFromXml(const QDomElement &doc)
Load the layer order from an XML element.
const QgsLayoutManager * layoutManager() const
Returns the project's layout manager, which manages print layouts, atlases and reports within the pro...
QStringList makeKeyTokens_(const QString &scope, const QString &key)
Take the given scope and key and convert them to a string list of key tokens that will be used to nav...
void setSelectionColor(const QColor &color)
Sets the color used to highlight selected features.
bool loadAuxiliaryLayer(const QgsAuxiliaryStorage &storage, const QString &key=QString())
Loads the auxiliary layer for this vector layer.
bool removeLayers(const QList< QgsMapLayer *> &layers)
Removes the specified layers from the individual layer configuration.
void registerTranslatableObjects(QgsTranslationContext *translationContext)
Registers the objects that require translation into the translationContext.
static Q_INVOKABLE QString encodeUnit(QgsUnitTypes::DistanceUnit unit)
Encodes a distance unit to a string.
QString absolutePath() const
Returns full absolute path to the project folder if the project is stored in a file system - derived ...
void setMetadata(const QgsProjectMetadata &metadata)
Sets the project's metadata store.
void mapThemeCollectionChanged()
Emitted when the map theme collection changes.
bool topologicalEditing() const
Convenience function to query topological editing status.
bool readLayer(const QDomNode &layerNode)
Reads the layer described in the associated DOM node.
QString homePath() const
Returns the project's home path.
bool isEmpty() const
Returns true if this property contains no sub-keys.
QgsMapThemeCollection * mapThemeCollection()
Returns pointer to the project's map theme collection.
Contains settings and properties relating to how a QgsProject should be displayed inside map canvas...
QString fileName() const
Returns the project's file name.
Project property key node.
DistanceUnit
Units of distance.
QString originalXmlProperties() const
Returns the XML properties of the original layer as they were when the layer was first read from the ...
QgsLayerTree * layerTreeRoot() const
Returns pointer to the root (invisible) node of the project's layer tree.
void writeXml(QDomElement &element, const QgsReadWriteContext &context) const
Writes the context's state to a DOM element.
Q_DECL_DEPRECATED bool useProjectScales() const
Returns true if project mapScales() are enabled.
void transactionGroupsChanged()
Emitted whenever a new transaction group has been created or a transaction group has been removed...
void setPresetHomePath(const QString &path)
Sets the project's home path.
void layerWillBeRemoved(const QString &layerId)
Emitted when a layer is about to be removed from the registry.
void writeTsFile(const QString &locale)
Writes the Ts-file.
#define Q_NOWARN_DEPRECATED_POP
void setFileName(const QString &fileName)
Sets the fileName of the TS file.
void setBackgroundColor(const QColor &color)
Sets the default background color used by default map canvases.
void registerTranslation(const QString &context, const QString &source)
Registers the source to be translated.
void writeProject(QDomDocument &)
Emitted when the project is being written.
QVector< T > layers() const
Returns a list of registered map layers with a specified layer type.
bool isZipped() const
Returns true if the project comes from a zip archive, false otherwise.
void oldProjectVersionWarning(const QString &)
Emitted when an old project file is read.
static QgsCoordinateReferenceSystem fromProj(const QString &proj)
Creates a CRS from a proj style formatted string.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads the settings's state from a DOM element.
void customVariablesChanged()
Emitted whenever the expression variables stored in the project have been changed.
Q_DECL_DEPRECATED QFileInfo fileInfo() const
Returns QFileInfo object for the project's associated file.
void layerRemoved(const QString &layerId)
Emitted after a layer was removed from the registry.
static QgsCoordinateReferenceSystem fromOgcWmsCrs(const QString &ogcCrs)
Creates a CRS from a given OGC WMS-format Coordinate Reference System string.
void resolveReferences(const QgsProject *project, bool looseMatching=false) override
Resolves reference to layer from stored layer ID (if it has not been resolved already) ...
void cleared()
Emitted when the project is cleared (and additionally when an open project is cleared just before a n...
void layersWillBeRemoved(const QStringList &layerIds)
Emitted when one or more layers are about to be removed from the registry.
virtual bool visitEnter(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor starts visiting a node.
bool autoTransaction() const
Transactional editing means that on supported datasources (postgres databases) the edit state of all ...
void setAutoTransaction(bool autoTransaction)
Transactional editing means that on supported datasources (postgres databases) the edit state of all ...
QString source() const
Returns the source for the layer.
QMap< QPair< QString, QString >, QgsTransactionGroup * > transactionGroups()
Map of transaction groups.
void setProject(QgsProject *project)
Sets the project being translated.
void registerTranslatableContainers(QgsTranslationContext *translationContext, QgsAttributeEditorContainer *parent, const QString &layerId)
Registers the containers that require translation into the translationContext.
virtual void handleBadLayers(const QList< QDomNode > &layers)
This method will be called whenever the project tries to load layers which cannot be accessed...
Q_DECL_DEPRECATED QVector< double > mapScales() const
Returns the list of custom project map scales.
This class manages a set of relations between layers.
QgsLayerTreeGroup * findGroup(const QString &name)
Find group node with specified name.
QgsSnappingConfig snappingConfig() const
The snapping configuration for this project.
Stores global configuration for labeling engine.
static QgsProject * instance()
Returns the QgsProject singleton instance.
void removeMapLayer(const QString &layerId)
Remove a layer from the registry by layer ID.
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...
This class represents a coordinate reference system (CRS).
Q_DECL_DEPRECATED void setUseProjectScales(bool enabled)
Sets whether project mapScales() are enabled.
static void storeOriginalLayersProperties(QgsLayerTreeGroup *group, const QDomDocument *doc)
Stores in a layer's originalXmlProperties the layer properties information.
void setTransformContext(const QgsCoordinateTransformContext &context)
Sets the project's coordinate transform context, which stores various information regarding which dat...
bool read(const QString &filename, QgsProject::ReadFlags flags=nullptr)
Reads given project file from the given file.
void setTitle(const QString &title)
Sets the project's title.
This is a container for attribute editors, used to group them visually in the attribute form if it is...
void loadingLayer(const QString &layerName)
Emitted when a layer is loaded.
QgsCoordinateReferenceSystem crs() const
Returns the project's native coordinate reference system.
bool isEmpty() const
Checks whether the container is empty.
void setEnabled(bool enabled)
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
Abstract interface for project storage - to be implemented by various backends and registered in QgsP...
If the layer can be removed from the project. The layer will not be removable from the legend menu en...
void loadingLayerMessageReceived(const QString &layerName, const QList< QgsReadWriteContext::ReadWriteMessage > &messages)
Emitted when loading layers has produced some messages.
void mapScalesChanged()
Emitted when the list of custom project map scales changes.
bool readXml(const QDomNode &node)
Restores state from the given DOM node.
An Abstract Base Class for QGIS project property hierarchys.
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
void setItemVisibilityChecked(bool checked)
Check or uncheck a node (independently of its ancestors or children)
QgsMapLayer * addMapLayer(QgsMapLayer *mapLayer, bool addToLegend=true, bool takeOwnership=true)
Add a layer to the map of loaded layers.
bool accept(QgsStyleEntityVisitorInterface *visitor) const
Accepts the specified style entity visitor, causing it to visit all style entities associated with th...
void homePathChanged()
Emitted when the home path of the project changes.
void removeMapLayers(const QStringList &layerIds)
Remove a set of layers from the registry by layer ID.
double readDoubleEntry(const QString &scope, const QString &key, double def=0, bool *ok=nullptr) const
void subkeyList(QStringList &entries) const
Returns any sub-keys contained by this property which themselves contain other keys.
bool readXml(const QDomNode &keyNode) override
Restores the property hierarchy from a specified DOM node.
A storage object for map layers, in which the layers are owned by the store and have their lifetime b...
QString name() const override
Returns the group's name.
void avoidIntersectionsLayersChanged()
Emitted whenever avoidIntersectionsLayers has changed.
QStringList findLayerIds() const
Find layer IDs used in all layer nodes.
Contains settings and properties relating to how a QgsProject should display values such as map coord...
Container class that allows storage of map themes consisting of visible map layers and layer styles...
void transformContextChanged()
Emitted when the project transformContext() is changed.
QString title() const
Returns the project's title.
This is a container for configuration of the snapping of the project.
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
QgsUnitTypes::DistanceUnit distanceUnits() const
Convenience function to query default distance measurement units for project.
QgsFields auxiliaryFields() const
Returns a list of all auxiliary fields currently managed by the layer.
QVariantMap customVariables() const
A map of custom project variables.
void readMapLayer(QgsMapLayer *mapLayer, const QDomElement &layerNode)
Emitted after the basic initialization of a layer from the project file is done.
QList< QgsLayerTreeLayer * > findLayers() const
Find all layer nodes.
Don't resolve layer paths (i.e. don't load any layer content). Dramatically improves project read tim...
QString ellipsoid() const
Returns a proj string representing the project's ellipsoid setting, e.g., "WGS84".
QgsLayerTreeLayer * findLayer(QgsMapLayer *layer) const
Find layer node representing the map layer.
QString baseName() const
Returns the base name of the project file without the path and without extension - derived from fileN...
QDomElement writeXml(QDomDocument &doc) const
Returns a DOM element representing the state of the manager.
Resolves relative paths into absolute paths and vice versa.
bool addLayers(const QList< QgsMapLayer *> &layers)
Adds the specified layers as individual layers to the configuration with standard configuration...
void collectTranslatableObjects(QgsTranslationContext *translationContext)
Emits the signal to collect all the strings of .qgs to be included in ts file.
Class for storing the component parts of a RDBMS data source URI (e.g.
bool writeXml(QDomNode &node, QDomDocument &doc) const
Stores state to the given Dom node in the given document.
QString absoluteFilePath() const
Returns full absolute path to the project file if the project is stored in a file system - derived fr...
QgsProjectProperty * findKey_(const QString &scope, const QString &key, QgsProjectPropertyKey &rootProperty)
return the property that matches the given key sequence, if any
void setEvaluateDefaultValues(bool evaluateDefaultValues)
Defines if default values should be evaluated on provider side when requested and not when committed...
Represents a vector layer which manages a vector based data sets.
QgsMapLayer * mapLayer(const QString &id) const
Retrieve a pointer to a layer by layer id.
QColor backgroundColor() const
Returns the default background color used by default map canvases.
void reset()
Resets the settings to a default state.
QString name() const
Returns the name of this element.
QList< QgsVectorLayer * > avoidIntersectionsLayers() const
A list of layers with which intersections should be avoided.
QgsProjectStorage * projectStorageFromUri(const QString &uri)
Returns storage implementation if the URI matches one. Returns nullptr otherwise (it is a normal file...
CONSTLATIN1STRING geoEpsgCrsAuthId()
Geographic coord sys from EPSG authority.
bool writeLayerXml(QDomElement &layerElement, QDomDocument &document, const QgsReadWriteContext &context) const
Stores state in DOM node.
QgsLayerTree * clone() const override
Create a copy of the node. Returns new instance.
void setName(const QString &name)
The name of the property is used as identifier.
Evaluate default values on provider side when calling QgsVectorDataProvider::defaultValue( int index ...
QgsProjectProperty * addKey_(const QString &scope, const QString &key, QgsProjectPropertyKey *rootProperty, const QVariant &value, bool &propertiesModified)
Add the given key and value.
If the layer is identifiable using the identify map tool and as a WMS layer.
void ellipsoidChanged(const QString &ellipsoid)
Emitted when the project ellipsoid is changed.
QStringList entryList(const QString &scope, const QString &key) const
Returns keys with values – do not return keys that contain other keys.
void removeAll()
Emitted when all layers are removed, before layersWillBeRemoved() and layerWillBeRemoved() signals ar...
void _getProperties(const QDomDocument &doc, QgsProjectPropertyKey &project_properties)
Restore any optional properties found in "doc" to "properties".
bool writeXml(const QString &nodeName, QDomElement &element, QDomDocument &document) override
Writes the property hierarchy to a specified DOM element.
Expression function for use within a QgsExpressionContextScope.
QString authid() const
Returns the authority identifier for the CRS.
void setLabelingEngineSettings(const QgsLabelingEngineSettings &settings)
Sets project's global labeling engine settings.
void clear()
Clears the project, removing all settings and resetting it back to an empty, default state...
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...
static void updateEmbeddedGroupsProjectPath(QgsLayerTreeGroup *group, const QgsProject *project)
Updates an embedded group from a project.
Interface for classes that handle missing layer files when reading project file.
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
Q_DECL_DEPRECATED void nonIdentifiableLayersChanged(QStringList nonIdentifiableLayers)
Emitted when the list of layer which are excluded from map identification changes.
static QgsCoordinateReferenceSystem fromSrsId(long srsId)
Creates a CRS from a specified QGIS SRS ID.
static QColor decodeColor(const QString &str)
QString saveUserFullName() const
Returns the full user name that did the last save.
void layerWasAdded(QgsMapLayer *layer)
Emitted when a layer was added to the registry.
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...
Layer tree node points to a map layer.
void setReadExtentFromXml(bool readExtentFromXml)
Flag allowing to indicate if the extent has to be read from the XML document when data source has no ...
const QgsLabelingEngineSettings & labelingEngineSettings() const
Returns project's global labeling engine settings.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
int validCount() const
Returns the number of registered valid layers.
QgsLayerTreeGroup * createEmbeddedGroup(const QString &groupName, const QString &projectFilePath, const QStringList &invisibleLayers, QgsProject::ReadFlags flags=nullptr)
Create layer group instance defined in an arbitrary project file.