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 )
556 Qgis::ProjectFlags newFlags = mFlags;
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 );
951 writeEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectionsEnabled" ),
crs.
isValid() ? 1 : 0 );
952 mProjectScope.reset();
963 if ( adjustEllipsoid )
972 if ( !
crs().isValid() )
975 return readEntry( QStringLiteral(
"Measure" ), QStringLiteral(
"/Ellipsoid" ),
geoNone() );
982 if (
ellipsoid ==
readEntry( QStringLiteral(
"Measure" ), QStringLiteral(
"/Ellipsoid" ) ) )
985 mProjectScope.reset();
995 return mTransformContext;
1002 if ( context == mTransformContext )
1005 mTransformContext = context;
1006 mProjectScope.reset();
1009 for (
auto &layer : mLayerStore.get()->mapLayers() )
1011 layer->setTransformContext( context );
1020 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
1024 mProjectScope.reset();
1025 mFile.setFileName( QString() );
1028 mSaveUserFull.clear();
1029 mSaveDateTime = QDateTime();
1032 mCachedHomePath.clear();
1034 mFlags = Qgis::ProjectFlags();
1036 mCustomVariables.clear();
1040 if ( !mSettings.
value( QStringLiteral(
"projects/anonymize_new_projects" ),
false,
QgsSettings::Core ).toBool() )
1059 mEmbeddedLayers.clear();
1060 mRelationManager->
clear();
1061 mAnnotationManager->clear();
1062 mLayoutManager->clear();
1063 m3DViewsManager->clear();
1064 mBookmarkManager->
clear();
1065 mSensorManager->
clear();
1066 mViewSettings->
reset();
1067 mTimeSettings->
reset();
1068 mElevationProperties->
reset();
1069 mDisplaySettings->
reset();
1070 mGpsSettings->
reset();
1071 mSnappingConfig.
reset();
1079 mLabelingEngineSettings->clear();
1083 releaseHandlesToProjectArchive();
1089 mStyleSettings->
reset();
1093 if ( !mIsBeingDeleted )
1101 writeEntry( QStringLiteral(
"PositionPrecision" ), QStringLiteral(
"/Automatic" ),
true );
1102 writeEntry( QStringLiteral(
"PositionPrecision" ), QStringLiteral(
"/DecimalPlaces" ), 2 );
1104 const bool defaultRelativePaths = mSettings.
value( QStringLiteral(
"/qgis/defaultProjectPathsRelative" ),
true ).toBool();
1107 int red = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_red" ), 255 ).toInt();
1108 int green = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_green" ), 255 ).toInt();
1109 int blue = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_blue" ), 255 ).toInt();
1112 red = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_red" ), 255 ).toInt();
1113 green = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_green" ), 255 ).toInt();
1114 blue = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_blue" ), 0 ).toInt();
1115 const int alpha = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_alpha" ), 255 ).toInt();
1121 mRootGroup->
clear();
1122 if ( mMainAnnotationLayer )
1123 mMainAnnotationLayer->
reset();
1125 snapSingleBlocker.release();
1127 if ( !mBlockSnappingUpdates )
1139 topQgsPropertyKey.
dump();
1172 const QDomElement propertiesElem = doc.documentElement().firstChildElement( QStringLiteral(
"properties" ) );
1174 if ( propertiesElem.isNull() )
1179 const QDomNodeList scopes = propertiesElem.childNodes();
1181 if ( propertiesElem.firstChild().isNull() )
1183 QgsDebugError( QStringLiteral(
"empty ``properties'' XML tag ... bailing" ) );
1187 if ( ! project_properties.
readXml( propertiesElem ) )
1189 QgsDebugError( QStringLiteral(
"Project_properties.readXml() failed" ) );
1203 const QDomElement ddElem = doc.documentElement().firstChildElement( QStringLiteral(
"dataDefinedServerProperties" ) );
1204 if ( !ddElem.isNull() )
1206 if ( !ddServerProperties.
readXml( ddElem, dataDefinedServerPropertyDefinitions ) )
1208 QgsDebugError( QStringLiteral(
"dataDefinedServerProperties.readXml() failed" ) );
1211 return ddServerProperties;
1218static void _getTitle(
const QDomDocument &doc, QString &title )
1220 const QDomElement titleNode = doc.documentElement().firstChildElement( QStringLiteral(
"title" ) );
1224 if ( titleNode.isNull() )
1230 if ( !titleNode.hasChildNodes() )
1236 const QDomNode titleTextNode = titleNode.firstChild();
1238 if ( !titleTextNode.isText() )
1244 const QDomText titleText = titleTextNode.toText();
1246 title = titleText.data();
1250static void readProjectFileMetadata(
const QDomDocument &doc, QString &lastUser, QString &lastUserFull, QDateTime &lastSaveDateTime )
1252 const QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"qgis" ) );
1256 QgsDebugError( QStringLiteral(
"unable to find qgis element" ) );
1260 const QDomNode qgisNode = nl.item( 0 );
1262 const QDomElement qgisElement = qgisNode.toElement();
1263 lastUser = qgisElement.attribute( QStringLiteral(
"saveUser" ), QString() );
1264 lastUserFull = qgisElement.attribute( QStringLiteral(
"saveUserFull" ), QString() );
1265 lastSaveDateTime = QDateTime::fromString( qgisElement.attribute( QStringLiteral(
"saveDateTime" ), QString() ), Qt::ISODate );
1270 const QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"qgis" ) );
1274 QgsDebugError( QStringLiteral(
" unable to find qgis element in project file" ) );
1278 const QDomNode qgisNode = nl.item( 0 );
1280 const QDomElement qgisElement = qgisNode.toElement();
1281 QgsProjectVersion projectVersion( qgisElement.attribute( QStringLiteral(
"version" ) ) );
1282 return projectVersion;
1289 return mSnappingConfig;
1308 if ( mAvoidIntersectionsMode == mode )
1311 mAvoidIntersectionsMode = mode;
1315static QgsMapLayer::ReadFlags projectFlagsToLayerReadFlags( Qgis::ProjectReadFlags projectReadFlags, Qgis::ProjectFlags projectFlags )
1317 QgsMapLayer::ReadFlags layerFlags = QgsMapLayer::ReadFlags();
1340void QgsProject::preloadProviders(
const QVector<QDomNode> ¶llelLayerNodes,
1342 QMap<QString, QgsDataProvider *> &loadedProviders,
1343 QgsMapLayer::ReadFlags layerReadFlags,
1344 int totalProviderCount )
1349 QMap<QString, LayerToLoad> layersToLoad;
1351 for (
const QDomNode &node : parallelLayerNodes )
1355 const QDomElement layerElement = node.toElement();
1357 layerToLoad.
layerId = layerElement.namedItem( QStringLiteral(
"id" ) ).toElement().text();
1358 layerToLoad.
provider = layerElement.namedItem( QStringLiteral(
"provider" ) ).toElement().text();
1359 layerToLoad.
dataSource = layerElement.namedItem( QStringLiteral(
"datasource" ) ).toElement().text();
1370 layersToLoad.insert( layerToLoad.
layerId, layerToLoad );
1373 while ( !layersToLoad.isEmpty() )
1375 const QList<LayerToLoad> layersToAttemptInParallel = layersToLoad.values();
1376 QString layerToAttemptInMainThread;
1378 QHash<QString, QgsRunnableProviderCreator *> runnables;
1379 QThreadPool threadPool;
1382 for (
const LayerToLoad &lay : layersToAttemptInParallel )
1385 runnables.insert( lay.layerId, run );
1391 layersToLoad.remove( layId );
1394 Q_ASSERT( finishedRun );
1396 std::unique_ptr<QgsDataProvider> provider( finishedRun->
dataProvider() );
1397 Q_ASSERT( provider && provider->isValid() );
1399 loadedProviders.insert( layId, provider.release() );
1404 if ( layerToAttemptInMainThread.isEmpty() )
1405 layerToAttemptInMainThread = layId;
1409 if ( i == parallelLayerNodes.count() || !isValid )
1412 threadPool.start( run );
1416 threadPool.waitForDone();
1418 qDeleteAll( runnables );
1421 auto it = layersToLoad.find( layerToAttemptInMainThread );
1422 if ( it != layersToLoad.end() )
1424 std::unique_ptr<QgsDataProvider> provider;
1428 QgsDataProvider::ReadFlags providerFlags = lay.
flags;
1434 if ( provider && provider->isValid() )
1439 layersToLoad.erase( it );
1442 loadedProviders.insert( layerId, provider.release() );
1450void QgsProject::releaseHandlesToProjectArchive()
1455bool QgsProject::_getMapLayers(
const QDomDocument &doc, QList<QDomNode> &brokenNodes, Qgis::ProjectReadFlags flags )
1462 QDomElement layerElement = doc.documentElement().firstChildElement( QStringLiteral(
"projectlayers" ) ).firstChildElement( QStringLiteral(
"maplayer" ) );
1466 if ( layerElement.isNull() )
1476 bool returnStatus =
true;
1479 while ( ! layerElement.isNull() )
1482 layerElement = layerElement.nextSiblingElement( QStringLiteral(
"maplayer" ) );
1488 if ( depSorter.hasCycle() )
1492 if ( depSorter.hasMissingDependency() )
1493 returnStatus =
false;
1497 const QVector<QDomNode> sortedLayerNodes = depSorter.sortedLayerNodes();
1498 const int totalLayerCount = sortedLayerNodes.count();
1500 QVector<QDomNode> parallelLoading;
1501 QMap<QString, QgsDataProvider *> loadedProviders;
1505 profile.switchTask( tr(
"Load providers in parallel" ) );
1506 for (
const QDomNode &node : sortedLayerNodes )
1508 const QDomElement element = node.toElement();
1509 if ( element.attribute( QStringLiteral(
"embedded" ) ) != QLatin1String(
"1" ) )
1511 const QString layerId = node.namedItem( QStringLiteral(
"id" ) ).toElement().text();
1512 if ( !depSorter.isLayerDependent( layerId ) )
1514 const QDomNode mnl = element.namedItem( QStringLiteral(
"provider" ) );
1515 const QDomElement mne = mnl.toElement();
1516 const QString provider = mne.text();
1520 parallelLoading.append( node );
1529 if ( !parallelLoading.isEmpty() )
1530 preloadProviders( parallelLoading, context, loadedProviders, projectFlagsToLayerReadFlags(
flags, mFlags ), sortedLayerNodes.count() );
1533 int i = loadedProviders.count();
1534 for (
const QDomNode &node : std::as_const( sortedLayerNodes ) )
1536 const QDomElement element = node.toElement();
1537 const QString name =
translate( QStringLiteral(
"project:layers:%1" ).arg( node.namedItem( QStringLiteral(
"id" ) ).toElement().text() ), node.namedItem( QStringLiteral(
"layername" ) ).toElement().text() );
1538 if ( !name.isNull() )
1539 emit
loadingLayer( tr(
"Loading layer %1" ).arg( name ) );
1541 profile.switchTask( name );
1542 if ( element.attribute( QStringLiteral(
"embedded" ) ) == QLatin1String(
"1" ) )
1544 createEmbeddedLayer( element.attribute( QStringLiteral(
"id" ) ),
readPath( element.attribute( QStringLiteral(
"project" ) ) ), brokenNodes,
true,
flags );
1552 QString layerId = element.namedItem( QStringLiteral(
"id" ) ).toElement().text();
1554 if ( !addLayer( element, brokenNodes, context,
flags, loadedProviders.take( layerId ) ) )
1556 returnStatus =
false;
1559 if ( !messages.isEmpty() )
1568 return returnStatus;
1571bool QgsProject::addLayer(
const QDomElement &layerElem,
1572 QList<QDomNode> &brokenNodes,
1574 Qgis::ProjectReadFlags flags,
1579 const QString type = layerElem.attribute( QStringLiteral(
"type" ) );
1581 std::unique_ptr<QgsMapLayer>
mapLayer;
1589 QgsDebugError( QStringLiteral(
"Unknown layer type \"%1\"" ).arg( type ) );
1593 switch ( layerType )
1596 mapLayer = std::make_unique<QgsVectorLayer>();
1600 mapLayer = std::make_unique<QgsRasterLayer>();
1604 mapLayer = std::make_unique<QgsMeshLayer>();
1608 mapLayer = std::make_unique<QgsVectorTileLayer>();
1612 mapLayer = std::make_unique<QgsPointCloudLayer>();
1616 mapLayer = std::make_unique<QgsTiledSceneLayer>();
1621 const QString
typeName = layerElem.attribute( QStringLiteral(
"name" ) );
1629 mapLayer = std::make_unique<QgsAnnotationLayer>( QString(), options );
1636 mapLayer = std::make_unique<QgsGroupLayer>( QString(), options );
1643 QgsDebugError( QStringLiteral(
"Unable to create layer" ) );
1651 const QString layerId { layerElem.namedItem( QStringLiteral(
"id" ) ).toElement().text() };
1652 Q_ASSERT( ! layerId.isEmpty() );
1656 QgsMapLayer::ReadFlags layerFlags = projectFlagsToLayerReadFlags(
flags, mFlags );
1658 profile.switchTask( tr(
"Load layer source" ) );
1665 if ( vl->dataProvider() )
1672 profile.switchTask( tr(
"Add layer to project" ) );
1673 QList<QgsMapLayer *> newLayers;
1685 vLayer->joinBuffer()->resolveReferences(
this );
1694 brokenNodes.push_back( layerElem );
1697 const bool wasEditable = layerElem.attribute( QStringLiteral(
"editable" ), QStringLiteral(
"0" ) ).toInt();
1709 if ( ! layerWasStored )
1714 return layerIsValid;
1721 mFile.setFileName( filename );
1722 mCachedHomePath.clear();
1723 mProjectScope.reset();
1732 const QString filename = mFile.fileName();
1737 QTemporaryFile inDevice;
1738 if ( !inDevice.open() )
1740 setError( tr(
"Unable to open %1" ).arg( inDevice.fileName() ) );
1746 if ( !storage->readProject( filename, &inDevice, context ) )
1748 QString err = tr(
"Unable to open %1" ).arg( filename );
1749 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
1750 if ( !messages.isEmpty() )
1751 err += QStringLiteral(
"\n\n" ) + messages.last().message();
1755 returnValue = unzip( inDevice.fileName(),
flags );
1761 returnValue = unzip( mFile.fileName(),
flags );
1766 const QFileInfo finfo( mFile.fileName() );
1767 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( QStringLiteral(
"%1_attachments.zip" ).arg( finfo.completeBaseName() ) );
1768 if ( QFile( attachmentsZip ).exists() )
1770 std::unique_ptr<QgsArchive> archive(
new QgsArchive() );
1771 if ( archive->unzip( attachmentsZip ) )
1773 releaseHandlesToProjectArchive();
1774 mArchive = std::move( archive );
1777 returnValue = readProjectFile( mFile.fileName(),
flags );
1783 mFile.setFileName( filename );
1784 mCachedHomePath.clear();
1785 mProjectScope.reset();
1790 mTranslator.reset(
nullptr );
1797bool QgsProject::readProjectFile(
const QString &filename, Qgis::ProjectReadFlags flags )
1802 ScopedIntIncrementor snapSignalBlock( &mBlockSnappingUpdates );
1804 QFile projectFile( filename );
1812 if ( QFile( QStringLiteral(
"%1/%2.qm" ).arg( QFileInfo( projectFile.fileName() ).absolutePath(), localeFileName ) ).exists() )
1814 mTranslator.reset(
new QTranslator() );
1815 ( void )mTranslator->load( localeFileName, QFileInfo( projectFile.fileName() ).absolutePath() );
1818 profile.switchTask( tr(
"Reading project file" ) );
1819 std::unique_ptr<QDomDocument> doc(
new QDomDocument( QStringLiteral(
"qgis" ) ) );
1821 if ( !projectFile.open( QIODevice::ReadOnly | QIODevice::Text ) )
1823 projectFile.close();
1825 setError( tr(
"Unable to open %1" ).arg( projectFile.fileName() ) );
1830 QTextStream textStream( &projectFile );
1831#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1832 textStream.setCodec(
"UTF-8" );
1834 QString projectString = textStream.readAll();
1835 projectFile.close();
1837 for (
int i = 0; i < 32; i++ )
1839 if ( i == 9 || i == 10 || i == 13 )
1843 projectString.replace( QChar( i ), QStringLiteral(
"%1%2%1" ).arg(
FONTMARKER_CHR_FIX, QString::number( i ) ) );
1849 if ( !doc->setContent( projectString, &errorMsg, &line, &column ) )
1851 const QString errorString = tr(
"Project file read error in file %1: %2 at line %3 column %4" )
1852 .arg( projectFile.fileName(), errorMsg ).arg( line ).arg( column );
1854 setError( errorString );
1859 projectFile.close();
1867 profile.switchTask( tr(
"Updating project file" ) );
1868 if ( thisVersion > fileVersion )
1870 const bool isOlderMajorVersion = fileVersion.
majorVersion() < thisVersion.majorVersion();
1872 if ( isOlderMajorVersion )
1875 "version of qgis (saved in " + fileVersion.
text() +
1877 "). Problems may occur." );
1888 projectFile.updateRevision( thisVersion );
1890 else if ( fileVersion > thisVersion )
1893 "version of qgis (saved in " + fileVersion.
text() +
1895 "). Problems may occur." );
1901 profile.switchTask( tr(
"Creating auxiliary storage" ) );
1902 const QString
fileName = mFile.fileName();
1907 std::unique_ptr<QgsAuxiliaryStorage> aStorage = std::move( mAuxiliaryStorage );
1908 std::unique_ptr<QgsArchive> archive = std::move( mArchive );
1914 releaseHandlesToProjectArchive();
1916 mAuxiliaryStorage = std::move( aStorage );
1917 mArchive = std::move( archive );
1922 mCachedHomePath.clear();
1923 mProjectScope.reset();
1924 mSaveVersion = fileVersion;
1927 profile.switchTask( tr(
"Reading properties" ) );
1936 dump_( mProperties );
1941 _getTitle( *doc, oldTitle );
1943 readProjectFileMetadata( *doc, mSaveUser, mSaveUserFull, mSaveDateTime );
1945 const QDomNodeList homePathNl = doc->elementsByTagName( QStringLiteral(
"homePath" ) );
1946 if ( homePathNl.count() > 0 )
1948 const QDomElement homePathElement = homePathNl.at( 0 ).toElement();
1949 const QString
homePath = homePathElement.attribute( QStringLiteral(
"path" ) );
1959 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorGreenPart" ), 255 ),
1960 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorBluePart" ), 255 ) );
1963 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorGreenPart" ), 255 ),
1964 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorBluePart" ), 255 ),
1965 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorAlphaPart" ), 255 ) );
1969 const QString distanceUnitString =
readEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/DistanceUnits" ), QString() );
1970 if ( !distanceUnitString.isEmpty() )
1973 const QString areaUnitString =
readEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/AreaUnits" ), QString() );
1974 if ( !areaUnitString.isEmpty() )
1983 if (
readNumEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectionsEnabled" ), 0 ) )
1986 const QDomNode srsNode = doc->documentElement().namedItem( QStringLiteral(
"projectCrs" ) );
1987 if ( !srsNode.isNull() )
1989 projectCrs.
readXml( srsNode );
1994 const QString projCrsString =
readEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCRSProj4String" ) );
1995 const long currentCRS =
readNumEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCRSID" ), -1 );
1996 const QString authid =
readEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCrs" ) );
1999 const bool isUserAuthId = authid.startsWith( QLatin1String(
"USER:" ), Qt::CaseInsensitive );
2000 if ( !authid.isEmpty() && !isUserAuthId )
2004 if ( !projectCrs.
isValid() && currentCRS >= 0 )
2010 if ( !projCrsString.isEmpty() && ( authid.isEmpty() || isUserAuthId ) && ( !projectCrs.
isValid() || projectCrs.
toProj() != projCrsString ) )
2024 QStringList datumErrors;
2025 if ( !mTransformContext.
readXml( doc->documentElement(), context, datumErrors ) && !datumErrors.empty() )
2032 const QDomNode elevationShadingNode = doc->documentElement().namedItem( QStringLiteral(
"elevation-shading-renderer" ) );
2033 if ( !elevationShadingNode.isNull() )
2035 mElevationShadingRenderer.
readXml( elevationShadingNode.toElement(), context );
2042 const QStringList variableNames =
readListEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableNames" ) );
2043 const QStringList variableValues =
readListEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableValues" ) );
2045 mCustomVariables.clear();
2046 if ( variableNames.length() == variableValues.length() )
2048 for (
int i = 0; i < variableNames.length(); ++i )
2050 mCustomVariables.insert( variableNames.at( i ), variableValues.at( i ) );
2055 QgsMessageLog::logMessage( tr(
"Project Variables Invalid" ), tr(
"The project contains invalid variable settings." ) );
2058 QDomElement element = doc->documentElement().firstChildElement( QStringLiteral(
"projectMetadata" ) );
2060 if ( !element.isNull() )
2069 if ( mMetadata.
title().isEmpty() && !oldTitle.isEmpty() )
2077 element = doc->documentElement().firstChildElement( QStringLiteral(
"transaction" ) );
2078 if ( !element.isNull() )
2085 element = doc->documentElement().firstChildElement( QStringLiteral(
"autotransaction" ) );
2086 if ( ! element.isNull() )
2088 mTransactionMode =
static_cast<Qgis::TransactionMode>( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() );
2093 profile.switchTask( tr(
"Loading layer tree" ) );
2096 QDomElement layerTreeElem = doc->documentElement().firstChildElement( QStringLiteral(
"layer-tree-group" ) );
2097 if ( !layerTreeElem.isNull() )
2109 mLayerTreeRegistryBridge->
setEnabled(
false );
2112 profile.switchTask( tr(
"Reading map layers" ) );
2114 loadProjectFlags( doc.get() );
2116 QList<QDomNode> brokenNodes;
2117 const bool clean = _getMapLayers( *doc, brokenNodes,
flags );
2122 QgsDebugError( QStringLiteral(
"Unable to get map layers from project file." ) );
2124 if ( !brokenNodes.isEmpty() )
2126 QgsDebugError(
"there are " + QString::number( brokenNodes.size() ) +
" broken layers" );
2134 mMainAnnotationLayer->
readLayerXml( doc->documentElement().firstChildElement( QStringLiteral(
"main-annotation-layer" ) ), context );
2138 profile.switchTask( tr(
"Loading embedded layers" ) );
2139 loadEmbeddedNodes( mRootGroup,
flags );
2143 profile.switchTask( tr(
"Resolving layer references" ) );
2144 QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
2145 for ( QMap<QString, QgsMapLayer *>::iterator it =
layers.begin(); it !=
layers.end(); ++it )
2147 it.value()->resolveReferences(
this );
2150 mLayerTreeRegistryBridge->
setEnabled(
true );
2153 profile.switchTask( tr(
"Resolving references" ) );
2164 if ( !layerTreeElem.isNull() )
2170 const QDomElement layerTreeCanvasElem = doc->documentElement().firstChildElement( QStringLiteral(
"layer-tree-canvas" ) );
2171 if ( !layerTreeCanvasElem.isNull( ) )
2179 const QStringList requiredLayerIds =
readListEntry( QStringLiteral(
"RequiredLayers" ), QStringLiteral(
"Layers" ) );
2180 for (
const QString &layerId : requiredLayerIds )
2187 const QStringList disabledLayerIds =
readListEntry( QStringLiteral(
"Identify" ), QStringLiteral(
"/disabledLayers" ) );
2188 for (
const QString &layerId : disabledLayerIds )
2201 QString styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Marker" ) );
2202 if ( !styleName.isEmpty() )
2207 styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Line" ) );
2208 if ( !styleName.isEmpty() )
2213 styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Fill" ) );
2214 if ( !styleName.isEmpty() )
2219 styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/ColorRamp" ) );
2220 if ( !styleName.isEmpty() )
2230 double opacity = 1.0;
2233 double alpha =
readDoubleEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/AlphaInt" ), 255, &ok );
2235 opacity = alpha / 255.0;
2236 double newOpacity =
readDoubleEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Opacity" ), 1.0, &ok );
2238 opacity = newOpacity;
2242 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Marker" ) );
2243 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Line" ) );
2244 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Fill" ) );
2245 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/ColorRamp" ) );
2246 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/RandomColors" ) );
2247 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/AlphaInt" ) );
2248 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Opacity" ) );
2256 profile.switchTask( tr(
"Storing original layer properties" ) );
2262 profile.switchTask( tr(
"Loading map themes" ) );
2265 mMapThemeCollection->readXml( *doc );
2267 profile.switchTask( tr(
"Loading label settings" ) );
2268 mLabelingEngineSettings->readSettingsFromProject(
this );
2271 profile.switchTask( tr(
"Loading annotations" ) );
2272 mAnnotationManager->readXml( doc->documentElement(), context );
2275 profile.switchTask( tr(
"Loading layouts" ) );
2276 mLayoutManager->readXml( doc->documentElement(), *doc );
2281 profile.switchTask( tr(
"Loading 3D Views" ) );
2282 m3DViewsManager->readXml( doc->documentElement(), *doc );
2285 profile.switchTask( tr(
"Loading bookmarks" ) );
2286 mBookmarkManager->
readXml( doc->documentElement(), *doc );
2288 profile.switchTask( tr(
"Loading sensors" ) );
2289 mSensorManager->
readXml( doc->documentElement(), *doc );
2292 QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
2293 for ( QMap<QString, QgsMapLayer *>::iterator it = existingMaps.begin(); it != existingMaps.end(); ++it )
2295 it.value()->setDependencies( it.value()->dependencies() );
2298 profile.switchTask( tr(
"Loading snapping settings" ) );
2302 profile.switchTask( tr(
"Loading view settings" ) );
2305 const QStringList scales =
readListEntry( QStringLiteral(
"Scales" ), QStringLiteral(
"/ScalesList" ) );
2306 QVector<double> res;
2307 for (
const QString &scale : scales )
2309 const QStringList parts = scale.split(
':' );
2310 if ( parts.size() != 2 )
2314 const double denominator = QLocale().toDouble( parts[1], &ok );
2321 const QDomElement viewSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectViewSettings" ) );
2322 if ( !viewSettingsElement.isNull() )
2323 mViewSettings->
readXml( viewSettingsElement, context );
2326 profile.switchTask( tr(
"Loading style properties" ) );
2327 const QDomElement styleSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectStyleSettings" ) );
2328 if ( !styleSettingsElement.isNull() )
2331 mStyleSettings->
readXml( styleSettingsElement, context,
flags );
2335 profile.switchTask( tr(
"Loading temporal settings" ) );
2336 const QDomElement timeSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectTimeSettings" ) );
2337 if ( !timeSettingsElement.isNull() )
2338 mTimeSettings->
readXml( timeSettingsElement, context );
2341 profile.switchTask( tr(
"Loading elevation properties" ) );
2342 const QDomElement elevationPropertiesElement = doc->documentElement().firstChildElement( QStringLiteral(
"ElevationProperties" ) );
2343 if ( !elevationPropertiesElement.isNull() )
2344 mElevationProperties->
readXml( elevationPropertiesElement, context );
2347 profile.switchTask( tr(
"Loading display settings" ) );
2349 const QDomElement displaySettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectDisplaySettings" ) );
2350 if ( !displaySettingsElement.isNull() )
2351 mDisplaySettings->
readXml( displaySettingsElement, context );
2354 profile.switchTask( tr(
"Loading GPS settings" ) );
2356 const QDomElement gpsSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectGpsSettings" ) );
2357 if ( !gpsSettingsElement.isNull() )
2358 mGpsSettings->
readXml( gpsSettingsElement, context );
2362 profile.switchTask( tr(
"Updating variables" ) );
2364 profile.switchTask( tr(
"Updating CRS" ) );
2369 profile.switchTask( tr(
"Reading external settings" ) );
2373 profile.switchTask( tr(
"Updating interface" ) );
2375 snapSignalBlock.release();
2376 if ( !mBlockSnappingUpdates )
2387 QgsDebugMsgLevel( QStringLiteral(
"Project save user: %1" ).arg( mSaveUser ), 2 );
2388 QgsDebugMsgLevel( QStringLiteral(
"Project save user: %1" ).arg( mSaveUserFull ), 2 );
2397 const QString newFileName( QStringLiteral(
"%1/%2.qgs" ).arg( QFileInfo( projectFile.fileName() ).absolutePath(), localeFileName ) );
2412 const QMap<QString, QgsMapLayer *> loadedLayers =
mapLayers();
2413 for (
auto it = loadedLayers.constBegin(); it != loadedLayers.constEnd(); ++it )
2415 if ( it.value()->isValid() && it.value()->customProperty( QStringLiteral(
"_layer_was_editable" ) ).toBool() )
2417 if (
QgsVectorLayer *vl = qobject_cast< QgsVectorLayer * >( it.value() ) )
2419 it.value()->removeCustomProperty( QStringLiteral(
"_layer_was_editable" ) );
2426bool QgsProject::loadEmbeddedNodes(
QgsLayerTreeGroup *group, Qgis::ProjectReadFlags flags )
2431 const auto constChildren = group->
children();
2437 if ( childGroup->
customProperty( QStringLiteral(
"embedded" ) ).toInt() )
2440 const QString projectPath =
readPath( childGroup->
customProperty( QStringLiteral(
"embedded_project" ) ).toString() );
2441 childGroup->
setCustomProperty( QStringLiteral(
"embedded_project" ), projectPath );
2445 QList<QgsLayerTreeNode *> clonedChildren;
2446 const QList<QgsLayerTreeNode *> constChildren = newGroup->
children();
2447 clonedChildren.reserve( constChildren.size() );
2449 clonedChildren << newGroupChild->clone();
2457 loadEmbeddedNodes( childGroup,
flags );
2462 if ( child->customProperty( QStringLiteral(
"embedded" ) ).toInt() )
2464 QList<QDomNode> brokenNodes;
2467 valid = valid &&
false;
2482 return mCustomVariables;
2489 if ( variables == mCustomVariables )
2493 QStringList variableNames;
2494 QStringList variableValues;
2496 QVariantMap::const_iterator it = variables.constBegin();
2497 for ( ; it != variables.constEnd(); ++it )
2499 variableNames << it.key();
2500 variableValues << it.value().toString();
2503 writeEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableNames" ), variableNames );
2504 writeEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableValues" ), variableValues );
2506 mCustomVariables = variables;
2507 mProjectScope.reset();
2516 *mLabelingEngineSettings = settings;
2524 return *mLabelingEngineSettings;
2531 mProjectScope.reset();
2532 return mLayerStore.get();
2539 return mLayerStore.get();
2546 QList<QgsVectorLayer *>
layers;
2547 const QStringList layerIds =
readListEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsList" ), QStringList() );
2548 const auto constLayerIds = layerIds;
2549 for (
const QString &layerId : constLayerIds )
2562 list.reserve(
layers.size() );
2564 list << layer->id();
2565 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsList" ), list );
2587 if ( mProjectScope )
2589 std::unique_ptr< QgsExpressionContextScope > projectScope = std::make_unique< QgsExpressionContextScope >( *mProjectScope );
2596 projectScope->addFunction( QStringLiteral(
"sensor_data" ),
new GetSensorData(
sensorManager()->sensorsData() ) );
2598 return projectScope.release();
2601 mProjectScope = std::make_unique< QgsExpressionContextScope >( QObject::tr(
"Project" ) );
2605 QVariantMap::const_iterator it = vars.constBegin();
2607 for ( ; it != vars.constEnd(); ++it )
2609 mProjectScope->setVariable( it.key(), it.value(),
true );
2613 if ( projectPath.isEmpty() )
2614 projectPath = mOriginalPath;
2615 const QString projectFolder = QFileInfo( projectPath ).path();
2616 const QString projectFilename = QFileInfo( projectPath ).fileName();
2617 const QString projectBasename =
baseName();
2646 QVariantMap keywords;
2648 for (
auto it = metadataKeywords.constBegin(); it != metadataKeywords.constEnd(); ++it )
2650 keywords.insert( it.key(), it.value() );
2655 QVariantList layersIds;
2657 const QMap<QString, QgsMapLayer *> layersInProject = mLayerStore->mapLayers();
2658 layersIds.reserve( layersInProject.count() );
2659 layers.reserve( layersInProject.count() );
2660 for (
auto it = layersInProject.constBegin(); it != layersInProject.constEnd(); ++it )
2662 layersIds << it.value()->id();
2668 mProjectScope->addFunction( QStringLiteral(
"project_color" ),
new GetNamedProjectColor(
this ) );
2673void QgsProject::onMapLayersAdded(
const QList<QgsMapLayer *> &layers )
2677 const QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
2679 const auto constLayers =
layers;
2682 if ( ! layer->isValid() )
2685 if (
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer ) )
2688 if ( vlayer->dataProvider() )
2696 for ( QMap<QString, QgsMapLayer *>::const_iterator it = existingMaps.cbegin(); it != existingMaps.cend(); ++it )
2698 const QSet<QgsMapLayerDependency> deps = it.value()->dependencies();
2699 if ( deps.contains( layer->id() ) )
2702 it.value()->setDependencies( deps );
2707 updateTransactionGroups();
2713void QgsProject::onMapLayersRemoved(
const QList<QgsMapLayer *> &layers )
2721void QgsProject::cleanTransactionGroups(
bool force )
2725 bool changed =
false;
2726 for ( QMap< QPair< QString, QString>,
QgsTransactionGroup *>::Iterator tg = mTransactionGroups.begin(); tg != mTransactionGroups.end(); )
2728 if ( tg.value()->isEmpty() || force )
2731 tg = mTransactionGroups.erase( tg );
2743void QgsProject::updateTransactionGroups()
2747 mEditBufferGroup.
clear();
2749 switch ( mTransactionMode )
2753 cleanTransactionGroups(
true );
2758 cleanTransactionGroups(
true );
2761 cleanTransactionGroups(
false );
2765 bool tgChanged =
false;
2766 const auto constLayers =
mapLayers().values();
2769 if ( ! layer->isValid() )
2772 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
2776 switch ( mTransactionMode )
2793 mTransactionGroups.insert( qMakePair( key, connString ), tg );
2803 mEditBufferGroup.
addLayer( vlayer );
2819 context.setProjectTranslator(
this );
2821 QList<QDomNode> brokenNodes;
2822 if ( addLayer( layerNode.toElement(), brokenNodes, context ) )
2826 const QVector<QgsVectorLayer *> vectorLayers = layers<QgsVectorLayer *>();
2830 layer->resolveReferences(
this );
2832 if ( layer->isValid() && layer->customProperty( QStringLiteral(
"_layer_was_editable" ) ).toBool() )
2834 layer->startEditing();
2835 layer->removeCustomProperty( QStringLiteral(
"_layer_was_editable" ) );
2847 mFile.setFileName( filename );
2848 mCachedHomePath.clear();
2856 mProjectScope.reset();
2862 const QString storageFilePath { storage->filePath( mFile.fileName() ) };
2863 if ( storageFilePath.isEmpty() )
2869 const QString tempPath = QStandardPaths::standardLocations( QStandardPaths::TempLocation ).at( 0 );
2870 const QString tmpZipFilename( tempPath + QDir::separator() + QUuid::createUuid().toString() );
2872 if ( !zip( tmpZipFilename ) )
2875 QFile tmpZipFile( tmpZipFilename );
2876 if ( !tmpZipFile.open( QIODevice::ReadOnly ) )
2878 setError( tr(
"Unable to read file %1" ).arg( tmpZipFilename ) );
2883 if ( !storage->writeProject( mFile.fileName(), &tmpZipFile, context ) )
2885 QString err = tr(
"Unable to save project to storage %1" ).arg( mFile.fileName() );
2886 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
2887 if ( !messages.isEmpty() )
2888 err += QStringLiteral(
"\n\n" ) + messages.last().message();
2894 QFile::remove( tmpZipFilename );
2901 return zip( mFile.fileName() );
2907 const bool asOk = saveAuxiliaryStorage();
2908 const bool writeOk = writeProjectFile( mFile.fileName() );
2909 bool attachmentsOk =
true;
2910 if ( !mArchive->files().isEmpty() )
2912 const QFileInfo finfo( mFile.fileName() );
2913 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( QStringLiteral(
"%1_attachments.zip" ).arg( finfo.completeBaseName() ) );
2914 attachmentsOk = mArchive->zip( attachmentsZip );
2918 if ( ( !asOk || !attachmentsOk ) && writeOk )
2920 QStringList errorMessage;
2923 const QString err = mAuxiliaryStorage->errorString();
2924 errorMessage.append( tr(
"Unable to save auxiliary storage ('%1')" ).arg( err ) );
2926 if ( !attachmentsOk )
2928 errorMessage.append( tr(
"Unable to save attachments archive" ) );
2930 setError( errorMessage.join(
'\n' ) );
2933 return asOk && writeOk && attachmentsOk;
2937bool QgsProject::writeProjectFile(
const QString &filename )
2941 QFile projectFile( filename );
2947 const QFileInfo myFileInfo( projectFile );
2948 if ( myFileInfo.exists() && !myFileInfo.isWritable() )
2950 setError( tr(
"%1 is not writable. Please adjust permissions (if possible) and try again." )
2951 .arg( projectFile.fileName() ) );
2959 QDomImplementation::setInvalidDataPolicy( QDomImplementation::DropInvalidChars );
2961 const QDomDocumentType documentType =
2962 QDomImplementation().createDocumentType( QStringLiteral(
"qgis" ), QStringLiteral(
"http://mrcc.com/qgis.dtd" ),
2963 QStringLiteral(
"SYSTEM" ) );
2964 std::unique_ptr<QDomDocument> doc(
new QDomDocument( documentType ) );
2966 QDomElement qgisNode = doc->createElement( QStringLiteral(
"qgis" ) );
2967 qgisNode.setAttribute( QStringLiteral(
"projectname" ),
title() );
2968 qgisNode.setAttribute( QStringLiteral(
"version" ),
Qgis::version() );
2970 if ( !mSettings.
value( QStringLiteral(
"projects/anonymize_saved_projects" ),
false,
QgsSettings::Core ).toBool() )
2974 qgisNode.setAttribute( QStringLiteral(
"saveUser" ), newSaveUser );
2975 qgisNode.setAttribute( QStringLiteral(
"saveUserFull" ), newSaveUserFull );
2976 mSaveUser = newSaveUser;
2977 mSaveUserFull = newSaveUserFull;
2978 mSaveDateTime = QDateTime::currentDateTime();
2979 qgisNode.setAttribute( QStringLiteral(
"saveDateTime" ), mSaveDateTime.toString( Qt::ISODate ) );
2984 mSaveUserFull.clear();
2985 mSaveDateTime = QDateTime();
2987 doc->appendChild( qgisNode );
2990 QDomElement homePathNode = doc->createElement( QStringLiteral(
"homePath" ) );
2991 homePathNode.setAttribute( QStringLiteral(
"path" ), mHomePath );
2992 qgisNode.appendChild( homePathNode );
2995 QDomElement titleNode = doc->createElement( QStringLiteral(
"title" ) );
2996 qgisNode.appendChild( titleNode );
2998 QDomElement transactionNode = doc->createElement( QStringLiteral(
"transaction" ) );
2999 transactionNode.setAttribute( QStringLiteral(
"mode" ),
qgsEnumValueToKey( mTransactionMode ) );
3000 qgisNode.appendChild( transactionNode );
3002 QDomElement flagsNode = doc->createElement( QStringLiteral(
"projectFlags" ) );
3004 qgisNode.appendChild( flagsNode );
3006 const QDomText titleText = doc->createTextNode(
title() );
3007 titleNode.appendChild( titleText );
3010 QDomElement srsNode = doc->createElement( QStringLiteral(
"projectCrs" ) );
3012 qgisNode.appendChild( srsNode );
3014 QDomElement elevationShadingNode = doc->createElement( QStringLiteral(
"elevation-shading-renderer" ) );
3015 mElevationShadingRenderer.
writeXml( elevationShadingNode, context );
3016 qgisNode.appendChild( elevationShadingNode );
3023 clonedRoot->
writeXml( qgisNode, context );
3027 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsMode" ),
static_cast<int>( mAvoidIntersectionsMode ) );
3035 QDomElement annotationLayerNode = doc->createElement( QStringLiteral(
"main-annotation-layer" ) );
3036 mMainAnnotationLayer->
writeLayerXml( annotationLayerNode, *doc, context );
3037 qgisNode.appendChild( annotationLayerNode );
3041 QDomElement projectLayersNode = doc->createElement( QStringLiteral(
"projectlayers" ) );
3043 QMap<QString, QgsMapLayer *>::ConstIterator li =
layers.constBegin();
3044 while ( li !=
layers.end() )
3050 const QHash< QString, QPair< QString, bool> >::const_iterator emIt = mEmbeddedLayers.constFind( ml->
id() );
3051 if ( emIt == mEmbeddedLayers.constEnd() )
3053 QDomElement maplayerElem;
3059 maplayerElem = doc->createElement( QStringLiteral(
"maplayer" ) );
3063 maplayerElem.setAttribute( QStringLiteral(
"editable" ), QStringLiteral(
"1" ) );
3067 QDomDocument document;
3070 maplayerElem = document.firstChildElement();
3074 QgsDebugError( QStringLiteral(
"Could not restore layer properties for layer %1" ).arg( ml->
id() ) );
3080 projectLayersNode.appendChild( maplayerElem );
3086 if ( emIt.value().second )
3088 QDomElement mapLayerElem = doc->createElement( QStringLiteral(
"maplayer" ) );
3089 mapLayerElem.setAttribute( QStringLiteral(
"embedded" ), 1 );
3090 mapLayerElem.setAttribute( QStringLiteral(
"project" ),
writePath( emIt.value().first ) );
3091 mapLayerElem.setAttribute( QStringLiteral(
"id" ), ml->
id() );
3092 projectLayersNode.appendChild( mapLayerElem );
3099 qgisNode.appendChild( projectLayersNode );
3101 QDomElement layerOrderNode = doc->createElement( QStringLiteral(
"layerorder" ) );
3103 for (
QgsMapLayer *layer : constCustomLayerOrder )
3105 QDomElement mapLayerElem = doc->createElement( QStringLiteral(
"layer" ) );
3106 mapLayerElem.setAttribute( QStringLiteral(
"id" ), layer->id() );
3107 layerOrderNode.appendChild( mapLayerElem );
3109 qgisNode.appendChild( layerOrderNode );
3111 mLabelingEngineSettings->writeSettingsToProject(
this );
3113 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorRedPart" ), mBackgroundColor.red() );
3114 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorGreenPart" ), mBackgroundColor.green() );
3115 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorBluePart" ), mBackgroundColor.blue() );
3117 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorRedPart" ), mSelectionColor.red() );
3118 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorGreenPart" ), mSelectionColor.green() );
3119 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorBluePart" ), mSelectionColor.blue() );
3120 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorAlphaPart" ), mSelectionColor.alpha() );
3127 dump_( mProperties );
3130 QgsDebugMsgLevel( QStringLiteral(
"there are %1 property scopes" ).arg(
static_cast<int>( mProperties.
count() ) ), 2 );
3135 mProperties.
writeXml( QStringLiteral(
"properties" ), qgisNode, *doc );
3138 QDomElement ddElem = doc->createElement( QStringLiteral(
"dataDefinedServerProperties" ) );
3139 mDataDefinedServerProperties.
writeXml( ddElem, dataDefinedServerPropertyDefinitions() );
3140 qgisNode.appendChild( ddElem );
3142 mMapThemeCollection->writeXml( *doc );
3144 mTransformContext.
writeXml( qgisNode, context );
3146 QDomElement metadataElem = doc->createElement( QStringLiteral(
"projectMetadata" ) );
3148 qgisNode.appendChild( metadataElem );
3151 const QDomElement annotationsElem = mAnnotationManager->writeXml( *doc, context );
3152 qgisNode.appendChild( annotationsElem );
3156 const QDomElement layoutElem = mLayoutManager->writeXml( *doc );
3157 qgisNode.appendChild( layoutElem );
3161 const QDomElement views3DElem = m3DViewsManager->writeXml( *doc );
3162 qgisNode.appendChild( views3DElem );
3166 const QDomElement bookmarkElem = mBookmarkManager->
writeXml( *doc );
3167 qgisNode.appendChild( bookmarkElem );
3171 const QDomElement sensorElem = mSensorManager->
writeXml( *doc );
3172 qgisNode.appendChild( sensorElem );
3176 const QDomElement viewSettingsElem = mViewSettings->
writeXml( *doc, context );
3177 qgisNode.appendChild( viewSettingsElem );
3181 const QDomElement styleSettingsElem = mStyleSettings->
writeXml( *doc, context );
3182 qgisNode.appendChild( styleSettingsElem );
3186 const QDomElement timeSettingsElement = mTimeSettings->
writeXml( *doc, context );
3187 qgisNode.appendChild( timeSettingsElement );
3191 const QDomElement elevationPropertiesElement = mElevationProperties->
writeXml( *doc, context );
3192 qgisNode.appendChild( elevationPropertiesElement );
3196 const QDomElement displaySettingsElem = mDisplaySettings->
writeXml( *doc, context );
3197 qgisNode.appendChild( displaySettingsElem );
3201 const QDomElement gpsSettingsElem = mGpsSettings->
writeXml( *doc, context );
3202 qgisNode.appendChild( gpsSettingsElem );
3211 QFile backupFile( QStringLiteral(
"%1~" ).arg( filename ) );
3213 ok &= backupFile.open( QIODevice::WriteOnly | QIODevice::Truncate );
3214 ok &= projectFile.open( QIODevice::ReadOnly );
3217 while ( ok && !projectFile.atEnd() )
3219 ba = projectFile.read( 10240 );
3220 ok &= backupFile.write( ba ) == ba.size();
3223 projectFile.close();
3228 setError( tr(
"Unable to create backup file %1" ).arg( backupFile.fileName() ) );
3233 struct utimbuf tb = {
static_cast<time_t
>( fi.lastRead().toSecsSinceEpoch() ),
static_cast<time_t
>( fi.lastModified().toSecsSinceEpoch() ) };
3234 utime( backupFile.fileName().toUtf8().constData(), &tb );
3237 if ( !projectFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
3239 projectFile.close();
3242 setError( tr(
"Unable to save to file %1" ).arg( projectFile.fileName() ) );
3246 QTemporaryFile tempFile;
3247 bool ok = tempFile.open();
3250 QTextStream projectFileStream( &tempFile );
3251 doc->save( projectFileStream, 2 );
3252 ok &= projectFileStream.pos() > -1;
3254 ok &= tempFile.seek( 0 );
3257 while ( ok && !tempFile.atEnd() )
3259 ba = tempFile.read( 10240 );
3260 ok &= projectFile.write( ba ) == ba.size();
3263 ok &= projectFile.error() == QFile::NoError;
3265 projectFile.close();
3272 setError( tr(
"Unable to save to file %1. Your project "
3273 "may be corrupted on disk. Try clearing some space on the volume and "
3274 "check file permissions before pressing save again." )
3275 .arg( projectFile.fileName() ) );
3289 bool propertiesModified;
3290 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3292 if ( propertiesModified )
3302 bool propertiesModified;
3303 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3305 if ( propertiesModified )
3315 bool propertiesModified;
3316 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3318 if ( propertiesModified )
3328 bool propertiesModified;
3329 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3331 if ( propertiesModified )
3341 bool propertiesModified;
3342 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3344 if ( propertiesModified )
3352 const QStringList &def,
3364 value =
property->value();
3366 const bool valid = QVariant::StringList == value.type();
3372 return value.toStringList();
3395 value =
property->value();
3397 const bool valid = value.canConvert( QVariant::String );
3402 return value.toString();
3421 value =
property->value();
3424 const bool valid = value.canConvert( QVariant::Int );
3433 return value.toInt();
3448 const QVariant value =
property->value();
3450 const bool valid = value.canConvert( QVariant::Double );
3455 return value.toDouble();
3472 const QVariant value =
property->value();
3474 const bool valid = value.canConvert( QVariant::Bool );
3479 return value.toBool();
3491 if (
findKey_( scope, key, mProperties ) )
3497 return !
findKey_( scope, key, mProperties );
3506 QStringList entries;
3508 if ( foundProperty )
3525 QStringList entries;
3527 if ( foundProperty )
3542 dump_( mProperties );
3562 filePath = storage->filePath( mFile.fileName() );
3589void QgsProject::setError(
const QString &errorMessage )
3593 mErrorMessage = errorMessage;
3600 return mErrorMessage;
3603void QgsProject::clearError()
3607 setError( QString() );
3614 delete mBadLayerHandler;
3615 mBadLayerHandler = handler;
3622 const QHash< QString, QPair< QString, bool > >::const_iterator it = mEmbeddedLayers.find(
id );
3623 if ( it == mEmbeddedLayers.constEnd() )
3627 return it.value().first;
3631 bool saveFlag, Qgis::ProjectReadFlags flags )
3637 static QString sPrevProjectFilePath;
3638 static QDateTime sPrevProjectFileTimestamp;
3639 static QDomDocument sProjectDocument;
3641 QString qgsProjectFile = projectFilePath;
3643 if ( projectFilePath.endsWith( QLatin1String(
".qgz" ), Qt::CaseInsensitive ) )
3645 archive.
unzip( projectFilePath );
3649 const QDateTime projectFileTimestamp = QFileInfo( projectFilePath ).lastModified();
3651 if ( projectFilePath != sPrevProjectFilePath || projectFileTimestamp != sPrevProjectFileTimestamp )
3653 sPrevProjectFilePath.clear();
3655 QFile projectFile( qgsProjectFile );
3656 if ( !projectFile.open( QIODevice::ReadOnly ) )
3661 if ( !sProjectDocument.setContent( &projectFile ) )
3666 sPrevProjectFilePath = projectFilePath;
3667 sPrevProjectFileTimestamp = projectFileTimestamp;
3671 bool useAbsolutePaths =
true;
3673 const QDomElement propertiesElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral(
"properties" ) );
3674 if ( !propertiesElem.isNull() )
3676 const QDomElement absElem = propertiesElem.firstChildElement( QStringLiteral(
"Paths" ) ).firstChildElement( QStringLiteral(
"Absolute" ) );
3677 if ( !absElem.isNull() )
3679 useAbsolutePaths = absElem.text().compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0;
3684 if ( !useAbsolutePaths )
3689 const QDomElement projectLayersElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral(
"projectlayers" ) );
3690 if ( projectLayersElem.isNull() )
3695 QDomElement mapLayerElem = projectLayersElem.firstChildElement( QStringLiteral(
"maplayer" ) );
3696 while ( ! mapLayerElem.isNull() )
3699 const QString
id = mapLayerElem.firstChildElement( QStringLiteral(
"id" ) ).text();
3700 if (
id == layerId )
3703 if ( mapLayerElem.attribute( QStringLiteral(
"embedded" ) ) == QLatin1String(
"1" ) )
3708 mEmbeddedLayers.insert( layerId, qMakePair( projectFilePath, saveFlag ) );
3710 if ( addLayer( mapLayerElem, brokenNodes, embeddedContext,
flags ) )
3716 mEmbeddedLayers.remove( layerId );
3720 mapLayerElem = mapLayerElem.nextSiblingElement( QStringLiteral(
"maplayer" ) );
3730 QString qgsProjectFile = projectFilePath;
3732 if ( projectFilePath.endsWith( QLatin1String(
".qgz" ), Qt::CaseInsensitive ) )
3734 archive.
unzip( projectFilePath );
3739 QFile projectFile( qgsProjectFile );
3740 if ( !projectFile.open( QIODevice::ReadOnly ) )
3745 QDomDocument projectDocument;
3746 if ( !projectDocument.setContent( &projectFile ) )
3758 QDomElement layerTreeElem = projectDocument.documentElement().firstChildElement( QStringLiteral(
"layer-tree-group" ) );
3759 if ( !layerTreeElem.isNull() )
3769 if ( !group || group->
customProperty( QStringLiteral(
"embedded" ) ).toBool() )
3782 newGroup->
setCustomProperty( QStringLiteral(
"embedded_project" ), projectFilePath );
3785 mLayerTreeRegistryBridge->
setEnabled(
false );
3786 initializeEmbeddedSubtree( projectFilePath, newGroup,
flags );
3787 mLayerTreeRegistryBridge->
setEnabled(
true );
3790 const auto constFindLayerIds = newGroup->
findLayerIds();
3791 for (
const QString &layerId : constFindLayerIds )
3804void QgsProject::initializeEmbeddedSubtree(
const QString &projectFilePath,
QgsLayerTreeGroup *group, Qgis::ProjectReadFlags flags )
3808 const auto constChildren = group->
children();
3812 child->setCustomProperty( QStringLiteral(
"embedded" ), 1 );
3821 QList<QDomNode> brokenNodes;
3845 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/TopologicalEditing" ), ( enabled ? 1 : 0 ) );
3853 return readNumEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/TopologicalEditing" ), 0 );
3860 if ( mDistanceUnits == unit )
3863 mDistanceUnits = unit;
3872 if ( mAreaUnits == unit )
3885 if ( !mCachedHomePath.isEmpty() )
3886 return mCachedHomePath;
3890 if ( !mHomePath.isEmpty() )
3892 const QFileInfo homeInfo( mHomePath );
3893 if ( !homeInfo.isRelative() )
3895 mCachedHomePath = mHomePath;
3905 const QString storagePath { storage->filePath(
fileName() ) };
3906 if ( ! storagePath.isEmpty() && QFileInfo::exists( storagePath ) )
3908 mCachedHomePath = QFileInfo( storagePath ).path();
3909 return mCachedHomePath;
3913 mCachedHomePath = pfi.path();
3914 return mCachedHomePath;
3917 if ( !pfi.exists() )
3919 mCachedHomePath = mHomePath;
3923 if ( !mHomePath.isEmpty() )
3926 mCachedHomePath = QDir::cleanPath( pfi.path() +
'/' + mHomePath );
3930 mCachedHomePath = pfi.canonicalPath();
3932 return mCachedHomePath;
3947 return mRelationManager;
3954 return mLayoutManager.get();
3961 return mLayoutManager.get();
3968 return m3DViewsManager.get();
3975 return m3DViewsManager.get();
3982 return mBookmarkManager;
3989 return mBookmarkManager;
3996 return mSensorManager;
4003 return mSensorManager;
4010 return mViewSettings;
4017 return mViewSettings;
4024 return mStyleSettings;
4032 return mStyleSettings;
4039 return mTimeSettings;
4046 return mTimeSettings;
4053 return mElevationProperties;
4060 return mElevationProperties;
4067 return mDisplaySettings;
4074 return mDisplaySettings;
4081 return mGpsSettings;
4088 return mGpsSettings;
4102 return mMapThemeCollection.get();
4109 return mAnnotationManager.get();
4116 return mAnnotationManager.get();
4123 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
4124 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
4129 if (
layers.contains( it.value() ) )
4130 it.value()->setFlags( it.value()->flags() &
~QgsMapLayer::Identifiable );
4146 for (
const QString &layerId : layerIds )
4164 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
4198 updateTransactionGroups();
4205 return mTransactionMode;
4216 const auto constLayers =
mapLayers().values();
4219 if ( layer->isEditable() )
4221 QgsLogger::warning( tr(
"Transaction mode can be changed only if all layers are not editable." ) );
4227 updateTransactionGroups();
4235 return mTransactionGroups;
4248 return mLayerStore->count();
4255 return mLayerStore->validCount();
4263 return mLayerStore->mapLayer( layerId );
4270 return mLayerStore->mapLayersByName( layerName );
4277 QList<QgsMapLayer *>
layers;
4278 const auto constMapLayers { mLayerStore->mapLayers() };
4279 for (
const auto &l : constMapLayers )
4281 if ( ! l->shortName().isEmpty() )
4283 if ( l->shortName() == shortName )
4286 else if ( l->name() == shortName )
4294bool QgsProject::unzip(
const QString &filename, Qgis::ProjectReadFlags flags )
4302 if ( !archive->unzip( filename ) )
4304 setError( tr(
"Unable to unzip file '%1'" ).arg( filename ) );
4309 if ( archive->projectFile().isEmpty() )
4311 setError( tr(
"Zip archive does not provide a project file" ) );
4316 releaseHandlesToProjectArchive();
4317 mArchive = std::move( archive );
4334 setError( tr(
"Cannot read unzipped qgs project file" ) + QStringLiteral(
": " ) +
error() );
4344bool QgsProject::zip(
const QString &filename )
4352 const QString
baseName = QFileInfo( filename ).baseName();
4353 const QString qgsFileName = QStringLiteral(
"%1.qgs" ).arg(
baseName );
4354 QFile qgsFile( QDir( archive->dir() ).filePath( qgsFileName ) );
4356 bool writeOk =
false;
4357 if ( qgsFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
4359 writeOk = writeProjectFile( qgsFile.fileName() );
4366 setError( tr(
"Unable to write temporary qgs file" ) );
4371 const QFileInfo info( qgsFile );
4373 const QString asFileName = info.path() + QDir::separator() + info.completeBaseName() + asExt;
4375 bool auxiliaryStorageSavedOk =
true;
4376 if ( ! saveAuxiliaryStorage( asFileName ) )
4378 const QString err = mAuxiliaryStorage->errorString();
4379 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 ) );
4380 auxiliaryStorageSavedOk =
false;
4383 if ( !mArchive->exists() )
4385 releaseHandlesToProjectArchive();
4387 mArchive->unzip( mFile.fileName() );
4390 const QString auxiliaryStorageFile =
static_cast<QgsProjectArchive *
>( mArchive.get() )->auxiliaryStorageFile();
4391 if ( ! auxiliaryStorageFile.isEmpty() )
4393 archive->
addFile( auxiliaryStorageFile );
4402 if ( QFile::exists( asFileName ) )
4404 archive->addFile( asFileName );
4409 archive->addFile( qgsFile.fileName() );
4412 const QStringList &
files = mArchive->files();
4413 for (
const QString &file :
files )
4415 if ( !file.endsWith( QLatin1String(
".qgs" ), Qt::CaseInsensitive ) && !file.endsWith( asExt, Qt::CaseInsensitive ) )
4417 archive->addFile( file );
4423 if ( !archive->zip( filename ) )
4425 setError( tr(
"Unable to perform zip" ) );
4429 return auxiliaryStorageSavedOk && zipOk;
4440 const QList<QgsMapLayer *> &layers,
4442 bool takeOwnership )
4446 const QList<QgsMapLayer *> myResultList { mLayerStore->addMapLayers(
layers, takeOwnership ) };
4447 if ( !myResultList.isEmpty() )
4450 for (
auto &l : myResultList )
4460 if ( mAuxiliaryStorage )
4475 mProjectScope.reset();
4477 return myResultList;
4483 bool takeOwnership )
4487 QList<QgsMapLayer *> addedLayers;
4488 addedLayers =
addMapLayers( QList<QgsMapLayer *>() << layer, addToLegend, takeOwnership );
4489 return addedLayers.isEmpty() ? nullptr : addedLayers[0];
4492void QgsProject::removeAuxiliaryLayer(
const QgsMapLayer *ml )
4499 const QgsVectorLayer *vl = qobject_cast<const QgsVectorLayer *>( ml );
4511 for (
const auto &layerId : layerIds )
4512 removeAuxiliaryLayer( mLayerStore->mapLayer( layerId ) );
4514 mProjectScope.reset();
4515 mLayerStore->removeMapLayers( layerIds );
4522 for (
const auto &layer :
layers )
4523 removeAuxiliaryLayer( layer );
4525 mProjectScope.reset();
4526 mLayerStore->removeMapLayers(
layers );
4533 removeAuxiliaryLayer( mLayerStore->mapLayer( layerId ) );
4534 mProjectScope.reset();
4535 mLayerStore->removeMapLayer( layerId );
4542 removeAuxiliaryLayer( layer );
4543 mProjectScope.reset();
4544 mLayerStore->removeMapLayer( layer );
4551 mProjectScope.reset();
4552 return mLayerStore->takeMapLayer( layer );
4559 return mMainAnnotationLayer;
4566 if ( mLayerStore->count() == 0 )
4569 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
4570 mProjectScope.reset();
4571 mLayerStore->removeAllMapLayers();
4573 snapSingleBlocker.release();
4575 if ( !mBlockSnappingUpdates )
4583 const QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
4584 QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin();
4585 for ( ; it !=
layers.constEnd(); ++it )
4587 it.value()->reload();
4596 return validOnly ? mLayerStore->validMapLayers() : mLayerStore->mapLayers();
4603 return mTransactionGroups.value( qMakePair( providerKey, connString ) );
4610 return &mEditBufferGroup;
4621 if ( mSettings.
value( QStringLiteral(
"/projections/unknownCrsBehavior" ), QStringLiteral(
"NoAction" ),
QgsSettings::App ).toString() == QStringLiteral(
"UseProjectCrs" )
4622 || mSettings.
value( QStringLiteral(
"/projections/unknownCrsBehavior" ), 0,
QgsSettings::App ).toString() == QLatin1String(
"2" ) )
4630 const QString layerDefaultCrs = mSettings.
value( QStringLiteral(
"/Projections/layerDefaultCrs" ),
geoEpsgCrsAuthId() ).toString();
4651bool QgsProject::saveAuxiliaryStorage(
const QString &filename )
4657 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
4662 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() );
4670 if ( !mAuxiliaryStorage->exists( *
this ) && empty )
4674 else if ( !filename.isEmpty() )
4676 return mAuxiliaryStorage->saveAs( filename );
4680 return mAuxiliaryStorage->saveAs( *
this );
4693 return sPropertyDefinitions;
4706 return mAuxiliaryStorage.get();
4713 return mAuxiliaryStorage.get();
4720 const QDir archiveDir( mArchive->dir() );
4721 QTemporaryFile tmpFile( archiveDir.filePath(
"XXXXXX_" + nameTemplate ),
this );
4722 tmpFile.setAutoRemove(
false );
4724 mArchive->addFile( tmpFile.fileName() );
4725 return tmpFile.fileName();
4732 QStringList attachments;
4734 const QStringList files = mArchive->files();
4735 attachments.reserve( files.size() );
4736 for (
const QString &file : files )
4738 if ( QFileInfo( file ).baseName() !=
baseName )
4740 attachments.append( file );
4750 return mArchive->removeFile( path );
4757 return QStringLiteral(
"attachment:///%1" ).arg( QFileInfo( attachedFile ).
fileName() );
4764 if ( identifier.startsWith( QLatin1String(
"attachment:///" ) ) )
4766 return QDir( mArchive->dir() ).absoluteFilePath( identifier.mid( 14 ) );
4787 mProjectScope.reset();
4801 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
4815 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
4816 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
4821 if (
layers.contains( it.value() ) )
4822 it.value()->setFlags( it.value()->flags() &
~QgsMapLayer::Removable );
4833 QStringList customColors;
4834 QStringList customColorLabels;
4836 QgsNamedColorList::const_iterator colorIt = colors.constBegin();
4837 for ( ; colorIt != colors.constEnd(); ++colorIt )
4840 const QString label = ( *colorIt ).second;
4841 customColors.append( color );
4842 customColorLabels.append( label );
4844 writeEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Colors" ), customColors );
4845 writeEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Labels" ), customColorLabels );
4846 mProjectScope.reset();
4854 if ( mBackgroundColor == color )
4857 mBackgroundColor = color;
4865 return mBackgroundColor;
4872 if ( mSelectionColor == color )
4875 mSelectionColor = color;
4883 return mSelectionColor;
4920 translationContext.setFileName( QStringLiteral(
"%1/%2.ts" ).arg(
absolutePath(),
baseName() ) );
4924 translationContext.writeTsFile( locale );
4927QString
QgsProject::translate(
const QString &context,
const QString &sourceText,
const char *disambiguation,
int n )
const
4936 QString result = mTranslator->translate( context.toUtf8(), sourceText.toUtf8(), disambiguation, n );
4938 if ( result.isEmpty() )
4952 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
4957 if ( !( ( *it )->accept( visitor ) ) )
4966 if ( !mLayoutManager->accept( visitor ) )
4969 if ( !mAnnotationManager->accept( visitor ) )
4977 return mElevationShadingRenderer;
4980void QgsProject::loadProjectFlags(
const QDomDocument *doc )
4984 QDomElement element = doc->documentElement().firstChildElement( QStringLiteral(
"projectFlags" ) );
4985 Qgis::ProjectFlags
flags;
4986 if ( !element.isNull() )
4993 element = doc->documentElement().firstChildElement( QStringLiteral(
"evaluateDefaultValues" ) );
4994 if ( !element.isNull() )
4996 if ( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
5001 element = doc->documentElement().firstChildElement( QStringLiteral(
"trust" ) );
5002 if ( !element.isNull() )
5004 if ( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
5013GetNamedProjectColor::GetNamedProjectColor(
const QgsProject *project )
5020 QStringList colorStrings = project->
readListEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Colors" ) );
5021 const QStringList colorLabels = project->
readListEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Labels" ) );
5025 for ( QStringList::iterator it = colorStrings.begin();
5026 it != colorStrings.end(); ++it )
5030 if ( colorLabels.length() > colorIndex )
5032 label = colorLabels.at( colorIndex );
5035 mColors.insert( label.toLower(), color );
5040GetNamedProjectColor::GetNamedProjectColor(
const QHash<QString, QColor> &colors )
5048 const QString colorName = values.at( 0 ).toString().toLower();
5049 if ( mColors.contains( colorName ) )
5051 return QStringLiteral(
"%1,%2,%3" ).arg( mColors.value( colorName ).red() ).arg( mColors.value( colorName ).green() ).arg( mColors.value( colorName ).blue() );
5059 return new GetNamedProjectColor( mColors );
5064GetSensorData::GetSensorData(
const QMap<QString, QgsAbstractSensor::SensorData> &sensorData )
5067 QStringLiteral(
"Sensors" ) )
5068 , mSensorData( sensorData )
5074 const QString sensorName = values.at( 0 ).toString();
5075 const int expiration = values.at( 1 ).toInt();
5076 const qint64 timestamp = QDateTime::currentMSecsSinceEpoch();
5077 if ( mSensorData.contains( sensorName ) )
5079 if ( expiration <= 0 || ( timestamp - mSensorData[sensorName].lastTimestamp.toMSecsSinceEpoch() ) < expiration )
5081 return mSensorData[sensorName].lastValue;
5090 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.
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.
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.
@ 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.
QString toProj() const
Returns a Proj string representation of this CRS.
bool readXml(const QDomNode &node)
Restores state from the given DOM node.
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.
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::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...
@ 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.
bool isEmpty() const
Checks whether the container is empty.
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 childrens, disconnect all the forwarded and external signals and sets their parent to nul...
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.
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 id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
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...
@ 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.
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 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.
QgsAnnotationManager * annotationManager()
Returns pointer to the project's annotation manager.
QgsProjectDisplaySettings * displaySettings
Qgis::TransactionMode transactionMode() const
Returns the transaction mode.
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 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.
QList< QgsMapLayer * > mapLayersByName(const QString &layerName) const
Retrieve a list of matching registered layers by layer name.
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...
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 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.
QgsFields fields() const FINAL
Returns the list of fields of this 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.