79#include <QApplication>
84#include <QTemporaryFile>
87#include <QStandardPaths>
89#include <QRegularExpression>
111 QStringList keyTokens = QStringList( scope );
112 keyTokens += key.split(
'/', Qt::SkipEmptyParts );
115 keyTokens.push_front( QStringLiteral(
"properties" ) );
118 for (
int i = 0; i < keyTokens.size(); ++i )
120 const QString keyToken = keyTokens.at( i );
124 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}])" ) );
125 if ( keyToken.contains( sInvalidRegexp ) )
127 const QString errorString = QObject::tr(
"Entry token invalid : '%1'. The token will not be saved to file." ).arg( keyToken );
155 while ( !keySequence.isEmpty() )
159 if ( keySequence.first() == currentProperty->
name() )
162 keySequence.pop_front();
164 if ( 1 == keySequence.count() )
167 return currentProperty->
find( keySequence.front() );
169 else if ( keySequence.isEmpty() )
174 return currentProperty;
176 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
178 if ( nextProperty->
isKey() )
182 else if ( nextProperty->
isValue() && 1 == keySequence.count() )
188 return currentProperty;
226 const QVariant &value,
227 bool &propertiesModified )
236 propertiesModified =
false;
237 while ( ! keySequence.isEmpty() )
241 if ( keySequence.first() == currentProperty->
name() )
244 keySequence.pop_front();
248 if ( 1 == keySequence.count() )
251 if ( !property || property->value() != value )
253 currentProperty->
setValue( keySequence.front(), value );
254 propertiesModified =
true;
257 return currentProperty;
261 else if ( keySequence.isEmpty() )
263 if ( currentProperty->
value() != value )
266 propertiesModified =
true;
269 return currentProperty;
271 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
275 if ( currentProperty )
286 if ( ( newPropertyKey = currentProperty->
addKey( keySequence.first() ) ) )
288 currentProperty = newPropertyKey;
320 while ( ! keySequence.isEmpty() )
324 if ( keySequence.first() == currentProperty->
name() )
327 keySequence.pop_front();
331 if ( 1 == keySequence.count() )
333 currentProperty->
removeKey( keySequence.front() );
338 else if ( keySequence.isEmpty() )
340 previousQgsPropertyKey->
removeKey( currentProperty->
name() );
342 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
344 previousQgsPropertyKey = currentProperty;
347 if ( currentProperty )
371 , mCapabilities( capabilities )
374 , mSnappingConfig( this )
392 mProperties.
setName( QStringLiteral(
"properties" ) );
395 mMainAnnotationLayer->setParent(
this );
409 this, [
this](
const QStringList &
layers ) { mProjectScope.reset(); emit layersWillBeRemoved( layers ); } );
411 this, [
this](
const QList<QgsMapLayer *> &
layers ) { mProjectScope.reset(); emit layersWillBeRemoved( layers ); } );
413 this, [
this](
const QString & layer ) { mProjectScope.reset(); emit layerWillBeRemoved( layer ); } );
415 this, [
this](
QgsMapLayer * layer ) { mProjectScope.reset(); emit layerWillBeRemoved( layer ); } );
417 [
this](
const QStringList &
layers ) { mProjectScope.reset(); emit layersRemoved( layers ); } );
419 [
this](
const QString & layer ) { mProjectScope.reset(); emit layerRemoved( layer ); } );
421 [
this]() { mProjectScope.reset(); emit removeAll(); } );
423 [
this](
const QList< QgsMapLayer * > &
layers ) { mProjectScope.reset(); emit layersAdded( layers ); } );
425 [
this](
QgsMapLayer * layer ) { mProjectScope.reset(); emit layerWasAdded( layer ); } );
433 [
this](
const QList<QgsMapLayer *> &
layers )
435 for ( const auto &layer : layers )
437 disconnect( layer, &QgsMapLayer::dataSourceChanged, mRelationManager, &QgsRelationManager::updateRelationsStatus );
442 [
this](
const QList<QgsMapLayer *> &layers )
444 for ( const auto &layer : layers )
446 connect( layer, &QgsMapLayer::dataSourceChanged, mRelationManager, &QgsRelationManager::updateRelationsStatus );
455 mStyleSettings->combinedStyleModel()->addDefaultStyle();
461 mIsBeingDeleted =
true;
464 releaseHandlesToProjectArchive();
465 delete mBadLayerHandler;
466 delete mRelationManager;
467 delete mLayerTreeRegistryBridge;
469 if (
this == sProject )
500 mProjectScope.reset();
511 return mMetadata.
title();
520 if ( oldEvaluateDefaultValues != newEvaluateDefaultValues )
523 for (
auto layerIt =
layers.constBegin(); layerIt !=
layers.constEnd(); ++layerIt )
525 if (
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layerIt.value() ) )
526 if ( vl->dataProvider() )
533 if ( oldTrustLayerMetadata != newTrustLayerMetadata )
536 for (
auto layerIt =
layers.constBegin(); layerIt !=
layers.constEnd(); ++layerIt )
538 if (
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layerIt.value() ) )
540 vl->setReadExtentFromXml( newTrustLayerMetadata );
545 if ( mFlags !=
flags )
560 newFlags &= ~(
static_cast< int >( flag ) );
575 return mSaveUserFull;
582 return mSaveDateTime;
603 if ( dirty && mDirtyBlockCount > 0 )
609 if ( mDirty == dirty )
620 if ( path == mHomePath )
624 mCachedHomePath.clear();
625 mProjectScope.reset();
636 const QList<QgsAttributeEditorElement *> elements = parent->
children();
644 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:formcontainers" ).arg( layerId ), container->
name() );
646 if ( !container->
children().empty() )
661 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1" ).arg( layer->layerId() ), layer->name() );
670 for (
const QgsField &field : fields )
673 if ( field.alias().isEmpty() )
674 fieldName = field.name();
676 fieldName = field.alias();
678 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:fieldaliases" ).arg( vlayer->
id() ), fieldName );
680 if ( field.editorWidgetSetup().type() == QLatin1String(
"ValueRelation" ) )
682 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:fields:%2:valuerelationvalue" ).arg( vlayer->
id(), field.name() ), field.editorWidgetSetup().config().value( QStringLiteral(
"Value" ) ).toString() );
693 const QList<QgsLayerTreeGroup *> groupLayers = mRootGroup->
findGroups();
696 translationContext->
registerTranslation( QStringLiteral(
"project:layergroups" ), groupLayer->name() );
700 const QList<QgsRelation> &relations = mRelationManager->
relations().values();
703 translationContext->
registerTranslation( QStringLiteral(
"project:relations" ), relation.name() );
711 mDataDefinedServerProperties = properties;
718 return mDataDefinedServerProperties;
725 switch ( mTransactionMode )
746 switch ( mTransactionMode )
753 commitErrors.append( tr(
"Trying to commit changes without a layer specified. This only works if the transaction mode is buffered" ) );
762 return mEditBufferGroup.
commitChanges( commitErrors, stopEditing );
772 switch ( mTransactionMode )
779 rollbackErrors.append( tr(
"Trying to roll back changes without a layer specified. This only works if the transaction mode is buffered" ) );
782 bool success = vectorLayer->
rollBack( stopEditing );
788 return mEditBufferGroup.
rollBack( rollbackErrors, stopEditing );
798 if ( name == mFile.fileName() )
801 const QString oldHomePath =
homePath();
803 mFile.setFileName( name );
804 mCachedHomePath.clear();
805 mProjectScope.reset();
809 const QString newHomePath =
homePath();
810 if ( newHomePath != oldHomePath )
821 return mFile.fileName();
828 mOriginalPath = path;
835 return mOriginalPath;
842 return QFileInfo( mFile );
860 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
865 return QFileInfo( mFile.fileName() ).lastModified();
876 if ( mFile.fileName().isEmpty() )
879 return QFileInfo( mFile.fileName() ).absolutePath();
890 if ( mFile.fileName().isEmpty() )
893 return QFileInfo( mFile.fileName() ).absoluteFilePath();
904 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
909 return QFileInfo( mFile.fileName() ).completeBaseName();
917 const bool absolutePaths =
readBoolEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
false );
928 writeEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
true );
931 writeEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
false );
948 return mCrs3D.
isValid() ? mCrs3D : mCrs;
960 writeEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectionsEnabled" ),
crs.
isValid() ? 1 : 0 );
961 mProjectScope.reset();
975 if ( oldCrs3D != mCrs3D )
979 if ( adjustEllipsoid )
988 if ( !
crs().isValid() )
991 return readEntry( QStringLiteral(
"Measure" ), QStringLiteral(
"/Ellipsoid" ),
geoNone() );
998 if (
ellipsoid ==
readEntry( QStringLiteral(
"Measure" ), QStringLiteral(
"/Ellipsoid" ) ) )
1001 mProjectScope.reset();
1011 switch ( mCrs.
type() )
1014 QgsDebugError( QStringLiteral(
"Project has a vertical CRS set as the horizontal CRS!" ) );
1033 return mVerticalCrs;
1061 *errorMessage = QObject::tr(
"Specified CRS is a %1 CRS, not a Vertical CRS" ).arg(
qgsEnumValueToKey(
crs.
type() ) );
1066 if (
crs != mVerticalCrs )
1071 switch ( mCrs.
type() )
1074 if (
crs != oldVerticalCrs )
1077 *errorMessage = QObject::tr(
"Project CRS is a Compound CRS, specified Vertical CRS will be ignored" );
1083 if (
crs != oldVerticalCrs )
1086 *errorMessage = QObject::tr(
"Project CRS is a Geographic 3D CRS, specified Vertical CRS will be ignored" );
1092 if (
crs != oldVerticalCrs )
1095 *errorMessage = QObject::tr(
"Project CRS is a Geocentric CRS, specified Vertical CRS will be ignored" );
1104 *errorMessage = QObject::tr(
"Project CRS is a Projected 3D CRS, specified Vertical CRS will be ignored" );
1122 res = rebuildCrs3D( errorMessage );
1123 mProjectScope.reset();
1130 if ( mCrs3D != oldCrs3D )
1141 return mTransformContext;
1148 if ( context == mTransformContext )
1151 mTransformContext = context;
1152 mProjectScope.reset();
1155 for (
auto &layer : mLayerStore.get()->mapLayers() )
1157 layer->setTransformContext( context );
1166 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
1170 mProjectScope.reset();
1171 mFile.setFileName( QString() );
1174 mSaveUserFull.clear();
1175 mSaveDateTime = QDateTime();
1178 mCachedHomePath.clear();
1182 mCustomVariables.clear();
1188 if ( !mSettings.
value( QStringLiteral(
"projects/anonymize_new_projects" ),
false,
QgsSettings::Core ).toBool() )
1207 mEmbeddedLayers.clear();
1208 mRelationManager->
clear();
1209 mAnnotationManager->clear();
1210 mLayoutManager->clear();
1211 m3DViewsManager->clear();
1212 mBookmarkManager->
clear();
1213 mSensorManager->
clear();
1214 mViewSettings->
reset();
1215 mTimeSettings->
reset();
1216 mElevationProperties->
reset();
1217 mDisplaySettings->
reset();
1218 mGpsSettings->
reset();
1219 mSnappingConfig.
reset();
1227 mLabelingEngineSettings->clear();
1231 releaseHandlesToProjectArchive();
1237 mStyleSettings->
reset();
1241 if ( !mIsBeingDeleted )
1249 writeEntry( QStringLiteral(
"PositionPrecision" ), QStringLiteral(
"/Automatic" ),
true );
1250 writeEntry( QStringLiteral(
"PositionPrecision" ), QStringLiteral(
"/DecimalPlaces" ), 2 );
1252 const bool defaultRelativePaths = mSettings.
value( QStringLiteral(
"/qgis/defaultProjectPathsRelative" ),
true ).toBool();
1255 int red = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_red" ), 255 ).toInt();
1256 int green = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_green" ), 255 ).toInt();
1257 int blue = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_blue" ), 255 ).toInt();
1260 red = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_red" ), 255 ).toInt();
1261 green = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_green" ), 255 ).toInt();
1262 blue = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_blue" ), 0 ).toInt();
1263 const int alpha = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_alpha" ), 255 ).toInt();
1269 mRootGroup->
clear();
1270 if ( mMainAnnotationLayer )
1271 mMainAnnotationLayer->
reset();
1273 snapSingleBlocker.release();
1275 if ( !mBlockSnappingUpdates )
1280 if ( !mBlockChangeSignalsDuringClear )
1292 topQgsPropertyKey.
dump();
1325 const QDomElement propertiesElem = doc.documentElement().firstChildElement( QStringLiteral(
"properties" ) );
1327 if ( propertiesElem.isNull() )
1332 const QDomNodeList scopes = propertiesElem.childNodes();
1334 if ( propertiesElem.firstChild().isNull() )
1336 QgsDebugError( QStringLiteral(
"empty ``properties'' XML tag ... bailing" ) );
1340 if ( ! project_properties.
readXml( propertiesElem ) )
1342 QgsDebugError( QStringLiteral(
"Project_properties.readXml() failed" ) );
1356 const QDomElement ddElem = doc.documentElement().firstChildElement( QStringLiteral(
"dataDefinedServerProperties" ) );
1357 if ( !ddElem.isNull() )
1359 if ( !ddServerProperties.
readXml( ddElem, dataDefinedServerPropertyDefinitions ) )
1361 QgsDebugError( QStringLiteral(
"dataDefinedServerProperties.readXml() failed" ) );
1364 return ddServerProperties;
1371static void _getTitle(
const QDomDocument &doc, QString &title )
1373 const QDomElement titleNode = doc.documentElement().firstChildElement( QStringLiteral(
"title" ) );
1377 if ( titleNode.isNull() )
1383 if ( !titleNode.hasChildNodes() )
1389 const QDomNode titleTextNode = titleNode.firstChild();
1391 if ( !titleTextNode.isText() )
1397 const QDomText titleText = titleTextNode.toText();
1399 title = titleText.data();
1403static void readProjectFileMetadata(
const QDomDocument &doc, QString &lastUser, QString &lastUserFull, QDateTime &lastSaveDateTime )
1405 const QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"qgis" ) );
1409 QgsDebugError( QStringLiteral(
"unable to find qgis element" ) );
1413 const QDomNode qgisNode = nl.item( 0 );
1415 const QDomElement qgisElement = qgisNode.toElement();
1416 lastUser = qgisElement.attribute( QStringLiteral(
"saveUser" ), QString() );
1417 lastUserFull = qgisElement.attribute( QStringLiteral(
"saveUserFull" ), QString() );
1418 lastSaveDateTime = QDateTime::fromString( qgisElement.attribute( QStringLiteral(
"saveDateTime" ), QString() ), Qt::ISODate );
1423 const QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"qgis" ) );
1427 QgsDebugError( QStringLiteral(
" unable to find qgis element in project file" ) );
1431 const QDomNode qgisNode = nl.item( 0 );
1433 const QDomElement qgisElement = qgisNode.toElement();
1434 QgsProjectVersion projectVersion( qgisElement.attribute( QStringLiteral(
"version" ) ) );
1435 return projectVersion;
1442 return mSnappingConfig;
1461 if ( mAvoidIntersectionsMode == mode )
1464 mAvoidIntersectionsMode = mode;
1498void QgsProject::preloadProviders(
const QVector<QDomNode> ¶llelLayerNodes,
1500 QMap<QString, QgsDataProvider *> &loadedProviders,
1502 int totalProviderCount )
1507 QMap<QString, LayerToLoad> layersToLoad;
1509 for (
const QDomNode &node : parallelLayerNodes )
1513 const QDomElement layerElement = node.toElement();
1515 layerToLoad.
layerId = layerElement.namedItem( QStringLiteral(
"id" ) ).toElement().text();
1516 layerToLoad.
provider = layerElement.namedItem( QStringLiteral(
"provider" ) ).toElement().text();
1517 layerToLoad.
dataSource = layerElement.namedItem( QStringLiteral(
"datasource" ) ).toElement().text();
1528 layersToLoad.insert( layerToLoad.
layerId, layerToLoad );
1531 while ( !layersToLoad.isEmpty() )
1533 const QList<LayerToLoad> layersToAttemptInParallel = layersToLoad.values();
1534 QString layerToAttemptInMainThread;
1536 QHash<QString, QgsRunnableProviderCreator *> runnables;
1537 QThreadPool threadPool;
1540 for (
const LayerToLoad &lay : layersToAttemptInParallel )
1543 runnables.insert( lay.layerId, run );
1549 layersToLoad.remove( layId );
1552 Q_ASSERT( finishedRun );
1554 std::unique_ptr<QgsDataProvider> provider( finishedRun->
dataProvider() );
1555 Q_ASSERT( provider && provider->isValid() );
1557 loadedProviders.insert( layId, provider.release() );
1562 if ( layerToAttemptInMainThread.isEmpty() )
1563 layerToAttemptInMainThread = layId;
1567 if ( i == parallelLayerNodes.count() || !isValid )
1570 threadPool.start( run );
1574 threadPool.waitForDone();
1576 qDeleteAll( runnables );
1579 auto it = layersToLoad.find( layerToAttemptInMainThread );
1580 if ( it != layersToLoad.end() )
1582 std::unique_ptr<QgsDataProvider> provider;
1592 if ( provider && provider->isValid() )
1597 layersToLoad.erase( it );
1600 loadedProviders.insert( layerId, provider.release() );
1608void QgsProject::releaseHandlesToProjectArchive()
1613bool QgsProject::rebuildCrs3D( QString *error )
1620 else if ( !mVerticalCrs.
isValid() )
1626 switch ( mCrs.
type() )
1667bool QgsProject::_getMapLayers(
const QDomDocument &doc, QList<QDomNode> &brokenNodes,
Qgis::ProjectReadFlags flags )
1674 QDomElement layerElement = doc.documentElement().firstChildElement( QStringLiteral(
"projectlayers" ) ).firstChildElement( QStringLiteral(
"maplayer" ) );
1678 if ( layerElement.isNull() )
1688 bool returnStatus =
true;
1691 while ( ! layerElement.isNull() )
1694 layerElement = layerElement.nextSiblingElement( QStringLiteral(
"maplayer" ) );
1700 if ( depSorter.hasCycle() )
1704 if ( depSorter.hasMissingDependency() )
1705 returnStatus =
false;
1709 const QVector<QDomNode> sortedLayerNodes = depSorter.sortedLayerNodes();
1710 const int totalLayerCount = sortedLayerNodes.count();
1712 QVector<QDomNode> parallelLoading;
1713 QMap<QString, QgsDataProvider *> loadedProviders;
1717 profile.switchTask( tr(
"Load providers in parallel" ) );
1718 for (
const QDomNode &node : sortedLayerNodes )
1720 const QDomElement element = node.toElement();
1721 if ( element.attribute( QStringLiteral(
"embedded" ) ) != QLatin1String(
"1" ) )
1723 const QString layerId = node.namedItem( QStringLiteral(
"id" ) ).toElement().text();
1724 if ( !depSorter.isLayerDependent( layerId ) )
1726 const QDomNode mnl = element.namedItem( QStringLiteral(
"provider" ) );
1727 const QDomElement mne = mnl.toElement();
1728 const QString provider = mne.text();
1732 parallelLoading.append( node );
1741 if ( !parallelLoading.isEmpty() )
1742 preloadProviders( parallelLoading, context, loadedProviders, projectFlagsToLayerReadFlags(
flags, mFlags ), sortedLayerNodes.count() );
1745 int i = loadedProviders.count();
1746 for (
const QDomNode &node : std::as_const( sortedLayerNodes ) )
1748 const QDomElement element = node.toElement();
1749 const QString name =
translate( QStringLiteral(
"project:layers:%1" ).arg( node.namedItem( QStringLiteral(
"id" ) ).toElement().text() ), node.namedItem( QStringLiteral(
"layername" ) ).toElement().text() );
1750 if ( !name.isNull() )
1751 emit
loadingLayer( tr(
"Loading layer %1" ).arg( name ) );
1753 profile.switchTask( name );
1754 if ( element.attribute( QStringLiteral(
"embedded" ) ) == QLatin1String(
"1" ) )
1756 createEmbeddedLayer( element.attribute( QStringLiteral(
"id" ) ),
readPath( element.attribute( QStringLiteral(
"project" ) ) ), brokenNodes,
true,
flags );
1764 QString layerId = element.namedItem( QStringLiteral(
"id" ) ).toElement().text();
1766 if ( !addLayer( element, brokenNodes, context,
flags, loadedProviders.take( layerId ) ) )
1768 returnStatus =
false;
1771 if ( !messages.isEmpty() )
1780 return returnStatus;
1783bool QgsProject::addLayer(
const QDomElement &layerElem,
1784 QList<QDomNode> &brokenNodes,
1791 const QString type = layerElem.attribute( QStringLiteral(
"type" ) );
1793 std::unique_ptr<QgsMapLayer>
mapLayer;
1801 QgsDebugError( QStringLiteral(
"Unknown layer type \"%1\"" ).arg( type ) );
1805 switch ( layerType )
1808 mapLayer = std::make_unique<QgsVectorLayer>();
1812 mapLayer = std::make_unique<QgsRasterLayer>();
1816 mapLayer = std::make_unique<QgsMeshLayer>();
1820 mapLayer = std::make_unique<QgsVectorTileLayer>();
1824 mapLayer = std::make_unique<QgsPointCloudLayer>();
1828 mapLayer = std::make_unique<QgsTiledSceneLayer>();
1833 const QString
typeName = layerElem.attribute( QStringLiteral(
"name" ) );
1841 mapLayer = std::make_unique<QgsAnnotationLayer>( QString(), options );
1848 mapLayer = std::make_unique<QgsGroupLayer>( QString(), options );
1855 QgsDebugError( QStringLiteral(
"Unable to create layer" ) );
1863 const QString layerId { layerElem.namedItem( QStringLiteral(
"id" ) ).toElement().text() };
1864 Q_ASSERT( ! layerId.isEmpty() );
1870 profile.switchTask( tr(
"Load layer source" ) );
1877 if ( vl->dataProvider() )
1884 profile.switchTask( tr(
"Add layer to project" ) );
1885 QList<QgsMapLayer *> newLayers;
1897 vLayer->joinBuffer()->resolveReferences(
this );
1906 brokenNodes.push_back( layerElem );
1909 const bool wasEditable = layerElem.attribute( QStringLiteral(
"editable" ), QStringLiteral(
"0" ) ).toInt();
1921 if ( ! layerWasStored )
1926 return layerIsValid;
1933 mFile.setFileName( filename );
1934 mCachedHomePath.clear();
1935 mProjectScope.reset();
1944 const QString filename = mFile.fileName();
1949 QTemporaryFile inDevice;
1950 if ( !inDevice.open() )
1952 setError( tr(
"Unable to open %1" ).arg( inDevice.fileName() ) );
1958 if ( !storage->readProject( filename, &inDevice, context ) )
1960 QString err = tr(
"Unable to open %1" ).arg( filename );
1961 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
1962 if ( !messages.isEmpty() )
1963 err += QStringLiteral(
"\n\n" ) + messages.last().message();
1967 returnValue = unzip( inDevice.fileName(),
flags );
1973 returnValue = unzip( mFile.fileName(),
flags );
1978 const QFileInfo finfo( mFile.fileName() );
1979 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( QStringLiteral(
"%1_attachments.zip" ).arg( finfo.completeBaseName() ) );
1980 if ( QFile( attachmentsZip ).exists() )
1982 std::unique_ptr<QgsArchive> archive(
new QgsArchive() );
1983 if ( archive->unzip( attachmentsZip ) )
1985 releaseHandlesToProjectArchive();
1986 mArchive = std::move( archive );
1989 returnValue = readProjectFile( mFile.fileName(),
flags );
1995 mFile.setFileName( filename );
1996 mCachedHomePath.clear();
1997 mProjectScope.reset();
2002 mTranslator.reset(
nullptr );
2014 ScopedIntIncrementor snapSignalBlock( &mBlockSnappingUpdates );
2016 QFile projectFile( filename );
2024 if ( QFile( QStringLiteral(
"%1/%2.qm" ).arg( QFileInfo( projectFile.fileName() ).absolutePath(), localeFileName ) ).exists() )
2026 mTranslator.reset(
new QTranslator() );
2027 ( void )mTranslator->load( localeFileName, QFileInfo( projectFile.fileName() ).absolutePath() );
2030 profile.switchTask( tr(
"Reading project file" ) );
2031 std::unique_ptr<QDomDocument> doc(
new QDomDocument( QStringLiteral(
"qgis" ) ) );
2033 if ( !projectFile.open( QIODevice::ReadOnly | QIODevice::Text ) )
2035 projectFile.close();
2037 setError( tr(
"Unable to open %1" ).arg( projectFile.fileName() ) );
2042 QTextStream textStream( &projectFile );
2043#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
2044 textStream.setCodec(
"UTF-8" );
2046 QString projectString = textStream.readAll();
2047 projectFile.close();
2049 for (
int i = 0; i < 32; i++ )
2051 if ( i == 9 || i == 10 || i == 13 )
2055 projectString.replace( QChar( i ), QStringLiteral(
"%1%2%1" ).arg(
FONTMARKER_CHR_FIX, QString::number( i ) ) );
2061 if ( !doc->setContent( projectString, &errorMsg, &line, &column ) )
2063 const QString errorString = tr(
"Project file read error in file %1: %2 at line %3 column %4" )
2064 .arg( projectFile.fileName(), errorMsg ).arg( line ).arg( column );
2066 setError( errorString );
2071 projectFile.close();
2079 profile.switchTask( tr(
"Updating project file" ) );
2080 if ( thisVersion > fileVersion )
2082 const bool isOlderMajorVersion = fileVersion.
majorVersion() < thisVersion.majorVersion();
2084 if ( isOlderMajorVersion )
2087 "version of qgis (saved in " + fileVersion.
text() +
2089 "). Problems may occur." );
2100 projectFile.updateRevision( thisVersion );
2102 else if ( fileVersion > thisVersion )
2105 "version of qgis (saved in " + fileVersion.
text() +
2107 "). Problems may occur." );
2113 profile.switchTask( tr(
"Creating auxiliary storage" ) );
2114 const QString
fileName = mFile.fileName();
2121 std::unique_ptr<QgsAuxiliaryStorage> aStorage = std::move( mAuxiliaryStorage );
2122 std::unique_ptr<QgsArchive> archive = std::move( mArchive );
2126 mBlockChangeSignalsDuringClear =
true;
2128 mBlockChangeSignalsDuringClear =
false;
2133 releaseHandlesToProjectArchive();
2135 mAuxiliaryStorage = std::move( aStorage );
2136 mArchive = std::move( archive );
2139 mCachedHomePath.clear();
2140 mProjectScope.reset();
2141 mSaveVersion = fileVersion;
2144 profile.switchTask( tr(
"Reading properties" ) );
2153 dump_( mProperties );
2158 _getTitle( *doc, oldTitle );
2160 readProjectFileMetadata( *doc, mSaveUser, mSaveUserFull, mSaveDateTime );
2162 const QDomNodeList homePathNl = doc->elementsByTagName( QStringLiteral(
"homePath" ) );
2163 if ( homePathNl.count() > 0 )
2165 const QDomElement homePathElement = homePathNl.at( 0 ).toElement();
2166 const QString
homePath = homePathElement.attribute( QStringLiteral(
"path" ) );
2176 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorGreenPart" ), 255 ),
2177 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorBluePart" ), 255 ) );
2180 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorGreenPart" ), 255 ),
2181 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorBluePart" ), 255 ),
2182 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorAlphaPart" ), 255 ) );
2186 const QString distanceUnitString =
readEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/DistanceUnits" ), QString() );
2187 if ( !distanceUnitString.isEmpty() )
2190 const QString areaUnitString =
readEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/AreaUnits" ), QString() );
2191 if ( !areaUnitString.isEmpty() )
2200 if (
readNumEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectionsEnabled" ), 0 ) )
2203 const QDomNode srsNode = doc->documentElement().namedItem( QStringLiteral(
"projectCrs" ) );
2204 if ( !srsNode.isNull() )
2206 projectCrs.
readXml( srsNode );
2211 const QString projCrsString =
readEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCRSProj4String" ) );
2212 const long currentCRS =
readNumEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCRSID" ), -1 );
2213 const QString authid =
readEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCrs" ) );
2216 const bool isUserAuthId = authid.startsWith( QLatin1String(
"USER:" ), Qt::CaseInsensitive );
2217 if ( !authid.isEmpty() && !isUserAuthId )
2221 if ( !projectCrs.
isValid() && currentCRS >= 0 )
2227 if ( !projCrsString.isEmpty() && ( authid.isEmpty() || isUserAuthId ) && ( !projectCrs.
isValid() || projectCrs.
toProj() != projCrsString ) )
2244 const QDomNode verticalCrsNode = doc->documentElement().namedItem( QStringLiteral(
"verticalCrs" ) );
2245 if ( !verticalCrsNode.isNull() )
2253 QStringList datumErrors;
2254 if ( !mTransformContext.
readXml( doc->documentElement(), context, datumErrors ) && !datumErrors.empty() )
2261 const QDomNode elevationShadingNode = doc->documentElement().namedItem( QStringLiteral(
"elevation-shading-renderer" ) );
2262 if ( !elevationShadingNode.isNull() )
2264 mElevationShadingRenderer.
readXml( elevationShadingNode.toElement(), context );
2271 const QStringList variableNames =
readListEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableNames" ) );
2272 const QStringList variableValues =
readListEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableValues" ) );
2274 mCustomVariables.clear();
2275 if ( variableNames.length() == variableValues.length() )
2277 for (
int i = 0; i < variableNames.length(); ++i )
2279 mCustomVariables.insert( variableNames.at( i ), variableValues.at( i ) );
2284 QgsMessageLog::logMessage( tr(
"Project Variables Invalid" ), tr(
"The project contains invalid variable settings." ) );
2287 QDomElement element = doc->documentElement().firstChildElement( QStringLiteral(
"projectMetadata" ) );
2289 if ( !element.isNull() )
2298 if ( mMetadata.
title().isEmpty() && !oldTitle.isEmpty() )
2306 element = doc->documentElement().firstChildElement( QStringLiteral(
"transaction" ) );
2307 if ( !element.isNull() )
2314 element = doc->documentElement().firstChildElement( QStringLiteral(
"autotransaction" ) );
2315 if ( ! element.isNull() )
2317 mTransactionMode =
static_cast<Qgis::TransactionMode>( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() );
2322 profile.switchTask( tr(
"Loading layer tree" ) );
2325 QDomElement layerTreeElem = doc->documentElement().firstChildElement( QStringLiteral(
"layer-tree-group" ) );
2326 if ( !layerTreeElem.isNull() )
2338 mLayerTreeRegistryBridge->
setEnabled(
false );
2341 profile.switchTask( tr(
"Reading map layers" ) );
2343 loadProjectFlags( doc.get() );
2345 QList<QDomNode> brokenNodes;
2346 const bool clean = _getMapLayers( *doc, brokenNodes,
flags );
2351 QgsDebugError( QStringLiteral(
"Unable to get map layers from project file." ) );
2353 if ( !brokenNodes.isEmpty() )
2355 QgsDebugError(
"there are " + QString::number( brokenNodes.size() ) +
" broken layers" );
2363 mMainAnnotationLayer->
readLayerXml( doc->documentElement().firstChildElement( QStringLiteral(
"main-annotation-layer" ) ), context );
2367 profile.switchTask( tr(
"Loading embedded layers" ) );
2368 loadEmbeddedNodes( mRootGroup,
flags );
2372 profile.switchTask( tr(
"Resolving layer references" ) );
2373 QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
2374 for ( QMap<QString, QgsMapLayer *>::iterator it =
layers.begin(); it !=
layers.end(); ++it )
2376 it.value()->resolveReferences(
this );
2379 mLayerTreeRegistryBridge->
setEnabled(
true );
2382 profile.switchTask( tr(
"Resolving references" ) );
2393 if ( !layerTreeElem.isNull() )
2399 const QDomElement layerTreeCanvasElem = doc->documentElement().firstChildElement( QStringLiteral(
"layer-tree-canvas" ) );
2400 if ( !layerTreeCanvasElem.isNull( ) )
2408 const QStringList requiredLayerIds =
readListEntry( QStringLiteral(
"RequiredLayers" ), QStringLiteral(
"Layers" ) );
2409 for (
const QString &layerId : requiredLayerIds )
2416 const QStringList disabledLayerIds =
readListEntry( QStringLiteral(
"Identify" ), QStringLiteral(
"/disabledLayers" ) );
2417 for (
const QString &layerId : disabledLayerIds )
2430 QString styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Marker" ) );
2431 if ( !styleName.isEmpty() )
2436 styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Line" ) );
2437 if ( !styleName.isEmpty() )
2442 styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Fill" ) );
2443 if ( !styleName.isEmpty() )
2448 styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/ColorRamp" ) );
2449 if ( !styleName.isEmpty() )
2459 double opacity = 1.0;
2462 double alpha =
readDoubleEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/AlphaInt" ), 255, &ok );
2464 opacity = alpha / 255.0;
2465 double newOpacity =
readDoubleEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Opacity" ), 1.0, &ok );
2467 opacity = newOpacity;
2471 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Marker" ) );
2472 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Line" ) );
2473 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Fill" ) );
2474 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/ColorRamp" ) );
2475 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/RandomColors" ) );
2476 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/AlphaInt" ) );
2477 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Opacity" ) );
2485 profile.switchTask( tr(
"Storing original layer properties" ) );
2491 profile.switchTask( tr(
"Loading map themes" ) );
2494 mMapThemeCollection->readXml( *doc );
2496 profile.switchTask( tr(
"Loading label settings" ) );
2497 mLabelingEngineSettings->readSettingsFromProject(
this );
2500 profile.switchTask( tr(
"Loading annotations" ) );
2501 mAnnotationManager->readXml( doc->documentElement(), context );
2504 profile.switchTask( tr(
"Loading layouts" ) );
2505 mLayoutManager->readXml( doc->documentElement(), *doc );
2510 profile.switchTask( tr(
"Loading 3D Views" ) );
2511 m3DViewsManager->readXml( doc->documentElement(), *doc );
2514 profile.switchTask( tr(
"Loading bookmarks" ) );
2515 mBookmarkManager->
readXml( doc->documentElement(), *doc );
2517 profile.switchTask( tr(
"Loading sensors" ) );
2518 mSensorManager->
readXml( doc->documentElement(), *doc );
2521 QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
2522 for ( QMap<QString, QgsMapLayer *>::iterator it = existingMaps.begin(); it != existingMaps.end(); ++it )
2524 it.value()->setDependencies( it.value()->dependencies() );
2527 profile.switchTask( tr(
"Loading snapping settings" ) );
2531 profile.switchTask( tr(
"Loading view settings" ) );
2534 const QStringList scales =
readListEntry( QStringLiteral(
"Scales" ), QStringLiteral(
"/ScalesList" ) );
2535 QVector<double> res;
2536 for (
const QString &scale : scales )
2538 const QStringList parts = scale.split(
':' );
2539 if ( parts.size() != 2 )
2543 const double denominator = QLocale().toDouble( parts[1], &ok );
2550 const QDomElement viewSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectViewSettings" ) );
2551 if ( !viewSettingsElement.isNull() )
2552 mViewSettings->
readXml( viewSettingsElement, context );
2555 profile.switchTask( tr(
"Loading style properties" ) );
2556 const QDomElement styleSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectStyleSettings" ) );
2557 if ( !styleSettingsElement.isNull() )
2560 mStyleSettings->
readXml( styleSettingsElement, context,
flags );
2564 profile.switchTask( tr(
"Loading temporal settings" ) );
2565 const QDomElement timeSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectTimeSettings" ) );
2566 if ( !timeSettingsElement.isNull() )
2567 mTimeSettings->
readXml( timeSettingsElement, context );
2570 profile.switchTask( tr(
"Loading elevation properties" ) );
2571 const QDomElement elevationPropertiesElement = doc->documentElement().firstChildElement( QStringLiteral(
"ElevationProperties" ) );
2572 if ( !elevationPropertiesElement.isNull() )
2573 mElevationProperties->
readXml( elevationPropertiesElement, context );
2576 profile.switchTask( tr(
"Loading display settings" ) );
2578 const QDomElement displaySettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectDisplaySettings" ) );
2579 if ( !displaySettingsElement.isNull() )
2580 mDisplaySettings->
readXml( displaySettingsElement, context );
2583 profile.switchTask( tr(
"Loading GPS settings" ) );
2585 const QDomElement gpsSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectGpsSettings" ) );
2586 if ( !gpsSettingsElement.isNull() )
2587 mGpsSettings->
readXml( gpsSettingsElement, context );
2591 profile.switchTask( tr(
"Updating variables" ) );
2593 profile.switchTask( tr(
"Updating CRS" ) );
2597 if ( mCrs3D != oldCrs3D )
2602 profile.switchTask( tr(
"Reading external settings" ) );
2606 profile.switchTask( tr(
"Updating interface" ) );
2608 snapSignalBlock.release();
2609 if ( !mBlockSnappingUpdates )
2620 QgsDebugMsgLevel( QStringLiteral(
"Project save user: %1" ).arg( mSaveUser ), 2 );
2621 QgsDebugMsgLevel( QStringLiteral(
"Project save user: %1" ).arg( mSaveUserFull ), 2 );
2630 const QString newFileName( QStringLiteral(
"%1/%2.qgs" ).arg( QFileInfo( projectFile.fileName() ).absolutePath(), localeFileName ) );
2645 const QMap<QString, QgsMapLayer *> loadedLayers =
mapLayers();
2646 for (
auto it = loadedLayers.constBegin(); it != loadedLayers.constEnd(); ++it )
2648 if ( it.value()->isValid() && it.value()->customProperty( QStringLiteral(
"_layer_was_editable" ) ).toBool() )
2650 if (
QgsVectorLayer *vl = qobject_cast< QgsVectorLayer * >( it.value() ) )
2652 it.value()->removeCustomProperty( QStringLiteral(
"_layer_was_editable" ) );
2664 const auto constChildren = group->
children();
2670 if ( childGroup->
customProperty( QStringLiteral(
"embedded" ) ).toInt() )
2673 const QString projectPath =
readPath( childGroup->
customProperty( QStringLiteral(
"embedded_project" ) ).toString() );
2674 childGroup->
setCustomProperty( QStringLiteral(
"embedded_project" ), projectPath );
2678 QList<QgsLayerTreeNode *> clonedChildren;
2679 const QList<QgsLayerTreeNode *> constChildren = newGroup->
children();
2680 clonedChildren.reserve( constChildren.size() );
2682 clonedChildren << newGroupChild->clone();
2690 loadEmbeddedNodes( childGroup,
flags );
2695 if ( child->customProperty( QStringLiteral(
"embedded" ) ).toInt() )
2697 QList<QDomNode> brokenNodes;
2700 valid = valid &&
false;
2715 return mCustomVariables;
2722 if ( variables == mCustomVariables )
2726 QStringList variableNames;
2727 QStringList variableValues;
2729 QVariantMap::const_iterator it = variables.constBegin();
2730 for ( ; it != variables.constEnd(); ++it )
2732 variableNames << it.key();
2733 variableValues << it.value().toString();
2736 writeEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableNames" ), variableNames );
2737 writeEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableValues" ), variableValues );
2739 mCustomVariables = variables;
2740 mProjectScope.reset();
2749 *mLabelingEngineSettings = settings;
2757 return *mLabelingEngineSettings;
2764 mProjectScope.reset();
2765 return mLayerStore.get();
2772 return mLayerStore.get();
2779 QList<QgsVectorLayer *>
layers;
2780 const QStringList layerIds =
readListEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsList" ), QStringList() );
2781 const auto constLayerIds = layerIds;
2782 for (
const QString &layerId : constLayerIds )
2795 list.reserve(
layers.size() );
2797 list << layer->id();
2798 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsList" ), list );
2820 if ( mProjectScope )
2822 std::unique_ptr< QgsExpressionContextScope > projectScope = std::make_unique< QgsExpressionContextScope >( *mProjectScope );
2829 projectScope->addFunction( QStringLiteral(
"sensor_data" ),
new GetSensorData(
sensorManager()->sensorsData() ) );
2831 return projectScope.release();
2834 mProjectScope = std::make_unique< QgsExpressionContextScope >( QObject::tr(
"Project" ) );
2838 QVariantMap::const_iterator it = vars.constBegin();
2840 for ( ; it != vars.constEnd(); ++it )
2842 mProjectScope->setVariable( it.key(), it.value(),
true );
2846 if ( projectPath.isEmpty() )
2847 projectPath = mOriginalPath;
2848 const QString projectFolder = QFileInfo( projectPath ).path();
2849 const QString projectFilename = QFileInfo( projectPath ).fileName();
2850 const QString projectBasename =
baseName();
2887 QVariantMap keywords;
2889 for (
auto it = metadataKeywords.constBegin(); it != metadataKeywords.constEnd(); ++it )
2891 keywords.insert( it.key(), it.value() );
2896 QVariantList layersIds;
2898 const QMap<QString, QgsMapLayer *> layersInProject = mLayerStore->mapLayers();
2899 layersIds.reserve( layersInProject.count() );
2900 layers.reserve( layersInProject.count() );
2901 for (
auto it = layersInProject.constBegin(); it != layersInProject.constEnd(); ++it )
2903 layersIds << it.value()->id();
2909 mProjectScope->addFunction( QStringLiteral(
"project_color" ),
new GetNamedProjectColor(
this ) );
2914void QgsProject::onMapLayersAdded(
const QList<QgsMapLayer *> &layers )
2918 const QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
2920 const auto constLayers =
layers;
2923 if ( ! layer->isValid() )
2926 if (
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer ) )
2929 if ( vlayer->dataProvider() )
2937 for ( QMap<QString, QgsMapLayer *>::const_iterator it = existingMaps.cbegin(); it != existingMaps.cend(); ++it )
2939 const QSet<QgsMapLayerDependency> deps = it.value()->dependencies();
2940 if ( deps.contains( layer->id() ) )
2943 it.value()->setDependencies( deps );
2948 updateTransactionGroups();
2954void QgsProject::onMapLayersRemoved(
const QList<QgsMapLayer *> &layers )
2962void QgsProject::cleanTransactionGroups(
bool force )
2966 bool changed =
false;
2967 for ( QMap< QPair< QString, QString>,
QgsTransactionGroup *>::Iterator tg = mTransactionGroups.begin(); tg != mTransactionGroups.end(); )
2969 if ( tg.value()->isEmpty() || force )
2972 tg = mTransactionGroups.erase( tg );
2984void QgsProject::updateTransactionGroups()
2988 mEditBufferGroup.
clear();
2990 switch ( mTransactionMode )
2994 cleanTransactionGroups(
true );
2999 cleanTransactionGroups(
true );
3002 cleanTransactionGroups(
false );
3006 bool tgChanged =
false;
3007 const auto constLayers =
mapLayers().values();
3010 if ( ! layer->isValid() )
3013 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
3017 switch ( mTransactionMode )
3034 mTransactionGroups.insert( qMakePair( key, connString ), tg );
3044 mEditBufferGroup.
addLayer( vlayer );
3060 context.setProjectTranslator(
this );
3062 QList<QDomNode> brokenNodes;
3063 if ( addLayer( layerNode.toElement(), brokenNodes, context ) )
3067 const QVector<QgsVectorLayer *> vectorLayers = layers<QgsVectorLayer *>();
3071 layer->resolveReferences(
this );
3073 if ( layer->isValid() && layer->customProperty( QStringLiteral(
"_layer_was_editable" ) ).toBool() )
3075 layer->startEditing();
3076 layer->removeCustomProperty( QStringLiteral(
"_layer_was_editable" ) );
3088 mFile.setFileName( filename );
3089 mCachedHomePath.clear();
3097 mProjectScope.reset();
3103 const QString storageFilePath { storage->filePath( mFile.fileName() ) };
3104 if ( storageFilePath.isEmpty() )
3110 const QString tempPath = QStandardPaths::standardLocations( QStandardPaths::TempLocation ).at( 0 );
3111 const QString tmpZipFilename( tempPath + QDir::separator() + QUuid::createUuid().toString() );
3113 if ( !zip( tmpZipFilename ) )
3116 QFile tmpZipFile( tmpZipFilename );
3117 if ( !tmpZipFile.open( QIODevice::ReadOnly ) )
3119 setError( tr(
"Unable to read file %1" ).arg( tmpZipFilename ) );
3124 if ( !storage->writeProject( mFile.fileName(), &tmpZipFile, context ) )
3126 QString err = tr(
"Unable to save project to storage %1" ).arg( mFile.fileName() );
3127 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
3128 if ( !messages.isEmpty() )
3129 err += QStringLiteral(
"\n\n" ) + messages.last().message();
3135 QFile::remove( tmpZipFilename );
3142 return zip( mFile.fileName() );
3148 const bool asOk = saveAuxiliaryStorage();
3149 const bool writeOk = writeProjectFile( mFile.fileName() );
3150 bool attachmentsOk =
true;
3151 if ( !mArchive->files().isEmpty() )
3153 const QFileInfo finfo( mFile.fileName() );
3154 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( QStringLiteral(
"%1_attachments.zip" ).arg( finfo.completeBaseName() ) );
3155 attachmentsOk = mArchive->zip( attachmentsZip );
3159 if ( ( !asOk || !attachmentsOk ) && writeOk )
3161 QStringList errorMessage;
3164 const QString err = mAuxiliaryStorage->errorString();
3165 errorMessage.append( tr(
"Unable to save auxiliary storage ('%1')" ).arg( err ) );
3167 if ( !attachmentsOk )
3169 errorMessage.append( tr(
"Unable to save attachments archive" ) );
3171 setError( errorMessage.join(
'\n' ) );
3174 return asOk && writeOk && attachmentsOk;
3178bool QgsProject::writeProjectFile(
const QString &filename )
3182 QFile projectFile( filename );
3188 const QFileInfo myFileInfo( projectFile );
3189 if ( myFileInfo.exists() && !myFileInfo.isWritable() )
3191 setError( tr(
"%1 is not writable. Please adjust permissions (if possible) and try again." )
3192 .arg( projectFile.fileName() ) );
3200 QDomImplementation::setInvalidDataPolicy( QDomImplementation::DropInvalidChars );
3202 const QDomDocumentType documentType =
3203 QDomImplementation().createDocumentType( QStringLiteral(
"qgis" ), QStringLiteral(
"http://mrcc.com/qgis.dtd" ),
3204 QStringLiteral(
"SYSTEM" ) );
3205 std::unique_ptr<QDomDocument> doc(
new QDomDocument( documentType ) );
3207 QDomElement qgisNode = doc->createElement( QStringLiteral(
"qgis" ) );
3208 qgisNode.setAttribute( QStringLiteral(
"projectname" ),
title() );
3209 qgisNode.setAttribute( QStringLiteral(
"version" ),
Qgis::version() );
3211 if ( !mSettings.
value( QStringLiteral(
"projects/anonymize_saved_projects" ),
false,
QgsSettings::Core ).toBool() )
3215 qgisNode.setAttribute( QStringLiteral(
"saveUser" ), newSaveUser );
3216 qgisNode.setAttribute( QStringLiteral(
"saveUserFull" ), newSaveUserFull );
3217 mSaveUser = newSaveUser;
3218 mSaveUserFull = newSaveUserFull;
3219 mSaveDateTime = QDateTime::currentDateTime();
3220 qgisNode.setAttribute( QStringLiteral(
"saveDateTime" ), mSaveDateTime.toString( Qt::ISODate ) );
3225 mSaveUserFull.clear();
3226 mSaveDateTime = QDateTime();
3228 doc->appendChild( qgisNode );
3231 QDomElement homePathNode = doc->createElement( QStringLiteral(
"homePath" ) );
3232 homePathNode.setAttribute( QStringLiteral(
"path" ), mHomePath );
3233 qgisNode.appendChild( homePathNode );
3236 QDomElement titleNode = doc->createElement( QStringLiteral(
"title" ) );
3237 qgisNode.appendChild( titleNode );
3239 QDomElement transactionNode = doc->createElement( QStringLiteral(
"transaction" ) );
3240 transactionNode.setAttribute( QStringLiteral(
"mode" ),
qgsEnumValueToKey( mTransactionMode ) );
3241 qgisNode.appendChild( transactionNode );
3243 QDomElement flagsNode = doc->createElement( QStringLiteral(
"projectFlags" ) );
3245 qgisNode.appendChild( flagsNode );
3247 const QDomText titleText = doc->createTextNode(
title() );
3248 titleNode.appendChild( titleText );
3252 QDomElement srsNode = doc->createElement( QStringLiteral(
"projectCrs" ) );
3254 qgisNode.appendChild( srsNode );
3257 QDomElement verticalSrsNode = doc->createElement( QStringLiteral(
"verticalCrs" ) );
3258 mVerticalCrs.
writeXml( verticalSrsNode, *doc );
3259 qgisNode.appendChild( verticalSrsNode );
3262 QDomElement elevationShadingNode = doc->createElement( QStringLiteral(
"elevation-shading-renderer" ) );
3263 mElevationShadingRenderer.
writeXml( elevationShadingNode, context );
3264 qgisNode.appendChild( elevationShadingNode );
3271 clonedRoot->
writeXml( qgisNode, context );
3275 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsMode" ),
static_cast<int>( mAvoidIntersectionsMode ) );
3283 QDomElement annotationLayerNode = doc->createElement( QStringLiteral(
"main-annotation-layer" ) );
3284 mMainAnnotationLayer->
writeLayerXml( annotationLayerNode, *doc, context );
3285 qgisNode.appendChild( annotationLayerNode );
3289 QDomElement projectLayersNode = doc->createElement( QStringLiteral(
"projectlayers" ) );
3291 QMap<QString, QgsMapLayer *>::ConstIterator li =
layers.constBegin();
3292 while ( li !=
layers.end() )
3298 const QHash< QString, QPair< QString, bool> >::const_iterator emIt = mEmbeddedLayers.constFind( ml->
id() );
3299 if ( emIt == mEmbeddedLayers.constEnd() )
3301 QDomElement maplayerElem;
3307 maplayerElem = doc->createElement( QStringLiteral(
"maplayer" ) );
3311 maplayerElem.setAttribute( QStringLiteral(
"editable" ), QStringLiteral(
"1" ) );
3315 QDomDocument document;
3318 maplayerElem = document.firstChildElement();
3322 QgsDebugError( QStringLiteral(
"Could not restore layer properties for layer %1" ).arg( ml->
id() ) );
3328 projectLayersNode.appendChild( maplayerElem );
3334 if ( emIt.value().second )
3336 QDomElement mapLayerElem = doc->createElement( QStringLiteral(
"maplayer" ) );
3337 mapLayerElem.setAttribute( QStringLiteral(
"embedded" ), 1 );
3338 mapLayerElem.setAttribute( QStringLiteral(
"project" ),
writePath( emIt.value().first ) );
3339 mapLayerElem.setAttribute( QStringLiteral(
"id" ), ml->
id() );
3340 projectLayersNode.appendChild( mapLayerElem );
3347 qgisNode.appendChild( projectLayersNode );
3349 QDomElement layerOrderNode = doc->createElement( QStringLiteral(
"layerorder" ) );
3351 for (
QgsMapLayer *layer : constCustomLayerOrder )
3353 QDomElement mapLayerElem = doc->createElement( QStringLiteral(
"layer" ) );
3354 mapLayerElem.setAttribute( QStringLiteral(
"id" ), layer->id() );
3355 layerOrderNode.appendChild( mapLayerElem );
3357 qgisNode.appendChild( layerOrderNode );
3359 mLabelingEngineSettings->writeSettingsToProject(
this );
3361 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorRedPart" ), mBackgroundColor.red() );
3362 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorGreenPart" ), mBackgroundColor.green() );
3363 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorBluePart" ), mBackgroundColor.blue() );
3365 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorRedPart" ), mSelectionColor.red() );
3366 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorGreenPart" ), mSelectionColor.green() );
3367 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorBluePart" ), mSelectionColor.blue() );
3368 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorAlphaPart" ), mSelectionColor.alpha() );
3375 dump_( mProperties );
3378 QgsDebugMsgLevel( QStringLiteral(
"there are %1 property scopes" ).arg(
static_cast<int>( mProperties.
count() ) ), 2 );
3383 mProperties.
writeXml( QStringLiteral(
"properties" ), qgisNode, *doc );
3386 QDomElement ddElem = doc->createElement( QStringLiteral(
"dataDefinedServerProperties" ) );
3387 mDataDefinedServerProperties.
writeXml( ddElem, dataDefinedServerPropertyDefinitions() );
3388 qgisNode.appendChild( ddElem );
3390 mMapThemeCollection->writeXml( *doc );
3392 mTransformContext.
writeXml( qgisNode, context );
3394 QDomElement metadataElem = doc->createElement( QStringLiteral(
"projectMetadata" ) );
3396 qgisNode.appendChild( metadataElem );
3399 const QDomElement annotationsElem = mAnnotationManager->writeXml( *doc, context );
3400 qgisNode.appendChild( annotationsElem );
3404 const QDomElement layoutElem = mLayoutManager->writeXml( *doc );
3405 qgisNode.appendChild( layoutElem );
3409 const QDomElement views3DElem = m3DViewsManager->writeXml( *doc );
3410 qgisNode.appendChild( views3DElem );
3414 const QDomElement bookmarkElem = mBookmarkManager->
writeXml( *doc );
3415 qgisNode.appendChild( bookmarkElem );
3419 const QDomElement sensorElem = mSensorManager->
writeXml( *doc );
3420 qgisNode.appendChild( sensorElem );
3424 const QDomElement viewSettingsElem = mViewSettings->
writeXml( *doc, context );
3425 qgisNode.appendChild( viewSettingsElem );
3429 const QDomElement styleSettingsElem = mStyleSettings->
writeXml( *doc, context );
3430 qgisNode.appendChild( styleSettingsElem );
3434 const QDomElement timeSettingsElement = mTimeSettings->
writeXml( *doc, context );
3435 qgisNode.appendChild( timeSettingsElement );
3439 const QDomElement elevationPropertiesElement = mElevationProperties->
writeXml( *doc, context );
3440 qgisNode.appendChild( elevationPropertiesElement );
3444 const QDomElement displaySettingsElem = mDisplaySettings->
writeXml( *doc, context );
3445 qgisNode.appendChild( displaySettingsElem );
3449 const QDomElement gpsSettingsElem = mGpsSettings->
writeXml( *doc, context );
3450 qgisNode.appendChild( gpsSettingsElem );
3459 QFile backupFile( QStringLiteral(
"%1~" ).arg( filename ) );
3461 ok &= backupFile.open( QIODevice::WriteOnly | QIODevice::Truncate );
3462 ok &= projectFile.open( QIODevice::ReadOnly );
3465 while ( ok && !projectFile.atEnd() )
3467 ba = projectFile.read( 10240 );
3468 ok &= backupFile.write( ba ) == ba.size();
3471 projectFile.close();
3476 setError( tr(
"Unable to create backup file %1" ).arg( backupFile.fileName() ) );
3481 struct utimbuf tb = {
static_cast<time_t
>( fi.lastRead().toSecsSinceEpoch() ),
static_cast<time_t
>( fi.lastModified().toSecsSinceEpoch() ) };
3482 utime( backupFile.fileName().toUtf8().constData(), &tb );
3485 if ( !projectFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
3487 projectFile.close();
3490 setError( tr(
"Unable to save to file %1" ).arg( projectFile.fileName() ) );
3494 QTemporaryFile tempFile;
3495 bool ok = tempFile.open();
3498 QTextStream projectFileStream( &tempFile );
3499 doc->save( projectFileStream, 2 );
3500 ok &= projectFileStream.pos() > -1;
3502 ok &= tempFile.seek( 0 );
3505 while ( ok && !tempFile.atEnd() )
3507 ba = tempFile.read( 10240 );
3508 ok &= projectFile.write( ba ) == ba.size();
3511 ok &= projectFile.error() == QFile::NoError;
3513 projectFile.close();
3520 setError( tr(
"Unable to save to file %1. Your project "
3521 "may be corrupted on disk. Try clearing some space on the volume and "
3522 "check file permissions before pressing save again." )
3523 .arg( projectFile.fileName() ) );
3537 bool propertiesModified;
3538 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3540 if ( propertiesModified )
3550 bool propertiesModified;
3551 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3553 if ( propertiesModified )
3563 bool propertiesModified;
3564 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3566 if ( propertiesModified )
3576 bool propertiesModified;
3577 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3579 if ( propertiesModified )
3589 bool propertiesModified;
3590 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3592 if ( propertiesModified )
3600 const QStringList &def,
3612 value =
property->value();
3614 const bool valid = QMetaType::Type::QStringList == value.userType();
3620 return value.toStringList();
3643 value =
property->value();
3645 const bool valid = value.canConvert( QMetaType::Type::QString );
3650 return value.toString();
3669 value =
property->value();
3672 const bool valid = value.canConvert( QMetaType::Type::Int );
3681 return value.toInt();
3696 const QVariant value =
property->value();
3698 const bool valid = value.canConvert( QMetaType::Type::Double );
3703 return value.toDouble();
3720 const QVariant value =
property->value();
3722 const bool valid = value.canConvert( QMetaType::Type::Bool );
3727 return value.toBool();
3739 if (
findKey_( scope, key, mProperties ) )
3745 return !
findKey_( scope, key, mProperties );
3754 QStringList entries;
3756 if ( foundProperty )
3773 QStringList entries;
3775 if ( foundProperty )
3790 dump_( mProperties );
3810 filePath = storage->filePath( mFile.fileName() );
3837void QgsProject::setError(
const QString &errorMessage )
3841 mErrorMessage = errorMessage;
3848 return mErrorMessage;
3851void QgsProject::clearError()
3855 setError( QString() );
3862 delete mBadLayerHandler;
3863 mBadLayerHandler = handler;
3870 const QHash< QString, QPair< QString, bool > >::const_iterator it = mEmbeddedLayers.find(
id );
3871 if ( it == mEmbeddedLayers.constEnd() )
3875 return it.value().first;
3885 static QString sPrevProjectFilePath;
3886 static QDateTime sPrevProjectFileTimestamp;
3887 static QDomDocument sProjectDocument;
3889 QString qgsProjectFile = projectFilePath;
3891 if ( projectFilePath.endsWith( QLatin1String(
".qgz" ), Qt::CaseInsensitive ) )
3893 archive.
unzip( projectFilePath );
3897 const QDateTime projectFileTimestamp = QFileInfo( projectFilePath ).lastModified();
3899 if ( projectFilePath != sPrevProjectFilePath || projectFileTimestamp != sPrevProjectFileTimestamp )
3901 sPrevProjectFilePath.clear();
3903 QFile projectFile( qgsProjectFile );
3904 if ( !projectFile.open( QIODevice::ReadOnly ) )
3909 if ( !sProjectDocument.setContent( &projectFile ) )
3914 sPrevProjectFilePath = projectFilePath;
3915 sPrevProjectFileTimestamp = projectFileTimestamp;
3919 bool useAbsolutePaths =
true;
3921 const QDomElement propertiesElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral(
"properties" ) );
3922 if ( !propertiesElem.isNull() )
3924 const QDomElement absElem = propertiesElem.firstChildElement( QStringLiteral(
"Paths" ) ).firstChildElement( QStringLiteral(
"Absolute" ) );
3925 if ( !absElem.isNull() )
3927 useAbsolutePaths = absElem.text().compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0;
3932 if ( !useAbsolutePaths )
3937 const QDomElement projectLayersElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral(
"projectlayers" ) );
3938 if ( projectLayersElem.isNull() )
3943 QDomElement mapLayerElem = projectLayersElem.firstChildElement( QStringLiteral(
"maplayer" ) );
3944 while ( ! mapLayerElem.isNull() )
3947 const QString
id = mapLayerElem.firstChildElement( QStringLiteral(
"id" ) ).text();
3948 if (
id == layerId )
3951 if ( mapLayerElem.attribute( QStringLiteral(
"embedded" ) ) == QLatin1String(
"1" ) )
3956 mEmbeddedLayers.insert( layerId, qMakePair( projectFilePath, saveFlag ) );
3958 if ( addLayer( mapLayerElem, brokenNodes, embeddedContext,
flags ) )
3964 mEmbeddedLayers.remove( layerId );
3968 mapLayerElem = mapLayerElem.nextSiblingElement( QStringLiteral(
"maplayer" ) );
3978 QString qgsProjectFile = projectFilePath;
3980 if ( projectFilePath.endsWith( QLatin1String(
".qgz" ), Qt::CaseInsensitive ) )
3982 archive.
unzip( projectFilePath );
3987 QFile projectFile( qgsProjectFile );
3988 if ( !projectFile.open( QIODevice::ReadOnly ) )
3993 QDomDocument projectDocument;
3994 if ( !projectDocument.setContent( &projectFile ) )
4006 QDomElement layerTreeElem = projectDocument.documentElement().firstChildElement( QStringLiteral(
"layer-tree-group" ) );
4007 if ( !layerTreeElem.isNull() )
4017 if ( !group || group->
customProperty( QStringLiteral(
"embedded" ) ).toBool() )
4030 newGroup->
setCustomProperty( QStringLiteral(
"embedded_project" ), projectFilePath );
4033 mLayerTreeRegistryBridge->
setEnabled(
false );
4034 initializeEmbeddedSubtree( projectFilePath, newGroup,
flags );
4035 mLayerTreeRegistryBridge->
setEnabled(
true );
4038 const auto constFindLayerIds = newGroup->
findLayerIds();
4039 for (
const QString &layerId : constFindLayerIds )
4056 const auto constChildren = group->
children();
4060 child->setCustomProperty( QStringLiteral(
"embedded" ), 1 );
4069 QList<QDomNode> brokenNodes;
4093 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/TopologicalEditing" ), ( enabled ? 1 : 0 ) );
4101 return readNumEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/TopologicalEditing" ), 0 );
4108 if ( mDistanceUnits == unit )
4111 mDistanceUnits = unit;
4120 if ( mAreaUnits == unit )
4133 if ( !mCachedHomePath.isEmpty() )
4134 return mCachedHomePath;
4138 if ( !mHomePath.isEmpty() )
4140 const QFileInfo homeInfo( mHomePath );
4141 if ( !homeInfo.isRelative() )
4143 mCachedHomePath = mHomePath;
4153 const QString storagePath { storage->filePath(
fileName() ) };
4154 if ( ! storagePath.isEmpty() && QFileInfo::exists( storagePath ) )
4156 mCachedHomePath = QFileInfo( storagePath ).path();
4157 return mCachedHomePath;
4161 mCachedHomePath = pfi.path();
4162 return mCachedHomePath;
4165 if ( !pfi.exists() )
4167 mCachedHomePath = mHomePath;
4171 if ( !mHomePath.isEmpty() )
4174 mCachedHomePath = QDir::cleanPath( pfi.path() +
'/' + mHomePath );
4178 mCachedHomePath = pfi.canonicalPath();
4180 return mCachedHomePath;
4195 return mRelationManager;
4202 return mLayoutManager.get();
4209 return mLayoutManager.get();
4216 return m3DViewsManager.get();
4223 return m3DViewsManager.get();
4230 return mBookmarkManager;
4237 return mBookmarkManager;
4244 return mSensorManager;
4251 return mSensorManager;
4258 return mViewSettings;
4265 return mViewSettings;
4272 return mStyleSettings;
4280 return mStyleSettings;
4287 return mTimeSettings;
4294 return mTimeSettings;
4301 return mElevationProperties;
4308 return mElevationProperties;
4315 return mDisplaySettings;
4322 return mDisplaySettings;
4329 return mGpsSettings;
4336 return mGpsSettings;
4350 return mMapThemeCollection.get();
4357 return mAnnotationManager.get();
4364 return mAnnotationManager.get();
4371 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
4372 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
4377 if (
layers.contains( it.value() ) )
4378 it.value()->setFlags( it.value()->flags() &
~QgsMapLayer::Identifiable );
4394 for (
const QString &layerId : layerIds )
4412 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
4446 updateTransactionGroups();
4453 return mTransactionMode;
4464 const auto constLayers =
mapLayers().values();
4467 if ( layer->isEditable() )
4469 QgsLogger::warning( tr(
"Transaction mode can be changed only if all layers are not editable." ) );
4475 updateTransactionGroups();
4484 return mTransactionGroups;
4497 return mLayerStore->count();
4504 return mLayerStore->validCount();
4512 return mLayerStore->mapLayer( layerId );
4519 return mLayerStore->mapLayersByName( layerName );
4526 QList<QgsMapLayer *>
layers;
4527 const auto constMapLayers { mLayerStore->mapLayers() };
4528 for (
const auto &l : constMapLayers )
4530 if ( ! l->serverProperties()->shortName().isEmpty() )
4532 if ( l->serverProperties()->shortName() == shortName )
4535 else if ( l->name() == shortName )
4551 if ( !archive->unzip( filename ) )
4553 setError( tr(
"Unable to unzip file '%1'" ).arg( filename ) );
4558 if ( archive->projectFile().isEmpty() )
4560 setError( tr(
"Zip archive does not provide a project file" ) );
4565 releaseHandlesToProjectArchive();
4566 mArchive = std::move( archive );
4583 setError( tr(
"Cannot read unzipped qgs project file" ) + QStringLiteral(
": " ) +
error() );
4593bool QgsProject::zip(
const QString &filename )
4601 const QString
baseName = QFileInfo( filename ).baseName();
4602 const QString qgsFileName = QStringLiteral(
"%1.qgs" ).arg(
baseName );
4603 QFile qgsFile( QDir( archive->dir() ).filePath( qgsFileName ) );
4605 bool writeOk =
false;
4606 if ( qgsFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
4608 writeOk = writeProjectFile( qgsFile.fileName() );
4615 setError( tr(
"Unable to write temporary qgs file" ) );
4620 const QFileInfo info( qgsFile );
4622 const QString asFileName = info.path() + QDir::separator() + info.completeBaseName() + asExt;
4624 bool auxiliaryStorageSavedOk =
true;
4625 if ( ! saveAuxiliaryStorage( asFileName ) )
4627 const QString err = mAuxiliaryStorage->errorString();
4628 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 ) );
4629 auxiliaryStorageSavedOk =
false;
4632 if ( !mArchive->exists() )
4634 releaseHandlesToProjectArchive();
4636 mArchive->unzip( mFile.fileName() );
4639 const QString auxiliaryStorageFile =
static_cast<QgsProjectArchive *
>( mArchive.get() )->auxiliaryStorageFile();
4640 if ( ! auxiliaryStorageFile.isEmpty() )
4642 archive->
addFile( auxiliaryStorageFile );
4651 if ( QFile::exists( asFileName ) )
4653 archive->addFile( asFileName );
4658 archive->addFile( qgsFile.fileName() );
4661 const QStringList &
files = mArchive->files();
4662 for (
const QString &file :
files )
4664 if ( !file.endsWith( QLatin1String(
".qgs" ), Qt::CaseInsensitive ) && !file.endsWith( asExt, Qt::CaseInsensitive ) )
4666 archive->addFile( file );
4672 if ( !archive->zip( filename ) )
4674 setError( tr(
"Unable to perform zip" ) );
4678 return auxiliaryStorageSavedOk && zipOk;
4689 const QList<QgsMapLayer *> &layers,
4691 bool takeOwnership )
4695 const QList<QgsMapLayer *> myResultList { mLayerStore->addMapLayers(
layers, takeOwnership ) };
4696 if ( !myResultList.isEmpty() )
4699 for (
auto &l : myResultList )
4709 if ( mAuxiliaryStorage )
4724 mProjectScope.reset();
4726 return myResultList;
4732 bool takeOwnership )
4736 QList<QgsMapLayer *> addedLayers;
4737 addedLayers =
addMapLayers( QList<QgsMapLayer *>() << layer, addToLegend, takeOwnership );
4738 return addedLayers.isEmpty() ? nullptr : addedLayers[0];
4741void QgsProject::removeAuxiliaryLayer(
const QgsMapLayer *ml )
4748 const QgsVectorLayer *vl = qobject_cast<const QgsVectorLayer *>( ml );
4760 for (
const auto &layerId : layerIds )
4761 removeAuxiliaryLayer( mLayerStore->mapLayer( layerId ) );
4763 mProjectScope.reset();
4764 mLayerStore->removeMapLayers( layerIds );
4771 for (
const auto &layer :
layers )
4772 removeAuxiliaryLayer( layer );
4774 mProjectScope.reset();
4775 mLayerStore->removeMapLayers(
layers );
4782 removeAuxiliaryLayer( mLayerStore->mapLayer( layerId ) );
4783 mProjectScope.reset();
4784 mLayerStore->removeMapLayer( layerId );
4791 removeAuxiliaryLayer( layer );
4792 mProjectScope.reset();
4793 mLayerStore->removeMapLayer( layer );
4800 mProjectScope.reset();
4801 return mLayerStore->takeMapLayer( layer );
4808 return mMainAnnotationLayer;
4815 if ( mLayerStore->count() == 0 )
4818 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
4819 mProjectScope.reset();
4820 mLayerStore->removeAllMapLayers();
4822 snapSingleBlocker.release();
4824 if ( !mBlockSnappingUpdates )
4832 const QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
4833 QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin();
4834 for ( ; it !=
layers.constEnd(); ++it )
4836 it.value()->reload();
4845 return validOnly ? mLayerStore->validMapLayers() : mLayerStore->mapLayers();
4852 return mTransactionGroups.value( qMakePair( providerKey, connString ) );
4859 return &mEditBufferGroup;
4870 if ( mSettings.
value( QStringLiteral(
"/projections/unknownCrsBehavior" ), QStringLiteral(
"NoAction" ),
QgsSettings::App ).toString() == QStringLiteral(
"UseProjectCrs" )
4871 || mSettings.
value( QStringLiteral(
"/projections/unknownCrsBehavior" ), 0,
QgsSettings::App ).toString() == QLatin1String(
"2" ) )
4879 const QString layerDefaultCrs = mSettings.
value( QStringLiteral(
"/Projections/layerDefaultCrs" ),
geoEpsgCrsAuthId() ).toString();
4900bool QgsProject::saveAuxiliaryStorage(
const QString &filename )
4906 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
4911 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() );
4919 if ( !mAuxiliaryStorage->exists( *
this ) && empty )
4923 else if ( !filename.isEmpty() )
4925 return mAuxiliaryStorage->saveAs( filename );
4929 return mAuxiliaryStorage->saveAs( *
this );
4942 return sPropertyDefinitions;
4955 return mAuxiliaryStorage.get();
4962 return mAuxiliaryStorage.get();
4969 const QDir archiveDir( mArchive->dir() );
4970 QTemporaryFile tmpFile( archiveDir.filePath(
"XXXXXX_" + nameTemplate ),
this );
4971 tmpFile.setAutoRemove(
false );
4973 mArchive->addFile( tmpFile.fileName() );
4974 return tmpFile.fileName();
4981 QStringList attachments;
4983 const QStringList files = mArchive->files();
4984 attachments.reserve( files.size() );
4985 for (
const QString &file : files )
4987 if ( QFileInfo( file ).baseName() !=
baseName )
4989 attachments.append( file );
4999 return mArchive->removeFile( path );
5006 return QStringLiteral(
"attachment:///%1" ).arg( QFileInfo( attachedFile ).
fileName() );
5013 if ( identifier.startsWith( QLatin1String(
"attachment:///" ) ) )
5015 return QDir( mArchive->dir() ).absoluteFilePath( identifier.mid( 14 ) );
5036 mProjectScope.reset();
5050 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5064 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
5065 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
5070 if (
layers.contains( it.value() ) )
5071 it.value()->setFlags( it.value()->flags() &
~QgsMapLayer::Removable );
5082 QStringList customColors;
5083 QStringList customColorLabels;
5085 QgsNamedColorList::const_iterator colorIt = colors.constBegin();
5086 for ( ; colorIt != colors.constEnd(); ++colorIt )
5089 const QString label = ( *colorIt ).second;
5090 customColors.append( color );
5091 customColorLabels.append( label );
5093 writeEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Colors" ), customColors );
5094 writeEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Labels" ), customColorLabels );
5095 mProjectScope.reset();
5103 if ( mBackgroundColor == color )
5106 mBackgroundColor = color;
5114 return mBackgroundColor;
5121 if ( mSelectionColor == color )
5124 mSelectionColor = color;
5132 return mSelectionColor;
5169 translationContext.setFileName( QStringLiteral(
"%1/%2.ts" ).arg(
absolutePath(),
baseName() ) );
5173 translationContext.writeTsFile( locale );
5176QString
QgsProject::translate(
const QString &context,
const QString &sourceText,
const char *disambiguation,
int n )
const
5185 QString result = mTranslator->translate( context.toUtf8(), sourceText.toUtf8(), disambiguation, n );
5187 if ( result.isEmpty() )
5201 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5206 if ( !( ( *it )->accept( visitor ) ) )
5215 if ( !mLayoutManager->accept( visitor ) )
5218 if ( !mAnnotationManager->accept( visitor ) )
5226 return mElevationShadingRenderer;
5229void QgsProject::loadProjectFlags(
const QDomDocument *doc )
5233 QDomElement element = doc->documentElement().firstChildElement( QStringLiteral(
"projectFlags" ) );
5235 if ( !element.isNull() )
5242 element = doc->documentElement().firstChildElement( QStringLiteral(
"evaluateDefaultValues" ) );
5243 if ( !element.isNull() )
5245 if ( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
5250 element = doc->documentElement().firstChildElement( QStringLiteral(
"trust" ) );
5251 if ( !element.isNull() )
5253 if ( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
5262GetNamedProjectColor::GetNamedProjectColor(
const QgsProject *project )
5269 QStringList colorStrings = project->
readListEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Colors" ) );
5270 const QStringList colorLabels = project->
readListEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Labels" ) );
5274 for ( QStringList::iterator it = colorStrings.begin();
5275 it != colorStrings.end(); ++it )
5279 if ( colorLabels.length() > colorIndex )
5281 label = colorLabels.at( colorIndex );
5284 mColors.insert( label.toLower(), color );
5289GetNamedProjectColor::GetNamedProjectColor(
const QHash<QString, QColor> &colors )
5297 const QString colorName = values.at( 0 ).toString().toLower();
5298 if ( mColors.contains( colorName ) )
5300 return QStringLiteral(
"%1,%2,%3" ).arg( mColors.value( colorName ).red() ).arg( mColors.value( colorName ).green() ).arg( mColors.value( colorName ).blue() );
5308 return new GetNamedProjectColor( mColors );
5313GetSensorData::GetSensorData(
const QMap<QString, QgsAbstractSensor::SensorData> &sensorData )
5316 QStringLiteral(
"Sensors" ) )
5317 , mSensorData( sensorData )
5323 const QString sensorName = values.at( 0 ).toString();
5324 const int expiration = values.at( 1 ).toInt();
5325 const qint64 timestamp = QDateTime::currentMSecsSinceEpoch();
5326 if ( mSensorData.contains( sensorName ) )
5328 if ( expiration <= 0 || ( timestamp - mSensorData[sensorName].lastTimestamp.toMSecsSinceEpoch() ) < expiration )
5330 return mSensorData[sensorName].lastValue;
5339 return new GetSensorData( mSensorData );
@ DontLoad3DViews
Skip loading 3D views (since QGIS 3.26)
@ 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. (since QGIS 3.28)
@ TrustLayerMetadata
Trust layer metadata. Improves project read time. Do not use it if layers' extent is not fixed during...
@ 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.
@ 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...
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.
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 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.
@ ParallelThreadLoading
Skip credentials if the provided one are not valid, let the provider be invalid, avoiding to block th...
QFlags< ReadFlag > ReadFlags
@ 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.
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.
static QgsDataProvider::ReadFlags providerReadFlags(const QDomNode &layerNode, QgsMapLayer::ReadFlags layerReadFlags)
Returns provider read flag deduced from layer read flags layerReadFlags and a dom node layerNode that...
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 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.
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 the project with QTranslator and qm file.
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...
Q_DECL_DEPRECATED void oldProjectVersionWarning(const QString &)
Emitted when an old project file is read.
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.
void readProject(const QDomDocument &)
Emitted when a project is being read.
QString originalPath() const
Returns the original path associated with the project.
void setOriginalPath(const QString &path)
Sets the original path associated with the project.
void dumpProperties() const
Dump out current project properties to stderr.
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
void readProjectWithContext(const QDomDocument &, QgsReadWriteContext &context)
Emitted when a project is being read.
QgsMapLayer * addMapLayer(QgsMapLayer *mapLayer, bool addToLegend=true, bool takeOwnership=true)
Add a layer to the map of loaded layers.
QStringList nonIdentifiableLayers
void 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 writeProject(QDomDocument &)
Emitted when the project is being written.
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 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 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...
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.
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.
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.
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.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
This is a container for configuration of the snapping of the project.
bool addLayers(const QList< QgsMapLayer * > &layers)
Adds the specified layers as individual layers to the configuration with standard configuration.
void readProject(const QDomDocument &doc)
Reads the configuration from the specified QGIS project document.
void reset()
reset to default values
void writeProject(QDomDocument &doc)
Writes the configuration to the specified QGIS project document.
void clearIndividualLayerSettings()
Removes all individual layer snapping settings.
bool removeLayers(const QList< QgsMapLayer * > &layers)
Removes the specified layers from the individual layer configuration.
An interface for classes which can visit style entity (e.g.
virtual bool visitExit(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor stops visiting a node.
virtual bool visitEnter(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor starts visiting a node.
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
QgsDataProvider::ReadFlags 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.