57 #include <QApplication> 61 #include <QTextStream> 62 #include <QTemporaryFile> 67 #include <sys/utime.h> 85 QStringList keyTokens = QStringList( scope );
86 keyTokens += key.split(
'/', QString::SkipEmptyParts );
89 keyTokens.push_front( QStringLiteral(
"properties" ) );
92 for (
int i = 0; i < keyTokens.size(); ++i )
94 QString keyToken = keyTokens.at( i );
98 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]" );
99 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]" );
101 if ( keyToken.contains( QRegExp( nameCharRegexp ) ) || keyToken.contains( QRegExp( nameStartCharRegexp ) ) )
104 QString errorString = QObject::tr(
"Entry token invalid : '%1'. The token will not be saved to file." ).arg( keyToken );
134 while ( !keySequence.isEmpty() )
138 if ( keySequence.first() == currentProperty->
name() )
141 keySequence.pop_front();
143 if ( 1 == keySequence.count() )
146 return currentProperty->
find( keySequence.front() );
148 else if ( keySequence.isEmpty() )
153 return currentProperty;
155 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
157 if ( nextProperty->
isKey() )
161 else if ( nextProperty->
isValue() && 1 == keySequence.count() )
167 return currentProperty;
204 const QVariant &value )
213 while ( ! keySequence.isEmpty() )
217 if ( keySequence.first() == currentProperty->
name() )
220 keySequence.pop_front();
224 if ( 1 == keySequence.count() )
226 currentProperty->
setValue( keySequence.front(), value );
227 return currentProperty;
231 else if ( keySequence.isEmpty() )
235 return currentProperty;
237 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
241 if ( currentProperty )
252 if ( ( newPropertyKey = currentProperty->
addKey( keySequence.first() ) ) )
254 currentProperty = newPropertyKey;
281 while ( ! keySequence.isEmpty() )
285 if ( keySequence.first() == currentProperty->
name() )
288 keySequence.pop_front();
292 if ( 1 == keySequence.count() )
294 currentProperty->
removeKey( keySequence.front() );
299 else if ( keySequence.isEmpty() )
301 previousQgsPropertyKey->
removeKey( currentProperty->
name() );
303 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
305 previousQgsPropertyKey = currentProperty;
308 if ( currentProperty )
335 , mSnappingConfig( this )
344 mProperties.
setName( QStringLiteral(
"properties" ) );
375 delete mBadLayerHandler;
376 delete mRelationManager;
377 delete mLayerTreeRegistryBridge;
379 if (
this == sProject )
385 void QgsProject::setInstance(
QgsProject *project )
402 if ( title == mMetadata.
title() )
413 return mMetadata.
title();
423 if ( dirty && mDirtyBlockCount > 0 )
426 if ( mDirty == dirty )
435 if ( path == mHomePath )
446 if ( name == mFile.fileName() )
451 mFile.setFileName( name );
455 if ( newHomePath != oldHomePath )
463 return mFile.fileName();
468 return QFileInfo( mFile );
481 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
495 if ( mFile.fileName().isEmpty() )
506 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
507 return metadata.
name;
511 return QFileInfo( mFile.fileName() ).
baseName();
523 writeEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectionsEnabled" ), crs.
isValid() ? 1 : 0 );
530 if ( !
crs().isValid() )
533 return readEntry( QStringLiteral(
"Measure" ), QStringLiteral(
"/Ellipsoid" ),
GEO_NONE );
538 writeEntry( QStringLiteral(
"Measure" ), QStringLiteral(
"/Ellipsoid" ), ellipsoid );
545 return mTransformContext;
550 mTransformContext = context;
558 mFile.setFileName( QString() );
561 mAutoTransaction =
false;
562 mEvaluateDefaultValues =
false;
564 mTrustLayerMetadata =
false;
565 mCustomVariables.clear();
578 mEmbeddedLayers.clear();
579 mRelationManager->
clear();
580 mAnnotationManager->clear();
581 mLayoutManager->clear();
582 mSnappingConfig.
reset();
588 mLabelingEngineSettings->clear();
597 writeEntry( QStringLiteral(
"PositionPrecision" ), QStringLiteral(
"/Automatic" ),
true );
598 writeEntry( QStringLiteral(
"PositionPrecision" ), QStringLiteral(
"/DecimalPlaces" ), 2 );
599 writeEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
false );
602 writeEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/DistanceUnits" ), s.
value( QStringLiteral(
"/qgis/measure/displayunits" ) ).toString() );
603 writeEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/AreaUnits" ), s.
value( QStringLiteral(
"/qgis/measure/areaunits" ) ).toString() );
616 topQgsPropertyKey.
dump();
652 QDomElement propertiesElem = doc.documentElement().firstChildElement( QStringLiteral(
"properties" ) );
654 if ( propertiesElem.isNull() )
659 QDomNodeList scopes = propertiesElem.childNodes();
661 if ( scopes.count() < 1 )
663 QgsDebugMsg(
"empty ``properties'' XML tag ... bailing" );
667 if ( ! project_properties.
readXml( propertiesElem ) )
669 QgsDebugMsg(
"Project_properties.readXml() failed" );
678 static void _getTitle(
const QDomDocument &doc, QString &
title )
680 QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"title" ) );
690 QDomNode titleNode = nl.item( 0 );
692 if ( !titleNode.hasChildNodes() )
698 QDomNode titleTextNode = titleNode.firstChild();
700 if ( !titleTextNode.isText() )
706 QDomText titleText = titleTextNode.toText();
708 title = titleText.data();
714 QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"qgis" ) );
718 QgsDebugMsg(
" unable to find qgis element in project file" );
722 QDomNode qgisNode = nl.item( 0 );
724 QDomElement qgisElement = qgisNode.toElement();
725 QgsProjectVersion projectVersion( qgisElement.attribute( QStringLiteral(
"version" ) ) );
726 return projectVersion;
732 return mSnappingConfig;
737 if ( mSnappingConfig == snappingConfig )
745 bool QgsProject::_getMapLayers(
const QDomDocument &doc, QList<QDomNode> &brokenNodes )
750 QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"maplayer" ) );
754 if ( 0 == nl.count() )
764 bool returnStatus =
true;
770 if ( depSorter.hasCycle() || depSorter.hasMissingDependency() )
773 QVector<QDomNode> sortedLayerNodes = depSorter.sortedLayerNodes();
776 Q_FOREACH (
const QDomNode &node, sortedLayerNodes )
778 QDomElement element = node.toElement();
780 QString name = node.namedItem( QStringLiteral(
"layername" ) ).toElement().text();
781 if ( !name.isNull() )
782 emit
loadingLayer( tr(
"Loading layer %1" ).arg( name ) );
784 if ( element.attribute( QStringLiteral(
"embedded" ) ) == QLatin1String(
"1" ) )
786 createEmbeddedLayer( element.attribute( QStringLiteral(
"id" ) ),
readPath( element.attribute( QStringLiteral(
"project" ) ) ), brokenNodes );
793 if ( !addLayer( element, brokenNodes, context ) )
795 returnStatus =
false;
798 if ( messages.count() )
810 bool QgsProject::addLayer(
const QDomElement &layerElem, QList<QDomNode> &brokenNodes,
QgsReadWriteContext &context )
812 QString type = layerElem.attribute( QStringLiteral(
"type" ) );
816 if ( type == QLatin1String(
"vector" ) )
821 if (
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( mapLayer ) )
826 else if ( type == QLatin1String(
"raster" ) )
830 else if ( type == QLatin1String(
"mesh" ) )
834 else if ( type == QLatin1String(
"plugin" ) )
836 QString typeName = layerElem.attribute( QStringLiteral(
"name" ) );
847 Q_CHECK_PTR( mapLayer );
854 QList<QgsMapLayer *> myLayers;
864 QgsDebugMsg(
"Unable to load " + type +
" layer" );
865 brokenNodes.push_back( layerElem );
872 mFile.setFileName( filename );
879 QString filename = mFile.fileName();
884 QTemporaryFile inDevice;
885 if ( !inDevice.open() )
887 setError( tr(
"Unable to open %1" ).arg( inDevice.fileName() ) );
892 if ( !storage->readProject( filename, &inDevice, context ) )
894 QString err = tr(
"Unable to open %1" ).arg( filename );
895 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
896 if ( !messages.isEmpty() )
897 err += QStringLiteral(
"\n\n" ) + messages.last().message();
902 return unzip( inDevice.fileName() );
907 rc = unzip( mFile.fileName() );
912 rc = readProjectFile( mFile.fileName() );
915 mFile.setFileName( filename );
919 bool QgsProject::readProjectFile(
const QString &filename )
921 QFile projectFile( filename );
924 std::unique_ptr<QDomDocument> doc(
new QDomDocument( QStringLiteral(
"qgis" ) ) );
926 if ( !projectFile.open( QIODevice::ReadOnly | QIODevice::Text ) )
930 setError( tr(
"Unable to open %1" ).arg( projectFile.fileName() ) );
939 if ( !doc->setContent( &projectFile, &errorMsg, &line, &column ) )
943 QMessageBox::critical( 0, tr(
"Read Project File" ),
944 tr(
"%1 at line %2 column %3" ).arg( errorMsg ).arg( line ).arg( column ) );
947 QString errorString = tr(
"Project file read error in file %1: %2 at line %3 column %4" )
948 .arg( projectFile.fileName(), errorMsg ).arg( line ).arg( column );
954 setError( tr(
"%1 for file %2" ).arg( errorString, projectFile.fileName() ) );
962 QgsDebugMsg(
"Opened document " + projectFile.fileName() );
968 if ( thisVersion > fileVersion )
971 "version of qgis (saved in " + fileVersion.text() +
973 "). Problems may occur." );
979 QgsDebugMsg(
"Emitting oldProjectVersionWarning(oldVersion)." );
981 projectFile.updateRevision( thisVersion );
985 QString
fileName = mFile.fileName();
986 std::unique_ptr<QgsAuxiliaryStorage> aStorage = std::move( mAuxiliaryStorage );
988 mAuxiliaryStorage = std::move( aStorage );
989 mFile.setFileName( fileName );
996 dump_( mProperties );
1000 _getTitle( *doc, oldTitle );
1002 QDomNodeList homePathNl = doc->elementsByTagName( QStringLiteral(
"homePath" ) );
1003 if ( homePathNl.count() > 0 )
1005 QDomElement homePathElement = homePathNl.at( 0 ).toElement();
1006 QString
homePath = homePathElement.attribute( QStringLiteral(
"path" ) );
1007 if ( !homePath.isEmpty() )
1020 if (
readNumEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectionsEnabled" ), 0 ) )
1023 QDomNode srsNode = doc->documentElement().namedItem( QStringLiteral(
"projectCrs" ) );
1024 if ( !srsNode.isNull() )
1026 projectCrs.
readXml( srsNode );
1031 QString projCrsString =
readEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCRSProj4String" ) );
1032 long currentCRS =
readNumEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCRSID" ), -1 );
1035 if ( currentCRS >= 0 )
1041 if ( !projCrsString.isEmpty() && ( !projectCrs.
isValid() || projectCrs.
toProj4() != projCrsString ) )
1055 QStringList datumErrors;
1056 if ( !mTransformContext.
readXml( doc->documentElement(), context, datumErrors ) )
1062 QDomNodeList nl = doc->elementsByTagName( QStringLiteral(
"projectMetadata" ) );
1063 if ( !nl.isEmpty() )
1065 QDomElement metadataElement = nl.at( 0 ).toElement();
1073 if ( mMetadata.
title().isEmpty() && !oldTitle.isEmpty() )
1080 nl = doc->elementsByTagName( QStringLiteral(
"autotransaction" ) );
1083 QDomElement transactionElement = nl.at( 0 ).toElement();
1084 if ( transactionElement.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
1085 mAutoTransaction =
true;
1088 nl = doc->elementsByTagName( QStringLiteral(
"evaluateDefaultValues" ) );
1091 QDomElement evaluateDefaultValuesElement = nl.at( 0 ).toElement();
1092 if ( evaluateDefaultValuesElement.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
1093 mEvaluateDefaultValues =
true;
1096 nl = doc->elementsByTagName( QStringLiteral(
"trust" ) );
1099 QDomElement trustElement = nl.at( 0 ).toElement();
1100 if ( trustElement.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
1101 mTrustLayerMetadata =
true;
1108 QDomElement layerTreeElem = doc->documentElement().firstChildElement( QStringLiteral(
"layer-tree-group" ) );
1109 if ( !layerTreeElem.isNull() )
1118 mLayerTreeRegistryBridge->
setEnabled(
false );
1121 QList<QDomNode> brokenNodes;
1122 bool clean = _getMapLayers( *doc, brokenNodes );
1127 QgsDebugMsg(
"Unable to get map layers from project file." );
1129 if ( !brokenNodes.isEmpty() )
1131 QgsDebugMsg(
"there are " + QString::number( brokenNodes.size() ) +
" broken layers" );
1141 QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
1142 for ( QMap<QString, QgsMapLayer *>::iterator it = layers.begin(); it != layers.end(); it++ )
1144 it.value()->resolveReferences(
this );
1147 mLayerTreeRegistryBridge->
setEnabled(
true );
1150 loadEmbeddedNodes( mRootGroup );
1156 if ( !layerTreeElem.isNull() )
1162 QDomElement layerTreeCanvasElem = doc->documentElement().firstChildElement( QStringLiteral(
"layer-tree-canvas" ) );
1163 if ( !layerTreeCanvasElem.isNull( ) )
1175 mMapThemeCollection->readXml( *doc );
1177 mLabelingEngineSettings->readSettingsFromProject(
this );
1180 mAnnotationManager->readXml( doc->documentElement(), context );
1181 mLayoutManager->readXml( doc->documentElement(), *doc );
1184 QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
1185 for ( QMap<QString, QgsMapLayer *>::iterator it = existingMaps.begin(); it != existingMaps.end(); it++ )
1187 it.value()->setDependencies( it.value()->dependencies() );
1193 QStringList variableNames =
readListEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableNames" ) );
1194 QStringList variableValues =
readListEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableValues" ) );
1196 mCustomVariables.clear();
1197 if ( variableNames.length() == variableValues.length() )
1199 for (
int i = 0; i < variableNames.length(); ++i )
1201 mCustomVariables.insert( variableNames.at( i ), variableValues.at( i ) );
1206 QgsMessageLog::logMessage( tr(
"Project Variables Invalid" ), tr(
"The project contains invalid variable settings." ) );
1234 if ( childGroup->
customProperty( QStringLiteral(
"embedded" ) ).toInt() )
1237 QString projectPath =
readPath( childGroup->
customProperty( QStringLiteral(
"embedded_project" ) ).toString() );
1238 childGroup->
setCustomProperty( QStringLiteral(
"embedded_project" ), projectPath );
1242 QList<QgsLayerTreeNode *> clonedChildren;
1244 clonedChildren << newGroupChild->
clone();
1252 loadEmbeddedNodes( childGroup );
1257 if ( child->
customProperty( QStringLiteral(
"embedded" ) ).toInt() )
1259 QList<QDomNode> brokenNodes;
1269 return mCustomVariables;
1274 if ( variables == mCustomVariables )
1278 QStringList variableNames;
1279 QStringList variableValues;
1281 QVariantMap::const_iterator it = variables.constBegin();
1282 for ( ; it != variables.constEnd(); ++it )
1284 variableNames << it.key();
1285 variableValues << it.value().toString();
1288 writeEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableNames" ), variableNames );
1289 writeEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableValues" ), variableValues );
1291 mCustomVariables = variables;
1298 *mLabelingEngineSettings = settings;
1304 return *mLabelingEngineSettings;
1309 return mLayerStore.get();
1314 return mLayerStore.get();
1319 QList<QgsVectorLayer *>
layers;
1320 QStringList layerIds =
readListEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsList" ), QStringList() );
1321 Q_FOREACH (
const QString &layerId, layerIds )
1333 list << layer->
id();
1334 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsList" ), list );
1348 void QgsProject::onMapLayersAdded(
const QList<QgsMapLayer *> &
layers )
1350 QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
1352 bool tgChanged =
false;
1371 mTransactionGroups.insert( qMakePair( key, connString ), tg );
1386 for ( QMap<QString, QgsMapLayer *>::iterator it = existingMaps.begin(); it != existingMaps.end(); it++ )
1388 QSet<QgsMapLayerDependency> deps = it.value()->dependencies();
1389 if ( deps.contains( layer->
id() ) )
1392 it.value()->setDependencies( deps );
1397 if ( mSnappingConfig.
addLayers( layers ) )
1401 void QgsProject::onMapLayersRemoved(
const QList<QgsMapLayer *> &
layers )
1407 void QgsProject::cleanTransactionGroups(
bool force )
1409 bool changed =
false;
1410 for ( QMap< QPair< QString, QString>,
QgsTransactionGroup *>::Iterator tg = mTransactionGroups.begin(); tg != mTransactionGroups.end(); )
1412 if ( tg.value()->isEmpty() || force )
1415 tg = mTransactionGroups.erase( tg );
1431 QList<QDomNode> brokenNodes;
1432 if ( addLayer( layerNode.toElement(), brokenNodes, context ) )
1436 QVector<QgsVectorLayer *> vectorLayers = layers<QgsVectorLayer *>();
1450 mFile.setFileName( filename );
1461 writeEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
true );
1463 QString tempPath = QStandardPaths::standardLocations( QStandardPaths::TempLocation ).at( 0 );
1464 QString tmpZipFilename( tempPath + QDir::separator() + QUuid::createUuid().toString() );
1466 if ( !zip( tmpZipFilename ) )
1469 QFile tmpZipFile( tmpZipFilename );
1470 if ( !tmpZipFile.open( QIODevice::ReadOnly ) )
1472 setError( tr(
"Unable to read file %1" ).arg( tmpZipFilename ) );
1477 if ( !storage->writeProject( mFile.fileName(), &tmpZipFile, context ) )
1479 QString err = tr(
"Unable to save project to storage %1" ).arg( mFile.fileName() );
1480 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
1481 if ( !messages.isEmpty() )
1482 err += QStringLiteral(
"\n\n" ) + messages.last().message();
1488 QFile::remove( tmpZipFilename );
1495 return zip( mFile.fileName() );
1501 const bool asOk = saveAuxiliaryStorage();
1502 const bool writeOk = writeProjectFile( mFile.fileName() );
1505 if ( !asOk && writeOk )
1506 setError( tr(
"Unable to save auxiliary storage" ) );
1508 return asOk && writeOk;
1512 bool QgsProject::writeProjectFile(
const QString &filename )
1514 QFile projectFile( filename );
1520 QFileInfo myFileInfo( projectFile );
1521 if ( myFileInfo.exists() && !myFileInfo.isWritable() )
1523 setError( tr(
"%1 is not writable. Please adjust permissions (if possible) and try again." )
1524 .arg( projectFile.fileName() ) );
1531 QDomImplementation DomImplementation;
1532 DomImplementation.setInvalidDataPolicy( QDomImplementation::DropInvalidChars );
1534 QDomDocumentType documentType =
1535 DomImplementation.createDocumentType( QStringLiteral(
"qgis" ), QStringLiteral(
"http://mrcc.com/qgis.dtd" ),
1536 QStringLiteral(
"SYSTEM" ) );
1537 std::unique_ptr<QDomDocument> doc(
new QDomDocument( documentType ) );
1539 QDomElement qgisNode = doc->createElement( QStringLiteral(
"qgis" ) );
1540 qgisNode.setAttribute( QStringLiteral(
"projectname" ),
title() );
1541 qgisNode.setAttribute( QStringLiteral(
"version" ), QStringLiteral(
"%1" ).arg(
Qgis::QGIS_VERSION ) );
1543 doc->appendChild( qgisNode );
1545 QDomElement homePathNode = doc->createElement( QStringLiteral(
"homePath" ) );
1546 homePathNode.setAttribute( QStringLiteral(
"path" ), mHomePath );
1547 qgisNode.appendChild( homePathNode );
1550 QDomElement titleNode = doc->createElement( QStringLiteral(
"title" ) );
1551 qgisNode.appendChild( titleNode );
1553 QDomElement transactionNode = doc->createElement( QStringLiteral(
"autotransaction" ) );
1554 transactionNode.setAttribute( QStringLiteral(
"active" ), mAutoTransaction ?
"1" :
"0" );
1555 qgisNode.appendChild( transactionNode );
1557 QDomElement evaluateDefaultValuesNode = doc->createElement( QStringLiteral(
"evaluateDefaultValues" ) );
1558 evaluateDefaultValuesNode.setAttribute( QStringLiteral(
"active" ), mEvaluateDefaultValues ?
"1" :
"0" );
1559 qgisNode.appendChild( evaluateDefaultValuesNode );
1561 QDomElement trustNode = doc->createElement( QStringLiteral(
"trust" ) );
1562 trustNode.setAttribute( QStringLiteral(
"active" ), mTrustLayerMetadata ?
"1" :
"0" );
1563 qgisNode.appendChild( trustNode );
1565 QDomText titleText = doc->createTextNode(
title() );
1566 titleNode.appendChild( titleText );
1569 QDomElement srsNode = doc->createElement( QStringLiteral(
"projectCrs" ) );
1571 qgisNode.appendChild( srsNode );
1578 clonedRoot->
writeXml( qgisNode, context );
1591 QDomElement projectLayersNode = doc->createElement( QStringLiteral(
"projectlayers" ) );
1593 QMap<QString, QgsMapLayer *>::ConstIterator li = layers.constBegin();
1594 while ( li != layers.end() )
1600 QHash< QString, QPair< QString, bool> >::const_iterator emIt = mEmbeddedLayers.constFind( ml->
id() );
1601 if ( emIt == mEmbeddedLayers.constEnd() )
1604 QDomElement maplayerElem = doc->createElement( QStringLiteral(
"maplayer" ) );
1610 projectLayersNode.appendChild( maplayerElem );
1616 if ( emIt.value().second )
1618 QDomElement mapLayerElem = doc->createElement( QStringLiteral(
"maplayer" ) );
1619 mapLayerElem.setAttribute( QStringLiteral(
"embedded" ), 1 );
1620 mapLayerElem.setAttribute( QStringLiteral(
"project" ),
writePath( emIt.value().first ) );
1621 mapLayerElem.setAttribute( QStringLiteral(
"id" ), ml->
id() );
1622 projectLayersNode.appendChild( mapLayerElem );
1629 qgisNode.appendChild( projectLayersNode );
1631 QDomElement layerOrderNode = doc->createElement( QStringLiteral(
"layerorder" ) );
1634 QDomElement mapLayerElem = doc->createElement( QStringLiteral(
"layer" ) );
1635 mapLayerElem.setAttribute( QStringLiteral(
"id" ), layer->
id() );
1636 layerOrderNode.appendChild( mapLayerElem );
1638 qgisNode.appendChild( layerOrderNode );
1640 mLabelingEngineSettings->writeSettingsToProject(
this );
1644 dump_( mProperties );
1646 QgsDebugMsg( QString(
"there are %1 property scopes" ).arg( static_cast<int>( mProperties.
count() ) ) );
1651 mProperties.
writeXml( QStringLiteral(
"properties" ), qgisNode, *doc );
1654 mMapThemeCollection->writeXml( *doc );
1656 mTransformContext.
writeXml( qgisNode, context );
1658 QDomElement metadataElem = doc->createElement( QStringLiteral(
"projectMetadata" ) );
1660 qgisNode.appendChild( metadataElem );
1662 QDomElement annotationsElem = mAnnotationManager->writeXml( *doc, context );
1663 qgisNode.appendChild( annotationsElem );
1665 QDomElement layoutElem = mLayoutManager->writeXml( *doc );
1666 qgisNode.appendChild( layoutElem );
1674 QFile backupFile( QStringLiteral(
"%1~" ).arg( filename ) );
1676 ok &= backupFile.open( QIODevice::WriteOnly | QIODevice::Truncate );
1677 ok &= projectFile.open( QIODevice::ReadOnly );
1680 while ( ok && !projectFile.atEnd() )
1682 ba = projectFile.read( 10240 );
1683 ok &= backupFile.write( ba ) == ba.size();
1686 projectFile.close();
1691 setError( tr(
"Unable to create backup file %1" ).arg( backupFile.fileName() ) );
1696 struct utimbuf tb = { fi.lastRead().toTime_t(), fi.lastModified().toTime_t() };
1697 utime( backupFile.fileName().toUtf8().constData(), &tb );
1700 if ( !projectFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
1702 projectFile.close();
1705 setError( tr(
"Unable to save to file %1" ).arg( projectFile.fileName() ) );
1709 QTemporaryFile tempFile;
1710 bool ok = tempFile.open();
1713 QTextStream projectFileStream( &tempFile );
1714 doc->save( projectFileStream, 2 );
1715 ok &= projectFileStream.pos() > -1;
1717 ok &= tempFile.seek( 0 );
1720 while ( ok && !tempFile.atEnd() )
1722 ba = tempFile.read( 10240 );
1723 ok &= projectFile.write( ba ) == ba.size();
1726 ok &= projectFile.error() == QFile::NoError;
1728 projectFile.close();
1735 setError( tr(
"Unable to save to file %1. Your project " 1736 "may be corrupted on disk. Try clearing some space on the volume and " 1737 "check file permissions before pressing save again." )
1738 .arg( projectFile.fileName() ) );
1753 return addKey_( scope, key, &mProperties, value );
1760 return addKey_( scope, key, &mProperties, value );
1767 return addKey_( scope, key, &mProperties, value );
1774 return addKey_( scope, key, &mProperties, value );
1781 return addKey_( scope, key, &mProperties, value );
1786 const QStringList &def,
1795 value =
property->value();
1797 bool valid = QVariant::StringList == value.type();
1803 return value.toStringList();
1822 value =
property->value();
1824 bool valid = value.canConvert( QVariant::String );
1829 return value.toString();
1844 value =
property->value();
1847 bool valid = value.canConvert( QVariant::Int );
1856 return value.toInt();
1869 QVariant value =
property->value();
1871 bool valid = value.canConvert( QVariant::Double );
1876 return value.toDouble();
1889 QVariant value =
property->value();
1891 bool valid = value.canConvert( QVariant::Bool );
1896 return value.toBool();
1909 return !
findKey_( scope, key, mProperties );
1917 QStringList entries;
1919 if ( foundProperty )
1934 QStringList entries;
1936 if ( foundProperty )
1949 dump_( mProperties );
1954 bool absolutePaths =
readBoolEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
false );
1968 void QgsProject::setError(
const QString &errorMessage )
1970 mErrorMessage = errorMessage;
1975 return mErrorMessage;
1978 void QgsProject::clearError()
1980 setError( QString() );
1985 delete mBadLayerHandler;
1986 mBadLayerHandler = handler;
1991 QHash< QString, QPair< QString, bool > >::const_iterator it = mEmbeddedLayers.find(
id );
1992 if ( it == mEmbeddedLayers.constEnd() )
1996 return it.value().first;
2004 static QString sPrevProjectFilePath;
2005 static QDateTime sPrevProjectFileTimestamp;
2006 static QDomDocument sProjectDocument;
2008 QDateTime projectFileTimestamp = QFileInfo( projectFilePath ).lastModified();
2010 if ( projectFilePath != sPrevProjectFilePath || projectFileTimestamp != sPrevProjectFileTimestamp )
2012 sPrevProjectFilePath.clear();
2014 QFile projectFile( projectFilePath );
2015 if ( !projectFile.open( QIODevice::ReadOnly ) )
2020 if ( !sProjectDocument.setContent( &projectFile ) )
2025 sPrevProjectFilePath = projectFilePath;
2026 sPrevProjectFileTimestamp = projectFileTimestamp;
2030 bool useAbsolutePaths =
true;
2032 QDomElement propertiesElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral(
"properties" ) );
2033 if ( !propertiesElem.isNull() )
2035 QDomElement absElem = propertiesElem.firstChildElement( QStringLiteral(
"Paths" ) ).firstChildElement( QStringLiteral(
"Absolute" ) );
2036 if ( !absElem.isNull() )
2038 useAbsolutePaths = absElem.text().compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0;
2043 if ( !useAbsolutePaths )
2046 QDomElement projectLayersElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral(
"projectlayers" ) );
2047 if ( projectLayersElem.isNull() )
2052 QDomNodeList mapLayerNodes = projectLayersElem.elementsByTagName( QStringLiteral(
"maplayer" ) );
2053 for (
int i = 0; i < mapLayerNodes.size(); ++i )
2056 QDomElement mapLayerElem = mapLayerNodes.at( i ).toElement();
2057 QString
id = mapLayerElem.firstChildElement( QStringLiteral(
"id" ) ).text();
2058 if (
id == layerId )
2061 if ( mapLayerElem.attribute( QStringLiteral(
"embedded" ) ) == QLatin1String(
"1" ) )
2066 mEmbeddedLayers.insert( layerId, qMakePair( projectFilePath, saveFlag ) );
2068 if ( addLayer( mapLayerElem, brokenNodes, embeddedContext ) )
2074 mEmbeddedLayers.remove( layerId );
2087 QFile projectFile( projectFilePath );
2088 if ( !projectFile.open( QIODevice::ReadOnly ) )
2093 QDomDocument projectDocument;
2094 if ( !projectDocument.setContent( &projectFile ) )
2103 QSet<QString> embeddedIdentifyDisabledLayers;
2104 QDomElement disabledLayersElem = projectDocument.documentElement().firstChildElement( QStringLiteral(
"properties" ) ).firstChildElement( QStringLiteral(
"Identify" ) ).firstChildElement( QStringLiteral(
"disabledLayers" ) );
2105 if ( !disabledLayersElem.isNull() )
2107 QDomNodeList valueList = disabledLayersElem.elementsByTagName( QStringLiteral(
"value" ) );
2108 for (
int i = 0; i < valueList.size(); ++i )
2110 embeddedIdentifyDisabledLayers.insert( valueList.at( i ).toElement().text() );
2116 QDomElement layerTreeElem = projectDocument.documentElement().firstChildElement( QStringLiteral(
"layer-tree-group" ) );
2117 if ( !layerTreeElem.isNull() )
2127 if ( !group || group->customProperty( QStringLiteral(
"embedded" ) ).toBool() )
2140 newGroup->
setCustomProperty( QStringLiteral(
"embedded_project" ), projectFilePath );
2143 mLayerTreeRegistryBridge->
setEnabled(
false );
2144 initializeEmbeddedSubtree( projectFilePath, newGroup );
2145 mLayerTreeRegistryBridge->
setEnabled(
true );
2150 Q_FOREACH (
const QString &layerId, newGroup->
findLayerIds() )
2152 if ( embeddedIdentifyDisabledLayers.contains( layerId ) )
2154 thisProjectIdentifyDisabledLayers.append( layerId );
2170 void QgsProject::initializeEmbeddedSubtree(
const QString &projectFilePath,
QgsLayerTreeGroup *group )
2184 QList<QDomNode> brokenNodes;
2192 return mEvaluateDefaultValues;
2198 QMap<QString, QgsMapLayer *>::const_iterator layerIt = layers.constBegin();
2199 for ( ; layerIt != layers.constEnd(); ++layerIt )
2213 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/TopologicalEditing" ), ( enabled ? 1 : 0 ) );
2219 return readNumEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/TopologicalEditing" ), 0 );
2224 QString distanceUnitString =
readEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/DistanceUnits" ), QString() );
2225 if ( !distanceUnitString.isEmpty() )
2242 QString areaUnitString =
readEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/AreaUnits" ), QString() );
2243 if ( !areaUnitString.isEmpty() )
2260 if ( !mHomePath.isEmpty() )
2262 QFileInfo homeInfo( mHomePath );
2263 if ( !homeInfo.isRelative() )
2268 if ( !pfi.exists() )
2271 if ( !mHomePath.isEmpty() )
2274 return QDir::cleanPath( pfi.path() +
'/' + mHomePath );
2278 return pfi.canonicalPath();
2289 return mRelationManager;
2294 return mLayoutManager.get();
2299 return mLayoutManager.get();
2309 return mMapThemeCollection.get();
2314 return mAnnotationManager.get();
2319 return mAnnotationManager.get();
2326 QStringList newLayers;
2329 newLayers << l->
id();
2332 if ( newLayers == currentLayers )
2335 QStringList disabledLayerIds;
2339 disabledLayerIds << l->
id();
2347 writeEntry( QStringLiteral(
"Identify" ), QStringLiteral(
"/disabledLayers" ), layerIds );
2354 return readListEntry( QStringLiteral(
"Identify" ), QStringLiteral(
"/disabledLayers" ) );
2359 return mAutoTransaction;
2364 if ( autoTransaction != mAutoTransaction )
2368 if ( autoTransaction )
2369 onMapLayersAdded(
mapLayers().values() );
2371 cleanTransactionGroups(
true );
2377 return mTransactionGroups;
2388 return mLayerStore->count();
2393 return mLayerStore->mapLayer( layerId );
2398 return mLayerStore->mapLayersByName( layerName );
2401 bool QgsProject::unzip(
const QString &filename )
2407 if ( !archive->unzip( filename ) )
2409 setError( tr(
"Unable to unzip file '%1'" ).arg( filename ) );
2414 if ( archive->projectFile().isEmpty() )
2416 setError( tr(
"Zip archive does not provide a project file" ) );
2421 if ( !archive->auxiliaryStorageFile().isEmpty() )
2425 mAuxiliaryStorage.reset(
new QgsAuxiliaryStorage( archive->auxiliaryStorageFile(), false ) );
2433 if ( ! readProjectFile( archive->projectFile() ) )
2435 setError( tr(
"Cannot read unzipped qgs project file" ) );
2440 mArchive = std::move( archive );
2441 mArchive->clearProjectFile();
2446 bool QgsProject::zip(
const QString &filename )
2452 const QString
baseName = QFileInfo( filename ).baseName();
2453 const QString qgsFileName = QStringLiteral(
"%1.qgs" ).arg( baseName );
2454 QFile qgsFile( QDir( archive->dir() ).filePath( qgsFileName ) );
2456 bool writeOk =
false;
2457 if ( qgsFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
2459 writeOk = writeProjectFile( qgsFile.fileName() );
2466 setError( tr(
"Unable to write temporary qgs file" ) );
2471 const QFileInfo info( qgsFile );
2474 if ( ! saveAuxiliaryStorage( asFileName ) )
2476 setError( tr(
"Unable to save auxiliary storage" ) );
2481 archive->addFile( qgsFile.fileName() );
2482 archive->addFile( asFileName );
2485 if ( !archive->zip( filename ) )
2487 setError( tr(
"Unable to perform zip" ) );
2500 const QList<QgsMapLayer *> &
layers,
2502 bool takeOwnership )
2504 const QList<QgsMapLayer *> myResultList = mLayerStore->addMapLayers( layers, takeOwnership );
2505 if ( !myResultList.isEmpty() )
2511 if ( mAuxiliaryStorage )
2526 return myResultList;
2532 bool takeOwnership )
2534 QList<QgsMapLayer *> addedLayers;
2535 addedLayers =
addMapLayers( QList<QgsMapLayer *>() << layer, addToLegend, takeOwnership );
2536 return addedLayers.isEmpty() ? nullptr : addedLayers[0];
2541 mLayerStore->removeMapLayers( layerIds );
2546 mLayerStore->removeMapLayers( layers );
2551 mLayerStore->removeMapLayer( layerId );
2556 mLayerStore->removeMapLayer( layer );
2561 return mLayerStore->takeMapLayer( layer );
2566 mLayerStore->removeAllMapLayers();
2571 QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
2572 QMap<QString, QgsMapLayer *>::const_iterator it = layers.constBegin();
2573 for ( ; it != layers.constEnd(); ++it )
2575 it.value()->reload();
2581 return mLayerStore->mapLayers();
2586 return mTransactionGroups.value( qMakePair( providerKey, connString ) );
2593 if ( settings.
value( QStringLiteral(
"/Projections/defaultBehavior" ), QStringLiteral(
"prompt" ) ).toString() == QStringLiteral(
"useProject" )
2594 || settings.
value( QStringLiteral(
"/Projections/defaultBehavior" ), QStringLiteral(
"prompt" ) ).toString() == QStringLiteral(
"prompt" ) )
2603 QString layerDefaultCrs = settings.
value( QStringLiteral(
"/Projections/layerDefaultCrs" ),
GEO_EPSG_CRS_AUTHID ).toString();
2612 mTrustLayerMetadata = trust;
2615 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
2625 bool QgsProject::saveAuxiliaryStorage(
const QString &filename )
2629 for (
auto it = layers.constBegin(); it != layers.constEnd(); ++it )
2642 if ( !mAuxiliaryStorage->exists( *
this ) && filename.isEmpty() && empty )
2646 else if ( !filename.isEmpty() )
2648 return mAuxiliaryStorage->saveAs( filename );
2652 return mAuxiliaryStorage->saveAs( *
this );
2658 return mAuxiliaryStorage.get();
2663 return mAuxiliaryStorage.get();
2681 QSet<QgsMapLayer *>
layers;
2682 const QStringList lst =
readListEntry( QStringLiteral(
"RequiredLayers" ), QStringLiteral(
"Layers" ) );
2683 for (
const QString &layerId : lst )
2686 layers.insert( layer );
2693 QStringList layerIds;
2696 layerIds << layer->id();
2698 writeEntry( QStringLiteral(
"RequiredLayers" ), QStringLiteral(
"Layers" ), layerIds );
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.
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 void removeInvalidLayers(QgsLayerTreeGroup *group)
Remove layer nodes that refer to invalid layers.
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.
static bool isGroup(QgsLayerTreeNode *node)
Check whether the node is a valid group node.
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. ...
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.
This class is a composition of two QSettings instances:
void resolveReferences(QgsProject *project) override
Resolve references to other layers (kept as layer IDs after reading XML) into layer objects...
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
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.
This class provides qgis with the ability to render raster datasets onto the mapcanvas.
virtual QgsLayerTreeNode * clone() const =0
Create a copy of the node. Returns new instance.
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.
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...
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
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 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.
void labelingEngineSettingsChanged()
Emitted when global configuration of the labeling engine changes.
bool readLayerXml(const QDomElement &layerElement, QgsReadWriteContext &context)
Sets state from Dom document.
static QgsPluginLayerRegistry * pluginLayerRegistry()
Returns the application's plugin layer registry, used for managing plugin layer types.
QMap< QString, QgsMapLayer * > mapLayers() const
Returns a map of all registered layers by layer ID.
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.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
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.
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.
QStringList nonIdentifiableLayers() const
Gets the list of layers which currently should not be taken into account on map identification.
void reset()
reset to default values
void allLayersRemoved()
Emitted when all layers are removed, before layersWillBeRemoved() and layerWillBeRemoved() signals ar...
QgsMapLayerStore * layerStore()
Returns a pointer to the project's internal layer store.
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.
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.
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.
bool read()
Reads the project from its currently associated file (see fileName() ).
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.
QgsProjectProperty * addKey_(const QString &scope, const QString &key, QgsProjectPropertyKey *rootProperty, const QVariant &value)
Add the given key and value.
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...
QString name() const
The name of the property is used as identifier.
Namespace with helper functions for layer tree operations.
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.
void setAreaUnits(QgsUnitTypes::AreaUnit unit)
Sets the default area measurement units for the project.
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).
void readProject(const QDomDocument &)
Emitted when a project is being read.
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.
void setCrs(const QgsCoordinateReferenceSystem &crs)
Sets the project's native coordinate reference system.
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 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.
bool removeEntry(const QString &scope, const QString &key)
Remove the given key.
Reads and writes project states.
const QString GEO_EPSG_CRS_AUTHID
Geographic coord sys from EPSG authority.
void setEllipsoid(const QString &ellipsoid)
Sets the project's ellipsoid from a proj string representation, e.g., "WGS84".
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.
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.
void removeAllMapLayers()
Removes all registered layers.
void removeCustomProperty(const QString &key)
Remove a custom property from layer. Properties are stored in a map and saved in project file...
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)
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.
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() ).
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...
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.
QgsLayerTreeGroup * createEmbeddedGroup(const QString &groupName, const QString &projectFilePath, const QStringList &invisibleLayers)
Create layer group instance defined in an arbitrary project file.
static Q_INVOKABLE QString encodeUnit(QgsUnitTypes::DistanceUnit unit)
Encodes a distance unit to a string.
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.
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.
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 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.
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.
virtual void handleBadLayers(const QList< QDomNode > &layers)
This method will be called whenever the project tries to load layers which cannot be accessed...
This class manages a set of relations between layers.
void nonIdentifiableLayersChanged(QStringList nonIdentifiableLayers)
Emitted when the list of layer which are excluded from map identification changes.
QgsLayerTreeGroup * findGroup(const QString &name)
Find group node with specified name.
QgsSnappingConfig snappingConfig() const
The snapping configuration for this project.
bool createEmbeddedLayer(const QString &layerId, const QString &projectFilePath, QList< QDomNode > &brokenNodes, bool saveFlag=true)
Creates a maplayer instance defined in an arbitrary project file.
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 setTransformContext(const QgsCoordinateTransformContext &context)
Sets the project's coordinate transform context, which stores various information regarding which dat...
void setTitle(const QString &title)
Sets the project's title.
QgsVectorDataProvider * dataProvider() override
Returns the layer's data provider.
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
Check 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...
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.
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.
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
Represents a mesh layer supporting display of data on structured or unstructured meshes.
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.
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.
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 providerType() const
Returns the provider type for this layer.
QString baseName() const
Returns the base name of the project file without the path and without extension - derived from fileN...
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...
Class for storing the component parts of a PostgreSQL/RDBMS datasource URI.
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.
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 null pointer otherwise (it is a normal...
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 ...
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.
QgsPluginLayer * createLayer(const QString &typeName, const QString &uri=QString())
Returns new layer if corresponding plugin has been found else returns a nullptr.
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.
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...
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.
static QgsCoordinateReferenceSystem fromSrsId(long srsId)
Creates a CRS from a specified QGIS SRS ID.
void layerWasAdded(QgsMapLayer *layer)
Emitted when a layer was added to the registry.
Layer tree node points to a map layer.
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...
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.