19#include "moc_qgsproject.cpp"
81#include <QApplication>
86#include <QTemporaryFile>
89#include <QStandardPaths>
91#include <QRegularExpression>
113 QStringList keyTokens = QStringList( scope );
114 keyTokens += key.split(
'/', Qt::SkipEmptyParts );
117 keyTokens.push_front( QStringLiteral(
"properties" ) );
120 for (
int i = 0; i < keyTokens.size(); ++i )
122 const QString keyToken = keyTokens.at( i );
126 const thread_local QRegularExpression sInvalidRegexp = QRegularExpression( QStringLiteral(
"([^:A-Z_a-z\\x{C0}-\\x{D6}\\x{D8}-\\x{F6}\\x{F8}-\\x{2FF}\\x{370}-\\x{37D}\\x{37F}-\\x{1FFF}\\x{200C}-\\x{200D}\\x{2070}-\\x{218F}\\x{2C00}-\\x{2FEF}\\x{3001}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFFD}\\-\\.0-9\\x{B7}\\x{0300}-\\x{036F}\\x{203F}-\\x{2040}]|^[^:A-Z_a-z\\x{C0}-\\x{D6}\\x{D8}-\\x{F6}\\x{F8}-\\x{2FF}\\x{370}-\\x{37D}\\x{37F}-\\x{1FFF}\\x{200C}-\\x{200D}\\x{2070}-\\x{218F}\\x{2C00}-\\x{2FEF}\\x{3001}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFFD}])" ) );
127 if ( keyToken.contains( sInvalidRegexp ) )
129 const QString errorString = QObject::tr(
"Entry token invalid : '%1'. The token will not be saved to file." ).arg( keyToken );
157 while ( !keySequence.isEmpty() )
161 if ( keySequence.first() == currentProperty->
name() )
164 keySequence.pop_front();
166 if ( 1 == keySequence.count() )
169 return currentProperty->
find( keySequence.front() );
171 else if ( keySequence.isEmpty() )
176 return currentProperty;
178 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
180 if ( nextProperty->
isKey() )
184 else if ( nextProperty->
isValue() && 1 == keySequence.count() )
190 return currentProperty;
228 const QVariant &value,
229 bool &propertiesModified )
238 propertiesModified =
false;
239 while ( ! keySequence.isEmpty() )
243 if ( keySequence.first() == currentProperty->
name() )
246 keySequence.pop_front();
250 if ( 1 == keySequence.count() )
253 if ( !property || property->value() != value )
255 currentProperty->
setValue( keySequence.front(), value );
256 propertiesModified =
true;
259 return currentProperty;
263 else if ( keySequence.isEmpty() )
265 if ( currentProperty->
value() != value )
268 propertiesModified =
true;
271 return currentProperty;
273 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
277 if ( currentProperty )
288 if ( ( newPropertyKey = currentProperty->
addKey( keySequence.first() ) ) )
290 currentProperty = newPropertyKey;
322 while ( ! keySequence.isEmpty() )
326 if ( keySequence.first() == currentProperty->
name() )
329 keySequence.pop_front();
333 if ( 1 == keySequence.count() )
335 currentProperty->
removeKey( keySequence.front() );
340 else if ( keySequence.isEmpty() )
342 previousQgsPropertyKey->
removeKey( currentProperty->
name() );
344 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
346 previousQgsPropertyKey = currentProperty;
349 if ( currentProperty )
373 , mCapabilities( capabilities )
376 , mSnappingConfig( this )
394 mProperties.
setName( QStringLiteral(
"properties" ) );
397 mMainAnnotationLayer->setParent(
this );
411 this, [
this](
const QStringList &
layers ) { mProjectScope.reset(); emit layersWillBeRemoved( layers ); } );
413 this, [
this](
const QList<QgsMapLayer *> &
layers ) { mProjectScope.reset(); emit layersWillBeRemoved( layers ); } );
415 this, [
this](
const QString & layer ) { mProjectScope.reset(); emit layerWillBeRemoved( layer ); } );
417 this, [
this](
QgsMapLayer * layer ) { mProjectScope.reset(); emit layerWillBeRemoved( layer ); } );
419 [
this](
const QStringList &
layers ) { mProjectScope.reset(); emit layersRemoved( layers ); } );
421 [
this](
const QString & layer ) { mProjectScope.reset(); emit layerRemoved( layer ); } );
423 [
this]() { mProjectScope.reset(); emit removeAll(); } );
425 [
this](
const QList< QgsMapLayer * > &
layers ) { mProjectScope.reset(); emit layersAdded( layers ); } );
427 [
this](
QgsMapLayer * layer ) { mProjectScope.reset(); emit layerWasAdded( layer ); } );
435 [
this](
const QList<QgsMapLayer *> &
layers )
437 for ( const auto &layer : layers )
439 disconnect( layer, &QgsMapLayer::dataSourceChanged, mRelationManager, &QgsRelationManager::updateRelationsStatus );
444 [
this](
const QList<QgsMapLayer *> &layers )
446 for ( const auto &layer : layers )
448 connect( layer, &QgsMapLayer::dataSourceChanged, mRelationManager, &QgsRelationManager::updateRelationsStatus );
457 mStyleSettings->combinedStyleModel()->addDefaultStyle();
463 mIsBeingDeleted =
true;
466 releaseHandlesToProjectArchive();
467 delete mBadLayerHandler;
468 delete mRelationManager;
469 delete mLayerTreeRegistryBridge;
471 if (
this == sProject )
502 mProjectScope.reset();
513 return mMetadata.
title();
522 if ( oldEvaluateDefaultValues != newEvaluateDefaultValues )
525 for (
auto layerIt =
layers.constBegin(); layerIt !=
layers.constEnd(); ++layerIt )
527 if (
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layerIt.value() ) )
528 if ( vl->dataProvider() )
535 if ( oldTrustLayerMetadata != newTrustLayerMetadata )
538 for (
auto layerIt =
layers.constBegin(); layerIt !=
layers.constEnd(); ++layerIt )
540 if (
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layerIt.value() ) )
542 vl->setReadExtentFromXml( newTrustLayerMetadata );
547 if ( mFlags !=
flags )
562 newFlags &= ~(
static_cast< int >( flag ) );
577 return mSaveUserFull;
584 return mSaveDateTime;
605 if ( dirty && mDirtyBlockCount > 0 )
611 if ( mDirty == dirty )
622 if ( path == mHomePath )
626 mCachedHomePath.clear();
627 mProjectScope.reset();
638 const QList<QgsAttributeEditorElement *> elements = parent->
children();
646 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:formcontainers" ).arg( layerId ), container->
name() );
648 if ( !container->
children().empty() )
663 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1" ).arg( layer->layerId() ), layer->name() );
672 for (
const QgsField &field : fields )
675 if ( field.alias().isEmpty() )
676 fieldName = field.name();
678 fieldName = field.alias();
680 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:fieldaliases" ).arg( vlayer->
id() ), fieldName );
682 if ( field.editorWidgetSetup().type() == QLatin1String(
"ValueRelation" ) )
684 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:fields:%2:valuerelationvalue" ).arg( vlayer->
id(), field.name() ), field.editorWidgetSetup().config().value( QStringLiteral(
"Value" ) ).toString() );
695 const QList<QgsLayerTreeGroup *> groupLayers = mRootGroup->
findGroups();
698 translationContext->
registerTranslation( QStringLiteral(
"project:layergroups" ), groupLayer->name() );
702 const QList<QgsRelation> &relations = mRelationManager->
relations().values();
705 translationContext->
registerTranslation( QStringLiteral(
"project:relations" ), relation.name() );
713 mDataDefinedServerProperties = properties;
720 return mDataDefinedServerProperties;
727 switch ( mTransactionMode )
748 switch ( mTransactionMode )
755 commitErrors.append( tr(
"Trying to commit changes without a layer specified. This only works if the transaction mode is buffered" ) );
764 return mEditBufferGroup.
commitChanges( commitErrors, stopEditing );
774 switch ( mTransactionMode )
781 rollbackErrors.append( tr(
"Trying to roll back changes without a layer specified. This only works if the transaction mode is buffered" ) );
784 bool success = vectorLayer->
rollBack( stopEditing );
790 return mEditBufferGroup.
rollBack( rollbackErrors, stopEditing );
800 if ( name == mFile.fileName() )
803 const QString oldHomePath =
homePath();
805 mFile.setFileName( name );
806 mCachedHomePath.clear();
807 mProjectScope.reset();
811 const QString newHomePath =
homePath();
812 if ( newHomePath != oldHomePath )
823 return mFile.fileName();
830 mOriginalPath = path;
837 return mOriginalPath;
844 return QFileInfo( mFile );
862 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
867 return QFileInfo( mFile.fileName() ).lastModified();
878 if ( mFile.fileName().isEmpty() )
881 return QFileInfo( mFile.fileName() ).absolutePath();
892 if ( mFile.fileName().isEmpty() )
895 return QFileInfo( mFile.fileName() ).absoluteFilePath();
906 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
911 return QFileInfo( mFile.fileName() ).completeBaseName();
919 const bool absolutePaths =
readBoolEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
false );
930 writeEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
true );
933 writeEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
false );
950 return mCrs3D.
isValid() ? mCrs3D : mCrs;
962 writeEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectionsEnabled" ),
crs.
isValid() ? 1 : 0 );
963 mProjectScope.reset();
977 if ( oldCrs3D != mCrs3D )
981 if ( adjustEllipsoid )
990 if ( !
crs().isValid() )
993 return readEntry( QStringLiteral(
"Measure" ), QStringLiteral(
"/Ellipsoid" ),
geoNone() );
1000 if (
ellipsoid ==
readEntry( QStringLiteral(
"Measure" ), QStringLiteral(
"/Ellipsoid" ) ) )
1003 mProjectScope.reset();
1013 switch ( mCrs.
type() )
1016 QgsDebugError( QStringLiteral(
"Project has a vertical CRS set as the horizontal CRS!" ) );
1035 return mVerticalCrs;
1063 *errorMessage = QObject::tr(
"Specified CRS is a %1 CRS, not a Vertical CRS" ).arg(
qgsEnumValueToKey(
crs.
type() ) );
1068 if (
crs != mVerticalCrs )
1073 switch ( mCrs.
type() )
1076 if (
crs != oldVerticalCrs )
1079 *errorMessage = QObject::tr(
"Project CRS is a Compound CRS, specified Vertical CRS will be ignored" );
1085 if (
crs != oldVerticalCrs )
1088 *errorMessage = QObject::tr(
"Project CRS is a Geographic 3D CRS, specified Vertical CRS will be ignored" );
1094 if (
crs != oldVerticalCrs )
1097 *errorMessage = QObject::tr(
"Project CRS is a Geocentric CRS, specified Vertical CRS will be ignored" );
1106 *errorMessage = QObject::tr(
"Project CRS is a Projected 3D CRS, specified Vertical CRS will be ignored" );
1124 res = rebuildCrs3D( errorMessage );
1125 mProjectScope.reset();
1132 if ( mCrs3D != oldCrs3D )
1143 return mTransformContext;
1150 if ( context == mTransformContext )
1153 mTransformContext = context;
1154 mProjectScope.reset();
1157 for (
auto &layer : mLayerStore.get()->mapLayers() )
1159 layer->setTransformContext( context );
1168 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
1172 if ( !mIsBeingDeleted )
1181 mProjectScope.reset();
1182 mFile.setFileName( QString() );
1185 mSaveUserFull.clear();
1186 mSaveDateTime = QDateTime();
1189 mCachedHomePath.clear();
1193 mCustomVariables.clear();
1199 if ( !mSettings.
value( QStringLiteral(
"projects/anonymize_new_projects" ),
false,
QgsSettings::Core ).toBool() )
1218 mEmbeddedLayers.clear();
1219 mRelationManager->
clear();
1220 mAnnotationManager->clear();
1221 mLayoutManager->clear();
1222 m3DViewsManager->clear();
1223 mBookmarkManager->
clear();
1224 mSensorManager->
clear();
1225 mViewSettings->
reset();
1226 mTimeSettings->
reset();
1227 mElevationProperties->
reset();
1228 mDisplaySettings->
reset();
1229 mGpsSettings->
reset();
1230 mSnappingConfig.
reset();
1238 mLabelingEngineSettings->clear();
1242 releaseHandlesToProjectArchive();
1248 mStyleSettings->
reset();
1252 if ( !mIsBeingDeleted )
1260 writeEntry( QStringLiteral(
"PositionPrecision" ), QStringLiteral(
"/Automatic" ),
true );
1261 writeEntry( QStringLiteral(
"PositionPrecision" ), QStringLiteral(
"/DecimalPlaces" ), 2 );
1263 const bool defaultRelativePaths = mSettings.
value( QStringLiteral(
"/qgis/defaultProjectPathsRelative" ),
true ).toBool();
1266 int red = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_red" ), 255 ).toInt();
1267 int green = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_green" ), 255 ).toInt();
1268 int blue = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_blue" ), 255 ).toInt();
1271 red = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_red" ), 255 ).toInt();
1272 green = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_green" ), 255 ).toInt();
1273 blue = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_blue" ), 0 ).toInt();
1274 const int alpha = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_alpha" ), 255 ).toInt();
1280 mRootGroup->
clear();
1281 if ( mMainAnnotationLayer )
1282 mMainAnnotationLayer->
reset();
1284 snapSingleBlocker.release();
1286 if ( !mBlockSnappingUpdates )
1291 if ( !mBlockChangeSignalsDuringClear )
1303 topQgsPropertyKey.
dump();
1336 const QDomElement propertiesElem = doc.documentElement().firstChildElement( QStringLiteral(
"properties" ) );
1338 if ( propertiesElem.isNull() )
1343 const QDomNodeList scopes = propertiesElem.childNodes();
1345 if ( propertiesElem.firstChild().isNull() )
1347 QgsDebugError( QStringLiteral(
"empty ``properties'' XML tag ... bailing" ) );
1351 if ( ! project_properties.
readXml( propertiesElem ) )
1353 QgsDebugError( QStringLiteral(
"Project_properties.readXml() failed" ) );
1367 const QDomElement ddElem = doc.documentElement().firstChildElement( QStringLiteral(
"dataDefinedServerProperties" ) );
1368 if ( !ddElem.isNull() )
1370 if ( !ddServerProperties.
readXml( ddElem, dataDefinedServerPropertyDefinitions ) )
1372 QgsDebugError( QStringLiteral(
"dataDefinedServerProperties.readXml() failed" ) );
1375 return ddServerProperties;
1382static void _getTitle(
const QDomDocument &doc, QString &title )
1384 const QDomElement titleNode = doc.documentElement().firstChildElement( QStringLiteral(
"title" ) );
1388 if ( titleNode.isNull() )
1394 if ( !titleNode.hasChildNodes() )
1400 const QDomNode titleTextNode = titleNode.firstChild();
1402 if ( !titleTextNode.isText() )
1408 const QDomText titleText = titleTextNode.toText();
1410 title = titleText.data();
1414static void readProjectFileMetadata(
const QDomDocument &doc, QString &lastUser, QString &lastUserFull, QDateTime &lastSaveDateTime )
1416 const QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"qgis" ) );
1420 QgsDebugError( QStringLiteral(
"unable to find qgis element" ) );
1424 const QDomNode qgisNode = nl.item( 0 );
1426 const QDomElement qgisElement = qgisNode.toElement();
1427 lastUser = qgisElement.attribute( QStringLiteral(
"saveUser" ), QString() );
1428 lastUserFull = qgisElement.attribute( QStringLiteral(
"saveUserFull" ), QString() );
1429 lastSaveDateTime = QDateTime::fromString( qgisElement.attribute( QStringLiteral(
"saveDateTime" ), QString() ), Qt::ISODate );
1434 const QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"qgis" ) );
1438 QgsDebugError( QStringLiteral(
" unable to find qgis element in project file" ) );
1442 const QDomNode qgisNode = nl.item( 0 );
1444 const QDomElement qgisElement = qgisNode.toElement();
1445 QgsProjectVersion projectVersion( qgisElement.attribute( QStringLiteral(
"version" ) ) );
1446 return projectVersion;
1453 return mSnappingConfig;
1472 if ( mAvoidIntersectionsMode == mode )
1475 mAvoidIntersectionsMode = mode;
1509void QgsProject::preloadProviders(
const QVector<QDomNode> ¶llelLayerNodes,
1511 QMap<QString, QgsDataProvider *> &loadedProviders,
1513 int totalProviderCount )
1518 QMap<QString, LayerToLoad> layersToLoad;
1520 for (
const QDomNode &node : parallelLayerNodes )
1524 const QDomElement layerElement = node.toElement();
1526 layerToLoad.
layerId = layerElement.namedItem( QStringLiteral(
"id" ) ).toElement().text();
1527 layerToLoad.
provider = layerElement.namedItem( QStringLiteral(
"provider" ) ).toElement().text();
1528 layerToLoad.
dataSource = layerElement.namedItem( QStringLiteral(
"datasource" ) ).toElement().text();
1539 layersToLoad.insert( layerToLoad.
layerId, layerToLoad );
1542 while ( !layersToLoad.isEmpty() )
1544 const QList<LayerToLoad> layersToAttemptInParallel = layersToLoad.values();
1545 QString layerToAttemptInMainThread;
1547 QHash<QString, QgsRunnableProviderCreator *> runnables;
1548 QThreadPool threadPool;
1551 for (
const LayerToLoad &lay : layersToAttemptInParallel )
1554 runnables.insert( lay.layerId, run );
1560 layersToLoad.remove( layId );
1563 Q_ASSERT( finishedRun );
1565 std::unique_ptr<QgsDataProvider> provider( finishedRun->
dataProvider() );
1566 Q_ASSERT( provider && provider->isValid() );
1568 loadedProviders.insert( layId, provider.release() );
1573 if ( layerToAttemptInMainThread.isEmpty() )
1574 layerToAttemptInMainThread = layId;
1578 if ( i == parallelLayerNodes.count() || !isValid )
1581 threadPool.start( run );
1585 threadPool.waitForDone();
1587 qDeleteAll( runnables );
1590 auto it = layersToLoad.find( layerToAttemptInMainThread );
1591 if ( it != layersToLoad.end() )
1593 std::unique_ptr<QgsDataProvider> provider;
1603 if ( provider && provider->isValid() )
1608 layersToLoad.erase( it );
1611 loadedProviders.insert( layerId, provider.release() );
1619void QgsProject::releaseHandlesToProjectArchive()
1624bool QgsProject::rebuildCrs3D( QString *error )
1631 else if ( !mVerticalCrs.
isValid() )
1637 switch ( mCrs.
type() )
1678bool QgsProject::_getMapLayers(
const QDomDocument &doc, QList<QDomNode> &brokenNodes,
Qgis::ProjectReadFlags flags )
1685 QDomElement layerElement = doc.documentElement().firstChildElement( QStringLiteral(
"projectlayers" ) ).firstChildElement( QStringLiteral(
"maplayer" ) );
1689 if ( layerElement.isNull() )
1699 bool returnStatus =
true;
1702 while ( ! layerElement.isNull() )
1705 layerElement = layerElement.nextSiblingElement( QStringLiteral(
"maplayer" ) );
1711 if ( depSorter.hasCycle() )
1715 if ( depSorter.hasMissingDependency() )
1716 returnStatus =
false;
1720 const QVector<QDomNode> sortedLayerNodes = depSorter.sortedLayerNodes();
1721 const int totalLayerCount = sortedLayerNodes.count();
1723 QVector<QDomNode> parallelLoading;
1724 QMap<QString, QgsDataProvider *> loadedProviders;
1729 profile.switchTask( tr(
"Load providers in parallel" ) );
1730 for (
const QDomNode &node : sortedLayerNodes )
1732 const QDomElement element = node.toElement();
1733 if ( element.attribute( QStringLiteral(
"embedded" ) ) != QLatin1String(
"1" ) )
1735 const QString layerId = node.namedItem( QStringLiteral(
"id" ) ).toElement().text();
1736 if ( !depSorter.isLayerDependent( layerId ) )
1738 const QDomNode mnl = element.namedItem( QStringLiteral(
"provider" ) );
1739 const QDomElement mne = mnl.toElement();
1740 const QString provider = mne.text();
1744 parallelLoading.append( node );
1753 if ( !parallelLoading.isEmpty() )
1754 preloadProviders( parallelLoading, context, loadedProviders, projectFlagsToLayerReadFlags(
flags, mFlags ), sortedLayerNodes.count() );
1757 int i = loadedProviders.count();
1758 for (
const QDomNode &node : std::as_const( sortedLayerNodes ) )
1760 const QDomElement element = node.toElement();
1761 const QString name =
translate( QStringLiteral(
"project:layers:%1" ).arg( node.namedItem( QStringLiteral(
"id" ) ).toElement().text() ), node.namedItem( QStringLiteral(
"layername" ) ).toElement().text() );
1762 if ( !name.isNull() )
1763 emit
loadingLayer( tr(
"Loading layer %1" ).arg( name ) );
1765 profile.switchTask( name );
1766 if ( element.attribute( QStringLiteral(
"embedded" ) ) == QLatin1String(
"1" ) )
1768 createEmbeddedLayer( element.attribute( QStringLiteral(
"id" ) ),
readPath( element.attribute( QStringLiteral(
"project" ) ) ), brokenNodes,
true,
flags );
1776 QString layerId = element.namedItem( QStringLiteral(
"id" ) ).toElement().text();
1778 if ( !addLayer( element, brokenNodes, context,
flags, loadedProviders.take( layerId ) ) )
1780 returnStatus =
false;
1783 if ( !messages.isEmpty() )
1792 return returnStatus;
1795bool QgsProject::addLayer(
const QDomElement &layerElem,
1796 QList<QDomNode> &brokenNodes,
1803 const QString type = layerElem.attribute( QStringLiteral(
"type" ) );
1805 std::unique_ptr<QgsMapLayer>
mapLayer;
1813 QgsDebugError( QStringLiteral(
"Unknown layer type \"%1\"" ).arg( type ) );
1817 switch ( layerType )
1820 mapLayer = std::make_unique<QgsVectorLayer>();
1824 mapLayer = std::make_unique<QgsRasterLayer>();
1828 mapLayer = std::make_unique<QgsMeshLayer>();
1832 mapLayer = std::make_unique<QgsVectorTileLayer>();
1836 mapLayer = std::make_unique<QgsPointCloudLayer>();
1840 mapLayer = std::make_unique<QgsTiledSceneLayer>();
1845 const QString
typeName = layerElem.attribute( QStringLiteral(
"name" ) );
1853 mapLayer = std::make_unique<QgsAnnotationLayer>( QString(), options );
1860 mapLayer = std::make_unique<QgsGroupLayer>( QString(), options );
1867 QgsDebugError( QStringLiteral(
"Unable to create layer" ) );
1875 const QString layerId { layerElem.namedItem( QStringLiteral(
"id" ) ).toElement().text() };
1876 Q_ASSERT( ! layerId.isEmpty() );
1882 profile.switchTask( tr(
"Load layer source" ) );
1889 if ( vl->dataProvider() )
1896 profile.switchTask( tr(
"Add layer to project" ) );
1897 QList<QgsMapLayer *> newLayers;
1909 vLayer->joinBuffer()->resolveReferences(
this );
1918 brokenNodes.push_back( layerElem );
1921 const bool wasEditable = layerElem.attribute( QStringLiteral(
"editable" ), QStringLiteral(
"0" ) ).toInt();
1933 if ( ! layerWasStored )
1938 return layerIsValid;
1945 mFile.setFileName( filename );
1946 mCachedHomePath.clear();
1947 mProjectScope.reset();
1956 const QString filename = mFile.fileName();
1961 QTemporaryFile inDevice;
1962 if ( !inDevice.open() )
1964 setError( tr(
"Unable to open %1" ).arg( inDevice.fileName() ) );
1970 if ( !storage->readProject( filename, &inDevice, context ) )
1972 QString err = tr(
"Unable to open %1" ).arg( filename );
1973 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
1974 if ( !messages.isEmpty() )
1975 err += QStringLiteral(
"\n\n" ) + messages.last().message();
1979 returnValue = unzip( inDevice.fileName(),
flags );
1985 returnValue = unzip( mFile.fileName(),
flags );
1990 const QFileInfo finfo( mFile.fileName() );
1991 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( QStringLiteral(
"%1_attachments.zip" ).arg( finfo.completeBaseName() ) );
1992 if ( QFile( attachmentsZip ).exists() )
1994 std::unique_ptr<QgsArchive> archive(
new QgsArchive() );
1995 if ( archive->unzip( attachmentsZip ) )
1997 releaseHandlesToProjectArchive();
1998 mArchive = std::move( archive );
2001 returnValue = readProjectFile( mFile.fileName(),
flags );
2007 mFile.setFileName( filename );
2008 mCachedHomePath.clear();
2009 mProjectScope.reset();
2014 mTranslator.reset(
nullptr );
2026 ScopedIntIncrementor snapSignalBlock( &mBlockSnappingUpdates );
2028 QFile projectFile( filename );
2036 if ( QFile( QStringLiteral(
"%1/%2.qm" ).arg( QFileInfo( projectFile.fileName() ).absolutePath(), localeFileName ) ).exists() )
2038 mTranslator.reset(
new QTranslator() );
2039 ( void )mTranslator->load( localeFileName, QFileInfo( projectFile.fileName() ).absolutePath() );
2042 profile.switchTask( tr(
"Reading project file" ) );
2043 std::unique_ptr<QDomDocument> doc(
new QDomDocument( QStringLiteral(
"qgis" ) ) );
2045 if ( !projectFile.open( QIODevice::ReadOnly | QIODevice::Text ) )
2047 projectFile.close();
2049 setError( tr(
"Unable to open %1" ).arg( projectFile.fileName() ) );
2054 QTextStream textStream( &projectFile );
2055#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
2056 textStream.setCodec(
"UTF-8" );
2058 QString projectString = textStream.readAll();
2059 projectFile.close();
2061 for (
int i = 0; i < 32; i++ )
2063 if ( i == 9 || i == 10 || i == 13 )
2067 projectString.replace( QChar( i ), QStringLiteral(
"%1%2%1" ).arg(
FONTMARKER_CHR_FIX, QString::number( i ) ) );
2073 if ( !doc->setContent( projectString, &errorMsg, &line, &column ) )
2075 const QString errorString = tr(
"Project file read error in file %1: %2 at line %3 column %4" )
2076 .arg( projectFile.fileName(), errorMsg ).arg( line ).arg( column );
2078 setError( errorString );
2083 projectFile.close();
2091 profile.switchTask( tr(
"Updating project file" ) );
2092 if ( thisVersion > fileVersion )
2094 const bool isOlderMajorVersion = fileVersion.
majorVersion() < thisVersion.majorVersion();
2096 if ( isOlderMajorVersion )
2099 "version of qgis (saved in " + fileVersion.
text() +
2101 "). Problems may occur." );
2112 projectFile.updateRevision( thisVersion );
2114 else if ( fileVersion > thisVersion )
2117 "version of qgis (saved in " + fileVersion.
text() +
2119 "). Problems may occur." );
2125 profile.switchTask( tr(
"Creating auxiliary storage" ) );
2126 const QString
fileName = mFile.fileName();
2133 std::unique_ptr<QgsAuxiliaryStorage> aStorage = std::move( mAuxiliaryStorage );
2134 std::unique_ptr<QgsArchive> archive = std::move( mArchive );
2138 mBlockChangeSignalsDuringClear =
true;
2140 mBlockChangeSignalsDuringClear =
false;
2145 releaseHandlesToProjectArchive();
2147 mAuxiliaryStorage = std::move( aStorage );
2148 mArchive = std::move( archive );
2151 mCachedHomePath.clear();
2152 mProjectScope.reset();
2153 mSaveVersion = fileVersion;
2156 profile.switchTask( tr(
"Reading properties" ) );
2165 dump_( mProperties );
2170 _getTitle( *doc, oldTitle );
2172 readProjectFileMetadata( *doc, mSaveUser, mSaveUserFull, mSaveDateTime );
2174 const QDomNodeList homePathNl = doc->elementsByTagName( QStringLiteral(
"homePath" ) );
2175 if ( homePathNl.count() > 0 )
2177 const QDomElement homePathElement = homePathNl.at( 0 ).toElement();
2178 const QString
homePath = homePathElement.attribute( QStringLiteral(
"path" ) );
2188 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorGreenPart" ), 255 ),
2189 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorBluePart" ), 255 ) );
2192 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorGreenPart" ), 255 ),
2193 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorBluePart" ), 255 ),
2194 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorAlphaPart" ), 255 ) );
2198 const QString distanceUnitString =
readEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/DistanceUnits" ), QString() );
2199 if ( !distanceUnitString.isEmpty() )
2202 const QString areaUnitString =
readEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/AreaUnits" ), QString() );
2203 if ( !areaUnitString.isEmpty() )
2212 if (
readNumEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectionsEnabled" ), 0 ) )
2215 const QDomNode srsNode = doc->documentElement().namedItem( QStringLiteral(
"projectCrs" ) );
2216 if ( !srsNode.isNull() )
2218 projectCrs.
readXml( srsNode );
2223 const QString projCrsString =
readEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCRSProj4String" ) );
2224 const long currentCRS =
readNumEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCRSID" ), -1 );
2225 const QString authid =
readEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCrs" ) );
2228 const bool isUserAuthId = authid.startsWith( QLatin1String(
"USER:" ), Qt::CaseInsensitive );
2229 if ( !authid.isEmpty() && !isUserAuthId )
2233 if ( !projectCrs.
isValid() && currentCRS >= 0 )
2239 if ( !projCrsString.isEmpty() && ( authid.isEmpty() || isUserAuthId ) && ( !projectCrs.
isValid() || projectCrs.
toProj() != projCrsString ) )
2256 const QDomNode verticalCrsNode = doc->documentElement().namedItem( QStringLiteral(
"verticalCrs" ) );
2257 if ( !verticalCrsNode.isNull() )
2265 QStringList datumErrors;
2266 if ( !mTransformContext.
readXml( doc->documentElement(), context, datumErrors ) && !datumErrors.empty() )
2273 const QDomNode elevationShadingNode = doc->documentElement().namedItem( QStringLiteral(
"elevation-shading-renderer" ) );
2274 if ( !elevationShadingNode.isNull() )
2276 mElevationShadingRenderer.
readXml( elevationShadingNode.toElement(), context );
2283 const QStringList variableNames =
readListEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableNames" ) );
2284 const QStringList variableValues =
readListEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableValues" ) );
2286 mCustomVariables.clear();
2287 if ( variableNames.length() == variableValues.length() )
2289 for (
int i = 0; i < variableNames.length(); ++i )
2291 mCustomVariables.insert( variableNames.at( i ), variableValues.at( i ) );
2296 QgsMessageLog::logMessage( tr(
"Project Variables Invalid" ), tr(
"The project contains invalid variable settings." ) );
2304 QDomElement element = doc->documentElement().firstChildElement( QStringLiteral(
"projectMetadata" ) );
2306 if ( !element.isNull() )
2315 if ( mMetadata.
title().isEmpty() && !oldTitle.isEmpty() )
2323 element = doc->documentElement().firstChildElement( QStringLiteral(
"transaction" ) );
2324 if ( !element.isNull() )
2331 element = doc->documentElement().firstChildElement( QStringLiteral(
"autotransaction" ) );
2332 if ( ! element.isNull() )
2334 mTransactionMode =
static_cast<Qgis::TransactionMode>( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() );
2339 profile.switchTask( tr(
"Loading layer tree" ) );
2342 QDomElement layerTreeElem = doc->documentElement().firstChildElement( QStringLiteral(
"layer-tree-group" ) );
2343 if ( !layerTreeElem.isNull() )
2355 mLayerTreeRegistryBridge->
setEnabled(
false );
2358 profile.switchTask( tr(
"Reading map layers" ) );
2360 loadProjectFlags( doc.get() );
2362 QList<QDomNode> brokenNodes;
2363 const bool clean = _getMapLayers( *doc, brokenNodes,
flags );
2368 QgsDebugError( QStringLiteral(
"Unable to get map layers from project file." ) );
2370 if ( !brokenNodes.isEmpty() )
2372 QgsDebugError(
"there are " + QString::number( brokenNodes.size() ) +
" broken layers" );
2380 mMainAnnotationLayer->
readLayerXml( doc->documentElement().firstChildElement( QStringLiteral(
"main-annotation-layer" ) ), context );
2384 profile.switchTask( tr(
"Loading embedded layers" ) );
2385 loadEmbeddedNodes( mRootGroup,
flags );
2389 profile.switchTask( tr(
"Resolving layer references" ) );
2390 QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
2391 for ( QMap<QString, QgsMapLayer *>::iterator it =
layers.begin(); it !=
layers.end(); ++it )
2393 it.value()->resolveReferences(
this );
2397 mLayerTreeRegistryBridge->
setEnabled(
true );
2400 profile.switchTask( tr(
"Resolving references" ) );
2411 if ( !layerTreeElem.isNull() )
2417 const QDomElement layerTreeCanvasElem = doc->documentElement().firstChildElement( QStringLiteral(
"layer-tree-canvas" ) );
2418 if ( !layerTreeCanvasElem.isNull( ) )
2426 const QStringList requiredLayerIds =
readListEntry( QStringLiteral(
"RequiredLayers" ), QStringLiteral(
"Layers" ) );
2427 for (
const QString &layerId : requiredLayerIds )
2434 const QStringList disabledLayerIds =
readListEntry( QStringLiteral(
"Identify" ), QStringLiteral(
"/disabledLayers" ) );
2435 for (
const QString &layerId : disabledLayerIds )
2448 QString styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Marker" ) );
2449 if ( !styleName.isEmpty() )
2454 styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Line" ) );
2455 if ( !styleName.isEmpty() )
2460 styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Fill" ) );
2461 if ( !styleName.isEmpty() )
2466 styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/ColorRamp" ) );
2467 if ( !styleName.isEmpty() )
2477 double opacity = 1.0;
2480 double alpha =
readDoubleEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/AlphaInt" ), 255, &ok );
2482 opacity = alpha / 255.0;
2483 double newOpacity =
readDoubleEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Opacity" ), 1.0, &ok );
2485 opacity = newOpacity;
2489 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Marker" ) );
2490 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Line" ) );
2491 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Fill" ) );
2492 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/ColorRamp" ) );
2493 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/RandomColors" ) );
2494 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/AlphaInt" ) );
2495 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Opacity" ) );
2503 profile.switchTask( tr(
"Storing original layer properties" ) );
2509 profile.switchTask( tr(
"Loading map themes" ) );
2512 mMapThemeCollection->readXml( *doc );
2514 profile.switchTask( tr(
"Loading label settings" ) );
2515 mLabelingEngineSettings->readSettingsFromProject(
this );
2517 const QDomElement labelEngineSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"labelEngineSettings" ) );
2518 mLabelingEngineSettings->readXml( labelEngineSettingsElement, context );
2520 mLabelingEngineSettings->resolveReferences(
this );
2524 profile.switchTask( tr(
"Loading annotations" ) );
2527 mAnnotationManager->readXml( doc->documentElement(), context );
2531 mAnnotationManager->readXmlAndUpgradeToAnnotationLayerItems( doc->documentElement(), context, mMainAnnotationLayer, mTransformContext );
2535 profile.switchTask( tr(
"Loading layouts" ) );
2536 mLayoutManager->readXml( doc->documentElement(), *doc );
2541 profile.switchTask( tr(
"Loading 3D Views" ) );
2542 m3DViewsManager->readXml( doc->documentElement(), *doc );
2545 profile.switchTask( tr(
"Loading bookmarks" ) );
2546 mBookmarkManager->
readXml( doc->documentElement(), *doc );
2548 profile.switchTask( tr(
"Loading sensors" ) );
2549 mSensorManager->
readXml( doc->documentElement(), *doc );
2552 QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
2553 for ( QMap<QString, QgsMapLayer *>::iterator it = existingMaps.begin(); it != existingMaps.end(); ++it )
2555 it.value()->setDependencies( it.value()->dependencies() );
2558 profile.switchTask( tr(
"Loading snapping settings" ) );
2562 profile.switchTask( tr(
"Loading view settings" ) );
2565 const QStringList scales =
readListEntry( QStringLiteral(
"Scales" ), QStringLiteral(
"/ScalesList" ) );
2566 QVector<double> res;
2567 for (
const QString &scale : scales )
2569 const QStringList parts = scale.split(
':' );
2570 if ( parts.size() != 2 )
2574 const double denominator = QLocale().toDouble( parts[1], &ok );
2581 const QDomElement viewSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectViewSettings" ) );
2582 if ( !viewSettingsElement.isNull() )
2583 mViewSettings->
readXml( viewSettingsElement, context );
2586 profile.switchTask( tr(
"Loading style properties" ) );
2587 const QDomElement styleSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectStyleSettings" ) );
2588 if ( !styleSettingsElement.isNull() )
2591 mStyleSettings->
readXml( styleSettingsElement, context,
flags );
2595 profile.switchTask( tr(
"Loading temporal settings" ) );
2596 const QDomElement timeSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectTimeSettings" ) );
2597 if ( !timeSettingsElement.isNull() )
2598 mTimeSettings->
readXml( timeSettingsElement, context );
2601 profile.switchTask( tr(
"Loading elevation properties" ) );
2602 const QDomElement elevationPropertiesElement = doc->documentElement().firstChildElement( QStringLiteral(
"ElevationProperties" ) );
2603 if ( !elevationPropertiesElement.isNull() )
2604 mElevationProperties->
readXml( elevationPropertiesElement, context );
2607 profile.switchTask( tr(
"Loading display settings" ) );
2609 const QDomElement displaySettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectDisplaySettings" ) );
2610 if ( !displaySettingsElement.isNull() )
2611 mDisplaySettings->
readXml( displaySettingsElement, context );
2614 profile.switchTask( tr(
"Loading GPS settings" ) );
2616 const QDomElement gpsSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectGpsSettings" ) );
2617 if ( !gpsSettingsElement.isNull() )
2618 mGpsSettings->
readXml( gpsSettingsElement, context );
2622 profile.switchTask( tr(
"Updating variables" ) );
2624 profile.switchTask( tr(
"Updating CRS" ) );
2628 if ( mCrs3D != oldCrs3D )
2633 profile.switchTask( tr(
"Reading external settings" ) );
2637 profile.switchTask( tr(
"Updating interface" ) );
2639 snapSignalBlock.release();
2640 if ( !mBlockSnappingUpdates )
2651 QgsDebugMsgLevel( QStringLiteral(
"Project save user: %1" ).arg( mSaveUser ), 2 );
2652 QgsDebugMsgLevel( QStringLiteral(
"Project save user: %1" ).arg( mSaveUserFull ), 2 );
2661 const QString newFileName( QStringLiteral(
"%1/%2.qgs" ).arg( QFileInfo( projectFile.fileName() ).absolutePath(), localeFileName ) );
2676 const QMap<QString, QgsMapLayer *> loadedLayers =
mapLayers();
2677 for (
auto it = loadedLayers.constBegin(); it != loadedLayers.constEnd(); ++it )
2679 if ( it.value()->isValid() && it.value()->customProperty( QStringLiteral(
"_layer_was_editable" ) ).toBool() )
2681 if (
QgsVectorLayer *vl = qobject_cast< QgsVectorLayer * >( it.value() ) )
2683 it.value()->removeCustomProperty( QStringLiteral(
"_layer_was_editable" ) );
2695 const auto constChildren = group->
children();
2701 if ( childGroup->
customProperty( QStringLiteral(
"embedded" ) ).toInt() )
2704 const QString projectPath =
readPath( childGroup->
customProperty( QStringLiteral(
"embedded_project" ) ).toString() );
2705 childGroup->
setCustomProperty( QStringLiteral(
"embedded_project" ), projectPath );
2709 QList<QgsLayerTreeNode *> clonedChildren;
2710 const QList<QgsLayerTreeNode *> constChildren = newGroup->
children();
2711 clonedChildren.reserve( constChildren.size() );
2713 clonedChildren << newGroupChild->clone();
2721 loadEmbeddedNodes( childGroup,
flags );
2726 if ( child->customProperty( QStringLiteral(
"embedded" ) ).toInt() )
2728 QList<QDomNode> brokenNodes;
2731 valid = valid &&
false;
2746 return mCustomVariables;
2753 if ( variables == mCustomVariables )
2757 QStringList variableNames;
2758 QStringList variableValues;
2760 QVariantMap::const_iterator it = variables.constBegin();
2761 for ( ; it != variables.constEnd(); ++it )
2763 variableNames << it.key();
2764 variableValues << it.value().toString();
2767 writeEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableNames" ), variableNames );
2768 writeEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableValues" ), variableValues );
2770 mCustomVariables = variables;
2771 mProjectScope.reset();
2780 *mLabelingEngineSettings = settings;
2788 return *mLabelingEngineSettings;
2795 mProjectScope.reset();
2796 return mLayerStore.get();
2803 return mLayerStore.get();
2810 QList<QgsVectorLayer *>
layers;
2811 const QStringList layerIds =
readListEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsList" ), QStringList() );
2812 const auto constLayerIds = layerIds;
2813 for (
const QString &layerId : constLayerIds )
2826 list.reserve(
layers.size() );
2831 list << layer->id();
2834 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsList" ), list );
2856 if ( mProjectScope )
2858 std::unique_ptr< QgsExpressionContextScope > projectScope = std::make_unique< QgsExpressionContextScope >( *mProjectScope );
2865 projectScope->addFunction( QStringLiteral(
"sensor_data" ),
new GetSensorData(
sensorManager()->sensorsData() ) );
2867 return projectScope.release();
2870 mProjectScope = std::make_unique< QgsExpressionContextScope >( QObject::tr(
"Project" ) );
2874 QVariantMap::const_iterator it = vars.constBegin();
2876 for ( ; it != vars.constEnd(); ++it )
2878 mProjectScope->setVariable( it.key(), it.value(),
true );
2882 if ( projectPath.isEmpty() )
2883 projectPath = mOriginalPath;
2884 const QString projectFolder = QFileInfo( projectPath ).path();
2885 const QString projectFilename = QFileInfo( projectPath ).fileName();
2886 const QString projectBasename =
baseName();
2923 QVariantMap keywords;
2925 for (
auto it = metadataKeywords.constBegin(); it != metadataKeywords.constEnd(); ++it )
2927 keywords.insert( it.key(), it.value() );
2932 QVariantList layersIds;
2934 const QMap<QString, QgsMapLayer *> layersInProject = mLayerStore->mapLayers();
2935 layersIds.reserve( layersInProject.count() );
2936 layers.reserve( layersInProject.count() );
2937 for (
auto it = layersInProject.constBegin(); it != layersInProject.constEnd(); ++it )
2939 layersIds << it.value()->id();
2945 mProjectScope->addFunction( QStringLiteral(
"project_color" ),
new GetNamedProjectColor(
this ) );
2946 mProjectScope->addFunction( QStringLiteral(
"project_color_object" ),
new GetNamedProjectColorObject(
this ) );
2951void QgsProject::onMapLayersAdded(
const QList<QgsMapLayer *> &layers )
2955 const QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
2957 const auto constLayers =
layers;
2960 if ( ! layer->isValid() )
2963 if (
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer ) )
2966 if ( vlayer->dataProvider() )
2974 for ( QMap<QString, QgsMapLayer *>::const_iterator it = existingMaps.cbegin(); it != existingMaps.cend(); ++it )
2976 const QSet<QgsMapLayerDependency> deps = it.value()->dependencies();
2977 if ( deps.contains( layer->id() ) )
2980 it.value()->setDependencies( deps );
2985 updateTransactionGroups();
2991void QgsProject::onMapLayersRemoved(
const QList<QgsMapLayer *> &layers )
2999void QgsProject::cleanTransactionGroups(
bool force )
3003 bool changed =
false;
3004 for ( QMap< QPair< QString, QString>,
QgsTransactionGroup *>::Iterator tg = mTransactionGroups.begin(); tg != mTransactionGroups.end(); )
3006 if ( tg.value()->isEmpty() || force )
3009 tg = mTransactionGroups.erase( tg );
3021void QgsProject::updateTransactionGroups()
3025 mEditBufferGroup.
clear();
3027 switch ( mTransactionMode )
3031 cleanTransactionGroups(
true );
3036 cleanTransactionGroups(
true );
3039 cleanTransactionGroups(
false );
3043 bool tgChanged =
false;
3044 const auto constLayers =
mapLayers().values();
3047 if ( ! layer->isValid() )
3050 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
3054 switch ( mTransactionMode )
3071 mTransactionGroups.insert( qMakePair( key, connString ), tg );
3081 mEditBufferGroup.
addLayer( vlayer );
3097 context.setProjectTranslator(
this );
3099 QList<QDomNode> brokenNodes;
3100 if ( addLayer( layerNode.toElement(), brokenNodes, context ) )
3104 const QVector<QgsVectorLayer *> vectorLayers = layers<QgsVectorLayer *>();
3108 layer->resolveReferences(
this );
3110 if ( layer->isValid() && layer->customProperty( QStringLiteral(
"_layer_was_editable" ) ).toBool() )
3112 layer->startEditing();
3113 layer->removeCustomProperty( QStringLiteral(
"_layer_was_editable" ) );
3125 mFile.setFileName( filename );
3126 mCachedHomePath.clear();
3134 mProjectScope.reset();
3140 const QString storageFilePath { storage->filePath( mFile.fileName() ) };
3141 if ( storageFilePath.isEmpty() )
3147 const QString tempPath = QStandardPaths::standardLocations( QStandardPaths::TempLocation ).at( 0 );
3148 const QString tmpZipFilename( tempPath + QDir::separator() + QUuid::createUuid().toString() );
3150 if ( !zip( tmpZipFilename ) )
3153 QFile tmpZipFile( tmpZipFilename );
3154 if ( !tmpZipFile.open( QIODevice::ReadOnly ) )
3156 setError( tr(
"Unable to read file %1" ).arg( tmpZipFilename ) );
3161 if ( !storage->writeProject( mFile.fileName(), &tmpZipFile, context ) )
3163 QString err = tr(
"Unable to save project to storage %1" ).arg( mFile.fileName() );
3164 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
3165 if ( !messages.isEmpty() )
3166 err += QStringLiteral(
"\n\n" ) + messages.last().message();
3172 QFile::remove( tmpZipFilename );
3179 return zip( mFile.fileName() );
3185 const bool asOk = saveAuxiliaryStorage();
3186 const bool writeOk = writeProjectFile( mFile.fileName() );
3187 bool attachmentsOk =
true;
3188 if ( !mArchive->files().isEmpty() )
3190 const QFileInfo finfo( mFile.fileName() );
3191 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( QStringLiteral(
"%1_attachments.zip" ).arg( finfo.completeBaseName() ) );
3192 attachmentsOk = mArchive->zip( attachmentsZip );
3196 if ( ( !asOk || !attachmentsOk ) && writeOk )
3198 QStringList errorMessage;
3201 const QString err = mAuxiliaryStorage->errorString();
3202 errorMessage.append( tr(
"Unable to save auxiliary storage ('%1')" ).arg( err ) );
3204 if ( !attachmentsOk )
3206 errorMessage.append( tr(
"Unable to save attachments archive" ) );
3208 setError( errorMessage.join(
'\n' ) );
3211 return asOk && writeOk && attachmentsOk;
3215bool QgsProject::writeProjectFile(
const QString &filename )
3219 QFile projectFile( filename );
3225 const QFileInfo myFileInfo( projectFile );
3226 if ( myFileInfo.exists() && !myFileInfo.isWritable() )
3228 setError( tr(
"%1 is not writable. Please adjust permissions (if possible) and try again." )
3229 .arg( projectFile.fileName() ) );
3237 QDomImplementation::setInvalidDataPolicy( QDomImplementation::DropInvalidChars );
3239 const QDomDocumentType documentType =
3240 QDomImplementation().createDocumentType( QStringLiteral(
"qgis" ), QStringLiteral(
"http://mrcc.com/qgis.dtd" ),
3241 QStringLiteral(
"SYSTEM" ) );
3242 std::unique_ptr<QDomDocument> doc(
new QDomDocument( documentType ) );
3244 QDomElement qgisNode = doc->createElement( QStringLiteral(
"qgis" ) );
3245 qgisNode.setAttribute( QStringLiteral(
"projectname" ),
title() );
3246 qgisNode.setAttribute( QStringLiteral(
"version" ),
Qgis::version() );
3248 if ( !mSettings.
value( QStringLiteral(
"projects/anonymize_saved_projects" ),
false,
QgsSettings::Core ).toBool() )
3252 qgisNode.setAttribute( QStringLiteral(
"saveUser" ), newSaveUser );
3253 qgisNode.setAttribute( QStringLiteral(
"saveUserFull" ), newSaveUserFull );
3254 mSaveUser = newSaveUser;
3255 mSaveUserFull = newSaveUserFull;
3256 mSaveDateTime = QDateTime::currentDateTime();
3257 qgisNode.setAttribute( QStringLiteral(
"saveDateTime" ), mSaveDateTime.toString( Qt::ISODate ) );
3262 mSaveUserFull.clear();
3263 mSaveDateTime = QDateTime();
3265 doc->appendChild( qgisNode );
3268 QDomElement homePathNode = doc->createElement( QStringLiteral(
"homePath" ) );
3269 homePathNode.setAttribute( QStringLiteral(
"path" ), mHomePath );
3270 qgisNode.appendChild( homePathNode );
3273 QDomElement titleNode = doc->createElement( QStringLiteral(
"title" ) );
3274 qgisNode.appendChild( titleNode );
3276 QDomElement transactionNode = doc->createElement( QStringLiteral(
"transaction" ) );
3277 transactionNode.setAttribute( QStringLiteral(
"mode" ),
qgsEnumValueToKey( mTransactionMode ) );
3278 qgisNode.appendChild( transactionNode );
3280 QDomElement flagsNode = doc->createElement( QStringLiteral(
"projectFlags" ) );
3282 qgisNode.appendChild( flagsNode );
3284 const QDomText titleText = doc->createTextNode(
title() );
3285 titleNode.appendChild( titleText );
3289 QDomElement srsNode = doc->createElement( QStringLiteral(
"projectCrs" ) );
3291 qgisNode.appendChild( srsNode );
3294 QDomElement verticalSrsNode = doc->createElement( QStringLiteral(
"verticalCrs" ) );
3295 mVerticalCrs.
writeXml( verticalSrsNode, *doc );
3296 qgisNode.appendChild( verticalSrsNode );
3299 QDomElement elevationShadingNode = doc->createElement( QStringLiteral(
"elevation-shading-renderer" ) );
3300 mElevationShadingRenderer.
writeXml( elevationShadingNode, context );
3301 qgisNode.appendChild( elevationShadingNode );
3308 clonedRoot->
writeXml( qgisNode, context );
3312 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsMode" ),
static_cast<int>( mAvoidIntersectionsMode ) );
3320 QDomElement annotationLayerNode = doc->createElement( QStringLiteral(
"main-annotation-layer" ) );
3321 mMainAnnotationLayer->
writeLayerXml( annotationLayerNode, *doc, context );
3322 qgisNode.appendChild( annotationLayerNode );
3326 QDomElement projectLayersNode = doc->createElement( QStringLiteral(
"projectlayers" ) );
3328 QMap<QString, QgsMapLayer *>::ConstIterator li =
layers.constBegin();
3329 while ( li !=
layers.end() )
3335 const QHash< QString, QPair< QString, bool> >::const_iterator emIt = mEmbeddedLayers.constFind( ml->
id() );
3336 if ( emIt == mEmbeddedLayers.constEnd() )
3338 QDomElement maplayerElem;
3344 maplayerElem = doc->createElement( QStringLiteral(
"maplayer" ) );
3348 maplayerElem.setAttribute( QStringLiteral(
"editable" ), QStringLiteral(
"1" ) );
3352 QDomDocument document;
3355 maplayerElem = document.firstChildElement();
3359 QgsDebugError( QStringLiteral(
"Could not restore layer properties for layer %1" ).arg( ml->
id() ) );
3365 projectLayersNode.appendChild( maplayerElem );
3371 if ( emIt.value().second )
3373 QDomElement mapLayerElem = doc->createElement( QStringLiteral(
"maplayer" ) );
3374 mapLayerElem.setAttribute( QStringLiteral(
"embedded" ), 1 );
3375 mapLayerElem.setAttribute( QStringLiteral(
"project" ),
writePath( emIt.value().first ) );
3376 mapLayerElem.setAttribute( QStringLiteral(
"id" ), ml->
id() );
3377 projectLayersNode.appendChild( mapLayerElem );
3384 qgisNode.appendChild( projectLayersNode );
3386 QDomElement layerOrderNode = doc->createElement( QStringLiteral(
"layerorder" ) );
3388 for (
QgsMapLayer *layer : constCustomLayerOrder )
3390 QDomElement mapLayerElem = doc->createElement( QStringLiteral(
"layer" ) );
3391 mapLayerElem.setAttribute( QStringLiteral(
"id" ), layer->id() );
3392 layerOrderNode.appendChild( mapLayerElem );
3394 qgisNode.appendChild( layerOrderNode );
3396 mLabelingEngineSettings->writeSettingsToProject(
this );
3398 QDomElement labelEngineSettingsElement = doc->createElement( QStringLiteral(
"labelEngineSettings" ) );
3399 mLabelingEngineSettings->writeXml( *doc, labelEngineSettingsElement, context );
3400 qgisNode.appendChild( labelEngineSettingsElement );
3403 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorRedPart" ), mBackgroundColor.red() );
3404 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorGreenPart" ), mBackgroundColor.green() );
3405 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorBluePart" ), mBackgroundColor.blue() );
3407 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorRedPart" ), mSelectionColor.red() );
3408 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorGreenPart" ), mSelectionColor.green() );
3409 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorBluePart" ), mSelectionColor.blue() );
3410 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorAlphaPart" ), mSelectionColor.alpha() );
3417 dump_( mProperties );
3420 QgsDebugMsgLevel( QStringLiteral(
"there are %1 property scopes" ).arg(
static_cast<int>( mProperties.
count() ) ), 2 );
3425 mProperties.
writeXml( QStringLiteral(
"properties" ), qgisNode, *doc );
3428 QDomElement ddElem = doc->createElement( QStringLiteral(
"dataDefinedServerProperties" ) );
3429 mDataDefinedServerProperties.
writeXml( ddElem, dataDefinedServerPropertyDefinitions() );
3430 qgisNode.appendChild( ddElem );
3432 mMapThemeCollection->writeXml( *doc );
3434 mTransformContext.
writeXml( qgisNode, context );
3436 QDomElement metadataElem = doc->createElement( QStringLiteral(
"projectMetadata" ) );
3438 qgisNode.appendChild( metadataElem );
3441 const QDomElement annotationsElem = mAnnotationManager->writeXml( *doc, context );
3442 qgisNode.appendChild( annotationsElem );
3446 const QDomElement layoutElem = mLayoutManager->writeXml( *doc );
3447 qgisNode.appendChild( layoutElem );
3451 const QDomElement views3DElem = m3DViewsManager->writeXml( *doc );
3452 qgisNode.appendChild( views3DElem );
3456 const QDomElement bookmarkElem = mBookmarkManager->
writeXml( *doc );
3457 qgisNode.appendChild( bookmarkElem );
3461 const QDomElement sensorElem = mSensorManager->
writeXml( *doc );
3462 qgisNode.appendChild( sensorElem );
3466 const QDomElement viewSettingsElem = mViewSettings->
writeXml( *doc, context );
3467 qgisNode.appendChild( viewSettingsElem );
3471 const QDomElement styleSettingsElem = mStyleSettings->
writeXml( *doc, context );
3472 qgisNode.appendChild( styleSettingsElem );
3476 const QDomElement timeSettingsElement = mTimeSettings->
writeXml( *doc, context );
3477 qgisNode.appendChild( timeSettingsElement );
3481 const QDomElement elevationPropertiesElement = mElevationProperties->
writeXml( *doc, context );
3482 qgisNode.appendChild( elevationPropertiesElement );
3486 const QDomElement displaySettingsElem = mDisplaySettings->
writeXml( *doc, context );
3487 qgisNode.appendChild( displaySettingsElem );
3491 const QDomElement gpsSettingsElem = mGpsSettings->
writeXml( *doc, context );
3492 qgisNode.appendChild( gpsSettingsElem );
3501 QFile backupFile( QStringLiteral(
"%1~" ).arg( filename ) );
3503 ok &= backupFile.open( QIODevice::WriteOnly | QIODevice::Truncate );
3504 ok &= projectFile.open( QIODevice::ReadOnly );
3507 while ( ok && !projectFile.atEnd() )
3509 ba = projectFile.read( 10240 );
3510 ok &= backupFile.write( ba ) == ba.size();
3513 projectFile.close();
3518 setError( tr(
"Unable to create backup file %1" ).arg( backupFile.fileName() ) );
3523 struct utimbuf tb = {
static_cast<time_t
>( fi.lastRead().toSecsSinceEpoch() ),
static_cast<time_t
>( fi.lastModified().toSecsSinceEpoch() ) };
3524 utime( backupFile.fileName().toUtf8().constData(), &tb );
3527 if ( !projectFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
3529 projectFile.close();
3532 setError( tr(
"Unable to save to file %1" ).arg( projectFile.fileName() ) );
3536 QTemporaryFile tempFile;
3537 bool ok = tempFile.open();
3540 QTextStream projectFileStream( &tempFile );
3541 doc->save( projectFileStream, 2 );
3542 ok &= projectFileStream.pos() > -1;
3544 ok &= tempFile.seek( 0 );
3547 while ( ok && !tempFile.atEnd() )
3549 ba = tempFile.read( 10240 );
3550 ok &= projectFile.write( ba ) == ba.size();
3553 ok &= projectFile.error() == QFile::NoError;
3555 projectFile.close();
3562 setError( tr(
"Unable to save to file %1. Your project "
3563 "may be corrupted on disk. Try clearing some space on the volume and "
3564 "check file permissions before pressing save again." )
3565 .arg( projectFile.fileName() ) );
3579 bool propertiesModified;
3580 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3582 if ( propertiesModified )
3592 bool propertiesModified;
3593 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3595 if ( propertiesModified )
3605 bool propertiesModified;
3606 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3608 if ( propertiesModified )
3618 bool propertiesModified;
3619 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3621 if ( propertiesModified )
3631 bool propertiesModified;
3632 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3634 if ( propertiesModified )
3642 const QStringList &def,
3654 value =
property->value();
3656 const bool valid = QMetaType::Type::QStringList == value.userType();
3662 return value.toStringList();
3685 value =
property->value();
3687 const bool valid = value.canConvert( QMetaType::Type::QString );
3692 return value.toString();
3711 value =
property->value();
3714 const bool valid = value.canConvert( QMetaType::Type::Int );
3723 return value.toInt();
3738 const QVariant value =
property->value();
3740 const bool valid = value.canConvert( QMetaType::Type::Double );
3745 return value.toDouble();
3762 const QVariant value =
property->value();
3764 const bool valid = value.canConvert( QMetaType::Type::Bool );
3769 return value.toBool();
3781 if (
findKey_( scope, key, mProperties ) )
3787 return !
findKey_( scope, key, mProperties );
3796 QStringList entries;
3798 if ( foundProperty )
3815 QStringList entries;
3817 if ( foundProperty )
3832 dump_( mProperties );
3852 filePath = storage->filePath( mFile.fileName() );
3879void QgsProject::setError(
const QString &errorMessage )
3883 mErrorMessage = errorMessage;
3890 return mErrorMessage;
3893void QgsProject::clearError()
3897 setError( QString() );
3904 delete mBadLayerHandler;
3905 mBadLayerHandler = handler;
3912 const QHash< QString, QPair< QString, bool > >::const_iterator it = mEmbeddedLayers.find(
id );
3913 if ( it == mEmbeddedLayers.constEnd() )
3917 return it.value().first;
3927 static QString sPrevProjectFilePath;
3928 static QDateTime sPrevProjectFileTimestamp;
3929 static QDomDocument sProjectDocument;
3931 QString qgsProjectFile = projectFilePath;
3933 if ( projectFilePath.endsWith( QLatin1String(
".qgz" ), Qt::CaseInsensitive ) )
3935 archive.
unzip( projectFilePath );
3939 const QDateTime projectFileTimestamp = QFileInfo( projectFilePath ).lastModified();
3941 if ( projectFilePath != sPrevProjectFilePath || projectFileTimestamp != sPrevProjectFileTimestamp )
3943 sPrevProjectFilePath.clear();
3945 QFile projectFile( qgsProjectFile );
3946 if ( !projectFile.open( QIODevice::ReadOnly ) )
3951 if ( !sProjectDocument.setContent( &projectFile ) )
3956 sPrevProjectFilePath = projectFilePath;
3957 sPrevProjectFileTimestamp = projectFileTimestamp;
3961 bool useAbsolutePaths =
true;
3963 const QDomElement propertiesElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral(
"properties" ) );
3964 if ( !propertiesElem.isNull() )
3966 const QDomElement absElem = propertiesElem.firstChildElement( QStringLiteral(
"Paths" ) ).firstChildElement( QStringLiteral(
"Absolute" ) );
3967 if ( !absElem.isNull() )
3969 useAbsolutePaths = absElem.text().compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0;
3974 if ( !useAbsolutePaths )
3979 const QDomElement projectLayersElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral(
"projectlayers" ) );
3980 if ( projectLayersElem.isNull() )
3985 QDomElement mapLayerElem = projectLayersElem.firstChildElement( QStringLiteral(
"maplayer" ) );
3986 while ( ! mapLayerElem.isNull() )
3989 const QString
id = mapLayerElem.firstChildElement( QStringLiteral(
"id" ) ).text();
3990 if (
id == layerId )
3993 if ( mapLayerElem.attribute( QStringLiteral(
"embedded" ) ) == QLatin1String(
"1" ) )
3998 mEmbeddedLayers.insert( layerId, qMakePair( projectFilePath, saveFlag ) );
4000 if ( addLayer( mapLayerElem, brokenNodes, embeddedContext,
flags ) )
4006 mEmbeddedLayers.remove( layerId );
4010 mapLayerElem = mapLayerElem.nextSiblingElement( QStringLiteral(
"maplayer" ) );
4020 QString qgsProjectFile = projectFilePath;
4022 if ( projectFilePath.endsWith( QLatin1String(
".qgz" ), Qt::CaseInsensitive ) )
4024 archive.
unzip( projectFilePath );
4029 QFile projectFile( qgsProjectFile );
4030 if ( !projectFile.open( QIODevice::ReadOnly ) )
4035 QDomDocument projectDocument;
4036 if ( !projectDocument.setContent( &projectFile ) )
4048 QDomElement layerTreeElem = projectDocument.documentElement().firstChildElement( QStringLiteral(
"layer-tree-group" ) );
4049 if ( !layerTreeElem.isNull() )
4059 if ( !group || group->
customProperty( QStringLiteral(
"embedded" ) ).toBool() )
4072 newGroup->
setCustomProperty( QStringLiteral(
"embedded_project" ), projectFilePath );
4075 mLayerTreeRegistryBridge->
setEnabled(
false );
4076 initializeEmbeddedSubtree( projectFilePath, newGroup,
flags );
4077 mLayerTreeRegistryBridge->
setEnabled(
true );
4080 const auto constFindLayerIds = newGroup->
findLayerIds();
4081 for (
const QString &layerId : constFindLayerIds )
4098 const auto constChildren = group->
children();
4102 child->setCustomProperty( QStringLiteral(
"embedded" ), 1 );
4111 QList<QDomNode> brokenNodes;
4135 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/TopologicalEditing" ), ( enabled ? 1 : 0 ) );
4143 return readNumEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/TopologicalEditing" ), 0 );
4150 if ( mDistanceUnits == unit )
4153 mDistanceUnits = unit;
4162 if ( mAreaUnits == unit )
4175 if ( !mCachedHomePath.isEmpty() )
4176 return mCachedHomePath;
4180 if ( !mHomePath.isEmpty() )
4182 const QFileInfo homeInfo( mHomePath );
4183 if ( !homeInfo.isRelative() )
4185 mCachedHomePath = mHomePath;
4195 const QString storagePath { storage->filePath(
fileName() ) };
4196 if ( ! storagePath.isEmpty() && QFileInfo::exists( storagePath ) )
4198 mCachedHomePath = QFileInfo( storagePath ).path();
4199 return mCachedHomePath;
4203 mCachedHomePath = pfi.path();
4204 return mCachedHomePath;
4207 if ( !pfi.exists() )
4209 mCachedHomePath = mHomePath;
4213 if ( !mHomePath.isEmpty() )
4216 mCachedHomePath = QDir::cleanPath( pfi.path() +
'/' + mHomePath );
4220 mCachedHomePath = pfi.canonicalPath();
4222 return mCachedHomePath;
4237 return mRelationManager;
4244 return mLayoutManager.get();
4251 return mLayoutManager.get();
4258 return m3DViewsManager.get();
4265 return m3DViewsManager.get();
4272 return mBookmarkManager;
4279 return mBookmarkManager;
4286 return mSensorManager;
4293 return mSensorManager;
4300 return mViewSettings;
4307 return mViewSettings;
4314 return mStyleSettings;
4322 return mStyleSettings;
4329 return mTimeSettings;
4336 return mTimeSettings;
4343 return mElevationProperties;
4350 return mElevationProperties;
4357 return mDisplaySettings;
4364 return mDisplaySettings;
4371 return mGpsSettings;
4378 return mGpsSettings;
4392 return mMapThemeCollection.get();
4399 return mAnnotationManager.get();
4406 return mAnnotationManager.get();
4413 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
4414 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
4419 if (
layers.contains( it.value() ) )
4420 it.value()->setFlags( it.value()->flags() &
~QgsMapLayer::Identifiable );
4436 for (
const QString &layerId : layerIds )
4454 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
4488 updateTransactionGroups();
4495 return mTransactionMode;
4506 const auto constLayers =
mapLayers().values();
4509 if ( layer->isEditable() )
4511 QgsLogger::warning( tr(
"Transaction mode can be changed only if all layers are not editable." ) );
4517 updateTransactionGroups();
4526 return mTransactionGroups;
4539 return mLayerStore->count();
4546 return mLayerStore->validCount();
4554 return mLayerStore->mapLayer( layerId );
4561 return mLayerStore->mapLayersByName( layerName );
4568 QList<QgsMapLayer *>
layers;
4569 const auto constMapLayers { mLayerStore->mapLayers() };
4570 for (
const auto &l : constMapLayers )
4572 if ( ! l->serverProperties()->shortName().isEmpty() )
4574 if ( l->serverProperties()->shortName() == shortName )
4577 else if ( l->name() == shortName )
4593 if ( !archive->unzip( filename ) )
4595 setError( tr(
"Unable to unzip file '%1'" ).arg( filename ) );
4600 if ( archive->projectFile().isEmpty() )
4602 setError( tr(
"Zip archive does not provide a project file" ) );
4607 releaseHandlesToProjectArchive();
4608 mArchive = std::move( archive );
4625 setError( tr(
"Cannot read unzipped qgs project file" ) + QStringLiteral(
": " ) +
error() );
4635bool QgsProject::zip(
const QString &filename )
4643 const QString
baseName = QFileInfo( filename ).baseName();
4644 const QString qgsFileName = QStringLiteral(
"%1.qgs" ).arg(
baseName );
4645 QFile qgsFile( QDir( archive->dir() ).filePath( qgsFileName ) );
4647 bool writeOk =
false;
4648 if ( qgsFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
4650 writeOk = writeProjectFile( qgsFile.fileName() );
4657 setError( tr(
"Unable to write temporary qgs file" ) );
4662 const QFileInfo info( qgsFile );
4664 const QString asFileName = info.path() + QDir::separator() + info.completeBaseName() + asExt;
4666 bool auxiliaryStorageSavedOk =
true;
4667 if ( ! saveAuxiliaryStorage( asFileName ) )
4669 const QString err = mAuxiliaryStorage->errorString();
4670 setError( tr(
"Unable to save auxiliary storage file ('%1'). The project has been saved but the latest changes to auxiliary data cannot be recovered. It is recommended to reload the project." ).arg( err ) );
4671 auxiliaryStorageSavedOk =
false;
4674 if ( !mArchive->exists() )
4676 releaseHandlesToProjectArchive();
4678 mArchive->unzip( mFile.fileName() );
4681 const QString auxiliaryStorageFile =
static_cast<QgsProjectArchive *
>( mArchive.get() )->auxiliaryStorageFile();
4682 if ( ! auxiliaryStorageFile.isEmpty() )
4684 archive->
addFile( auxiliaryStorageFile );
4693 if ( QFile::exists( asFileName ) )
4695 archive->addFile( asFileName );
4700 archive->addFile( qgsFile.fileName() );
4703 const QStringList &
files = mArchive->files();
4704 for (
const QString &file :
files )
4706 if ( !file.endsWith( QLatin1String(
".qgs" ), Qt::CaseInsensitive ) && !file.endsWith( asExt, Qt::CaseInsensitive ) )
4708 archive->addFile( file );
4714 if ( !archive->zip( filename ) )
4716 setError( tr(
"Unable to perform zip" ) );
4720 return auxiliaryStorageSavedOk && zipOk;
4731 const QList<QgsMapLayer *> &layers,
4733 bool takeOwnership )
4737 const QList<QgsMapLayer *> myResultList { mLayerStore->addMapLayers(
layers, takeOwnership ) };
4738 if ( !myResultList.isEmpty() )
4741 for (
auto &l : myResultList )
4751 if ( mAuxiliaryStorage )
4766 mProjectScope.reset();
4768 return myResultList;
4774 bool takeOwnership )
4778 QList<QgsMapLayer *> addedLayers;
4779 addedLayers =
addMapLayers( QList<QgsMapLayer *>() << layer, addToLegend, takeOwnership );
4780 return addedLayers.isEmpty() ? nullptr : addedLayers[0];
4783void QgsProject::removeAuxiliaryLayer(
const QgsMapLayer *ml )
4790 const QgsVectorLayer *vl = qobject_cast<const QgsVectorLayer *>( ml );
4802 for (
const auto &layerId : layerIds )
4803 removeAuxiliaryLayer( mLayerStore->mapLayer( layerId ) );
4805 mProjectScope.reset();
4806 mLayerStore->removeMapLayers( layerIds );
4813 for (
const auto &layer :
layers )
4814 removeAuxiliaryLayer( layer );
4816 mProjectScope.reset();
4817 mLayerStore->removeMapLayers(
layers );
4824 removeAuxiliaryLayer( mLayerStore->mapLayer( layerId ) );
4825 mProjectScope.reset();
4826 mLayerStore->removeMapLayer( layerId );
4833 removeAuxiliaryLayer( layer );
4834 mProjectScope.reset();
4835 mLayerStore->removeMapLayer( layer );
4842 mProjectScope.reset();
4843 return mLayerStore->takeMapLayer( layer );
4850 return mMainAnnotationLayer;
4857 if ( mLayerStore->count() == 0 )
4860 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
4861 mProjectScope.reset();
4862 mLayerStore->removeAllMapLayers();
4864 snapSingleBlocker.release();
4866 if ( !mBlockSnappingUpdates )
4874 const QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
4875 QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin();
4876 for ( ; it !=
layers.constEnd(); ++it )
4878 it.value()->reload();
4887 return validOnly ? mLayerStore->validMapLayers() : mLayerStore->mapLayers();
4894 return mTransactionGroups.value( qMakePair( providerKey, connString ) );
4901 return &mEditBufferGroup;
4912 if ( mSettings.
value( QStringLiteral(
"/projections/unknownCrsBehavior" ), QStringLiteral(
"NoAction" ),
QgsSettings::App ).toString() == QStringLiteral(
"UseProjectCrs" )
4913 || mSettings.
value( QStringLiteral(
"/projections/unknownCrsBehavior" ), 0,
QgsSettings::App ).toString() == QLatin1String(
"2" ) )
4921 const QString layerDefaultCrs = mSettings.
value( QStringLiteral(
"/Projections/layerDefaultCrs" ),
geoEpsgCrsAuthId() ).toString();
4942bool QgsProject::saveAuxiliaryStorage(
const QString &filename )
4948 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
4953 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() );
4961 if ( !mAuxiliaryStorage->exists( *
this ) && empty )
4965 else if ( !filename.isEmpty() )
4967 return mAuxiliaryStorage->saveAs( filename );
4971 return mAuxiliaryStorage->saveAs( *
this );
4984 return sPropertyDefinitions;
4997 return mAuxiliaryStorage.get();
5004 return mAuxiliaryStorage.get();
5011 const QDir archiveDir( mArchive->dir() );
5012 QTemporaryFile tmpFile( archiveDir.filePath(
"XXXXXX_" + nameTemplate ),
this );
5013 tmpFile.setAutoRemove(
false );
5015 mArchive->addFile( tmpFile.fileName() );
5016 return tmpFile.fileName();
5023 QStringList attachments;
5025 const QStringList files = mArchive->files();
5026 attachments.reserve( files.size() );
5027 for (
const QString &file : files )
5029 if ( QFileInfo( file ).baseName() !=
baseName )
5031 attachments.append( file );
5041 return mArchive->removeFile( path );
5048 return QStringLiteral(
"attachment:///%1" ).arg( QFileInfo( attachedFile ).
fileName() );
5055 if ( identifier.startsWith( QLatin1String(
"attachment:///" ) ) )
5057 return QDir( mArchive->dir() ).absoluteFilePath( identifier.mid( 14 ) );
5078 mProjectScope.reset();
5092 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5106 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
5107 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
5112 if (
layers.contains( it.value() ) )
5113 it.value()->setFlags( it.value()->flags() &
~QgsMapLayer::Removable );
5124 QStringList customColors;
5125 QStringList customColorLabels;
5127 QgsNamedColorList::const_iterator colorIt = colors.constBegin();
5128 for ( ; colorIt != colors.constEnd(); ++colorIt )
5131 const QString label = ( *colorIt ).second;
5132 customColors.append( color );
5133 customColorLabels.append( label );
5135 writeEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Colors" ), customColors );
5136 writeEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Labels" ), customColorLabels );
5137 mProjectScope.reset();
5145 if ( mBackgroundColor == color )
5148 mBackgroundColor = color;
5156 return mBackgroundColor;
5163 if ( mSelectionColor == color )
5166 mSelectionColor = color;
5174 return mSelectionColor;
5211 translationContext.setFileName( QStringLiteral(
"%1/%2.ts" ).arg(
absolutePath(),
baseName() ) );
5215 translationContext.writeTsFile( locale );
5218QString
QgsProject::translate(
const QString &context,
const QString &sourceText,
const char *disambiguation,
int n )
const
5227 QString result = mTranslator->translate( context.toUtf8(), sourceText.toUtf8(), disambiguation, n );
5229 if ( result.isEmpty() )
5243 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5248 if ( !( ( *it )->accept( visitor ) ) )
5257 if ( !mLayoutManager->accept( visitor ) )
5260 if ( !mAnnotationManager->accept( visitor ) )
5268 return mElevationShadingRenderer;
5271void QgsProject::loadProjectFlags(
const QDomDocument *doc )
5275 QDomElement element = doc->documentElement().firstChildElement( QStringLiteral(
"projectFlags" ) );
5277 if ( !element.isNull() )
5284 element = doc->documentElement().firstChildElement( QStringLiteral(
"evaluateDefaultValues" ) );
5285 if ( !element.isNull() )
5287 if ( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
5292 element = doc->documentElement().firstChildElement( QStringLiteral(
"trust" ) );
5293 if ( !element.isNull() )
5295 if ( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
5311 const QString projectFunctions =
readEntry( QStringLiteral(
"ExpressionFunctions" ), QStringLiteral(
"/pythonCode" ), QString() );
5312 if ( !projectFunctions.isEmpty() )
5332QHash< QString, QColor > loadColorsFromProject(
const QgsProject *project )
5334 QHash< QString, QColor > colors;
5337 QStringList colorStrings = project->
readListEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Colors" ) );
5338 const QStringList colorLabels = project->
readListEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Labels" ) );
5342 for ( QStringList::iterator it = colorStrings.begin();
5343 it != colorStrings.end(); ++it )
5347 if ( colorLabels.length() > colorIndex )
5349 label = colorLabels.at( colorIndex );
5352 colors.insert( label.toLower(), color );
5360GetNamedProjectColor::GetNamedProjectColor(
const QgsProject *project )
5366 mColors = loadColorsFromProject( project );
5369GetNamedProjectColor::GetNamedProjectColor(
const QHash<QString, QColor> &colors )
5377 const QString colorName = values.at( 0 ).toString().toLower();
5378 if ( mColors.contains( colorName ) )
5380 return QStringLiteral(
"%1,%2,%3" ).arg( mColors.value( colorName ).red() ).arg( mColors.value( colorName ).green() ).arg( mColors.value( colorName ).blue() );
5388 return new GetNamedProjectColor( mColors );
5391GetNamedProjectColorObject::GetNamedProjectColorObject(
const QgsProject *project )
5397 mColors = loadColorsFromProject( project );
5400GetNamedProjectColorObject::GetNamedProjectColorObject(
const QHash<QString, QColor> &colors )
5408 const QString colorName = values.at( 0 ).toString().toLower();
5409 if ( mColors.contains( colorName ) )
5411 return mColors.value( colorName );
5419 return new GetNamedProjectColorObject( mColors );
5424GetSensorData::GetSensorData(
const QMap<QString, QgsAbstractSensor::SensorData> &sensorData )
5427 QStringLiteral(
"Sensors" ) )
5428 , mSensorData( sensorData )
5434 const QString sensorName = values.at( 0 ).toString();
5435 const int expiration = values.at( 1 ).toInt();
5436 const qint64 timestamp = QDateTime::currentMSecsSinceEpoch();
5437 if ( mSensorData.contains( sensorName ) )
5439 if ( expiration <= 0 || ( timestamp - mSensorData[sensorName].lastTimestamp.toMSecsSinceEpoch() ) < expiration )
5441 return mSensorData[sensorName].lastValue;
5450 return new GetSensorData( mSensorData );
@ DontLoad3DViews
Skip loading 3D views.
@ DontStoreOriginalStyles
Skip the initial XML style storage for layers. Useful for minimising project load times in non-intera...
@ ForceReadOnlyLayers
Open layers in a read-only mode.
@ TrustLayerMetadata
Trust layer metadata. Improves project read time. Do not use it if layers' extent is not fixed during...
@ DontUpgradeAnnotations
Don't upgrade old annotation items to QgsAnnotationItem.
@ DontLoadLayouts
Don't load print layouts. Improves project read time if layouts are not required, and allows projects...
@ DontResolveLayers
Don't resolve layer paths (i.e. don't load any layer content). Dramatically improves project read tim...
static QString version()
Version string.
QFlags< ProjectCapability > ProjectCapabilities
Flags which control project capabilities.
QFlags< ProjectReadFlag > ProjectReadFlags
Project load flags.
DistanceUnit
Units of distance.
FilePathType
File path types.
TransactionMode
Transaction mode.
@ AutomaticGroups
Automatic transactional editing means that on supported datasources (postgres and geopackage database...
@ BufferedGroups
Buffered transactional editing means that all editable layers in the buffered transaction group are t...
@ Disabled
Edits are buffered locally and sent to the provider when toggling layer editing mode.
@ SquareMeters
Square meters.
@ Critical
Critical/error message.
@ Success
Used for reporting a successful operation.
PythonEmbeddedMode
Authorisation to run Python Embedded in projects.
@ Always
Python embedded is always run.
@ Ask
User is prompt before running.
@ SessionOnly
Only during this session.
@ Compound
Compound (horizontal + vertical) CRS.
@ Projected
Projected CRS.
@ DerivedProjected
Derived projected CRS.
@ Engineering
Engineering CRS.
@ Geographic3d
3D geopraphic CRS
@ Geographic2d
2D geographic CRS
@ Geocentric
Geocentric CRS.
AvoidIntersectionsMode
Flags which control how intersections of pre-existing feature are handled when digitizing new feature...
@ AvoidIntersectionsLayers
Overlap with features from a specified list of layers when digitizing new features not allowed.
@ AllowIntersections
Overlap with any feature allowed when digitizing new features.
ProjectFlag
Flags which control the behavior of QgsProjects.
@ RememberLayerEditStatusBetweenSessions
If set, then any layers set to be editable will be stored in the project and immediately made editabl...
@ EvaluateDefaultValuesOnProviderSide
If set, default values for fields will be evaluated on the provider side when features from the proje...
@ TrustStoredLayerStatistics
If set, then layer statistics (such as the layer extent) will be read from values stored in the proje...
QFlags< DataProviderReadFlag > DataProviderReadFlags
Flags which control data provider construction.
LayerType
Types of layers that can be added to a map.
@ Group
Composite group layer. Added in QGIS 3.24.
@ Plugin
Plugin based layer.
@ TiledScene
Tiled scene layer. Added in QGIS 3.34.
@ Annotation
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
@ VectorTile
Vector tile layer. Added in QGIS 3.14.
@ Mesh
Mesh layer. Added in QGIS 3.2.
@ PointCloud
Point cloud layer. Added in QGIS 3.18.
@ SkipCredentialsRequest
Skip credentials if the provided one are not valid, let the provider be invalid, avoiding to block th...
@ ParallelThreadLoading
Provider is created in a parallel thread than the one where it will live.
QFlags< ProjectFlag > ProjectFlags
@ Preferred
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
virtual bool readXml(const QDomElement &collectionElem, const QgsPropertiesDefinition &definitions)
Reads property collection state from an XML element.
virtual bool writeXml(QDomElement &collectionElem, const QgsPropertiesDefinition &definitions) const
Writes the current state of the property collection into an XML element.
Represents a map layer containing a set of georeferenced annotations, e.g.
void resolveReferences(QgsProject *project) override
Resolve references to other layers (kept as layer IDs after reading XML) into layer objects.
void setTransformContext(const QgsCoordinateTransformContext &context) override
Sets the coordinate transform context to transformContext.
void reset()
Resets the annotation layer to a default state, and clears all items from it.
bool isEmpty() const
Returns true if the annotation layer is empty and contains no annotations.
Manages storage of a set of QgsAnnotation annotation objects.
static QgsApplication * instance()
Returns the singleton instance of the QgsApplication.
static QgsProjectStorageRegistry * projectStorageRegistry()
Returns registry of available project storage implementations.
static const QgsSettingsEntryString * settingsLocaleUserLocale
Settings entry locale user locale.
static QgsRuntimeProfiler * profiler()
Returns the application runtime profiler.
void collectTranslatableObjects(QgsTranslationContext *translationContext)
Emits the signal to collect all the strings of .qgs to be included in ts file.
static QgsPluginLayerRegistry * pluginLayerRegistry()
Returns the application's plugin layer registry, used for managing plugin layer types.
void requestForTranslatableObjects(QgsTranslationContext *translationContext)
Emitted when project strings which require translation are being collected for inclusion in a ....
static QString userFullName()
Returns the user's operating system login account full display name.
static QString userLoginName()
Returns the user's operating system login account name.
Class allowing to manage the zip/unzip actions.
void addFile(const QString &filename)
Add a new file to this archive.
This is a container for attribute editors, used to group them visually in the attribute form if it is...
QList< QgsAttributeEditorElement * > children() const
Gets a list of the children elements of this container.
This is an abstract base class for any elements of a drag and drop form.
QString name() const
Returns the name of this element.
QgsFields auxiliaryFields() const
Returns a list of all auxiliary fields currently managed by the layer.
bool save()
Commits changes and starts editing then.
Class providing some utility methods to manage auxiliary storage.
static QString extension()
Returns the extension used for auxiliary databases.
static bool deleteTable(const QgsDataSourceUri &uri)
Removes a table from the auxiliary storage.
Manages storage of a set of bookmarks.
bool readXml(const QDomElement &element, const QDomDocument &doc)
Reads the manager's state from a DOM element, restoring all bookmarks present in the XML document.
void clear()
Removes and deletes all bookmarks from the manager.
QDomElement writeXml(QDomDocument &doc) const
Returns a DOM element representing the state of the manager.
static QColor colorFromString(const QString &string)
Decodes a string into a color value.
static QString colorToString(const QColor &color)
Encodes a color into a string value.
This class represents a coordinate reference system (CRS).
static QgsCoordinateReferenceSystem fromOgcWmsCrs(const QString &ogcCrs)
Creates a CRS from a given OGC WMS-format Coordinate Reference System string.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
bool hasVerticalAxis() const
Returns true if the CRS has a vertical axis.
QString toProj() const
Returns a Proj string representation of this CRS.
bool readXml(const QDomNode &node)
Restores state from the given DOM node.
static QgsCoordinateReferenceSystem createCompoundCrs(const QgsCoordinateReferenceSystem &horizontalCrs, const QgsCoordinateReferenceSystem &verticalCrs, QString &error)
Given a horizontal and vertical CRS, attempts to create a compound CRS from them.
QString ellipsoidAcronym() const
Returns the ellipsoid acronym for the ellipsoid used by the CRS.
QString projectionAcronym() const
Returns the projection acronym for the projection used by the CRS.
QgsCoordinateReferenceSystem verticalCrs() const
Returns the vertical CRS associated with this CRS object.
static QgsCoordinateReferenceSystem fromProj(const QString &proj)
Creates a CRS from a proj style formatted string.
QString toWkt(Qgis::CrsWktVariant variant=Qgis::CrsWktVariant::Wkt1Gdal, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
bool writeXml(QDomNode &node, QDomDocument &doc) const
Stores state to the given Dom node in the given document.
static QgsCoordinateReferenceSystem fromSrsId(long srsId)
Creates a CRS from a specified QGIS SRS ID.
Qgis::CrsType type() const
Returns the type of the CRS.
Qgis::DistanceUnit mapUnits
Contains information about the context in which a coordinate transform is executed.
void readSettings()
Reads the context's state from application settings.
void writeXml(QDomElement &element, const QgsReadWriteContext &context) const
Writes the context's state to a DOM element.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context, QStringList &missingTransforms)
Reads the context's state from a DOM element.
Abstract base class for spatial data provider implementations.
@ EvaluateDefaultValues
Evaluate default values on provider side when calling QgsVectorDataProvider::defaultValue( int index ...
Class for storing the component parts of a RDBMS data source URI (e.g.
This class can render elevation shading on an image with different methods (eye dome lighting,...
void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const
Writes configuration on a DOM element.
void readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads configuration from a DOM element.
Single scope for storing variables and functions for use within a QgsExpressionContext.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
A abstract base class for defining QgsExpression functions.
An expression node for expression functions.
Class for parsing and evaluation of expressions (formerly called "search strings").
Encapsulate a field in an attribute table or data source.
Container of fields for a vector layer.
Stores global configuration for labeling engine.
Class used to work with layer dependencies stored in a XML project or layer definition file.
Layer tree group node serves as a container for layers and further groups.
void resolveReferences(const QgsProject *project, bool looseMatching=false) override
Calls resolveReferences() on child tree nodes.
QgsLayerTreeGroup * findGroup(const QString &name)
Find group node with specified name.
QList< QgsLayerTreeGroup * > findGroups(bool recursive=false) const
Find group layer nodes.
QString name() const override
Returns the group's name.
QStringList findLayerIds() const
Find layer IDs used in all layer nodes.
void insertChildNodes(int index, const QList< QgsLayerTreeNode * > &nodes)
Insert existing nodes at specified position.
void readChildrenFromXml(QDomElement &element, const QgsReadWriteContext &context)
Read children from XML and append them to the group.
QgsLayerTreeGroup * clone() const override
Returns a clone of the group.
QList< QgsLayerTreeLayer * > findLayers() const
Find all layer nodes.
QgsLayerTreeLayer * findLayer(QgsMapLayer *layer) const
Find layer node representing the map layer.
Layer tree node points to a map layer.
void resolveReferences(const QgsProject *project, bool looseMatching=false) override
Resolves reference to layer from stored layer ID (if it has not been resolved already)
This class is a base class for nodes in a layer tree.
QList< QgsLayerTreeNode * > abandonChildren()
Removes the children, disconnect all the forwarded and external signals and sets their parent to null...
void setCustomProperty(const QString &key, const QVariant &value)
Sets a custom property for the node. Properties are stored in a map and saved in project file.
virtual void writeXml(QDomElement &parentElement, const QgsReadWriteContext &context)=0
Write layer tree to XML.
QList< QgsLayerTreeNode * > children()
Gets list of children of the node. Children are owned by the parent.
void removeCustomProperty(const QString &key)
Remove a custom property from layer. Properties are stored in a map and saved in project file.
QVariant customProperty(const QString &key, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer. Properties are stored in a map and saved in project file.
void setItemVisibilityChecked(bool checked)
Check or uncheck a node (independently of its ancestors or children)
Listens to the updates in map layer registry and does changes in layer tree.
void setEnabled(bool enabled)
static void replaceChildrenOfEmbeddedGroups(QgsLayerTreeGroup *group)
Remove subtree of embedded groups and replaces it with a custom property embedded-visible-layers.
static void storeOriginalLayersProperties(QgsLayerTreeGroup *group, const QDomDocument *doc)
Stores in a layer's originalXmlProperties the layer properties information.
static void updateEmbeddedGroupsProjectPath(QgsLayerTreeGroup *group, const QgsProject *project)
Updates an embedded group from a project.
static bool readOldLegend(QgsLayerTreeGroup *root, const QDomElement &legendElem)
Try to load layer tree from.
Namespace with helper functions for layer tree operations.
void readLayerOrderFromXml(const QDomElement &doc)
Load the layer order from an XML element.
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
void clear()
Clear any information from this layer tree.
static bool isLayer(const QgsLayerTreeNode *node)
Check whether the node is a valid layer node.
static bool isGroup(QgsLayerTreeNode *node)
Check whether the node is a valid group node.
static QgsLayerTreeGroup * toGroup(QgsLayerTreeNode *node)
Cast node to a group.
QList< QgsMapLayer * > customLayerOrder() const
The order in which layers will be rendered on the canvas.
QgsLayerTree * clone() const override
Create a copy of the node. Returns new instance.
Manages storage of a set of layouts.
static void warning(const QString &msg)
Goes to qWarning.
static Qgis::LayerType typeFromString(const QString &string, bool &ok)
Returns the map layer type corresponding a string value.
A storage object for map layers, in which the layers are owned by the store and have their lifetime b...
void layersWillBeRemoved(const QStringList &layerIds)
Emitted when one or more layers are about to be removed from the store.
void layerWillBeRemoved(const QString &layerId)
Emitted when a layer is about to be removed from the store.
void layersRemoved(const QStringList &layerIds)
Emitted after one or more layers were removed from the store.
void allLayersRemoved()
Emitted when all layers are removed, before layersWillBeRemoved() and layerWillBeRemoved() signals ar...
void layerRemoved(const QString &layerId)
Emitted after a layer was removed from the store.
void layerWasAdded(QgsMapLayer *layer)
Emitted when a layer was added to the store.
QgsMapLayer * mapLayer(const QString &id) const
Retrieve a pointer to a layer by layer id.
void layersAdded(const QList< QgsMapLayer * > &layers)
Emitted when one or more layers were added to the store.
Base class for all map layer types.
QFlags< ReadFlag > ReadFlags
QString source() const
Returns the source for the layer.
QString providerType() const
Returns the provider type (provider key) for this layer.
void removeCustomProperty(const QString &key)
Remove a custom property from layer.
void configChanged()
Emitted whenever the configuration is changed.
static Qgis::DataProviderReadFlags providerReadFlags(const QDomNode &layerNode, QgsMapLayer::ReadFlags layerReadFlags)
Returns provider read flag deduced from layer read flags layerReadFlags and a dom node layerNode that...
QgsCoordinateReferenceSystem crs
QString originalXmlProperties() const
Returns the XML properties of the original layer as they were when the layer was first read from the ...
Q_INVOKABLE void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
virtual bool isEditable() const
Returns true if the layer can be edited.
bool writeLayerXml(QDomElement &layerElement, QDomDocument &document, const QgsReadWriteContext &context) const
Stores state in DOM node.
@ Identifiable
If the layer is identifiable using the identify map tool and as a WMS layer.
@ Removable
If the layer can be removed from the project. The layer will not be removable from the legend menu en...
@ FlagReadExtentFromXml
Read extent from xml and skip get extent from provider.
@ FlagTrustLayerMetadata
Trust layer metadata. Improves layer load time by skipping expensive checks like primary key unicity,...
@ FlagForceReadOnly
Force open as read only.
@ FlagDontResolveLayers
Don't resolve layer paths or create data providers for layers.
bool readLayerXml(const QDomElement &layerElement, QgsReadWriteContext &context, QgsMapLayer::ReadFlags flags=QgsMapLayer::ReadFlags(), QgsDataProvider *preloadedProvider=nullptr)
Sets state from DOM document.
void setCrs(const QgsCoordinateReferenceSystem &srs, bool emitSignal=true)
Sets layer's spatial reference system.
Container class that allows storage of map themes consisting of visible map layers and layer styles.
Manages storage of a set of views.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Resolves relative paths into absolute paths and vice versa.
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
Class allowing to manage the zip/unzip actions on project file.
QString projectFile() const
Returns the current .qgs project file or an empty string if there's none.
QString auxiliaryStorageFile() const
Returns the current .qgd auxiliary storage file or an empty string if there's none.
bool unzip(const QString &zipFilename) override
Clear the current content of this archive and unzip.
Interface for classes that handle missing layer files when reading project file.
virtual void handleBadLayers(const QList< QDomNode > &layers)
This method will be called whenever the project tries to load layers which cannot be accessed.
Contains settings and properties relating to how a QgsProject should display values such as map coord...
void reset()
Resets the settings to a default state.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads the settings's state from a DOM element.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Returns a DOM element representing the settings.
Contains elevation properties for a QgsProject.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads the property state from a DOM element.
void reset()
Resets the properties to a default state.
QDomElement writeXml(QDomDocument &document, const QgsReadWriteContext &context) const
Returns a DOM element representing the properties.
void resolveReferences(const QgsProject *project)
Resolves reference to layers from stored layer ID.
Contains settings and properties relating to how a QgsProject should interact with a GPS device.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads the settings's state from a DOM element.
void reset()
Resets the settings to a default state.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Returns a DOM element representing the settings.
void resolveReferences(const QgsProject *project)
Resolves reference to layers from stored layer ID (if it has not been resolved already)
Project property key node.
QString name() const
The name of the property is used as identifier.
QgsProjectProperty * find(const QString &propertyName) const
Attempts to find a property with a matching sub-key name.
void removeKey(const QString &keyName)
Removes the specified key.
void dump(int tabs=0) const override
Dumps out the keys and values.
bool isEmpty() const
Returns true if this property contains no sub-keys.
virtual void clearKeys()
Deletes any sub-nodes from the property.
bool writeXml(const QString &nodeName, QDomElement &element, QDomDocument &document) override
Writes the property hierarchy to a specified DOM element.
void subkeyList(QStringList &entries) const
Returns any sub-keys contained by this property which themselves contain other keys.
void setName(const QString &name)
The name of the property is used as identifier.
QgsProjectPropertyKey * addKey(const QString &keyName)
Adds the specified property key as a sub-key.
QVariant value() const override
If this key has a value, it will be stored by its name in its properties.
QgsProjectPropertyValue * setValue(const QString &name, const QVariant &value)
Sets the value associated with this key.
void entryList(QStringList &entries) const
Returns any sub-keys contained by this property that do not contain other keys.
int count() const
Returns the number of sub-keys contained by this property.
bool readXml(const QDomNode &keyNode) override
Restores the property hierarchy from a specified DOM node.
An Abstract Base Class for QGIS project property hierarchys.
virtual bool isKey() const =0
Returns true if the property is a QgsProjectPropertyKey.
virtual bool isValue() const =0
Returns true if the property is a QgsProjectPropertyValue.
QgsProjectStorage * projectStorageFromUri(const QString &uri)
Returns storage implementation if the URI matches one. Returns nullptr otherwise (it is a normal file...
Abstract interface for project storage - to be implemented by various backends and registered in QgsP...
Contains settings and properties relating to how a QgsProject should handle styling.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Returns a DOM element representing the settings.
void setDefaultSymbol(Qgis::SymbolType symbolType, QgsSymbol *symbol)
Sets the project default symbol for a given type.
void reset()
Resets the settings to a default state.
void removeProjectStyle()
Removes and deletes the project style database.
void setRandomizeDefaultSymbolColor(bool randomized)
Sets whether the default symbol fill color is randomized.
void setDefaultColorRamp(QgsColorRamp *colorRamp)
Sets the project default color ramp.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context, Qgis::ProjectReadFlags flags=Qgis::ProjectReadFlags())
Reads the settings's state from a DOM element.
void setDefaultSymbolOpacity(double opacity)
Sets the default symbol opacity.
Contains temporal settings and properties for the project, this may be used when animating maps or sh...
bool readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads the settings's state from a DOM element.
void reset()
Resets the settings to a default state.
QDomElement writeXml(QDomDocument &document, const QgsReadWriteContext &context) const
Returns a DOM element representing the settings.
A class to describe the version of a project.
QString text() const
Returns a string representation of the version.
int majorVersion() const
Returns the major version number.
Contains settings and properties relating to how a QgsProject should be displayed inside map canvas,...
bool useProjectScales() const
Returns true if project mapScales() are enabled.
void reset()
Resets the settings to a default state.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads the settings's state from a DOM element.
void setMapScales(const QVector< double > &scales)
Sets the list of custom project map scales.
void setUseProjectScales(bool enabled)
Sets whether project mapScales() are enabled.
QVector< double > mapScales() const
Returns the list of custom project map scales.
void mapScalesChanged()
Emitted when the list of custom project map scales changes.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Returns a DOM element representing the settings.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
bool isZipped() const
Returns true if the project comes from a zip archive, false otherwise.
bool removeAttachedFile(const QString &path)
Removes the attached file.
QgsRelationManager * relationManager
bool write()
Writes the project to its current associated file (see fileName() ).
QgsProject(QObject *parent=nullptr, Qgis::ProjectCapabilities capabilities=Qgis::ProjectCapability::ProjectStyles)
Create a new QgsProject.
void removeMapLayer(const QString &layerId)
Remove a layer from the registry by layer ID.
Q_DECL_DEPRECATED void oldProjectVersionWarning(const QString &warning)
Emitted when an old project file is read.
Q_DECL_DEPRECATED bool evaluateDefaultValues() const
Should default values be evaluated on provider side when requested and not when committed.
Qgis::DistanceUnit distanceUnits
void layersRemoved(const QStringList &layerIds)
Emitted after one or more layers were removed from the registry.
void clear()
Clears the project, removing all settings and resetting it back to an empty, default state.
QString error() const
Returns error message from previous read/write.
Q_DECL_DEPRECATED void setUseProjectScales(bool enabled)
Sets whether project mapScales() are enabled.
void readProjectWithContext(const QDomDocument &document, QgsReadWriteContext &context)
Emitted when a project is being read.
int readNumEntry(const QString &scope, const QString &key, int def=0, bool *ok=nullptr) const
Reads an integer from the specified scope and key.
Q_DECL_DEPRECATED void setNonIdentifiableLayers(const QList< QgsMapLayer * > &layers)
Set a list of layers which should not be taken into account on map identification.
QList< QgsMapLayer * > addMapLayers(const QList< QgsMapLayer * > &mapLayers, bool addToLegend=true, bool takeOwnership=true)
Add a list of layers to the map of loaded layers.
Qgis::ProjectFlags flags() const
Returns the project's flags, which dictate the behavior of the project.
Q_DECL_DEPRECATED QFileInfo fileInfo() const
Returns QFileInfo object for the project's associated file.
QString presetHomePath() const
Returns any manual project home path setting, or an empty string if not set.
void setBackgroundColor(const QColor &color)
Sets the default background color used by default map canvases.
void setCrs(const QgsCoordinateReferenceSystem &crs, bool adjustEllipsoid=false)
Sets the project's native coordinate reference system.
QString title() const
Returns the project's title.
bool commitChanges(QStringList &commitErrors, bool stopEditing=true, QgsVectorLayer *vectorLayer=nullptr)
Attempts to commit to the underlying data provider any buffered changes made since the last to call t...
void mapThemeCollectionChanged()
Emitted when the map theme collection changes.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Qgis::FilePathType filePathStorage() const
Returns the type of paths used when storing file paths in a QGS/QGZ project file.
QString createAttachedFile(const QString &nameTemplate)
Attaches a file to the project.
Q_DECL_DEPRECATED void mapScalesChanged()
Emitted when the list of custom project map scales changes.
void readVersionMismatchOccurred(const QString &fileVersion)
Emitted when a project is read and the version of QGIS used to save the project differs from the curr...
void fileNameChanged()
Emitted when the file name of the project changes.
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
void writeMapLayer(QgsMapLayer *mapLayer, QDomElement &layerElem, QDomDocument &doc)
Emitted when a layer is being saved.
const QgsSensorManager * sensorManager() const
Returns the project's sensor manager, which manages sensors within the project.
void setSnappingConfig(const QgsSnappingConfig &snappingConfig)
The snapping configuration for this project.
void areaUnitsChanged()
Emitted when the default area units changes.
QgsPropertyCollection dataDefinedServerProperties() const
Returns the data defined properties used for overrides in user defined server parameters.
Q_DECL_DEPRECATED void nonIdentifiableLayersChanged(QStringList nonIdentifiableLayers)
Emitted when the list of layer which are excluded from map identification changes.
void layersWillBeRemoved(const QStringList &layerIds)
Emitted when one or more layers are about to be removed from the registry.
QString attachmentIdentifier(const QString &attachedFile) const
Returns an identifier for an attachment file path An attachment identifier is a string which does not...
QgsVectorLayerEditBufferGroup * editBufferGroup()
Returns the edit buffer group.
void setSelectionColor(const QColor &color)
Sets the color used to highlight selected features.
bool rollBack(QStringList &rollbackErrors, bool stopEditing=true, QgsVectorLayer *vectorLayer=nullptr)
Stops a current editing operation on vectorLayer and discards any uncommitted edits.
void snappingConfigChanged(const QgsSnappingConfig &config)
Emitted whenever the configuration for snapping has changed.
QgsPathResolver pathResolver() const
Returns path resolver object with considering whether the project uses absolute or relative paths and...
void setBadLayerHandler(QgsProjectBadLayerHandler *handler)
Change handler for missing layers.
Q_DECL_DEPRECATED void setEvaluateDefaultValues(bool evaluateDefaultValues)
Defines if default values should be evaluated on provider side when requested and not when committed.
void crsChanged()
Emitted when the crs() of the project has changed.
QString translate(const QString &context, const QString &sourceText, const char *disambiguation=nullptr, int n=-1) const override
Translates a string using the Qt QTranslator mechanism.
const QgsProjectStyleSettings * styleSettings() const
Returns the project's style settings, which contains settings and properties relating to how a QgsPro...
QgsSnappingConfig snappingConfig
const QgsProjectGpsSettings * gpsSettings() const
Returns the project's GPS settings, which contains settings and properties relating to how a QgsProje...
void setFileName(const QString &name)
Sets the file name associated with the project.
void avoidIntersectionsLayersChanged()
Emitted whenever avoidIntersectionsLayers has changed.
void setDataDefinedServerProperties(const QgsPropertyCollection &properties)
Sets the data defined properties used for overrides in user defined server parameters to properties.
void registerTranslatableObjects(QgsTranslationContext *translationContext)
Registers the objects that require translation into the translationContext.
void distanceUnitsChanged()
Emitted when the default distance units changes.
QgsAnnotationLayer * mainAnnotationLayer()
Returns the main annotation layer associated with the project.
const QgsBookmarkManager * bookmarkManager() const
Returns the project's bookmark manager, which manages bookmarks within the project.
void readMapLayer(QgsMapLayer *mapLayer, const QDomElement &layerNode)
Emitted after the basic initialization of a layer from the project file is done.
Q_DECL_DEPRECATED void setAutoTransaction(bool autoTransaction)
Transactional editing means that on supported datasources (postgres databases) the edit state of all ...
@ WMSOnlineResource
Alias.
bool startEditing(QgsVectorLayer *vectorLayer=nullptr)
Makes the layer editable.
void aboutToBeCleared()
Emitted when the project is about to be cleared.
Q_DECL_DEPRECATED void setTrustLayerMetadata(bool trust)
Sets the trust option allowing to indicate if the extent has to be read from the XML document when da...
void cleared()
Emitted when the project is cleared (and additionally when an open project is cleared just before a n...
bool setVerticalCrs(const QgsCoordinateReferenceSystem &crs, QString *errorMessage=nullptr)
Sets the project's vertical coordinate reference system.
void setLabelingEngineSettings(const QgsLabelingEngineSettings &settings)
Sets project's global labeling engine settings.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
void metadataChanged()
Emitted when the project's metadata is changed.
QString resolveAttachmentIdentifier(const QString &identifier) const
Resolves an attachment identifier to a attachment file path.
const QgsProjectElevationProperties * elevationProperties() const
Returns the project's elevation properties, which contains the project's elevation related settings.
QString absolutePath() const
Returns full absolute path to the project folder if the project is stored in a file system - derived ...
void crs3DChanged()
Emitted when the crs3D() of the project has changed.
void removeMapLayers(const QStringList &layerIds)
Remove a set of layers from the registry by layer ID.
Q_DECL_DEPRECATED void setRequiredLayers(const QSet< QgsMapLayer * > &layers)
Configures a set of map layers that are required in the project and therefore they should not get rem...
bool createEmbeddedLayer(const QString &layerId, const QString &projectFilePath, QList< QDomNode > &brokenNodes, bool saveFlag=true, Qgis::ProjectReadFlags flags=Qgis::ProjectReadFlags())
Creates a maplayer instance defined in an arbitrary project file.
QList< QgsVectorLayer * > avoidIntersectionsLayers
QString readEntry(const QString &scope, const QString &key, const QString &def=QString(), bool *ok=nullptr) const
Reads a string from the specified scope and key.
QgsExpressionContextScope * createExpressionContextScope() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
QString baseName() const
Returns the base name of the project file without the path and without extension - derived from fileN...
void ellipsoidChanged(const QString &ellipsoid)
Emitted when the project ellipsoid is changed.
QgsMapThemeCollection * mapThemeCollection
void generateTsFile(const QString &locale)
Triggers the collection strings of .qgs to be included in ts file and calls writeTsFile()
QStringList entryList(const QString &scope, const QString &key) const
Returns a list of child keys with values which exist within the the specified scope and key.
Qgis::TransactionMode transactionMode
QgsAnnotationManager * annotationManager()
Returns pointer to the project's annotation manager.
QgsProjectDisplaySettings * displaySettings
QgsProjectMetadata metadata
void projectColorsChanged()
Emitted whenever the project's color scheme has been changed.
QString saveUser() const
Returns the user name that did the last save.
QVector< T > layers() const
Returns a list of registered map layers with a specified layer type.
void setProjectColors(const QgsNamedColorList &colors)
Sets the colors for the project's color scheme (see QgsProjectColorScheme).
bool setTransactionMode(Qgis::TransactionMode transactionMode)
Set transaction mode.
QgsCoordinateTransformContext transformContext
void transactionModeChanged()
Emitted when the transaction mode has changed.
void labelingEngineSettingsChanged()
Emitted when global configuration of the labeling engine changes.
void customVariablesChanged()
Emitted whenever the expression variables stored in the project have been changed.
QgsLayerTree * layerTreeRoot() const
Returns pointer to the root (invisible) node of the project's layer tree.
bool readBoolEntry(const QString &scope, const QString &key, bool def=false, bool *ok=nullptr) const
Reads a boolean from the specified scope and key.
QgsMapLayerStore * layerStore()
Returns a pointer to the project's internal layer store.
QString originalPath() const
Returns the original path associated with the project.
void setOriginalPath(const QString &path)
Sets the original path associated with the project.
void dumpProperties() const
Dump out current project properties to stderr.
QgsElevationShadingRenderer elevationShadingRenderer() const
Returns the elevation shading renderer used for map shading.
const QgsMapViewsManager * viewsManager() const
Returns the project's views manager, which manages map views (including 3d maps) in the project.
static void setInstance(QgsProject *project)
Set the current project singleton instance to project.
int validCount() const
Returns the number of registered valid layers.
const QgsLayoutManager * layoutManager() const
Returns the project's layout manager, which manages print layouts, atlases and reports within the pro...
void elevationShadingRendererChanged()
Emitted when the map shading renderer changes.
Q_INVOKABLE QList< QgsMapLayer * > mapLayersByName(const QString &layerName) const
Retrieve a list of matching registered layers by layer name.
QgsCoordinateReferenceSystem crs3D() const
Returns the CRS to use for the project when transforming 3D data, or when z/elevation value handling ...
Q_DECL_DEPRECATED bool autoTransaction() const
Transactional editing means that on supported datasources (postgres databases) the edit state of all ...
bool accept(QgsStyleEntityVisitorInterface *visitor) const
Accepts the specified style entity visitor, causing it to visit all style entities associated with th...
QStringList attachedFiles() const
Returns a map of all attached files with identifier and real paths.
void setMetadata(const QgsProjectMetadata &metadata)
Sets the project's metadata store.
void missingDatumTransforms(const QStringList &missingTransforms)
Emitted when datum transforms stored in the project are not available locally.
QgsTransactionGroup * transactionGroup(const QString &providerKey, const QString &connString)
Returns the matching transaction group from a provider key and connection string.
QgsCoordinateReferenceSystem crs
QgsMapLayer * addMapLayer(QgsMapLayer *mapLayer, bool addToLegend=true, bool takeOwnership=true)
Add a layer to the map of loaded layers.
QStringList nonIdentifiableLayers
void setAvoidIntersectionsMode(const Qgis::AvoidIntersectionsMode mode)
Sets the avoid intersections mode.
void transactionGroupsChanged()
Emitted whenever a new transaction group has been created or a transaction group has been removed.
const QgsAuxiliaryStorage * auxiliaryStorage() const
Returns the current const auxiliary storage.
void reloadAllLayers()
Reload all registered layer's provider data caches, synchronising the layer with any changes in the d...
int count() const
Returns the number of registered layers.
void loadingLayerMessageReceived(const QString &layerName, const QList< QgsReadWriteContext::ReadWriteMessage > &messages)
Emitted when loading layers has produced some messages.
void setAreaUnits(Qgis::AreaUnit unit)
Sets the default area measurement units for the project.
void setTitle(const QString &title)
Sets the project's title.
QMap< QPair< QString, QString >, QgsTransactionGroup * > transactionGroups()
Map of transaction groups.
void setFlag(Qgis::ProjectFlag flag, bool enabled=true)
Sets whether a project flag is enabled.
QDateTime lastModified() const
Returns last modified time of the project file as returned by the file system (or other project stora...
bool loadFunctionsFromProject(bool force=false)
Loads python expression functions stored in the currrent project.
bool readLayer(const QDomNode &layerNode)
Reads the layer described in the associated DOM node.
double readDoubleEntry(const QString &scope, const QString &key, double def=0, bool *ok=nullptr) const
Reads a double from the specified scope and key.
bool writeEntry(const QString &scope, const QString &key, bool value)
Write a boolean value to the project file.
QString absoluteFilePath() const
Returns full absolute path to the project file if the project is stored in a file system - derived fr...
QDateTime lastSaveDateTime() const
Returns the date and time when the project was last saved.
void projectSaved()
Emitted when the project file has been written and closed.
Q_DECL_DEPRECATED bool trustLayerMetadata() const
Returns true if the trust option is activated, false otherwise.
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
void setEllipsoid(const QString &ellipsoid)
Sets the project's ellipsoid from a proj string representation, e.g., "WGS84".
void readProject(const QDomDocument &document)
Emitted when a project is being read.
void setTransformContext(const QgsCoordinateTransformContext &context)
Sets the project's coordinate transform context, which stores various information regarding which dat...
void layerLoaded(int i, int n)
Emitted when a layer from a projects was read.
QStringList subkeyList(const QString &scope, const QString &key) const
Returns a list of child keys which contain other keys that exist within the the specified scope and k...
bool read(const QString &filename, Qgis::ProjectReadFlags flags=Qgis::ProjectReadFlags())
Reads given project file from the given file.
QStringList readListEntry(const QString &scope, const QString &key, const QStringList &def=QStringList(), bool *ok=nullptr) const
Reads a string list from the specified scope and key.
void selectionColorChanged()
Emitted whenever the project's selection color has been changed.
const QgsLabelingEngineSettings & labelingEngineSettings() const
Returns project's global labeling engine settings.
void removeAllMapLayers()
Removes all registered layers.
Q_DECL_DEPRECATED QVector< double > mapScales() const
Returns the list of custom project map scales.
void setDirty(bool b=true)
Flag the project as dirty (modified).
void backgroundColorChanged()
Emitted whenever the project's canvas background color has been changed.
QgsLayerTreeGroup * createEmbeddedGroup(const QString &groupName, const QString &projectFilePath, const QStringList &invisibleLayers, Qgis::ProjectReadFlags flags=Qgis::ProjectReadFlags())
Create layer group instance defined in an arbitrary project file.
const QgsProjectViewSettings * viewSettings() const
Returns the project's view settings, which contains settings and properties relating to how a QgsProj...
void cleanFunctionsFromProject()
Unloads python expression functions stored in the current project and reloads local functions from th...
QgsCoordinateReferenceSystem verticalCrs() const
Returns the project's vertical coordinate reference system.
QString readPath(const QString &filename) const
Transforms a filename read from the project file to an absolute path.
void registerTranslatableContainers(QgsTranslationContext *translationContext, QgsAttributeEditorContainer *parent, const QString &layerId)
Registers the containers that require translation into the translationContext.
void setElevationShadingRenderer(const QgsElevationShadingRenderer &elevationShadingRenderer)
Sets the elevation shading renderer used for global map shading.
void setFilePathStorage(Qgis::FilePathType type)
Sets the type of paths used when storing file paths in a QGS/QGZ project file.
Q_DECL_DEPRECATED QSet< QgsMapLayer * > requiredLayers() const
Returns a set of map layers that are required in the project and therefore they should not get remove...
void transformContextChanged()
Emitted when the project transformContext() is changed.
void setTopologicalEditing(bool enabled)
Convenience function to set topological editing.
void legendLayersAdded(const QList< QgsMapLayer * > &layers)
Emitted, when a layer was added to the registry and the legend.
QVariantMap customVariables() const
A map of custom project variables.
void setAvoidIntersectionsLayers(const QList< QgsVectorLayer * > &layers)
Sets the list of layers with which intersections should be avoided.
void homePathChanged()
Emitted when the home path of the project changes.
void dirtySet()
Emitted when setDirty(true) is called.
void setCustomVariables(const QVariantMap &customVariables)
A map of custom project variables.
void writeProject(QDomDocument &document)
Emitted when the project is being written.
QgsCoordinateReferenceSystem defaultCrsForNewLayers() const
Returns the default CRS for new layers based on the settings and the current project CRS.
QString saveUserFullName() const
Returns the full user name that did the last save.
void layersAdded(const QList< QgsMapLayer * > &layers)
Emitted when one or more layers were added to the registry.
QMap< QString, QgsMapLayer * > mapLayers(const bool validOnly=false) const
Returns a map of all registered layers by layer ID.
bool isDirty() const
Returns true if the project has been modified since the last write()
QgsMapLayer * takeMapLayer(QgsMapLayer *layer)
Takes a layer from the registry.
void isDirtyChanged(bool dirty)
Emitted when the project dirty status changes.
void setDistanceUnits(Qgis::DistanceUnit unit)
Sets the default distance measurement units for the project.
Q_DECL_DEPRECATED bool useProjectScales() const
Returns true if project mapScales() are enabled.
Q_DECL_DEPRECATED void setMapScales(const QVector< double > &scales)
Sets the list of custom project map scales.
void setPresetHomePath(const QString &path)
Sets the project's home path.
void setFlags(Qgis::ProjectFlags flags)
Sets the project's flags, which dictate the behavior of the project.
QList< QgsMapLayer * > mapLayersByShortName(const QString &shortName) const
Retrieves a list of matching registered layers by layer shortName.
QgsProjectStorage * projectStorage() const
Returns pointer to project storage implementation that handles read/write of the project file.
QString layerIsEmbedded(const QString &id) const
Returns the source project file path if the layer with matching id is embedded from other project fil...
const QgsProjectTimeSettings * timeSettings() const
Returns the project's time settings, which contains the project's temporal range and other time based...
void verticalCrsChanged()
Emitted when the verticalCrs() of the project has changed.
void topologicalEditingChanged()
Emitted when the topological editing flag has changed.
bool removeEntry(const QString &scope, const QString &key)
Remove the given key from the specified scope.
QgsProjectVersion lastSaveVersion() const
Returns the QGIS version which the project was last saved using.
void avoidIntersectionsModeChanged()
Emitted whenever the avoid intersections mode has changed.
void loadingLayer(const QString &layerName)
Emitted when a layer is loaded.
A grouped map of multiple QgsProperty objects, each referenced by a integer key value.
Definition for a property.
@ String
Any string value.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
QString relativeToAbsoluteUri(const QString &providerKey, const QString &uri, const QgsReadWriteContext &context) const
Converts relative path(s) to absolute path(s) in the given provider-specific URI.
QgsProviderMetadata * providerMetadata(const QString &providerKey) const
Returns metadata of the provider or nullptr if not found.
static bool run(const QString &command, const QString &messageOnError=QString())
Execute a Python statement.
static bool isValid()
Returns true if the runner has an instance (and thus is able to run commands)
The class is used as a container of context for various read/write operations on other objects.
void setTransformContext(const QgsCoordinateTransformContext &transformContext)
Sets data coordinate transform context to transformContext.
QgsCoordinateTransformContext transformContext() const
Returns data provider coordinate transform context.
QList< QgsReadWriteContext::ReadWriteMessage > takeMessages()
Returns the stored messages and remove them.
void setProjectTranslator(QgsProjectTranslator *projectTranslator)
Sets the project translator.
void setPathResolver(const QgsPathResolver &resolver)
Sets up path resolver for conversion between relative and absolute paths.
This class manages a set of relations between layers.
void clear()
Remove any relation managed by this class.
QMap< QString, QgsRelation > relations() const
Gets access to the relations managed by this class.
Represents a relationship between two vector layers.
The QgsRunnableProviderCreator class is used when reading a project to create asynchronously provider...
void providerCreated(bool isValid, const QString &layerId)
Emitted when a provider is created with isValid set to True when the provider is valid.
QgsDataProvider * dataProvider()
Returns the created data provider.
void clear(const QString &group="startup")
clear Clear all profile data.
Expression function for use within a QgsExpressionContextScope.
Scoped object for logging of the runtime for a single operation or group of operations.
QDomElement writeXml(QDomDocument &document) const
Returns a DOM element representing the state of the manager.
void clear()
Deregisters and removes all sensors from the manager.
bool readXml(const QDomElement &element, const QDomDocument &document)
Reads the manager's state from a DOM element, restoring all sensors present in the XML document.
T value(const QString &dynamicKeyPart=QString()) const
Returns settings value.
static const QgsSettingsEntryInteger * settingsLayerParallelLoadingMaxCount
Settings entry maximum thread count used to load layer in parallel.
static const QgsSettingsEntryBool * settingsLayerParallelLoading
Settings entry whether layer are loading in parallel.
This class is a composition of two QSettings instances:
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
T enumValue(const QString &key, const T &defaultValue, const Section section=NoSection)
Returns the setting value for a setting based on an enum.
This is a container for configuration of the snapping of the project.
bool addLayers(const QList< QgsMapLayer * > &layers)
Adds the specified layers as individual layers to the configuration with standard configuration.
void readProject(const QDomDocument &doc)
Reads the configuration from the specified QGIS project document.
void reset()
reset to default values
void writeProject(QDomDocument &doc)
Writes the configuration to the specified QGIS project document.
void clearIndividualLayerSettings()
Removes all individual layer snapping settings.
bool removeLayers(const QList< QgsMapLayer * > &layers)
Removes the specified layers from the individual layer configuration.
An interface for classes which can visit style entity (e.g.
virtual bool visitExit(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor stops visiting a node.
virtual bool visitEnter(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor starts visiting a node.
void triggerIconRebuild()
Triggers emission of the rebuildIconPreviews() signal.
static QgsStyle * defaultStyle(bool initialize=true)
Returns the default application-wide style.
bool addLayer(QgsVectorLayer *layer)
Add a layer to this transaction group.
static bool supportsTransaction(const QgsVectorLayer *layer)
Checks if the provider of a given layer supports transactions.
QString connectionString() const
Returns the connection string of the transaction.
Used for the collecting of strings from projects for translation and creation of ts files.
void registerTranslation(const QString &context, const QString &source)
Registers the source to be translated.
void setProject(QgsProject *project)
Sets the project being translated.
static Q_INVOKABLE QString toString(Qgis::DistanceUnit unit)
Returns a translated string representing a distance unit.
static Q_INVOKABLE Qgis::AreaUnit decodeAreaUnit(const QString &string, bool *ok=nullptr)
Decodes an areal unit from a string.
static Q_INVOKABLE QString encodeUnit(Qgis::DistanceUnit unit)
Encodes a distance unit to a string.
static Q_INVOKABLE Qgis::DistanceUnit decodeDistanceUnit(const QString &string, bool *ok=nullptr)
Decodes a distance unit from a string.
The edit buffer group manages a group of edit buffers.
bool commitChanges(QStringList &commitErrors, bool stopEditing=true)
Attempts to commit any changes to disk.
bool startEditing()
Start editing.
void clear()
Remove all layers from this edit buffer group.
bool rollBack(QStringList &rollbackErrors, bool stopEditing=true)
Stop editing and discard the edits.
void addLayer(QgsVectorLayer *layer)
Add a layer to this edit buffer group.
Represents a vector layer which manages a vector based data sets.
Q_INVOKABLE bool startEditing()
Makes the layer editable.
bool loadAuxiliaryLayer(const QgsAuxiliaryStorage &storage, const QString &key=QString())
Loads the auxiliary layer for this vector layer.
QgsAuxiliaryLayer * auxiliaryLayer()
Returns the current auxiliary layer.
QStringList commitErrors() const
Returns a list containing any error messages generated when attempting to commit changes to the layer...
Q_INVOKABLE bool rollBack(bool deleteBuffer=true)
Stops a current editing operation and discards any uncommitted edits.
Q_INVOKABLE bool commitChanges(bool stopEditing=true)
Attempts to commit to the underlying data provider any buffered changes made since the last to call t...
QgsEditFormConfig editFormConfig
QList< QPair< QColor, QString > > QgsNamedColorList
List of colors paired with a friendly display name identifying the color.
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.
CORE_EXPORT const QStringList files(const QString &zip)
Returns the list of files within a zip file.
CONSTLATIN1STRING geoNone()
Constant that holds the string representation for "No ellips/No CRS".
T qgsEnumKeyToValue(const QString &key, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given key of an enum.
#define Q_NOWARN_DEPRECATED_POP
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
QString qgsFlagValueToKeys(const T &value, bool *returnOk=nullptr)
Returns the value for the given keys of a flag.
T qgsFlagKeysToValue(const QString &keys, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given keys of a flag.
#define Q_NOWARN_DEPRECATED_PUSH
CONSTLATIN1STRING geoEpsgCrsAuthId()
Geographic coord sys from EPSG authority.
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)
QPointer< QgsMapLayer > QgsWeakMapLayerPointer
Weak pointer for QgsMapLayer.
void _getProperties(const QDomDocument &doc, QgsProjectPropertyKey &project_properties)
Restores any optional properties found in "doc" to "properties".
QgsPropertyCollection getDataDefinedServerProperties(const QDomDocument &doc, const QgsPropertiesDefinition &dataDefinedServerPropertyDefinitions)
Returns the data defined server properties collection found in "doc" to "dataDefinedServerProperties"...
void removeKey_(const QString &scope, const QString &key, QgsProjectPropertyKey &rootProperty)
Removes a given key.
QgsProjectVersion getVersion(const QDomDocument &doc)
Returns the version string found in the given DOM document.
QStringList makeKeyTokens_(const QString &scope, const QString &key)
Takes the given scope and key and convert them to a string list of key tokens that will be used to na...
void dump_(const QgsProjectPropertyKey &topQgsPropertyKey)
QgsProjectProperty * findKey_(const QString &scope, const QString &key, QgsProjectPropertyKey &rootProperty)
Returns the property that matches the given key sequence, if any.
QgsProjectProperty * addKey_(const QString &scope, const QString &key, QgsProjectPropertyKey *rootProperty, const QVariant &value, bool &propertiesModified)
Adds the given key and value.
CORE_EXPORT QgsProjectVersion getVersion(QDomDocument const &doc)
Returns the version string found in the given DOM document.
QMap< int, QgsPropertyDefinition > QgsPropertiesDefinition
Definition of available properties.
#define FONTMARKER_CHR_FIX
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS_NON_FATAL
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS
const QgsCoordinateReferenceSystem & crs
Qgis::DataProviderReadFlags flags
QgsDataProvider::ProviderOptions options
Setting options for loading annotation layers.
Setting options for creating vector data providers.
Single variable definition for use within a QgsExpressionContextScope.
Setting options for loading group layers.
Contains information relating to a node (i.e.