62 #include <QApplication> 66 #include <QTextStream> 67 #include <QTemporaryFile> 73 #include <sys/utime.h> 91 QStringList keyTokens = QStringList( scope );
92 keyTokens += key.split(
'/', QString::SkipEmptyParts );
95 keyTokens.push_front( QStringLiteral(
"properties" ) );
98 for (
int i = 0; i < keyTokens.size(); ++i )
100 QString keyToken = keyTokens.at( i );
104 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]" );
105 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]" );
107 if ( keyToken.contains( QRegExp( nameCharRegexp ) ) || keyToken.contains( QRegExp( nameStartCharRegexp ) ) )
110 QString errorString = QObject::tr(
"Entry token invalid : '%1'. The token will not be saved to file." ).arg( keyToken );
140 while ( !keySequence.isEmpty() )
144 if ( keySequence.first() == currentProperty->
name() )
147 keySequence.pop_front();
149 if ( 1 == keySequence.count() )
152 return currentProperty->
find( keySequence.front() );
154 else if ( keySequence.isEmpty() )
159 return currentProperty;
161 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
163 if ( nextProperty->
isKey() )
167 else if ( nextProperty->
isValue() && 1 == keySequence.count() )
173 return currentProperty;
211 const QVariant &value,
212 bool &propertiesModified )
221 propertiesModified =
false;
222 while ( ! keySequence.isEmpty() )
226 if ( keySequence.first() == currentProperty->
name() )
229 keySequence.pop_front();
233 if ( 1 == keySequence.count() )
236 if ( !property || property->value() != value )
238 currentProperty->
setValue( keySequence.front(), value );
239 propertiesModified =
true;
242 return currentProperty;
246 else if ( keySequence.isEmpty() )
248 if ( currentProperty->
value() != value )
251 propertiesModified =
true;
254 return currentProperty;
256 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
260 if ( currentProperty )
271 if ( ( newPropertyKey = currentProperty->
addKey( keySequence.first() ) ) )
273 currentProperty = newPropertyKey;
306 while ( ! keySequence.isEmpty() )
310 if ( keySequence.first() == currentProperty->
name() )
313 keySequence.pop_front();
317 if ( 1 == keySequence.count() )
319 currentProperty->
removeKey( keySequence.front() );
324 else if ( keySequence.isEmpty() )
326 previousQgsPropertyKey->
removeKey( currentProperty->
name() );
328 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
330 previousQgsPropertyKey = currentProperty;
333 if ( currentProperty )
359 , mSnappingConfig( this )
369 mProperties.
setName( QStringLiteral(
"properties" ) );
401 [ = ](
const QList<QgsMapLayer *> &
layers )
403 for (
const auto &layer :
layers )
410 [ = ](
const QList<QgsMapLayer *> &
layers )
412 for (
const auto &layer :
layers )
423 mIsBeingDeleted =
true;
426 delete mBadLayerHandler;
427 delete mRelationManager;
428 delete mLayerTreeRegistryBridge;
430 if (
this == sProject )
436 void QgsProject::setInstance(
QgsProject *project )
453 if ( title == mMetadata.
title() )
457 mProjectScope.reset();
465 return mMetadata.
title();
475 if ( dirty && mDirtyBlockCount > 0 )
478 if ( mDirty == dirty )
487 if ( path == mHomePath )
491 mCachedHomePath.clear();
492 mProjectScope.reset();
501 const QList<QgsAttributeEditorElement *> elements = parent->
children();
509 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:formcontainers" ).arg( layerId ), container->
name() );
511 if ( !container->
children().empty() )
524 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1" ).arg( layer->layerId() ), layer->name() );
533 for (
const QgsField &field : fields )
536 if ( field.alias().isEmpty() )
537 fieldName = field.name();
539 fieldName = field.alias();
541 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:fieldaliases" ).arg( vlayer->
id() ), fieldName );
543 if ( field.editorWidgetSetup().type() == QStringLiteral(
"ValueRelation" ) )
545 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:fields:%2:valuerelationvalue" ).arg( vlayer->
id(), field.name() ), field.editorWidgetSetup().config().value( QStringLiteral(
"Value" ) ).toString() );
556 const QList<QgsLayerTreeGroup *> groupLayers = mRootGroup->
findGroups();
559 translationContext->
registerTranslation( QStringLiteral(
"project:layergroups" ), groupLayer->name() );
563 const QList<QgsRelation> &relations = mRelationManager->
relations().values();
566 translationContext->
registerTranslation( QStringLiteral(
"project:relations" ), relation.name() );
572 if ( name == mFile.fileName() )
577 mFile.setFileName( name );
578 mCachedHomePath.clear();
579 mProjectScope.reset();
584 if ( newHomePath != oldHomePath )
592 return mFile.fileName();
597 return QFileInfo( mFile );
610 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
624 if ( mFile.fileName().isEmpty() )
635 if ( mFile.fileName().isEmpty() )
646 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
647 return metadata.
name;
651 return QFileInfo( mFile.fileName() ).completeBaseName();
665 writeEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectionsEnabled" ), crs.
isValid() ? 1 : 0 );
666 mProjectScope.reset();
671 if ( adjustEllipsoid )
677 if ( !
crs().isValid() )
680 return readEntry( QStringLiteral(
"Measure" ), QStringLiteral(
"/Ellipsoid" ),
GEO_NONE );
685 if ( ellipsoid ==
readEntry( QStringLiteral(
"Measure" ), QStringLiteral(
"/Ellipsoid" ) ) )
688 mProjectScope.reset();
689 writeEntry( QStringLiteral(
"Measure" ), QStringLiteral(
"/Ellipsoid" ), ellipsoid );
695 return mTransformContext;
700 if ( context == mTransformContext )
703 mTransformContext = context;
704 mProjectScope.reset();
706 for (
auto &layer : mLayerStore.get()->mapLayers() )
708 layer->setTransformContext( context );
717 mProjectScope.reset();
718 mFile.setFileName( QString() );
721 mCachedHomePath.clear();
722 mAutoTransaction =
false;
723 mEvaluateDefaultValues =
false;
725 mTrustLayerMetadata =
false;
726 mCustomVariables.clear();
728 if ( !settings.
value( QStringLiteral(
"projects/anonymize_new_projects" ),
false,
QgsSettings::Core ).toBool() )
739 mEmbeddedLayers.clear();
740 mRelationManager->
clear();
741 mAnnotationManager->clear();
742 mLayoutManager->clear();
743 mBookmarkManager->
clear();
744 mSnappingConfig.
reset();
751 mLabelingEngineSettings->clear();
758 if ( !mIsBeingDeleted )
766 writeEntry( QStringLiteral(
"PositionPrecision" ), QStringLiteral(
"/Automatic" ),
true );
767 writeEntry( QStringLiteral(
"PositionPrecision" ), QStringLiteral(
"/DecimalPlaces" ), 2 );
768 writeEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
false );
771 writeEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/DistanceUnits" ), settings.
value( QStringLiteral(
"/qgis/measure/displayunits" ) ).toString() );
772 writeEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/AreaUnits" ), settings.
value( QStringLiteral(
"/qgis/measure/areaunits" ) ).toString() );
774 int red = settings.
value( QStringLiteral(
"qgis/default_canvas_color_red" ), 255 ).toInt();
775 int green = settings.
value( QStringLiteral(
"qgis/default_canvas_color_green" ), 255 ).toInt();
776 int blue = settings.
value( QStringLiteral(
"qgis/default_canvas_color_blue" ), 255 ).toInt();
779 red = settings.
value( QStringLiteral(
"qgis/default_selection_color_red" ), 255 ).toInt();
780 green = settings.
value( QStringLiteral(
"qgis/default_selection_color_green" ), 255 ).toInt();
781 blue = settings.
value( QStringLiteral(
"qgis/default_selection_color_blue" ), 0 ).toInt();
782 int alpha = settings.
value( QStringLiteral(
"qgis/default_selection_color_alpha" ), 255 ).toInt();
796 QgsDebugMsg( QStringLiteral(
"current properties:" ) );
797 topQgsPropertyKey.
dump();
833 QDomElement propertiesElem = doc.documentElement().firstChildElement( QStringLiteral(
"properties" ) );
835 if ( propertiesElem.isNull() )
840 QDomNodeList scopes = propertiesElem.childNodes();
842 if ( scopes.count() < 1 )
844 QgsDebugMsg( QStringLiteral(
"empty ``properties'' XML tag ... bailing" ) );
848 if ( ! project_properties.
readXml( propertiesElem ) )
850 QgsDebugMsg( QStringLiteral(
"Project_properties.readXml() failed" ) );
859 static void _getTitle(
const QDomDocument &doc, QString &
title )
861 QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"title" ) );
867 QgsDebugMsg( QStringLiteral(
"unable to find title element" ) );
871 QDomNode titleNode = nl.item( 0 );
873 if ( !titleNode.hasChildNodes() )
875 QgsDebugMsg( QStringLiteral(
"unable to find title element" ) );
879 QDomNode titleTextNode = titleNode.firstChild();
881 if ( !titleTextNode.isText() )
883 QgsDebugMsg( QStringLiteral(
"unable to find title element" ) );
887 QDomText titleText = titleTextNode.toText();
889 title = titleText.data();
895 QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"qgis" ) );
899 QgsDebugMsg( QStringLiteral(
" unable to find qgis element in project file" ) );
903 QDomNode qgisNode = nl.item( 0 );
905 QDomElement qgisElement = qgisNode.toElement();
906 QgsProjectVersion projectVersion( qgisElement.attribute( QStringLiteral(
"version" ) ) );
907 return projectVersion;
913 return mSnappingConfig;
918 if ( mSnappingConfig == snappingConfig )
926 bool QgsProject::_getMapLayers(
const QDomDocument &doc, QList<QDomNode> &brokenNodes, QgsProject::ReadFlags flags )
931 QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"maplayer" ) );
935 if ( 0 == nl.count() )
945 bool returnStatus =
true;
951 if ( depSorter.hasCycle() || depSorter.hasMissingDependency() )
954 const QVector<QDomNode> sortedLayerNodes = depSorter.sortedLayerNodes();
955 const int totalLayerCount = sortedLayerNodes.count();
958 for (
const QDomNode &node : sortedLayerNodes )
960 const QDomElement element = node.toElement();
962 const QString name =
translate( QStringLiteral(
"project:layers:%1" ).arg( node.namedItem( QStringLiteral(
"id" ) ).toElement().text() ), node.namedItem( QStringLiteral(
"layername" ) ).toElement().text() );
963 if ( !name.isNull() )
964 emit
loadingLayer( tr(
"Loading layer %1" ).arg( name ) );
966 if ( element.attribute( QStringLiteral(
"embedded" ) ) == QLatin1String(
"1" ) )
968 createEmbeddedLayer( element.attribute( QStringLiteral(
"id" ) ),
readPath( element.attribute( QStringLiteral(
"project" ) ) ), brokenNodes, flags );
977 if ( !addLayer( element, brokenNodes, context, flags ) )
979 returnStatus =
false;
982 if ( !messages.isEmpty() )
994 bool QgsProject::addLayer(
const QDomElement &layerElem, QList<QDomNode> &brokenNodes,
QgsReadWriteContext &context, QgsProject::ReadFlags flags )
996 QString type = layerElem.attribute( QStringLiteral(
"type" ) );
998 std::unique_ptr<QgsMapLayer>
mapLayer;
1000 if ( type == QLatin1String(
"vector" ) )
1002 mapLayer = qgis::make_unique<QgsVectorLayer>();
1004 if (
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( mapLayer.get() ) )
1006 vl->setReadExtentFromXml( mTrustLayerMetadata );
1009 else if ( type == QLatin1String(
"raster" ) )
1011 mapLayer = qgis::make_unique<QgsRasterLayer>();
1013 else if ( type == QLatin1String(
"mesh" ) )
1015 mapLayer = qgis::make_unique<QgsMeshLayer>();
1017 else if ( type == QLatin1String(
"plugin" ) )
1019 QString
typeName = layerElem.attribute( QStringLiteral(
"name" ) );
1025 QgsDebugMsg( QStringLiteral(
"Unable to create layer" ) );
1029 Q_CHECK_PTR( mapLayer );
1033 const QString layerId { layerElem.namedItem( QStringLiteral(
"id" ) ).toElement().text() };
1034 Q_ASSERT( ! layerId.isEmpty() );
1038 QgsMapLayer::ReadFlags layerFlags =
nullptr;
1041 bool layerIsValid = mapLayer->readLayerXml( layerElem, context, layerFlags ) && mapLayer->isValid();
1042 QList<QgsMapLayer *> newLayers;
1043 newLayers << mapLayer.get();
1044 if ( layerIsValid || flags & QgsProject::FlagDontResolveLayers )
1054 QgsDebugMsg(
"Unable to load " + type +
" layer" );
1055 brokenNodes.push_back( layerElem );
1060 if ( ! layerWasStored )
1065 return layerIsValid;
1070 mFile.setFileName( filename );
1071 mCachedHomePath.clear();
1072 mProjectScope.reset();
1074 return read( flags );
1079 QString filename = mFile.fileName();
1084 QTemporaryFile inDevice;
1085 if ( !inDevice.open() )
1087 setError( tr(
"Unable to open %1" ).arg( inDevice.fileName() ) );
1093 if ( !storage->readProject( filename, &inDevice, context ) )
1095 QString err = tr(
"Unable to open %1" ).arg( filename );
1096 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
1097 if ( !messages.isEmpty() )
1098 err += QStringLiteral(
"\n\n" ) + messages.last().message();
1102 returnValue = unzip( inDevice.fileName(), flags );
1108 returnValue = unzip( mFile.fileName(), flags );
1113 returnValue = readProjectFile( mFile.fileName(), flags );
1119 mFile.setFileName( filename );
1120 mCachedHomePath.clear();
1121 mProjectScope.reset();
1126 mTranslator.reset(
nullptr );
1133 bool QgsProject::readProjectFile(
const QString &filename, QgsProject::ReadFlags flags )
1135 QFile projectFile( filename );
1140 QString localeFileName = QStringLiteral(
"%1_%2" ).arg( QFileInfo( projectFile.fileName() ).
baseName(), settings.
value( QStringLiteral(
"locale/userLocale" ), QString() ).toString() );
1142 if ( QFile( QStringLiteral(
"%1/%2.qm" ).arg( QFileInfo( projectFile.fileName() ).
absolutePath(), localeFileName ) ).exists() )
1144 mTranslator.reset(
new QTranslator() );
1145 mTranslator->load( localeFileName, QFileInfo( projectFile.fileName() ).
absolutePath() );
1148 std::unique_ptr<QDomDocument> doc(
new QDomDocument( QStringLiteral(
"qgis" ) ) );
1150 if ( !projectFile.open( QIODevice::ReadOnly | QIODevice::Text ) )
1152 projectFile.close();
1154 setError( tr(
"Unable to open %1" ).arg( projectFile.fileName() ) );
1163 if ( !doc->setContent( &projectFile, &errorMsg, &line, &column ) )
1167 QMessageBox::critical( 0, tr(
"Read Project File" ),
1168 tr(
"%1 at line %2 column %3" ).arg( errorMsg ).arg( line ).arg( column ) );
1171 QString errorString = tr(
"Project file read error in file %1: %2 at line %3 column %4" )
1172 .arg( projectFile.fileName(), errorMsg ).arg( line ).arg( column );
1176 projectFile.close();
1178 setError( tr(
"%1 for file %2" ).arg( errorString, projectFile.fileName() ) );
1183 projectFile.close();
1185 QgsDebugMsg(
"Opened document " + projectFile.fileName() );
1191 if ( thisVersion > fileVersion )
1194 "version of qgis (saved in " + fileVersion.text() +
1196 "). Problems may occur." );
1203 projectFile.updateRevision( thisVersion );
1207 QString
fileName = mFile.fileName();
1208 std::unique_ptr<QgsAuxiliaryStorage> aStorage = std::move( mAuxiliaryStorage );
1210 mAuxiliaryStorage = std::move( aStorage );
1211 mFile.setFileName( fileName );
1212 mCachedHomePath.clear();
1213 mProjectScope.reset();
1218 QgsDebugMsg( QString::number( mProperties.
count() ) +
" properties read" );
1221 dump_( mProperties );
1226 _getTitle( *doc, oldTitle );
1228 QDomNodeList homePathNl = doc->elementsByTagName( QStringLiteral(
"homePath" ) );
1229 if ( homePathNl.count() > 0 )
1231 QDomElement homePathElement = homePathNl.at( 0 ).toElement();
1232 QString
homePath = homePathElement.attribute( QStringLiteral(
"path" ) );
1233 if ( !homePath.isEmpty() )
1242 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorGreenPart" ), 255 ),
1243 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorBluePart" ), 255 ) );
1246 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorGreenPart" ), 255 ),
1247 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorBluePart" ), 255 ),
1248 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorAlphaPart" ), 255 ) );
1257 if (
readNumEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectionsEnabled" ), 0 ) )
1260 QDomNode srsNode = doc->documentElement().namedItem( QStringLiteral(
"projectCrs" ) );
1261 if ( !srsNode.isNull() )
1263 projectCrs.
readXml( srsNode );
1268 QString projCrsString =
readEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCRSProj4String" ) );
1269 long currentCRS =
readNumEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCRSID" ), -1 );
1272 if ( currentCRS >= 0 )
1278 if ( !projCrsString.isEmpty() && ( !projectCrs.
isValid() || projectCrs.
toProj4() != projCrsString ) )
1292 QStringList datumErrors;
1293 if ( !mTransformContext.
readXml( doc->documentElement(), context, datumErrors ) && !datumErrors.empty() )
1299 QDomNodeList nl = doc->elementsByTagName( QStringLiteral(
"projectMetadata" ) );
1300 if ( !nl.isEmpty() )
1302 QDomElement metadataElement = nl.at( 0 ).toElement();
1310 if ( mMetadata.
title().isEmpty() && !oldTitle.isEmpty() )
1317 nl = doc->elementsByTagName( QStringLiteral(
"autotransaction" ) );
1320 QDomElement transactionElement = nl.at( 0 ).toElement();
1321 if ( transactionElement.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
1322 mAutoTransaction =
true;
1325 nl = doc->elementsByTagName( QStringLiteral(
"evaluateDefaultValues" ) );
1328 QDomElement evaluateDefaultValuesElement = nl.at( 0 ).toElement();
1329 if ( evaluateDefaultValuesElement.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
1330 mEvaluateDefaultValues =
true;
1333 nl = doc->elementsByTagName( QStringLiteral(
"trust" ) );
1336 QDomElement trustElement = nl.at( 0 ).toElement();
1337 if ( trustElement.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
1338 mTrustLayerMetadata =
true;
1345 QDomElement layerTreeElem = doc->documentElement().firstChildElement( QStringLiteral(
"layer-tree-group" ) );
1346 if ( !layerTreeElem.isNull() )
1355 mLayerTreeRegistryBridge->
setEnabled(
false );
1358 QList<QDomNode> brokenNodes;
1359 bool clean = _getMapLayers( *doc, brokenNodes, flags );
1364 QgsDebugMsg( QStringLiteral(
"Unable to get map layers from project file." ) );
1366 if ( !brokenNodes.isEmpty() )
1368 QgsDebugMsg(
"there are " + QString::number( brokenNodes.size() ) +
" broken layers" );
1378 QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
1379 for ( QMap<QString, QgsMapLayer *>::iterator it = layers.begin(); it != layers.end(); it++ )
1381 it.value()->resolveReferences(
this );
1384 mLayerTreeRegistryBridge->
setEnabled(
true );
1387 loadEmbeddedNodes( mRootGroup, flags );
1393 if ( !layerTreeElem.isNull() )
1399 QDomElement layerTreeCanvasElem = doc->documentElement().firstChildElement( QStringLiteral(
"layer-tree-canvas" ) );
1400 if ( !layerTreeCanvasElem.isNull( ) )
1408 const QStringList requiredLayerIds =
readListEntry( QStringLiteral(
"RequiredLayers" ), QStringLiteral(
"Layers" ) );
1409 for (
const QString &layerId : requiredLayerIds )
1413 layer->setFlags( layer->flags() & ~
QgsMapLayer::Removable );
1416 const QStringList disabledLayerIds =
readListEntry( QStringLiteral(
"Identify" ), QStringLiteral(
"/disabledLayers" ) );
1417 for (
const QString &layerId : disabledLayerIds )
1421 layer->setFlags( layer->flags() & ~
QgsMapLayer::Identifiable );
1435 mMapThemeCollection->readXml( *doc );
1437 mLabelingEngineSettings->readSettingsFromProject(
this );
1440 mAnnotationManager->readXml( doc->documentElement(), context );
1442 mLayoutManager->readXml( doc->documentElement(), *doc );
1443 mBookmarkManager->
readXml( doc->documentElement(), *doc );
1446 QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
1447 for ( QMap<QString, QgsMapLayer *>::iterator it = existingMaps.begin(); it != existingMaps.end(); it++ )
1449 it.value()->setDependencies( it.value()->dependencies() );
1454 QStringList variableNames =
readListEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableNames" ) );
1455 QStringList variableValues =
readListEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableValues" ) );
1457 mCustomVariables.clear();
1458 if ( variableNames.length() == variableValues.length() )
1460 for (
int i = 0; i < variableNames.length(); ++i )
1462 mCustomVariables.insert( variableNames.at( i ), variableValues.at( i ) );
1467 QgsMessageLog::logMessage( tr(
"Project Variables Invalid" ), tr(
"The project contains invalid variable settings." ) );
1491 QString newFileName( QStringLiteral(
"%1/%2.qgs" ).arg( QFileInfo( projectFile.fileName() ).
absolutePath(), localeFileName ) );
1508 void QgsProject::loadEmbeddedNodes(
QgsLayerTreeGroup *group, QgsProject::ReadFlags flags )
1511 const auto constChildren = group->
children();
1517 if ( childGroup->
customProperty( QStringLiteral(
"embedded" ) ).toInt() )
1520 QString projectPath =
readPath( childGroup->
customProperty( QStringLiteral(
"embedded_project" ) ).toString() );
1521 childGroup->
setCustomProperty( QStringLiteral(
"embedded_project" ), projectPath );
1525 QList<QgsLayerTreeNode *> clonedChildren;
1526 const auto constChildren = newGroup->
children();
1528 clonedChildren << newGroupChild->clone();
1536 loadEmbeddedNodes( childGroup, flags );
1541 if ( child->customProperty( QStringLiteral(
"embedded" ) ).toInt() )
1543 QList<QDomNode> brokenNodes;
1553 return mCustomVariables;
1558 if ( variables == mCustomVariables )
1562 QStringList variableNames;
1563 QStringList variableValues;
1565 QVariantMap::const_iterator it = variables.constBegin();
1566 for ( ; it != variables.constEnd(); ++it )
1568 variableNames << it.key();
1569 variableValues << it.value().toString();
1572 writeEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableNames" ), variableNames );
1573 writeEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableValues" ), variableValues );
1575 mCustomVariables = variables;
1576 mProjectScope.reset();
1583 *mLabelingEngineSettings = settings;
1589 return *mLabelingEngineSettings;
1594 return mLayerStore.get();
1599 return mLayerStore.get();
1604 QList<QgsVectorLayer *>
layers;
1605 QStringList layerIds =
readListEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsList" ), QStringList() );
1606 const auto constLayerIds = layerIds;
1607 for (
const QString &layerId : constLayerIds )
1618 const auto constLayers =
layers;
1620 list << layer->id();
1621 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsList" ), list );
1638 if ( mProjectScope )
1640 std::unique_ptr< QgsExpressionContextScope > projectScope = qgis::make_unique< QgsExpressionContextScope >( *mProjectScope );
1644 return projectScope.release();
1647 mProjectScope = qgis::make_unique< QgsExpressionContextScope >( QObject::tr(
"Project" ) );
1651 QVariantMap::const_iterator it = vars.constBegin();
1653 for ( ; it != vars.constEnd(); ++it )
1655 mProjectScope->setVariable( it.key(), it.value(), true );
1659 QString projectFolder = QFileInfo( projectPath ).path();
1660 QString projectFilename = QFileInfo( projectPath ).fileName();
1661 QString projectBasename =
baseName();
1683 QVariantMap keywords;
1685 for (
auto it = metadataKeywords.constBegin(); it != metadataKeywords.constEnd(); ++it )
1687 keywords.insert( it.key(), it.value() );
1691 mProjectScope->addFunction( QStringLiteral(
"project_color" ),
new GetNamedProjectColor(
this ) );
1696 void QgsProject::onMapLayersAdded(
const QList<QgsMapLayer *> &
layers )
1698 QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
1700 bool tgChanged =
false;
1702 const auto constLayers =
layers;
1705 if ( layer->isValid() )
1722 mTransactionGroups.insert( qMakePair( key, connString ), tg );
1737 for ( QMap<QString, QgsMapLayer *>::iterator it = existingMaps.begin(); it != existingMaps.end(); it++ )
1739 QSet<QgsMapLayerDependency> deps = it.value()->dependencies();
1740 if ( deps.contains( layer->id() ) )
1743 it.value()->setDependencies( deps );
1749 if ( mSnappingConfig.
addLayers( layers ) )
1753 void QgsProject::onMapLayersRemoved(
const QList<QgsMapLayer *> &
layers )
1759 void QgsProject::cleanTransactionGroups(
bool force )
1761 bool changed =
false;
1762 for ( QMap< QPair< QString, QString>,
QgsTransactionGroup *>::Iterator tg = mTransactionGroups.begin(); tg != mTransactionGroups.end(); )
1764 if ( tg.value()->isEmpty() || force )
1767 tg = mTransactionGroups.erase( tg );
1785 QList<QDomNode> brokenNodes;
1786 if ( addLayer( layerNode.toElement(), brokenNodes, context ) )
1790 QVector<QgsVectorLayer *> vectorLayers = layers<QgsVectorLayer *>();
1791 const auto constVectorLayers = vectorLayers;
1795 layer->resolveReferences(
this );
1805 mFile.setFileName( filename );
1806 mCachedHomePath.clear();
1807 mProjectScope.reset();
1819 QString storageFilePath { storage->filePath( mFile.fileName() ) };
1820 if ( storageFilePath.isEmpty() )
1822 writeEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
true );
1826 QString tempPath = QStandardPaths::standardLocations( QStandardPaths::TempLocation ).at( 0 );
1827 QString tmpZipFilename( tempPath + QDir::separator() + QUuid::createUuid().toString() );
1829 if ( !zip( tmpZipFilename ) )
1832 QFile tmpZipFile( tmpZipFilename );
1833 if ( !tmpZipFile.open( QIODevice::ReadOnly ) )
1835 setError( tr(
"Unable to read file %1" ).arg( tmpZipFilename ) );
1840 if ( !storage->writeProject( mFile.fileName(), &tmpZipFile, context ) )
1842 QString err = tr(
"Unable to save project to storage %1" ).arg( mFile.fileName() );
1843 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
1844 if ( !messages.isEmpty() )
1845 err += QStringLiteral(
"\n\n" ) + messages.last().message();
1851 QFile::remove( tmpZipFilename );
1858 return zip( mFile.fileName() );
1864 const bool asOk = saveAuxiliaryStorage();
1865 const bool writeOk = writeProjectFile( mFile.fileName() );
1868 if ( !asOk && writeOk )
1870 const QString err = mAuxiliaryStorage->errorString();
1871 setError( tr(
"Unable to save auxiliary storage ('%1')" ).arg( err ) );
1874 return asOk && writeOk;
1878 bool QgsProject::writeProjectFile(
const QString &filename )
1880 QFile projectFile( filename );
1886 QFileInfo myFileInfo( projectFile );
1887 if ( myFileInfo.exists() && !myFileInfo.isWritable() )
1889 setError( tr(
"%1 is not writable. Please adjust permissions (if possible) and try again." )
1890 .arg( projectFile.fileName() ) );
1898 QDomImplementation DomImplementation;
1899 DomImplementation.setInvalidDataPolicy( QDomImplementation::DropInvalidChars );
1901 QDomDocumentType documentType =
1902 DomImplementation.createDocumentType( QStringLiteral(
"qgis" ), QStringLiteral(
"http://mrcc.com/qgis.dtd" ),
1903 QStringLiteral(
"SYSTEM" ) );
1904 std::unique_ptr<QDomDocument> doc(
new QDomDocument( documentType ) );
1906 QDomElement qgisNode = doc->createElement( QStringLiteral(
"qgis" ) );
1907 qgisNode.setAttribute( QStringLiteral(
"projectname" ),
title() );
1908 qgisNode.setAttribute( QStringLiteral(
"version" ), QStringLiteral(
"%1" ).arg(
Qgis::QGIS_VERSION ) );
1910 doc->appendChild( qgisNode );
1912 QDomElement homePathNode = doc->createElement( QStringLiteral(
"homePath" ) );
1913 homePathNode.setAttribute( QStringLiteral(
"path" ), mHomePath );
1914 qgisNode.appendChild( homePathNode );
1917 QDomElement titleNode = doc->createElement( QStringLiteral(
"title" ) );
1918 qgisNode.appendChild( titleNode );
1920 QDomElement transactionNode = doc->createElement( QStringLiteral(
"autotransaction" ) );
1921 transactionNode.setAttribute( QStringLiteral(
"active" ), mAutoTransaction ? 1 : 0 );
1922 qgisNode.appendChild( transactionNode );
1924 QDomElement evaluateDefaultValuesNode = doc->createElement( QStringLiteral(
"evaluateDefaultValues" ) );
1925 evaluateDefaultValuesNode.setAttribute( QStringLiteral(
"active" ), mEvaluateDefaultValues ? 1 : 0 );
1926 qgisNode.appendChild( evaluateDefaultValuesNode );
1928 QDomElement trustNode = doc->createElement( QStringLiteral(
"trust" ) );
1929 trustNode.setAttribute( QStringLiteral(
"active" ), mTrustLayerMetadata ? 1 : 0 );
1930 qgisNode.appendChild( trustNode );
1932 QDomText titleText = doc->createTextNode(
title() );
1933 titleNode.appendChild( titleText );
1936 QDomElement srsNode = doc->createElement( QStringLiteral(
"projectCrs" ) );
1938 qgisNode.appendChild( srsNode );
1945 clonedRoot->
writeXml( qgisNode, context );
1958 QDomElement projectLayersNode = doc->createElement( QStringLiteral(
"projectlayers" ) );
1960 QMap<QString, QgsMapLayer *>::ConstIterator li = layers.constBegin();
1961 while ( li != layers.end() )
1967 QHash< QString, QPair< QString, bool> >::const_iterator emIt = mEmbeddedLayers.constFind( ml->
id() );
1968 if ( emIt == mEmbeddedLayers.constEnd() )
1970 QDomElement maplayerElem;
1976 maplayerElem = doc->createElement( QStringLiteral(
"maplayer" ) );
1981 QDomDocument document;
1984 maplayerElem = document.firstChildElement();
1988 QgsDebugMsg( QStringLiteral(
"Could not restore layer properties for layer %1" ).arg( ml->
id() ) );
1994 projectLayersNode.appendChild( maplayerElem );
2000 if ( emIt.value().second )
2002 QDomElement mapLayerElem = doc->createElement( QStringLiteral(
"maplayer" ) );
2003 mapLayerElem.setAttribute( QStringLiteral(
"embedded" ), 1 );
2004 mapLayerElem.setAttribute( QStringLiteral(
"project" ),
writePath( emIt.value().first ) );
2005 mapLayerElem.setAttribute( QStringLiteral(
"id" ), ml->
id() );
2006 projectLayersNode.appendChild( mapLayerElem );
2013 qgisNode.appendChild( projectLayersNode );
2015 QDomElement layerOrderNode = doc->createElement( QStringLiteral(
"layerorder" ) );
2017 for (
QgsMapLayer *layer : constCustomLayerOrder )
2019 QDomElement mapLayerElem = doc->createElement( QStringLiteral(
"layer" ) );
2020 mapLayerElem.setAttribute( QStringLiteral(
"id" ), layer->id() );
2021 layerOrderNode.appendChild( mapLayerElem );
2023 qgisNode.appendChild( layerOrderNode );
2025 mLabelingEngineSettings->writeSettingsToProject(
this );
2027 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorRedPart" ), mBackgroundColor.red() );
2028 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorGreenPart" ), mBackgroundColor.green() );
2029 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorBluePart" ), mBackgroundColor.blue() );
2031 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorRedPart" ), mSelectionColor.red() );
2032 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorGreenPart" ), mSelectionColor.green() );
2033 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorBluePart" ), mSelectionColor.blue() );
2034 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorAlphaPart" ), mSelectionColor.alpha() );
2038 dump_( mProperties );
2041 QgsDebugMsg( QStringLiteral(
"there are %1 property scopes" ).arg( static_cast<int>( mProperties.
count() ) ) );
2046 mProperties.
writeXml( QStringLiteral(
"properties" ), qgisNode, *doc );
2049 mMapThemeCollection->writeXml( *doc );
2051 mTransformContext.
writeXml( qgisNode, context );
2053 QDomElement metadataElem = doc->createElement( QStringLiteral(
"projectMetadata" ) );
2055 qgisNode.appendChild( metadataElem );
2057 QDomElement annotationsElem = mAnnotationManager->writeXml( *doc, context );
2058 qgisNode.appendChild( annotationsElem );
2060 QDomElement layoutElem = mLayoutManager->writeXml( *doc );
2061 qgisNode.appendChild( layoutElem );
2063 QDomElement bookmarkElem = mBookmarkManager->
writeXml( *doc );
2064 qgisNode.appendChild( bookmarkElem );
2072 QFile backupFile( QStringLiteral(
"%1~" ).arg( filename ) );
2074 ok &= backupFile.open( QIODevice::WriteOnly | QIODevice::Truncate );
2075 ok &= projectFile.open( QIODevice::ReadOnly );
2078 while ( ok && !projectFile.atEnd() )
2080 ba = projectFile.read( 10240 );
2081 ok &= backupFile.write( ba ) == ba.size();
2084 projectFile.close();
2089 setError( tr(
"Unable to create backup file %1" ).arg( backupFile.fileName() ) );
2094 struct utimbuf tb = {
static_cast<time_t
>( fi.lastRead().toSecsSinceEpoch() ), static_cast<time_t>( fi.lastModified().toSecsSinceEpoch() ) };
2095 utime( backupFile.fileName().toUtf8().constData(), &tb );
2098 if ( !projectFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
2100 projectFile.close();
2103 setError( tr(
"Unable to save to file %1" ).arg( projectFile.fileName() ) );
2107 QTemporaryFile tempFile;
2108 bool ok = tempFile.open();
2111 QTextStream projectFileStream( &tempFile );
2112 doc->save( projectFileStream, 2 );
2113 ok &= projectFileStream.pos() > -1;
2115 ok &= tempFile.seek( 0 );
2118 while ( ok && !tempFile.atEnd() )
2120 ba = tempFile.read( 10240 );
2121 ok &= projectFile.write( ba ) == ba.size();
2124 ok &= projectFile.error() == QFile::NoError;
2126 projectFile.close();
2133 setError( tr(
"Unable to save to file %1. Your project " 2134 "may be corrupted on disk. Try clearing some space on the volume and " 2135 "check file permissions before pressing save again." )
2136 .arg( projectFile.fileName() ) );
2149 bool propertiesModified;
2150 bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
2152 if ( propertiesModified )
2160 bool propertiesModified;
2161 bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
2163 if ( propertiesModified )
2171 bool propertiesModified;
2172 bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
2174 if ( propertiesModified )
2182 bool propertiesModified;
2183 bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
2185 if ( propertiesModified )
2193 bool propertiesModified;
2194 bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
2196 if ( propertiesModified )
2204 const QStringList &def,
2213 value =
property->value();
2215 bool valid = QVariant::StringList == value.type();
2221 return value.toStringList();
2240 value =
property->value();
2242 bool valid = value.canConvert( QVariant::String );
2247 return value.toString();
2262 value =
property->value();
2265 bool valid = value.canConvert( QVariant::Int );
2274 return value.toInt();
2287 QVariant value =
property->value();
2289 bool valid = value.canConvert( QVariant::Double );
2294 return value.toDouble();
2307 QVariant value =
property->value();
2309 bool valid = value.canConvert( QVariant::Bool );
2314 return value.toBool();
2323 if (
findKey_( scope, key, mProperties ) )
2329 return !
findKey_( scope, key, mProperties );
2337 QStringList entries;
2339 if ( foundProperty )
2354 QStringList entries;
2356 if ( foundProperty )
2369 dump_( mProperties );
2374 bool absolutePaths =
readBoolEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
false );
2376 if ( ! absolutePaths )
2383 filePath = storage->filePath( mFile.fileName() );
2403 void QgsProject::setError(
const QString &errorMessage )
2405 mErrorMessage = errorMessage;
2410 return mErrorMessage;
2413 void QgsProject::clearError()
2415 setError( QString() );
2420 delete mBadLayerHandler;
2421 mBadLayerHandler = handler;
2426 QHash< QString, QPair< QString, bool > >::const_iterator it = mEmbeddedLayers.find(
id );
2427 if ( it == mEmbeddedLayers.constEnd() )
2431 return it.value().first;
2435 bool saveFlag, QgsProject::ReadFlags flags )
2439 static QString sPrevProjectFilePath;
2440 static QDateTime sPrevProjectFileTimestamp;
2441 static QDomDocument sProjectDocument;
2443 QDateTime projectFileTimestamp = QFileInfo( projectFilePath ).lastModified();
2445 if ( projectFilePath != sPrevProjectFilePath || projectFileTimestamp != sPrevProjectFileTimestamp )
2447 sPrevProjectFilePath.clear();
2449 QFile projectFile( projectFilePath );
2450 if ( !projectFile.open( QIODevice::ReadOnly ) )
2455 if ( !sProjectDocument.setContent( &projectFile ) )
2460 sPrevProjectFilePath = projectFilePath;
2461 sPrevProjectFileTimestamp = projectFileTimestamp;
2465 bool useAbsolutePaths =
true;
2467 QDomElement propertiesElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral(
"properties" ) );
2468 if ( !propertiesElem.isNull() )
2470 QDomElement absElem = propertiesElem.firstChildElement( QStringLiteral(
"Paths" ) ).firstChildElement( QStringLiteral(
"Absolute" ) );
2471 if ( !absElem.isNull() )
2473 useAbsolutePaths = absElem.text().compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0;
2478 if ( !useAbsolutePaths )
2483 QDomElement projectLayersElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral(
"projectlayers" ) );
2484 if ( projectLayersElem.isNull() )
2489 QDomNodeList mapLayerNodes = projectLayersElem.elementsByTagName( QStringLiteral(
"maplayer" ) );
2490 for (
int i = 0; i < mapLayerNodes.size(); ++i )
2493 QDomElement mapLayerElem = mapLayerNodes.at( i ).toElement();
2494 QString
id = mapLayerElem.firstChildElement( QStringLiteral(
"id" ) ).text();
2495 if (
id == layerId )
2498 if ( mapLayerElem.attribute( QStringLiteral(
"embedded" ) ) == QLatin1String(
"1" ) )
2503 mEmbeddedLayers.insert( layerId, qMakePair( projectFilePath, saveFlag ) );
2505 if ( addLayer( mapLayerElem, brokenNodes, embeddedContext, flags ) )
2511 mEmbeddedLayers.remove( layerId );
2524 QFile projectFile( projectFilePath );
2525 if ( !projectFile.open( QIODevice::ReadOnly ) )
2530 QDomDocument projectDocument;
2531 if ( !projectDocument.setContent( &projectFile ) )
2543 QDomElement layerTreeElem = projectDocument.documentElement().firstChildElement( QStringLiteral(
"layer-tree-group" ) );
2544 if ( !layerTreeElem.isNull() )
2554 if ( !group || group->customProperty( QStringLiteral(
"embedded" ) ).toBool() )
2567 newGroup->
setCustomProperty( QStringLiteral(
"embedded_project" ), projectFilePath );
2570 mLayerTreeRegistryBridge->
setEnabled(
false );
2571 initializeEmbeddedSubtree( projectFilePath, newGroup, flags );
2572 mLayerTreeRegistryBridge->
setEnabled(
true );
2575 const auto constFindLayerIds = newGroup->
findLayerIds();
2576 for (
const QString &layerId : constFindLayerIds )
2589 void QgsProject::initializeEmbeddedSubtree(
const QString &projectFilePath,
QgsLayerTreeGroup *group, QgsProject::ReadFlags flags )
2591 const auto constChildren = group->
children();
2595 child->setCustomProperty( QStringLiteral(
"embedded" ), 1 );
2604 QList<QDomNode> brokenNodes;
2612 return mEvaluateDefaultValues;
2617 if ( evaluateDefaultValues == mEvaluateDefaultValues )
2621 QMap<QString, QgsMapLayer *>::const_iterator layerIt = layers.constBegin();
2622 for ( ; layerIt != layers.constEnd(); ++layerIt )
2636 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/TopologicalEditing" ), ( enabled ? 1 : 0 ) );
2642 return readNumEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/TopologicalEditing" ), 0 );
2647 QString distanceUnitString =
readEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/DistanceUnits" ), QString() );
2648 if ( !distanceUnitString.isEmpty() )
2665 QString areaUnitString =
readEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/AreaUnits" ), QString() );
2666 if ( !areaUnitString.isEmpty() )
2683 if ( !mCachedHomePath.isEmpty() )
2684 return mCachedHomePath;
2686 if ( !mHomePath.isEmpty() )
2688 QFileInfo homeInfo( mHomePath );
2689 if ( !homeInfo.isRelative() )
2691 mCachedHomePath = mHomePath;
2697 if ( !pfi.exists() )
2699 mCachedHomePath = mHomePath;
2703 if ( !mHomePath.isEmpty() )
2706 mCachedHomePath = QDir::cleanPath( pfi.path() +
'/' + mHomePath );
2710 mCachedHomePath = pfi.canonicalPath();
2712 return mCachedHomePath;
2722 return mRelationManager;
2727 return mLayoutManager.get();
2732 return mLayoutManager.get();
2737 return mBookmarkManager;
2742 return mBookmarkManager;
2752 return mMapThemeCollection.get();
2757 return mAnnotationManager.get();
2762 return mAnnotationManager.get();
2767 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
2768 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
2773 if ( layers.contains( it.value() ) )
2774 it.value()->setFlags( it.value()->flags() & ~
QgsMapLayer::Identifiable );
2787 nonIdentifiableLayers.reserve( layerIds.count() );
2788 for (
const QString &layerId : layerIds )
2792 nonIdentifiableLayers << layer;
2804 for ( QMap<QString, QgsMapLayer *>::const_iterator it = layers.constBegin(); it != layers.constEnd(); ++it )
2808 nonIdentifiableLayers.append( it.value()->id() );
2816 return mAutoTransaction;
2821 if ( autoTransaction != mAutoTransaction )
2825 if ( autoTransaction )
2826 onMapLayersAdded(
mapLayers().values() );
2828 cleanTransactionGroups(
true );
2834 return mTransactionGroups;
2845 return mLayerStore->count();
2850 return mLayerStore->validCount();
2855 return mLayerStore->mapLayer( layerId );
2860 return mLayerStore->mapLayersByName( layerName );
2865 QList<QgsMapLayer *>
layers;
2866 const auto constMapLayers { mLayerStore->mapLayers() };
2867 for (
const auto &l : constMapLayers )
2869 if ( ! l->shortName().isEmpty() )
2871 if ( l->shortName() == shortName )
2874 else if ( l->name() == shortName )
2882 bool QgsProject::unzip(
const QString &filename, QgsProject::ReadFlags flags )
2888 if ( !archive->unzip( filename ) )
2890 setError( tr(
"Unable to unzip file '%1'" ).arg( filename ) );
2895 if ( archive->projectFile().isEmpty() )
2897 setError( tr(
"Zip archive does not provide a project file" ) );
2902 if ( !archive->auxiliaryStorageFile().isEmpty() )
2906 mAuxiliaryStorage.reset(
new QgsAuxiliaryStorage( archive->auxiliaryStorageFile(), false ) );
2914 if ( ! readProjectFile( archive->projectFile(), flags ) )
2916 setError( tr(
"Cannot read unzipped qgs project file" ) );
2921 mArchive = std::move( archive );
2922 mArchive->clearProjectFile();
2927 bool QgsProject::zip(
const QString &filename )
2933 const QString
baseName = QFileInfo( filename ).baseName();
2934 const QString qgsFileName = QStringLiteral(
"%1.qgs" ).arg( baseName );
2935 QFile qgsFile( QDir( archive->dir() ).filePath( qgsFileName ) );
2937 bool writeOk =
false;
2938 if ( qgsFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
2940 writeOk = writeProjectFile( qgsFile.fileName() );
2947 setError( tr(
"Unable to write temporary qgs file" ) );
2952 const QFileInfo info( qgsFile );
2955 if ( ! saveAuxiliaryStorage( asFileName ) )
2957 const QString err = mAuxiliaryStorage->errorString();
2958 setError( tr(
"Unable to save auxiliary storage ('%1')" ).arg( err ) );
2963 archive->addFile( qgsFile.fileName() );
2964 archive->addFile( asFileName );
2967 if ( !archive->zip( filename ) )
2969 setError( tr(
"Unable to perform zip" ) );
2982 const QList<QgsMapLayer *> &
layers,
2984 bool takeOwnership )
2986 const QList<QgsMapLayer *> myResultList { mLayerStore->addMapLayers( layers, takeOwnership ) };
2987 if ( !myResultList.isEmpty() )
2990 for (
auto &l : myResultList )
3000 if ( mAuxiliaryStorage )
3015 return myResultList;
3021 bool takeOwnership )
3023 QList<QgsMapLayer *> addedLayers;
3024 addedLayers =
addMapLayers( QList<QgsMapLayer *>() << layer, addToLegend, takeOwnership );
3025 return addedLayers.isEmpty() ? nullptr : addedLayers[0];
3030 mLayerStore->removeMapLayers( layerIds );
3035 mLayerStore->removeMapLayers( layers );
3040 mLayerStore->removeMapLayer( layerId );
3045 mLayerStore->removeMapLayer( layer );
3050 return mLayerStore->takeMapLayer( layer );
3055 mLayerStore->removeAllMapLayers();
3060 QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
3061 QMap<QString, QgsMapLayer *>::const_iterator it = layers.constBegin();
3062 for ( ; it != layers.constEnd(); ++it )
3064 it.value()->reload();
3070 return validOnly ? mLayerStore->validMapLayers() : mLayerStore->mapLayers();
3075 return mTransactionGroups.value( qMakePair( providerKey, connString ) );
3085 if ( settings.
value( QStringLiteral(
"/projections/unknownCrsBehavior" ), QStringLiteral(
"NoAction" ),
QgsSettings::App ).toString() == QStringLiteral(
"UseProjectCrs" )
3086 || settings.
value( QStringLiteral(
"/projections/unknownCrsBehavior" ), 0,
QgsSettings::App ).toString() == 2 )
3094 QString layerDefaultCrs = settings.
value( QStringLiteral(
"/Projections/layerDefaultCrs" ),
GEO_EPSG_CRS_AUTHID ).toString();
3103 mTrustLayerMetadata = trust;
3106 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
3116 bool QgsProject::saveAuxiliaryStorage(
const QString &filename )
3120 for (
auto it = layers.constBegin(); it != layers.constEnd(); ++it )
3133 if ( !mAuxiliaryStorage->exists( *
this ) && filename.isEmpty() && empty )
3137 else if ( !filename.isEmpty() )
3139 return mAuxiliaryStorage->saveAs( filename );
3143 return mAuxiliaryStorage->saveAs( *
this );
3149 return mAuxiliaryStorage.get();
3154 return mAuxiliaryStorage.get();
3164 if ( metadata == mMetadata )
3168 mProjectScope.reset();
3180 for ( QMap<QString, QgsMapLayer *>::const_iterator it = layers.constBegin(); it != layers.constEnd(); ++it )
3184 requiredLayers.insert( it.value() );
3192 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
3193 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
3198 if ( layers.contains( it.value() ) )
3199 it.value()->setFlags( it.value()->flags() & ~
QgsMapLayer::Removable );
3208 QStringList customColors;
3209 QStringList customColorLabels;
3211 QgsNamedColorList::const_iterator colorIt = colors.constBegin();
3212 for ( ; colorIt != colors.constEnd(); ++colorIt )
3215 QString label = ( *colorIt ).second;
3216 customColors.append( color );
3217 customColorLabels.append( label );
3219 writeEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Colors" ), customColors );
3220 writeEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Labels" ), customColorLabels );
3221 mProjectScope.reset();
3227 if ( mBackgroundColor == color )
3230 mBackgroundColor = color;
3236 return mBackgroundColor;
3241 if ( mSelectionColor == color )
3244 mSelectionColor = color;
3250 return mSelectionColor;
3256 QVector< double > sorted = scales;
3257 std::sort( sorted.begin(), sorted.end(), std::greater<double>() );
3263 store.reserve( sorted.size() );
3264 for (
double scale : qgis::as_const( sorted ) )
3265 store << QStringLiteral(
"1:%1" ).arg( scale );
3267 writeEntry( QStringLiteral(
"Scales" ), QStringLiteral(
"/ScalesList" ), store );
3273 const QStringList scales =
readListEntry( QStringLiteral(
"Scales" ), QStringLiteral(
"/ScalesList" ) );
3274 QVector<double> res;
3275 for (
const QString &scale : scales )
3277 const QStringList parts = scale.split(
':' );
3278 if ( parts.size() != 2 )
3282 const double denominator = QLocale().toDouble( parts[1], &ok );
3296 writeEntry( QStringLiteral(
"Scales" ), QStringLiteral(
"/useProjectScales" ), enabled );
3302 return readBoolEntry( QStringLiteral(
"Scales" ), QStringLiteral(
"/useProjectScales" ) );
3316 QString
QgsProject::translate(
const QString &context,
const QString &sourceText,
const char *disambiguation,
int n )
const 3323 QString result = mTranslator->translate( context.toUtf8(), sourceText.toUtf8(), disambiguation, n );
3325 if ( result.isEmpty() )
3335 if ( !layers.empty() )
3337 for (
auto it = layers.constBegin(); it != layers.constEnd(); ++it )
3342 if ( !( ( *it )->accept( visitor ) ) )
3351 if ( !mLayoutManager->accept( visitor ) )
3354 if ( !mAnnotationManager->accept( visitor ) )
3361 GetNamedProjectColor::GetNamedProjectColor(
const QgsProject *project )
3368 QStringList colorStrings = project->
readListEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Colors" ) );
3369 QStringList colorLabels = project->
readListEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Labels" ) );
3373 for ( QStringList::iterator it = colorStrings.begin();
3374 it != colorStrings.end(); ++it )
3378 if ( colorLabels.length() > colorIndex )
3380 label = colorLabels.at( colorIndex );
3383 mColors.insert( label.toLower(), color );
3388 GetNamedProjectColor::GetNamedProjectColor(
const QHash<QString, QColor> &colors )
3396 QString colorName = values.at( 0 ).toString().toLower();
3397 if ( mColors.contains( colorName ) )
3399 return QStringLiteral(
"%1,%2,%3" ).arg( mColors.value( colorName ).red() ).arg( mColors.value( colorName ).green() ).arg( mColors.value( colorName ).blue() );
3407 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 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.
QDateTime lastModified() const
Returns last modified time of the project file as returned by the file system (or other project stora...
static QgsCoordinateReferenceSystem fromProj4(const QString &proj4)
Creates a CRS from a proj4 style formatted string.
static const QString QGIS_VERSION
Version string.
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
Don't resolve layer paths (i.e. don't load any layer content). Dramatically improves project read tim...
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:
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.
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.
#define Q_NOWARN_DEPRECATED_PUSH
static bool readOldLegend(QgsLayerTreeGroup *root, const QDomElement &legendElem)
Try to load layer tree from.
QString toProj4() const
Returns a Proj4 string representation of this CRS.
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.
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.
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 mapScalesChanged()
Emitted when the list of custom project map scales changes.
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.
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.
const QString GEO_NONE
Constant that holds the string representation for "No ellips/No CRS".
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...
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.
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.
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.
void setTransformContext(const QgsCoordinateTransformContext &transformContext)
Sets data coordinate transform context to transformContext.
A class to describe the version of a project.
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.
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.
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.
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.
const QString GEO_EPSG_CRS_AUTHID
Geographic coord sys from EPSG authority.
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.
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...
void setMapScales(const QVector< double > &scales)
Sets the list of custom project map scales.
QgsAnnotationManager * annotationManager()
Returns pointer to the project's annotation manager.
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 compositions within the project.
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.
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.
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.
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...
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).
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.
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.
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.
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.
Don't load print layouts. Improves project read time if layouts are not required, and allows projects...
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.
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...
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)
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.