79#include <QApplication>
84#include <QTemporaryFile>
87#include <QStandardPaths>
89#include <QRegularExpression>
111 QStringList keyTokens = QStringList( scope );
112#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
113 keyTokens += key.split(
'/', QString::SkipEmptyParts );
115 keyTokens += key.split(
'/', Qt::SkipEmptyParts );
119 keyTokens.push_front( QStringLiteral(
"properties" ) );
122 for (
int i = 0; i < keyTokens.size(); ++i )
124 const QString keyToken = keyTokens.at( i );
128 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}])" ) );
129 if ( keyToken.contains( sInvalidRegexp ) )
131 const QString errorString = QObject::tr(
"Entry token invalid : '%1'. The token will not be saved to file." ).arg( keyToken );
159 while ( !keySequence.isEmpty() )
163 if ( keySequence.first() == currentProperty->
name() )
166 keySequence.pop_front();
168 if ( 1 == keySequence.count() )
171 return currentProperty->
find( keySequence.front() );
173 else if ( keySequence.isEmpty() )
178 return currentProperty;
180 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
182 if ( nextProperty->
isKey() )
186 else if ( nextProperty->
isValue() && 1 == keySequence.count() )
192 return currentProperty;
230 const QVariant &value,
231 bool &propertiesModified )
240 propertiesModified =
false;
241 while ( ! keySequence.isEmpty() )
245 if ( keySequence.first() == currentProperty->
name() )
248 keySequence.pop_front();
252 if ( 1 == keySequence.count() )
255 if ( !property || property->value() != value )
257 currentProperty->
setValue( keySequence.front(), value );
258 propertiesModified =
true;
261 return currentProperty;
265 else if ( keySequence.isEmpty() )
267 if ( currentProperty->
value() != value )
270 propertiesModified =
true;
273 return currentProperty;
275 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
279 if ( currentProperty )
290 if ( ( newPropertyKey = currentProperty->
addKey( keySequence.first() ) ) )
292 currentProperty = newPropertyKey;
324 while ( ! keySequence.isEmpty() )
328 if ( keySequence.first() == currentProperty->
name() )
331 keySequence.pop_front();
335 if ( 1 == keySequence.count() )
337 currentProperty->
removeKey( keySequence.front() );
342 else if ( keySequence.isEmpty() )
344 previousQgsPropertyKey->
removeKey( currentProperty->
name() );
346 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
348 previousQgsPropertyKey = currentProperty;
351 if ( currentProperty )
375 , mCapabilities( capabilities )
378 , mSnappingConfig( this )
396 mProperties.
setName( QStringLiteral(
"properties" ) );
399 mMainAnnotationLayer->setParent(
this );
413 this, [ = ](
const QStringList &
layers ) { mProjectScope.reset(); emit layersWillBeRemoved( layers ); } );
415 this, [ = ](
const QList<QgsMapLayer *> &
layers ) { mProjectScope.reset(); emit layersWillBeRemoved( layers ); } );
417 this, [ = ](
const QString & layer ) { mProjectScope.reset(); emit layerWillBeRemoved( layer ); } );
419 this, [ = ](
QgsMapLayer * layer ) { mProjectScope.reset(); emit layerWillBeRemoved( layer ); } );
421 [ = ](
const QStringList &
layers ) { mProjectScope.reset(); emit layersRemoved( layers ); } );
423 [ = ](
const QString & layer ) { mProjectScope.reset(); emit layerRemoved( layer ); } );
425 [ = ]() { mProjectScope.reset(); emit removeAll(); } );
427 [ = ](
const QList< QgsMapLayer * > &
layers ) { mProjectScope.reset(); emit layersAdded( layers ); } );
429 [ = ](
QgsMapLayer * layer ) { mProjectScope.reset(); emit layerWasAdded( layer ); } );
437 [ = ](
const QList<QgsMapLayer *> &
layers )
439 for ( const auto &layer : layers )
441 disconnect( layer, &QgsMapLayer::dataSourceChanged, mRelationManager, &QgsRelationManager::updateRelationsStatus );
446 [ = ](
const QList<QgsMapLayer *> &layers )
448 for ( const auto &layer : layers )
450 connect( layer, &QgsMapLayer::dataSourceChanged, mRelationManager, &QgsRelationManager::updateRelationsStatus );
459 mStyleSettings->combinedStyleModel()->addDefaultStyle();
465 mIsBeingDeleted =
true;
468 releaseHandlesToProjectArchive();
469 delete mBadLayerHandler;
470 delete mRelationManager;
471 delete mLayerTreeRegistryBridge;
473 if (
this == sProject )
504 mProjectScope.reset();
515 return mMetadata.
title();
524 if ( oldEvaluateDefaultValues != newEvaluateDefaultValues )
527 for (
auto layerIt =
layers.constBegin(); layerIt !=
layers.constEnd(); ++layerIt )
529 if (
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layerIt.value() ) )
530 if ( vl->dataProvider() )
537 if ( oldTrustLayerMetadata != newTrustLayerMetadata )
540 for (
auto layerIt =
layers.constBegin(); layerIt !=
layers.constEnd(); ++layerIt )
542 if (
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layerIt.value() ) )
544 vl->setReadExtentFromXml( newTrustLayerMetadata );
549 if ( mFlags !=
flags )
560 Qgis::ProjectFlags newFlags = mFlags;
564 newFlags &= ~(
static_cast< int >( flag ) );
579 return mSaveUserFull;
586 return mSaveDateTime;
607 if ( dirty && mDirtyBlockCount > 0 )
613 if ( mDirty == dirty )
624 if ( path == mHomePath )
628 mCachedHomePath.clear();
629 mProjectScope.reset();
640 const QList<QgsAttributeEditorElement *> elements = parent->
children();
648 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:formcontainers" ).arg( layerId ), container->
name() );
650 if ( !container->
children().empty() )
665 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1" ).arg( layer->layerId() ), layer->name() );
674 for (
const QgsField &field : fields )
677 if ( field.alias().isEmpty() )
678 fieldName = field.name();
680 fieldName = field.alias();
682 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:fieldaliases" ).arg( vlayer->
id() ), fieldName );
684 if ( field.editorWidgetSetup().type() == QLatin1String(
"ValueRelation" ) )
686 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:fields:%2:valuerelationvalue" ).arg( vlayer->
id(), field.name() ), field.editorWidgetSetup().config().value( QStringLiteral(
"Value" ) ).toString() );
697 const QList<QgsLayerTreeGroup *> groupLayers = mRootGroup->
findGroups();
700 translationContext->
registerTranslation( QStringLiteral(
"project:layergroups" ), groupLayer->name() );
704 const QList<QgsRelation> &relations = mRelationManager->
relations().values();
707 translationContext->
registerTranslation( QStringLiteral(
"project:relations" ), relation.name() );
715 mDataDefinedServerProperties = properties;
722 return mDataDefinedServerProperties;
729 switch ( mTransactionMode )
750 switch ( mTransactionMode )
757 commitErrors.append( tr(
"Trying to commit changes without a layer specified. This only works if the transaction mode is buffered" ) );
766 return mEditBufferGroup.
commitChanges( commitErrors, stopEditing );
776 switch ( mTransactionMode )
783 rollbackErrors.append( tr(
"Trying to roll back changes without a layer specified. This only works if the transaction mode is buffered" ) );
786 bool success = vectorLayer->
rollBack( stopEditing );
792 return mEditBufferGroup.
rollBack( rollbackErrors, stopEditing );
802 if ( name == mFile.fileName() )
805 const QString oldHomePath =
homePath();
807 mFile.setFileName( name );
808 mCachedHomePath.clear();
809 mProjectScope.reset();
813 const QString newHomePath =
homePath();
814 if ( newHomePath != oldHomePath )
825 return mFile.fileName();
832 mOriginalPath = path;
839 return mOriginalPath;
846 return QFileInfo( mFile );
864 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
869 return QFileInfo( mFile.fileName() ).lastModified();
880 if ( mFile.fileName().isEmpty() )
883 return QFileInfo( mFile.fileName() ).absolutePath();
894 if ( mFile.fileName().isEmpty() )
897 return QFileInfo( mFile.fileName() ).absoluteFilePath();
908 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
913 return QFileInfo( mFile.fileName() ).completeBaseName();
921 const bool absolutePaths =
readBoolEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
false );
932 writeEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
true );
935 writeEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
false );
955 writeEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectionsEnabled" ),
crs.
isValid() ? 1 : 0 );
956 mProjectScope.reset();
967 if ( adjustEllipsoid )
976 if ( !
crs().isValid() )
979 return readEntry( QStringLiteral(
"Measure" ), QStringLiteral(
"/Ellipsoid" ),
geoNone() );
986 if (
ellipsoid ==
readEntry( QStringLiteral(
"Measure" ), QStringLiteral(
"/Ellipsoid" ) ) )
989 mProjectScope.reset();
999 return mTransformContext;
1006 if ( context == mTransformContext )
1009 mTransformContext = context;
1010 mProjectScope.reset();
1013 for (
auto &layer : mLayerStore.get()->mapLayers() )
1015 layer->setTransformContext( context );
1024 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
1028 mProjectScope.reset();
1029 mFile.setFileName( QString() );
1032 mSaveUserFull.clear();
1033 mSaveDateTime = QDateTime();
1036 mCachedHomePath.clear();
1038 mFlags = Qgis::ProjectFlags();
1040 mCustomVariables.clear();
1044 if ( !mSettings.
value( QStringLiteral(
"projects/anonymize_new_projects" ),
false,
QgsSettings::Core ).toBool() )
1063 mEmbeddedLayers.clear();
1064 mRelationManager->
clear();
1065 mAnnotationManager->clear();
1066 mLayoutManager->clear();
1067 m3DViewsManager->clear();
1068 mBookmarkManager->
clear();
1069 mSensorManager->
clear();
1070 mViewSettings->
reset();
1071 mTimeSettings->
reset();
1072 mElevationProperties->
reset();
1073 mDisplaySettings->
reset();
1074 mGpsSettings->
reset();
1075 mSnappingConfig.
reset();
1083 mLabelingEngineSettings->clear();
1087 releaseHandlesToProjectArchive();
1093 mStyleSettings->
reset();
1097 if ( !mIsBeingDeleted )
1105 writeEntry( QStringLiteral(
"PositionPrecision" ), QStringLiteral(
"/Automatic" ),
true );
1106 writeEntry( QStringLiteral(
"PositionPrecision" ), QStringLiteral(
"/DecimalPlaces" ), 2 );
1108 const bool defaultRelativePaths = mSettings.
value( QStringLiteral(
"/qgis/defaultProjectPathsRelative" ),
true ).toBool();
1111 int red = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_red" ), 255 ).toInt();
1112 int green = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_green" ), 255 ).toInt();
1113 int blue = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_blue" ), 255 ).toInt();
1116 red = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_red" ), 255 ).toInt();
1117 green = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_green" ), 255 ).toInt();
1118 blue = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_blue" ), 0 ).toInt();
1119 const int alpha = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_alpha" ), 255 ).toInt();
1125 mRootGroup->
clear();
1126 if ( mMainAnnotationLayer )
1127 mMainAnnotationLayer->
reset();
1129 snapSingleBlocker.release();
1131 if ( !mBlockSnappingUpdates )
1143 topQgsPropertyKey.
dump();
1176 const QDomElement propertiesElem = doc.documentElement().firstChildElement( QStringLiteral(
"properties" ) );
1178 if ( propertiesElem.isNull() )
1183 const QDomNodeList scopes = propertiesElem.childNodes();
1185 if ( propertiesElem.firstChild().isNull() )
1187 QgsDebugError( QStringLiteral(
"empty ``properties'' XML tag ... bailing" ) );
1191 if ( ! project_properties.
readXml( propertiesElem ) )
1193 QgsDebugError( QStringLiteral(
"Project_properties.readXml() failed" ) );
1207 const QDomElement ddElem = doc.documentElement().firstChildElement( QStringLiteral(
"dataDefinedServerProperties" ) );
1208 if ( !ddElem.isNull() )
1210 if ( !ddServerProperties.
readXml( ddElem, dataDefinedServerPropertyDefinitions ) )
1212 QgsDebugError( QStringLiteral(
"dataDefinedServerProperties.readXml() failed" ) );
1215 return ddServerProperties;
1222static void _getTitle(
const QDomDocument &doc, QString &title )
1224 const QDomElement titleNode = doc.documentElement().firstChildElement( QStringLiteral(
"title" ) );
1228 if ( titleNode.isNull() )
1234 if ( !titleNode.hasChildNodes() )
1240 const QDomNode titleTextNode = titleNode.firstChild();
1242 if ( !titleTextNode.isText() )
1248 const QDomText titleText = titleTextNode.toText();
1250 title = titleText.data();
1254static void readProjectFileMetadata(
const QDomDocument &doc, QString &lastUser, QString &lastUserFull, QDateTime &lastSaveDateTime )
1256 const QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"qgis" ) );
1260 QgsDebugError( QStringLiteral(
"unable to find qgis element" ) );
1264 const QDomNode qgisNode = nl.item( 0 );
1266 const QDomElement qgisElement = qgisNode.toElement();
1267 lastUser = qgisElement.attribute( QStringLiteral(
"saveUser" ), QString() );
1268 lastUserFull = qgisElement.attribute( QStringLiteral(
"saveUserFull" ), QString() );
1269 lastSaveDateTime = QDateTime::fromString( qgisElement.attribute( QStringLiteral(
"saveDateTime" ), QString() ), Qt::ISODate );
1274 const QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"qgis" ) );
1278 QgsDebugError( QStringLiteral(
" unable to find qgis element in project file" ) );
1282 const QDomNode qgisNode = nl.item( 0 );
1284 const QDomElement qgisElement = qgisNode.toElement();
1285 QgsProjectVersion projectVersion( qgisElement.attribute( QStringLiteral(
"version" ) ) );
1286 return projectVersion;
1293 return mSnappingConfig;
1312 if ( mAvoidIntersectionsMode == mode )
1315 mAvoidIntersectionsMode = mode;
1319static QgsMapLayer::ReadFlags projectFlagsToLayerReadFlags( Qgis::ProjectReadFlags projectReadFlags, Qgis::ProjectFlags projectFlags )
1321 QgsMapLayer::ReadFlags layerFlags = QgsMapLayer::ReadFlags();
1344void QgsProject::preloadProviders(
const QVector<QDomNode> ¶llelLayerNodes,
1346 QMap<QString, QgsDataProvider *> &loadedProviders,
1347 QgsMapLayer::ReadFlags layerReadFlags,
1348 int totalProviderCount )
1353 QMap<QString, LayerToLoad> layersToLoad;
1355 for (
const QDomNode &node : parallelLayerNodes )
1359 const QDomElement layerElement = node.toElement();
1361 layerToLoad.
layerId = layerElement.namedItem( QStringLiteral(
"id" ) ).toElement().text();
1362 layerToLoad.
provider = layerElement.namedItem( QStringLiteral(
"provider" ) ).toElement().text();
1363 layerToLoad.
dataSource = layerElement.namedItem( QStringLiteral(
"datasource" ) ).toElement().text();
1374 layersToLoad.insert( layerToLoad.
layerId, layerToLoad );
1377 while ( !layersToLoad.isEmpty() )
1379 const QList<LayerToLoad> layersToAttemptInParallel = layersToLoad.values();
1380 QString layerToAttemptInMainThread;
1382 QHash<QString, QgsRunnableProviderCreator *> runnables;
1383 QThreadPool threadPool;
1386 for (
const LayerToLoad &lay : layersToAttemptInParallel )
1389 runnables.insert( lay.layerId, run );
1395 layersToLoad.remove( layId );
1398 Q_ASSERT( finishedRun );
1400 std::unique_ptr<QgsDataProvider> provider( finishedRun->
dataProvider() );
1401 Q_ASSERT( provider && provider->isValid() );
1403 loadedProviders.insert( layId, provider.release() );
1408 if ( layerToAttemptInMainThread.isEmpty() )
1409 layerToAttemptInMainThread = layId;
1413 if ( i == parallelLayerNodes.count() || !isValid )
1416 threadPool.start( run );
1420 threadPool.waitForDone();
1422 qDeleteAll( runnables );
1425 auto it = layersToLoad.find( layerToAttemptInMainThread );
1426 if ( it != layersToLoad.end() )
1428 std::unique_ptr<QgsDataProvider> provider;
1432 QgsDataProvider::ReadFlags providerFlags = lay.
flags;
1438 if ( provider && provider->isValid() )
1443 layersToLoad.erase( it );
1446 loadedProviders.insert( layerId, provider.release() );
1454void QgsProject::releaseHandlesToProjectArchive()
1459bool QgsProject::_getMapLayers(
const QDomDocument &doc, QList<QDomNode> &brokenNodes, Qgis::ProjectReadFlags flags )
1466 QDomElement layerElement = doc.documentElement().firstChildElement( QStringLiteral(
"projectlayers" ) ).firstChildElement( QStringLiteral(
"maplayer" ) );
1470 if ( layerElement.isNull() )
1480 bool returnStatus =
true;
1483 while ( ! layerElement.isNull() )
1486 layerElement = layerElement.nextSiblingElement( QStringLiteral(
"maplayer" ) );
1492 if ( depSorter.hasCycle() )
1496 if ( depSorter.hasMissingDependency() )
1497 returnStatus =
false;
1501 const QVector<QDomNode> sortedLayerNodes = depSorter.sortedLayerNodes();
1502 const int totalLayerCount = sortedLayerNodes.count();
1504 QVector<QDomNode> parallelLoading;
1505 QMap<QString, QgsDataProvider *> loadedProviders;
1509 profile.switchTask( tr(
"Load providers in parallel" ) );
1510 for (
const QDomNode &node : sortedLayerNodes )
1512 const QDomElement element = node.toElement();
1513 if ( element.attribute( QStringLiteral(
"embedded" ) ) != QLatin1String(
"1" ) )
1515 const QString layerId = node.namedItem( QStringLiteral(
"id" ) ).toElement().text();
1516 if ( !depSorter.isLayerDependent( layerId ) )
1518 const QDomNode mnl = element.namedItem( QStringLiteral(
"provider" ) );
1519 const QDomElement mne = mnl.toElement();
1520 const QString provider = mne.text();
1524 parallelLoading.append( node );
1533 if ( !parallelLoading.isEmpty() )
1534 preloadProviders( parallelLoading, context, loadedProviders, projectFlagsToLayerReadFlags(
flags, mFlags ), sortedLayerNodes.count() );
1537 int i = loadedProviders.count();
1538 for (
const QDomNode &node : std::as_const( sortedLayerNodes ) )
1540 const QDomElement element = node.toElement();
1541 const QString name =
translate( QStringLiteral(
"project:layers:%1" ).arg( node.namedItem( QStringLiteral(
"id" ) ).toElement().text() ), node.namedItem( QStringLiteral(
"layername" ) ).toElement().text() );
1542 if ( !name.isNull() )
1543 emit
loadingLayer( tr(
"Loading layer %1" ).arg( name ) );
1545 profile.switchTask( name );
1546 if ( element.attribute( QStringLiteral(
"embedded" ) ) == QLatin1String(
"1" ) )
1548 createEmbeddedLayer( element.attribute( QStringLiteral(
"id" ) ),
readPath( element.attribute( QStringLiteral(
"project" ) ) ), brokenNodes,
true,
flags );
1556 QString layerId = element.namedItem( QStringLiteral(
"id" ) ).toElement().text();
1558 if ( !addLayer( element, brokenNodes, context,
flags, loadedProviders.take( layerId ) ) )
1560 returnStatus =
false;
1563 if ( !messages.isEmpty() )
1572 return returnStatus;
1575bool QgsProject::addLayer(
const QDomElement &layerElem,
1576 QList<QDomNode> &brokenNodes,
1578 Qgis::ProjectReadFlags flags,
1583 const QString type = layerElem.attribute( QStringLiteral(
"type" ) );
1585 std::unique_ptr<QgsMapLayer>
mapLayer;
1593 QgsDebugError( QStringLiteral(
"Unknown layer type \"%1\"" ).arg( type ) );
1597 switch ( layerType )
1600 mapLayer = std::make_unique<QgsVectorLayer>();
1604 mapLayer = std::make_unique<QgsRasterLayer>();
1608 mapLayer = std::make_unique<QgsMeshLayer>();
1612 mapLayer = std::make_unique<QgsVectorTileLayer>();
1616 mapLayer = std::make_unique<QgsPointCloudLayer>();
1620 mapLayer = std::make_unique<QgsTiledSceneLayer>();
1625 const QString
typeName = layerElem.attribute( QStringLiteral(
"name" ) );
1633 mapLayer = std::make_unique<QgsAnnotationLayer>( QString(), options );
1640 mapLayer = std::make_unique<QgsGroupLayer>( QString(), options );
1647 QgsDebugError( QStringLiteral(
"Unable to create layer" ) );
1655 const QString layerId { layerElem.namedItem( QStringLiteral(
"id" ) ).toElement().text() };
1656 Q_ASSERT( ! layerId.isEmpty() );
1660 QgsMapLayer::ReadFlags layerFlags = projectFlagsToLayerReadFlags(
flags, mFlags );
1662 profile.switchTask( tr(
"Load layer source" ) );
1669 if ( vl->dataProvider() )
1676 profile.switchTask( tr(
"Add layer to project" ) );
1677 QList<QgsMapLayer *> newLayers;
1689 vLayer->joinBuffer()->resolveReferences(
this );
1698 brokenNodes.push_back( layerElem );
1701 const bool wasEditable = layerElem.attribute( QStringLiteral(
"editable" ), QStringLiteral(
"0" ) ).toInt();
1713 if ( ! layerWasStored )
1718 return layerIsValid;
1725 mFile.setFileName( filename );
1726 mCachedHomePath.clear();
1727 mProjectScope.reset();
1736 const QString filename = mFile.fileName();
1741 QTemporaryFile inDevice;
1742 if ( !inDevice.open() )
1744 setError( tr(
"Unable to open %1" ).arg( inDevice.fileName() ) );
1750 if ( !storage->readProject( filename, &inDevice, context ) )
1752 QString err = tr(
"Unable to open %1" ).arg( filename );
1753 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
1754 if ( !messages.isEmpty() )
1755 err += QStringLiteral(
"\n\n" ) + messages.last().message();
1759 returnValue = unzip( inDevice.fileName(),
flags );
1765 returnValue = unzip( mFile.fileName(),
flags );
1770 const QFileInfo finfo( mFile.fileName() );
1771 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( QStringLiteral(
"%1_attachments.zip" ).arg( finfo.completeBaseName() ) );
1772 if ( QFile( attachmentsZip ).exists() )
1774 std::unique_ptr<QgsArchive> archive(
new QgsArchive() );
1775 if ( archive->unzip( attachmentsZip ) )
1777 releaseHandlesToProjectArchive();
1778 mArchive = std::move( archive );
1781 returnValue = readProjectFile( mFile.fileName(),
flags );
1787 mFile.setFileName( filename );
1788 mCachedHomePath.clear();
1789 mProjectScope.reset();
1794 mTranslator.reset(
nullptr );
1801bool QgsProject::readProjectFile(
const QString &filename, Qgis::ProjectReadFlags flags )
1806 ScopedIntIncrementor snapSignalBlock( &mBlockSnappingUpdates );
1808 QFile projectFile( filename );
1816 if ( QFile( QStringLiteral(
"%1/%2.qm" ).arg( QFileInfo( projectFile.fileName() ).absolutePath(), localeFileName ) ).exists() )
1818 mTranslator.reset(
new QTranslator() );
1819 ( void )mTranslator->load( localeFileName, QFileInfo( projectFile.fileName() ).absolutePath() );
1822 profile.switchTask( tr(
"Reading project file" ) );
1823 std::unique_ptr<QDomDocument> doc(
new QDomDocument( QStringLiteral(
"qgis" ) ) );
1825 if ( !projectFile.open( QIODevice::ReadOnly | QIODevice::Text ) )
1827 projectFile.close();
1829 setError( tr(
"Unable to open %1" ).arg( projectFile.fileName() ) );
1838 if ( !doc->setContent( &projectFile, &errorMsg, &line, &column ) )
1840 const QString errorString = tr(
"Project file read error in file %1: %2 at line %3 column %4" )
1841 .arg( projectFile.fileName(), errorMsg ).arg( line ).arg( column );
1845 projectFile.close();
1847 setError( errorString );
1852 projectFile.close();
1860 profile.switchTask( tr(
"Updating project file" ) );
1861 if ( thisVersion > fileVersion )
1863 const bool isOlderMajorVersion = fileVersion.
majorVersion() < thisVersion.majorVersion();
1865 if ( isOlderMajorVersion )
1868 "version of qgis (saved in " + fileVersion.
text() +
1870 "). Problems may occur." );
1881 projectFile.updateRevision( thisVersion );
1883 else if ( fileVersion > thisVersion )
1886 "version of qgis (saved in " + fileVersion.
text() +
1888 "). Problems may occur." );
1894 profile.switchTask( tr(
"Creating auxiliary storage" ) );
1895 const QString
fileName = mFile.fileName();
1900 std::unique_ptr<QgsAuxiliaryStorage> aStorage = std::move( mAuxiliaryStorage );
1901 std::unique_ptr<QgsArchive> archive = std::move( mArchive );
1907 releaseHandlesToProjectArchive();
1909 mAuxiliaryStorage = std::move( aStorage );
1910 mArchive = std::move( archive );
1915 mCachedHomePath.clear();
1916 mProjectScope.reset();
1917 mSaveVersion = fileVersion;
1920 profile.switchTask( tr(
"Reading properties" ) );
1929 dump_( mProperties );
1934 _getTitle( *doc, oldTitle );
1936 readProjectFileMetadata( *doc, mSaveUser, mSaveUserFull, mSaveDateTime );
1938 const QDomNodeList homePathNl = doc->elementsByTagName( QStringLiteral(
"homePath" ) );
1939 if ( homePathNl.count() > 0 )
1941 const QDomElement homePathElement = homePathNl.at( 0 ).toElement();
1942 const QString
homePath = homePathElement.attribute( QStringLiteral(
"path" ) );
1952 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorGreenPart" ), 255 ),
1953 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorBluePart" ), 255 ) );
1956 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorGreenPart" ), 255 ),
1957 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorBluePart" ), 255 ),
1958 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorAlphaPart" ), 255 ) );
1962 const QString distanceUnitString =
readEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/DistanceUnits" ), QString() );
1963 if ( !distanceUnitString.isEmpty() )
1966 const QString areaUnitString =
readEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/AreaUnits" ), QString() );
1967 if ( !areaUnitString.isEmpty() )
1976 if (
readNumEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectionsEnabled" ), 0 ) )
1979 const QDomNode srsNode = doc->documentElement().namedItem( QStringLiteral(
"projectCrs" ) );
1980 if ( !srsNode.isNull() )
1982 projectCrs.
readXml( srsNode );
1987 const QString projCrsString =
readEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCRSProj4String" ) );
1988 const long currentCRS =
readNumEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCRSID" ), -1 );
1989 const QString authid =
readEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCrs" ) );
1992 const bool isUserAuthId = authid.startsWith( QLatin1String(
"USER:" ), Qt::CaseInsensitive );
1993 if ( !authid.isEmpty() && !isUserAuthId )
1997 if ( !projectCrs.
isValid() && currentCRS >= 0 )
2003 if ( !projCrsString.isEmpty() && ( authid.isEmpty() || isUserAuthId ) && ( !projectCrs.
isValid() || projectCrs.
toProj() != projCrsString ) )
2017 QStringList datumErrors;
2018 if ( !mTransformContext.
readXml( doc->documentElement(), context, datumErrors ) && !datumErrors.empty() )
2025 const QDomNode elevationShadingNode = doc->documentElement().namedItem( QStringLiteral(
"elevation-shading-renderer" ) );
2026 if ( !elevationShadingNode.isNull() )
2028 mElevationShadingRenderer.
readXml( elevationShadingNode.toElement(), context );
2035 const QStringList variableNames =
readListEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableNames" ) );
2036 const QStringList variableValues =
readListEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableValues" ) );
2038 mCustomVariables.clear();
2039 if ( variableNames.length() == variableValues.length() )
2041 for (
int i = 0; i < variableNames.length(); ++i )
2043 mCustomVariables.insert( variableNames.at( i ), variableValues.at( i ) );
2048 QgsMessageLog::logMessage( tr(
"Project Variables Invalid" ), tr(
"The project contains invalid variable settings." ) );
2051 QDomElement element = doc->documentElement().firstChildElement( QStringLiteral(
"projectMetadata" ) );
2053 if ( !element.isNull() )
2062 if ( mMetadata.
title().isEmpty() && !oldTitle.isEmpty() )
2070 element = doc->documentElement().firstChildElement( QStringLiteral(
"transaction" ) );
2071 if ( !element.isNull() )
2078 element = doc->documentElement().firstChildElement( QStringLiteral(
"autotransaction" ) );
2079 if ( ! element.isNull() )
2081 mTransactionMode =
static_cast<Qgis::TransactionMode>( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() );
2086 profile.switchTask( tr(
"Loading layer tree" ) );
2089 QDomElement layerTreeElem = doc->documentElement().firstChildElement( QStringLiteral(
"layer-tree-group" ) );
2090 if ( !layerTreeElem.isNull() )
2102 mLayerTreeRegistryBridge->
setEnabled(
false );
2105 profile.switchTask( tr(
"Reading map layers" ) );
2107 loadProjectFlags( doc.get() );
2109 QList<QDomNode> brokenNodes;
2110 const bool clean = _getMapLayers( *doc, brokenNodes,
flags );
2115 QgsDebugError( QStringLiteral(
"Unable to get map layers from project file." ) );
2117 if ( !brokenNodes.isEmpty() )
2119 QgsDebugError(
"there are " + QString::number( brokenNodes.size() ) +
" broken layers" );
2127 mMainAnnotationLayer->
readLayerXml( doc->documentElement().firstChildElement( QStringLiteral(
"main-annotation-layer" ) ), context );
2131 profile.switchTask( tr(
"Loading embedded layers" ) );
2132 loadEmbeddedNodes( mRootGroup,
flags );
2136 profile.switchTask( tr(
"Resolving layer references" ) );
2137 QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
2138 for ( QMap<QString, QgsMapLayer *>::iterator it =
layers.begin(); it !=
layers.end(); ++it )
2140 it.value()->resolveReferences(
this );
2143 mLayerTreeRegistryBridge->
setEnabled(
true );
2146 profile.switchTask( tr(
"Resolving references" ) );
2157 if ( !layerTreeElem.isNull() )
2163 const QDomElement layerTreeCanvasElem = doc->documentElement().firstChildElement( QStringLiteral(
"layer-tree-canvas" ) );
2164 if ( !layerTreeCanvasElem.isNull( ) )
2172 const QStringList requiredLayerIds =
readListEntry( QStringLiteral(
"RequiredLayers" ), QStringLiteral(
"Layers" ) );
2173 for (
const QString &layerId : requiredLayerIds )
2180 const QStringList disabledLayerIds =
readListEntry( QStringLiteral(
"Identify" ), QStringLiteral(
"/disabledLayers" ) );
2181 for (
const QString &layerId : disabledLayerIds )
2194 QString styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Marker" ) );
2195 if ( !styleName.isEmpty() )
2200 styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Line" ) );
2201 if ( !styleName.isEmpty() )
2206 styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Fill" ) );
2207 if ( !styleName.isEmpty() )
2212 styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/ColorRamp" ) );
2213 if ( !styleName.isEmpty() )
2223 double opacity = 1.0;
2226 double alpha =
readDoubleEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/AlphaInt" ), 255, &ok );
2228 opacity = alpha / 255.0;
2229 double newOpacity =
readDoubleEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Opacity" ), 1.0, &ok );
2231 opacity = newOpacity;
2235 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Marker" ) );
2236 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Line" ) );
2237 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Fill" ) );
2238 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/ColorRamp" ) );
2239 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/RandomColors" ) );
2240 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/AlphaInt" ) );
2241 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Opacity" ) );
2249 profile.switchTask( tr(
"Storing original layer properties" ) );
2255 profile.switchTask( tr(
"Loading map themes" ) );
2258 mMapThemeCollection->readXml( *doc );
2260 profile.switchTask( tr(
"Loading label settings" ) );
2261 mLabelingEngineSettings->readSettingsFromProject(
this );
2264 profile.switchTask( tr(
"Loading annotations" ) );
2265 mAnnotationManager->readXml( doc->documentElement(), context );
2268 profile.switchTask( tr(
"Loading layouts" ) );
2269 mLayoutManager->readXml( doc->documentElement(), *doc );
2274 profile.switchTask( tr(
"Loading 3D Views" ) );
2275 m3DViewsManager->readXml( doc->documentElement(), *doc );
2278 profile.switchTask( tr(
"Loading bookmarks" ) );
2279 mBookmarkManager->
readXml( doc->documentElement(), *doc );
2281 profile.switchTask( tr(
"Loading sensors" ) );
2282 mSensorManager->
readXml( doc->documentElement(), *doc );
2285 QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
2286 for ( QMap<QString, QgsMapLayer *>::iterator it = existingMaps.begin(); it != existingMaps.end(); ++it )
2288 it.value()->setDependencies( it.value()->dependencies() );
2291 profile.switchTask( tr(
"Loading snapping settings" ) );
2295 profile.switchTask( tr(
"Loading view settings" ) );
2298 const QStringList scales =
readListEntry( QStringLiteral(
"Scales" ), QStringLiteral(
"/ScalesList" ) );
2299 QVector<double> res;
2300 for (
const QString &scale : scales )
2302 const QStringList parts = scale.split(
':' );
2303 if ( parts.size() != 2 )
2307 const double denominator = QLocale().toDouble( parts[1], &ok );
2314 const QDomElement viewSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectViewSettings" ) );
2315 if ( !viewSettingsElement.isNull() )
2316 mViewSettings->
readXml( viewSettingsElement, context );
2319 profile.switchTask( tr(
"Loading style properties" ) );
2320 const QDomElement styleSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectStyleSettings" ) );
2321 if ( !styleSettingsElement.isNull() )
2324 mStyleSettings->
readXml( styleSettingsElement, context,
flags );
2328 profile.switchTask( tr(
"Loading temporal settings" ) );
2329 const QDomElement timeSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectTimeSettings" ) );
2330 if ( !timeSettingsElement.isNull() )
2331 mTimeSettings->
readXml( timeSettingsElement, context );
2334 profile.switchTask( tr(
"Loading elevation properties" ) );
2335 const QDomElement elevationPropertiesElement = doc->documentElement().firstChildElement( QStringLiteral(
"ElevationProperties" ) );
2336 if ( !elevationPropertiesElement.isNull() )
2337 mElevationProperties->
readXml( elevationPropertiesElement, context );
2340 profile.switchTask( tr(
"Loading display settings" ) );
2342 const QDomElement displaySettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectDisplaySettings" ) );
2343 if ( !displaySettingsElement.isNull() )
2344 mDisplaySettings->
readXml( displaySettingsElement, context );
2347 profile.switchTask( tr(
"Loading GPS settings" ) );
2349 const QDomElement gpsSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectGpsSettings" ) );
2350 if ( !gpsSettingsElement.isNull() )
2351 mGpsSettings->
readXml( gpsSettingsElement, context );
2355 profile.switchTask( tr(
"Updating variables" ) );
2357 profile.switchTask( tr(
"Updating CRS" ) );
2362 profile.switchTask( tr(
"Reading external settings" ) );
2366 profile.switchTask( tr(
"Updating interface" ) );
2368 snapSignalBlock.release();
2369 if ( !mBlockSnappingUpdates )
2380 QgsDebugMsgLevel( QStringLiteral(
"Project save user: %1" ).arg( mSaveUser ), 2 );
2381 QgsDebugMsgLevel( QStringLiteral(
"Project save user: %1" ).arg( mSaveUserFull ), 2 );
2390 const QString newFileName( QStringLiteral(
"%1/%2.qgs" ).arg( QFileInfo( projectFile.fileName() ).absolutePath(), localeFileName ) );
2405 const QMap<QString, QgsMapLayer *> loadedLayers =
mapLayers();
2406 for (
auto it = loadedLayers.constBegin(); it != loadedLayers.constEnd(); ++it )
2408 if ( it.value()->isValid() && it.value()->customProperty( QStringLiteral(
"_layer_was_editable" ) ).toBool() )
2410 if (
QgsVectorLayer *vl = qobject_cast< QgsVectorLayer * >( it.value() ) )
2412 it.value()->removeCustomProperty( QStringLiteral(
"_layer_was_editable" ) );
2419bool QgsProject::loadEmbeddedNodes(
QgsLayerTreeGroup *group, Qgis::ProjectReadFlags flags )
2424 const auto constChildren = group->
children();
2430 if ( childGroup->
customProperty( QStringLiteral(
"embedded" ) ).toInt() )
2433 const QString projectPath =
readPath( childGroup->
customProperty( QStringLiteral(
"embedded_project" ) ).toString() );
2434 childGroup->
setCustomProperty( QStringLiteral(
"embedded_project" ), projectPath );
2438 QList<QgsLayerTreeNode *> clonedChildren;
2439 const QList<QgsLayerTreeNode *> constChildren = newGroup->
children();
2440 clonedChildren.reserve( constChildren.size() );
2442 clonedChildren << newGroupChild->clone();
2450 loadEmbeddedNodes( childGroup,
flags );
2455 if ( child->customProperty( QStringLiteral(
"embedded" ) ).toInt() )
2457 QList<QDomNode> brokenNodes;
2460 valid = valid &&
false;
2475 return mCustomVariables;
2482 if ( variables == mCustomVariables )
2486 QStringList variableNames;
2487 QStringList variableValues;
2489 QVariantMap::const_iterator it = variables.constBegin();
2490 for ( ; it != variables.constEnd(); ++it )
2492 variableNames << it.key();
2493 variableValues << it.value().toString();
2496 writeEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableNames" ), variableNames );
2497 writeEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableValues" ), variableValues );
2499 mCustomVariables = variables;
2500 mProjectScope.reset();
2509 *mLabelingEngineSettings = settings;
2517 return *mLabelingEngineSettings;
2524 mProjectScope.reset();
2525 return mLayerStore.get();
2532 return mLayerStore.get();
2539 QList<QgsVectorLayer *>
layers;
2540 const QStringList layerIds =
readListEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsList" ), QStringList() );
2541 const auto constLayerIds = layerIds;
2542 for (
const QString &layerId : constLayerIds )
2555 list.reserve(
layers.size() );
2557 list << layer->id();
2558 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsList" ), list );
2580 if ( mProjectScope )
2582 std::unique_ptr< QgsExpressionContextScope > projectScope = std::make_unique< QgsExpressionContextScope >( *mProjectScope );
2589 projectScope->addFunction( QStringLiteral(
"sensor_data" ),
new GetSensorData(
sensorManager()->sensorsData() ) );
2591 return projectScope.release();
2594 mProjectScope = std::make_unique< QgsExpressionContextScope >( QObject::tr(
"Project" ) );
2598 QVariantMap::const_iterator it = vars.constBegin();
2600 for ( ; it != vars.constEnd(); ++it )
2602 mProjectScope->setVariable( it.key(), it.value(),
true );
2606 if ( projectPath.isEmpty() )
2607 projectPath = mOriginalPath;
2608 const QString projectFolder = QFileInfo( projectPath ).path();
2609 const QString projectFilename = QFileInfo( projectPath ).fileName();
2610 const QString projectBasename =
baseName();
2639 QVariantMap keywords;
2641 for (
auto it = metadataKeywords.constBegin(); it != metadataKeywords.constEnd(); ++it )
2643 keywords.insert( it.key(), it.value() );
2648 QVariantList layersIds;
2650 const QMap<QString, QgsMapLayer *> layersInProject = mLayerStore->mapLayers();
2651 layersIds.reserve( layersInProject.count() );
2652 layers.reserve( layersInProject.count() );
2653 for (
auto it = layersInProject.constBegin(); it != layersInProject.constEnd(); ++it )
2655 layersIds << it.value()->id();
2661 mProjectScope->addFunction( QStringLiteral(
"project_color" ),
new GetNamedProjectColor(
this ) );
2666void QgsProject::onMapLayersAdded(
const QList<QgsMapLayer *> &layers )
2670 const QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
2672 const auto constLayers =
layers;
2675 if ( ! layer->isValid() )
2678 if (
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer ) )
2681 if ( vlayer->dataProvider() )
2689 for ( QMap<QString, QgsMapLayer *>::const_iterator it = existingMaps.cbegin(); it != existingMaps.cend(); ++it )
2691 const QSet<QgsMapLayerDependency> deps = it.value()->dependencies();
2692 if ( deps.contains( layer->id() ) )
2695 it.value()->setDependencies( deps );
2700 updateTransactionGroups();
2706void QgsProject::onMapLayersRemoved(
const QList<QgsMapLayer *> &layers )
2714void QgsProject::cleanTransactionGroups(
bool force )
2718 bool changed =
false;
2719 for ( QMap< QPair< QString, QString>,
QgsTransactionGroup *>::Iterator tg = mTransactionGroups.begin(); tg != mTransactionGroups.end(); )
2721 if ( tg.value()->isEmpty() || force )
2724 tg = mTransactionGroups.erase( tg );
2736void QgsProject::updateTransactionGroups()
2740 mEditBufferGroup.
clear();
2742 switch ( mTransactionMode )
2746 cleanTransactionGroups(
true );
2751 cleanTransactionGroups(
true );
2754 cleanTransactionGroups(
false );
2758 bool tgChanged =
false;
2759 const auto constLayers =
mapLayers().values();
2762 if ( ! layer->isValid() )
2765 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
2769 switch ( mTransactionMode )
2786 mTransactionGroups.insert( qMakePair( key, connString ), tg );
2796 mEditBufferGroup.
addLayer( vlayer );
2812 context.setProjectTranslator(
this );
2814 QList<QDomNode> brokenNodes;
2815 if ( addLayer( layerNode.toElement(), brokenNodes, context ) )
2819 const QVector<QgsVectorLayer *> vectorLayers = layers<QgsVectorLayer *>();
2823 layer->resolveReferences(
this );
2825 if ( layer->isValid() && layer->customProperty( QStringLiteral(
"_layer_was_editable" ) ).toBool() )
2827 layer->startEditing();
2828 layer->removeCustomProperty( QStringLiteral(
"_layer_was_editable" ) );
2840 mFile.setFileName( filename );
2841 mCachedHomePath.clear();
2849 mProjectScope.reset();
2855 const QString storageFilePath { storage->filePath( mFile.fileName() ) };
2856 if ( storageFilePath.isEmpty() )
2862 const QString tempPath = QStandardPaths::standardLocations( QStandardPaths::TempLocation ).at( 0 );
2863 const QString tmpZipFilename( tempPath + QDir::separator() + QUuid::createUuid().toString() );
2865 if ( !zip( tmpZipFilename ) )
2868 QFile tmpZipFile( tmpZipFilename );
2869 if ( !tmpZipFile.open( QIODevice::ReadOnly ) )
2871 setError( tr(
"Unable to read file %1" ).arg( tmpZipFilename ) );
2876 if ( !storage->writeProject( mFile.fileName(), &tmpZipFile, context ) )
2878 QString err = tr(
"Unable to save project to storage %1" ).arg( mFile.fileName() );
2879 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
2880 if ( !messages.isEmpty() )
2881 err += QStringLiteral(
"\n\n" ) + messages.last().message();
2887 QFile::remove( tmpZipFilename );
2894 return zip( mFile.fileName() );
2900 const bool asOk = saveAuxiliaryStorage();
2901 const bool writeOk = writeProjectFile( mFile.fileName() );
2902 bool attachmentsOk =
true;
2903 if ( !mArchive->files().isEmpty() )
2905 const QFileInfo finfo( mFile.fileName() );
2906 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( QStringLiteral(
"%1_attachments.zip" ).arg( finfo.completeBaseName() ) );
2907 attachmentsOk = mArchive->zip( attachmentsZip );
2911 if ( ( !asOk || !attachmentsOk ) && writeOk )
2913 QStringList errorMessage;
2916 const QString err = mAuxiliaryStorage->errorString();
2917 errorMessage.append( tr(
"Unable to save auxiliary storage ('%1')" ).arg( err ) );
2919 if ( !attachmentsOk )
2921 errorMessage.append( tr(
"Unable to save attachments archive" ) );
2923 setError( errorMessage.join(
'\n' ) );
2926 return asOk && writeOk && attachmentsOk;
2930bool QgsProject::writeProjectFile(
const QString &filename )
2934 QFile projectFile( filename );
2940 const QFileInfo myFileInfo( projectFile );
2941 if ( myFileInfo.exists() && !myFileInfo.isWritable() )
2943 setError( tr(
"%1 is not writable. Please adjust permissions (if possible) and try again." )
2944 .arg( projectFile.fileName() ) );
2952 QDomImplementation::setInvalidDataPolicy( QDomImplementation::DropInvalidChars );
2954 const QDomDocumentType documentType =
2955 QDomImplementation().createDocumentType( QStringLiteral(
"qgis" ), QStringLiteral(
"http://mrcc.com/qgis.dtd" ),
2956 QStringLiteral(
"SYSTEM" ) );
2957 std::unique_ptr<QDomDocument> doc(
new QDomDocument( documentType ) );
2959 QDomElement qgisNode = doc->createElement( QStringLiteral(
"qgis" ) );
2960 qgisNode.setAttribute( QStringLiteral(
"projectname" ),
title() );
2961 qgisNode.setAttribute( QStringLiteral(
"version" ),
Qgis::version() );
2963 if ( !mSettings.
value( QStringLiteral(
"projects/anonymize_saved_projects" ),
false,
QgsSettings::Core ).toBool() )
2967 qgisNode.setAttribute( QStringLiteral(
"saveUser" ), newSaveUser );
2968 qgisNode.setAttribute( QStringLiteral(
"saveUserFull" ), newSaveUserFull );
2969 mSaveUser = newSaveUser;
2970 mSaveUserFull = newSaveUserFull;
2971 mSaveDateTime = QDateTime::currentDateTime();
2972 qgisNode.setAttribute( QStringLiteral(
"saveDateTime" ), mSaveDateTime.toString( Qt::ISODate ) );
2977 mSaveUserFull.clear();
2978 mSaveDateTime = QDateTime();
2980 doc->appendChild( qgisNode );
2983 QDomElement homePathNode = doc->createElement( QStringLiteral(
"homePath" ) );
2984 homePathNode.setAttribute( QStringLiteral(
"path" ), mHomePath );
2985 qgisNode.appendChild( homePathNode );
2988 QDomElement titleNode = doc->createElement( QStringLiteral(
"title" ) );
2989 qgisNode.appendChild( titleNode );
2991 QDomElement transactionNode = doc->createElement( QStringLiteral(
"transaction" ) );
2992 transactionNode.setAttribute( QStringLiteral(
"mode" ),
qgsEnumValueToKey( mTransactionMode ) );
2993 qgisNode.appendChild( transactionNode );
2995 QDomElement flagsNode = doc->createElement( QStringLiteral(
"projectFlags" ) );
2997 qgisNode.appendChild( flagsNode );
2999 const QDomText titleText = doc->createTextNode(
title() );
3000 titleNode.appendChild( titleText );
3003 QDomElement srsNode = doc->createElement( QStringLiteral(
"projectCrs" ) );
3005 qgisNode.appendChild( srsNode );
3007 QDomElement elevationShadingNode = doc->createElement( QStringLiteral(
"elevation-shading-renderer" ) );
3008 mElevationShadingRenderer.
writeXml( elevationShadingNode, context );
3009 qgisNode.appendChild( elevationShadingNode );
3016 clonedRoot->
writeXml( qgisNode, context );
3020 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsMode" ),
static_cast<int>( mAvoidIntersectionsMode ) );
3028 QDomElement annotationLayerNode = doc->createElement( QStringLiteral(
"main-annotation-layer" ) );
3029 mMainAnnotationLayer->
writeLayerXml( annotationLayerNode, *doc, context );
3030 qgisNode.appendChild( annotationLayerNode );
3034 QDomElement projectLayersNode = doc->createElement( QStringLiteral(
"projectlayers" ) );
3036 QMap<QString, QgsMapLayer *>::ConstIterator li =
layers.constBegin();
3037 while ( li !=
layers.end() )
3043 const QHash< QString, QPair< QString, bool> >::const_iterator emIt = mEmbeddedLayers.constFind( ml->
id() );
3044 if ( emIt == mEmbeddedLayers.constEnd() )
3046 QDomElement maplayerElem;
3052 maplayerElem = doc->createElement( QStringLiteral(
"maplayer" ) );
3056 maplayerElem.setAttribute( QStringLiteral(
"editable" ), QStringLiteral(
"1" ) );
3060 QDomDocument document;
3063 maplayerElem = document.firstChildElement();
3067 QgsDebugError( QStringLiteral(
"Could not restore layer properties for layer %1" ).arg( ml->
id() ) );
3073 projectLayersNode.appendChild( maplayerElem );
3079 if ( emIt.value().second )
3081 QDomElement mapLayerElem = doc->createElement( QStringLiteral(
"maplayer" ) );
3082 mapLayerElem.setAttribute( QStringLiteral(
"embedded" ), 1 );
3083 mapLayerElem.setAttribute( QStringLiteral(
"project" ),
writePath( emIt.value().first ) );
3084 mapLayerElem.setAttribute( QStringLiteral(
"id" ), ml->
id() );
3085 projectLayersNode.appendChild( mapLayerElem );
3092 qgisNode.appendChild( projectLayersNode );
3094 QDomElement layerOrderNode = doc->createElement( QStringLiteral(
"layerorder" ) );
3096 for (
QgsMapLayer *layer : constCustomLayerOrder )
3098 QDomElement mapLayerElem = doc->createElement( QStringLiteral(
"layer" ) );
3099 mapLayerElem.setAttribute( QStringLiteral(
"id" ), layer->id() );
3100 layerOrderNode.appendChild( mapLayerElem );
3102 qgisNode.appendChild( layerOrderNode );
3104 mLabelingEngineSettings->writeSettingsToProject(
this );
3106 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorRedPart" ), mBackgroundColor.red() );
3107 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorGreenPart" ), mBackgroundColor.green() );
3108 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorBluePart" ), mBackgroundColor.blue() );
3110 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorRedPart" ), mSelectionColor.red() );
3111 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorGreenPart" ), mSelectionColor.green() );
3112 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorBluePart" ), mSelectionColor.blue() );
3113 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorAlphaPart" ), mSelectionColor.alpha() );
3120 dump_( mProperties );
3123 QgsDebugMsgLevel( QStringLiteral(
"there are %1 property scopes" ).arg(
static_cast<int>( mProperties.
count() ) ), 2 );
3128 mProperties.
writeXml( QStringLiteral(
"properties" ), qgisNode, *doc );
3131 QDomElement ddElem = doc->createElement( QStringLiteral(
"dataDefinedServerProperties" ) );
3132 mDataDefinedServerProperties.
writeXml( ddElem, dataDefinedServerPropertyDefinitions() );
3133 qgisNode.appendChild( ddElem );
3135 mMapThemeCollection->writeXml( *doc );
3137 mTransformContext.
writeXml( qgisNode, context );
3139 QDomElement metadataElem = doc->createElement( QStringLiteral(
"projectMetadata" ) );
3141 qgisNode.appendChild( metadataElem );
3144 const QDomElement annotationsElem = mAnnotationManager->writeXml( *doc, context );
3145 qgisNode.appendChild( annotationsElem );
3149 const QDomElement layoutElem = mLayoutManager->writeXml( *doc );
3150 qgisNode.appendChild( layoutElem );
3154 const QDomElement views3DElem = m3DViewsManager->writeXml( *doc );
3155 qgisNode.appendChild( views3DElem );
3159 const QDomElement bookmarkElem = mBookmarkManager->
writeXml( *doc );
3160 qgisNode.appendChild( bookmarkElem );
3164 const QDomElement sensorElem = mSensorManager->
writeXml( *doc );
3165 qgisNode.appendChild( sensorElem );
3169 const QDomElement viewSettingsElem = mViewSettings->
writeXml( *doc, context );
3170 qgisNode.appendChild( viewSettingsElem );
3174 const QDomElement styleSettingsElem = mStyleSettings->
writeXml( *doc, context );
3175 qgisNode.appendChild( styleSettingsElem );
3179 const QDomElement timeSettingsElement = mTimeSettings->
writeXml( *doc, context );
3180 qgisNode.appendChild( timeSettingsElement );
3184 const QDomElement elevationPropertiesElement = mElevationProperties->
writeXml( *doc, context );
3185 qgisNode.appendChild( elevationPropertiesElement );
3189 const QDomElement displaySettingsElem = mDisplaySettings->
writeXml( *doc, context );
3190 qgisNode.appendChild( displaySettingsElem );
3194 const QDomElement gpsSettingsElem = mGpsSettings->
writeXml( *doc, context );
3195 qgisNode.appendChild( gpsSettingsElem );
3204 QFile backupFile( QStringLiteral(
"%1~" ).arg( filename ) );
3206 ok &= backupFile.open( QIODevice::WriteOnly | QIODevice::Truncate );
3207 ok &= projectFile.open( QIODevice::ReadOnly );
3210 while ( ok && !projectFile.atEnd() )
3212 ba = projectFile.read( 10240 );
3213 ok &= backupFile.write( ba ) == ba.size();
3216 projectFile.close();
3221 setError( tr(
"Unable to create backup file %1" ).arg( backupFile.fileName() ) );
3226 struct utimbuf tb = {
static_cast<time_t
>( fi.lastRead().toSecsSinceEpoch() ),
static_cast<time_t
>( fi.lastModified().toSecsSinceEpoch() ) };
3227 utime( backupFile.fileName().toUtf8().constData(), &tb );
3230 if ( !projectFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
3232 projectFile.close();
3235 setError( tr(
"Unable to save to file %1" ).arg( projectFile.fileName() ) );
3239 QTemporaryFile tempFile;
3240 bool ok = tempFile.open();
3243 QTextStream projectFileStream( &tempFile );
3244 doc->save( projectFileStream, 2 );
3245 ok &= projectFileStream.pos() > -1;
3247 ok &= tempFile.seek( 0 );
3250 while ( ok && !tempFile.atEnd() )
3252 ba = tempFile.read( 10240 );
3253 ok &= projectFile.write( ba ) == ba.size();
3256 ok &= projectFile.error() == QFile::NoError;
3258 projectFile.close();
3265 setError( tr(
"Unable to save to file %1. Your project "
3266 "may be corrupted on disk. Try clearing some space on the volume and "
3267 "check file permissions before pressing save again." )
3268 .arg( projectFile.fileName() ) );
3282 bool propertiesModified;
3283 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3285 if ( propertiesModified )
3295 bool propertiesModified;
3296 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3298 if ( propertiesModified )
3308 bool propertiesModified;
3309 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3311 if ( propertiesModified )
3321 bool propertiesModified;
3322 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3324 if ( propertiesModified )
3334 bool propertiesModified;
3335 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3337 if ( propertiesModified )
3345 const QStringList &def,
3357 value =
property->value();
3359 const bool valid = QVariant::StringList == value.type();
3365 return value.toStringList();
3388 value =
property->value();
3390 const bool valid = value.canConvert( QVariant::String );
3395 return value.toString();
3414 value =
property->value();
3417 const bool valid = value.canConvert( QVariant::Int );
3426 return value.toInt();
3441 const QVariant value =
property->value();
3443 const bool valid = value.canConvert( QVariant::Double );
3448 return value.toDouble();
3465 const QVariant value =
property->value();
3467 const bool valid = value.canConvert( QVariant::Bool );
3472 return value.toBool();
3484 if (
findKey_( scope, key, mProperties ) )
3490 return !
findKey_( scope, key, mProperties );
3499 QStringList entries;
3501 if ( foundProperty )
3518 QStringList entries;
3520 if ( foundProperty )
3535 dump_( mProperties );
3555 filePath = storage->filePath( mFile.fileName() );
3582void QgsProject::setError(
const QString &errorMessage )
3586 mErrorMessage = errorMessage;
3593 return mErrorMessage;
3596void QgsProject::clearError()
3600 setError( QString() );
3607 delete mBadLayerHandler;
3608 mBadLayerHandler = handler;
3615 const QHash< QString, QPair< QString, bool > >::const_iterator it = mEmbeddedLayers.find(
id );
3616 if ( it == mEmbeddedLayers.constEnd() )
3620 return it.value().first;
3624 bool saveFlag, Qgis::ProjectReadFlags flags )
3630 static QString sPrevProjectFilePath;
3631 static QDateTime sPrevProjectFileTimestamp;
3632 static QDomDocument sProjectDocument;
3634 QString qgsProjectFile = projectFilePath;
3636 if ( projectFilePath.endsWith( QLatin1String(
".qgz" ), Qt::CaseInsensitive ) )
3638 archive.
unzip( projectFilePath );
3642 const QDateTime projectFileTimestamp = QFileInfo( projectFilePath ).lastModified();
3644 if ( projectFilePath != sPrevProjectFilePath || projectFileTimestamp != sPrevProjectFileTimestamp )
3646 sPrevProjectFilePath.clear();
3648 QFile projectFile( qgsProjectFile );
3649 if ( !projectFile.open( QIODevice::ReadOnly ) )
3654 if ( !sProjectDocument.setContent( &projectFile ) )
3659 sPrevProjectFilePath = projectFilePath;
3660 sPrevProjectFileTimestamp = projectFileTimestamp;
3664 bool useAbsolutePaths =
true;
3666 const QDomElement propertiesElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral(
"properties" ) );
3667 if ( !propertiesElem.isNull() )
3669 const QDomElement absElem = propertiesElem.firstChildElement( QStringLiteral(
"Paths" ) ).firstChildElement( QStringLiteral(
"Absolute" ) );
3670 if ( !absElem.isNull() )
3672 useAbsolutePaths = absElem.text().compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0;
3677 if ( !useAbsolutePaths )
3682 const QDomElement projectLayersElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral(
"projectlayers" ) );
3683 if ( projectLayersElem.isNull() )
3688 QDomElement mapLayerElem = projectLayersElem.firstChildElement( QStringLiteral(
"maplayer" ) );
3689 while ( ! mapLayerElem.isNull() )
3692 const QString
id = mapLayerElem.firstChildElement( QStringLiteral(
"id" ) ).text();
3693 if (
id == layerId )
3696 if ( mapLayerElem.attribute( QStringLiteral(
"embedded" ) ) == QLatin1String(
"1" ) )
3701 mEmbeddedLayers.insert( layerId, qMakePair( projectFilePath, saveFlag ) );
3703 if ( addLayer( mapLayerElem, brokenNodes, embeddedContext,
flags ) )
3709 mEmbeddedLayers.remove( layerId );
3713 mapLayerElem = mapLayerElem.nextSiblingElement( QStringLiteral(
"maplayer" ) );
3723 QString qgsProjectFile = projectFilePath;
3725 if ( projectFilePath.endsWith( QLatin1String(
".qgz" ), Qt::CaseInsensitive ) )
3727 archive.
unzip( projectFilePath );
3732 QFile projectFile( qgsProjectFile );
3733 if ( !projectFile.open( QIODevice::ReadOnly ) )
3738 QDomDocument projectDocument;
3739 if ( !projectDocument.setContent( &projectFile ) )
3751 QDomElement layerTreeElem = projectDocument.documentElement().firstChildElement( QStringLiteral(
"layer-tree-group" ) );
3752 if ( !layerTreeElem.isNull() )
3762 if ( !group || group->
customProperty( QStringLiteral(
"embedded" ) ).toBool() )
3775 newGroup->
setCustomProperty( QStringLiteral(
"embedded_project" ), projectFilePath );
3778 mLayerTreeRegistryBridge->
setEnabled(
false );
3779 initializeEmbeddedSubtree( projectFilePath, newGroup,
flags );
3780 mLayerTreeRegistryBridge->
setEnabled(
true );
3783 const auto constFindLayerIds = newGroup->
findLayerIds();
3784 for (
const QString &layerId : constFindLayerIds )
3797void QgsProject::initializeEmbeddedSubtree(
const QString &projectFilePath,
QgsLayerTreeGroup *group, Qgis::ProjectReadFlags flags )
3801 const auto constChildren = group->
children();
3805 child->setCustomProperty( QStringLiteral(
"embedded" ), 1 );
3814 QList<QDomNode> brokenNodes;
3838 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/TopologicalEditing" ), ( enabled ? 1 : 0 ) );
3846 return readNumEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/TopologicalEditing" ), 0 );
3853 if ( mDistanceUnits == unit )
3856 mDistanceUnits = unit;
3865 if ( mAreaUnits == unit )
3878 if ( !mCachedHomePath.isEmpty() )
3879 return mCachedHomePath;
3883 if ( !mHomePath.isEmpty() )
3885 const QFileInfo homeInfo( mHomePath );
3886 if ( !homeInfo.isRelative() )
3888 mCachedHomePath = mHomePath;
3898 const QString storagePath { storage->filePath(
fileName() ) };
3899 if ( ! storagePath.isEmpty() && QFileInfo::exists( storagePath ) )
3901 mCachedHomePath = QFileInfo( storagePath ).path();
3902 return mCachedHomePath;
3906 mCachedHomePath = pfi.path();
3907 return mCachedHomePath;
3910 if ( !pfi.exists() )
3912 mCachedHomePath = mHomePath;
3916 if ( !mHomePath.isEmpty() )
3919 mCachedHomePath = QDir::cleanPath( pfi.path() +
'/' + mHomePath );
3923 mCachedHomePath = pfi.canonicalPath();
3925 return mCachedHomePath;
3940 return mRelationManager;
3947 return mLayoutManager.get();
3954 return mLayoutManager.get();
3961 return m3DViewsManager.get();
3968 return m3DViewsManager.get();
3975 return mBookmarkManager;
3982 return mBookmarkManager;
3989 return mSensorManager;
3996 return mSensorManager;
4003 return mViewSettings;
4010 return mViewSettings;
4017 return mStyleSettings;
4025 return mStyleSettings;
4032 return mTimeSettings;
4039 return mTimeSettings;
4046 return mElevationProperties;
4053 return mElevationProperties;
4060 return mDisplaySettings;
4067 return mDisplaySettings;
4074 return mGpsSettings;
4081 return mGpsSettings;
4095 return mMapThemeCollection.get();
4102 return mAnnotationManager.get();
4109 return mAnnotationManager.get();
4116 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
4117 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
4122 if (
layers.contains( it.value() ) )
4123 it.value()->setFlags( it.value()->flags() &
~QgsMapLayer::Identifiable );
4139 for (
const QString &layerId : layerIds )
4157 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
4191 updateTransactionGroups();
4198 return mTransactionMode;
4209 const auto constLayers =
mapLayers().values();
4212 if ( layer->isEditable() )
4214 QgsLogger::warning( tr(
"Transaction mode can be changed only if all layers are not editable." ) );
4220 updateTransactionGroups();
4228 return mTransactionGroups;
4241 return mLayerStore->count();
4248 return mLayerStore->validCount();
4256 return mLayerStore->mapLayer( layerId );
4263 return mLayerStore->mapLayersByName( layerName );
4270 QList<QgsMapLayer *>
layers;
4271 const auto constMapLayers { mLayerStore->mapLayers() };
4272 for (
const auto &l : constMapLayers )
4274 if ( ! l->shortName().isEmpty() )
4276 if ( l->shortName() == shortName )
4279 else if ( l->name() == shortName )
4287bool QgsProject::unzip(
const QString &filename, Qgis::ProjectReadFlags flags )
4295 if ( !archive->unzip( filename ) )
4297 setError( tr(
"Unable to unzip file '%1'" ).arg( filename ) );
4302 if ( archive->projectFile().isEmpty() )
4304 setError( tr(
"Zip archive does not provide a project file" ) );
4309 releaseHandlesToProjectArchive();
4310 mArchive = std::move( archive );
4327 setError( tr(
"Cannot read unzipped qgs project file" ) + QStringLiteral(
": " ) +
error() );
4337bool QgsProject::zip(
const QString &filename )
4345 const QString
baseName = QFileInfo( filename ).baseName();
4346 const QString qgsFileName = QStringLiteral(
"%1.qgs" ).arg(
baseName );
4347 QFile qgsFile( QDir( archive->dir() ).filePath( qgsFileName ) );
4349 bool writeOk =
false;
4350 if ( qgsFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
4352 writeOk = writeProjectFile( qgsFile.fileName() );
4359 setError( tr(
"Unable to write temporary qgs file" ) );
4364 const QFileInfo info( qgsFile );
4366 const QString asFileName = info.path() + QDir::separator() + info.completeBaseName() + asExt;
4368 bool auxiliaryStorageSavedOk =
true;
4369 if ( ! saveAuxiliaryStorage( asFileName ) )
4371 const QString err = mAuxiliaryStorage->errorString();
4372 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 ) );
4373 auxiliaryStorageSavedOk =
false;
4376 if ( !mArchive->exists() )
4378 releaseHandlesToProjectArchive();
4380 mArchive->unzip( mFile.fileName() );
4383 const QString auxiliaryStorageFile =
static_cast<QgsProjectArchive *
>( mArchive.get() )->auxiliaryStorageFile();
4384 if ( ! auxiliaryStorageFile.isEmpty() )
4386 archive->
addFile( auxiliaryStorageFile );
4395 if ( QFile::exists( asFileName ) )
4397 archive->addFile( asFileName );
4402 archive->addFile( qgsFile.fileName() );
4405 const QStringList &
files = mArchive->files();
4406 for (
const QString &file :
files )
4408 if ( !file.endsWith( QLatin1String(
".qgs" ), Qt::CaseInsensitive ) && !file.endsWith( asExt, Qt::CaseInsensitive ) )
4410 archive->addFile( file );
4416 if ( !archive->zip( filename ) )
4418 setError( tr(
"Unable to perform zip" ) );
4422 return auxiliaryStorageSavedOk && zipOk;
4433 const QList<QgsMapLayer *> &layers,
4435 bool takeOwnership )
4439 const QList<QgsMapLayer *> myResultList { mLayerStore->addMapLayers(
layers, takeOwnership ) };
4440 if ( !myResultList.isEmpty() )
4443 for (
auto &l : myResultList )
4453 if ( mAuxiliaryStorage )
4468 mProjectScope.reset();
4470 return myResultList;
4476 bool takeOwnership )
4480 QList<QgsMapLayer *> addedLayers;
4481 addedLayers =
addMapLayers( QList<QgsMapLayer *>() << layer, addToLegend, takeOwnership );
4482 return addedLayers.isEmpty() ? nullptr : addedLayers[0];
4485void QgsProject::removeAuxiliaryLayer(
const QgsMapLayer *ml )
4492 const QgsVectorLayer *vl = qobject_cast<const QgsVectorLayer *>( ml );
4504 for (
const auto &layerId : layerIds )
4505 removeAuxiliaryLayer( mLayerStore->mapLayer( layerId ) );
4507 mProjectScope.reset();
4508 mLayerStore->removeMapLayers( layerIds );
4515 for (
const auto &layer :
layers )
4516 removeAuxiliaryLayer( layer );
4518 mProjectScope.reset();
4519 mLayerStore->removeMapLayers(
layers );
4526 removeAuxiliaryLayer( mLayerStore->mapLayer( layerId ) );
4527 mProjectScope.reset();
4528 mLayerStore->removeMapLayer( layerId );
4535 removeAuxiliaryLayer( layer );
4536 mProjectScope.reset();
4537 mLayerStore->removeMapLayer( layer );
4544 mProjectScope.reset();
4545 return mLayerStore->takeMapLayer( layer );
4552 return mMainAnnotationLayer;
4559 if ( mLayerStore->count() == 0 )
4562 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
4563 mProjectScope.reset();
4564 mLayerStore->removeAllMapLayers();
4566 snapSingleBlocker.release();
4568 if ( !mBlockSnappingUpdates )
4576 const QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
4577 QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin();
4578 for ( ; it !=
layers.constEnd(); ++it )
4580 it.value()->reload();
4589 return validOnly ? mLayerStore->validMapLayers() : mLayerStore->mapLayers();
4596 return mTransactionGroups.value( qMakePair( providerKey, connString ) );
4603 return &mEditBufferGroup;
4614 if ( mSettings.
value( QStringLiteral(
"/projections/unknownCrsBehavior" ), QStringLiteral(
"NoAction" ),
QgsSettings::App ).toString() == QStringLiteral(
"UseProjectCrs" )
4615 || mSettings.
value( QStringLiteral(
"/projections/unknownCrsBehavior" ), 0,
QgsSettings::App ).toString() == QLatin1String(
"2" ) )
4623 const QString layerDefaultCrs = mSettings.
value( QStringLiteral(
"/Projections/layerDefaultCrs" ),
geoEpsgCrsAuthId() ).toString();
4644bool QgsProject::saveAuxiliaryStorage(
const QString &filename )
4650 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
4655 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() );
4663 if ( !mAuxiliaryStorage->exists( *
this ) && empty )
4667 else if ( !filename.isEmpty() )
4669 return mAuxiliaryStorage->saveAs( filename );
4673 return mAuxiliaryStorage->saveAs( *
this );
4686 return sPropertyDefinitions;
4699 return mAuxiliaryStorage.get();
4706 return mAuxiliaryStorage.get();
4713 const QDir archiveDir( mArchive->dir() );
4714 QTemporaryFile tmpFile( archiveDir.filePath(
"XXXXXX_" + nameTemplate ),
this );
4715 tmpFile.setAutoRemove(
false );
4717 mArchive->addFile( tmpFile.fileName() );
4718 return tmpFile.fileName();
4725 QStringList attachments;
4727 const QStringList files = mArchive->files();
4728 attachments.reserve( files.size() );
4729 for (
const QString &file : files )
4731 if ( QFileInfo( file ).baseName() !=
baseName )
4733 attachments.append( file );
4743 return mArchive->removeFile( path );
4750 return QStringLiteral(
"attachment:///%1" ).arg( QFileInfo( attachedFile ).
fileName() );
4757 if ( identifier.startsWith( QLatin1String(
"attachment:///" ) ) )
4759 return QDir( mArchive->dir() ).absoluteFilePath( identifier.mid( 14 ) );
4780 mProjectScope.reset();
4794 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
4808 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
4809 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
4814 if (
layers.contains( it.value() ) )
4815 it.value()->setFlags( it.value()->flags() &
~QgsMapLayer::Removable );
4826 QStringList customColors;
4827 QStringList customColorLabels;
4829 QgsNamedColorList::const_iterator colorIt = colors.constBegin();
4830 for ( ; colorIt != colors.constEnd(); ++colorIt )
4833 const QString label = ( *colorIt ).second;
4834 customColors.append( color );
4835 customColorLabels.append( label );
4837 writeEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Colors" ), customColors );
4838 writeEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Labels" ), customColorLabels );
4839 mProjectScope.reset();
4847 if ( mBackgroundColor == color )
4850 mBackgroundColor = color;
4858 return mBackgroundColor;
4865 if ( mSelectionColor == color )
4868 mSelectionColor = color;
4876 return mSelectionColor;
4913 translationContext.setFileName( QStringLiteral(
"%1/%2.ts" ).arg(
absolutePath(),
baseName() ) );
4917 translationContext.writeTsFile( locale );
4920QString
QgsProject::translate(
const QString &context,
const QString &sourceText,
const char *disambiguation,
int n )
const
4929 QString result = mTranslator->translate( context.toUtf8(), sourceText.toUtf8(), disambiguation, n );
4931 if ( result.isEmpty() )
4945 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
4950 if ( !( ( *it )->accept( visitor ) ) )
4959 if ( !mLayoutManager->accept( visitor ) )
4962 if ( !mAnnotationManager->accept( visitor ) )
4970 return mElevationShadingRenderer;
4973void QgsProject::loadProjectFlags(
const QDomDocument *doc )
4977 QDomElement element = doc->documentElement().firstChildElement( QStringLiteral(
"projectFlags" ) );
4978 Qgis::ProjectFlags
flags;
4979 if ( !element.isNull() )
4986 element = doc->documentElement().firstChildElement( QStringLiteral(
"evaluateDefaultValues" ) );
4987 if ( !element.isNull() )
4989 if ( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
4994 element = doc->documentElement().firstChildElement( QStringLiteral(
"trust" ) );
4995 if ( !element.isNull() )
4997 if ( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
5006GetNamedProjectColor::GetNamedProjectColor(
const QgsProject *project )
5013 QStringList colorStrings = project->
readListEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Colors" ) );
5014 const QStringList colorLabels = project->
readListEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Labels" ) );
5018 for ( QStringList::iterator it = colorStrings.begin();
5019 it != colorStrings.end(); ++it )
5023 if ( colorLabels.length() > colorIndex )
5025 label = colorLabels.at( colorIndex );
5028 mColors.insert( label.toLower(), color );
5033GetNamedProjectColor::GetNamedProjectColor(
const QHash<QString, QColor> &colors )
5041 const QString colorName = values.at( 0 ).toString().toLower();
5042 if ( mColors.contains( colorName ) )
5044 return QStringLiteral(
"%1,%2,%3" ).arg( mColors.value( colorName ).red() ).arg( mColors.value( colorName ).green() ).arg( mColors.value( colorName ).blue() );
5052 return new GetNamedProjectColor( mColors );
5057GetSensorData::GetSensorData(
const QMap<QString, QgsAbstractSensor::SensorData> &sensorData )
5060 QStringLiteral(
"Sensors" ) )
5061 , mSensorData( sensorData )
5067 const QString sensorName = values.at( 0 ).toString();
5068 const int expiration = values.at( 1 ).toInt();
5069 const qint64 timestamp = QDateTime::currentMSecsSinceEpoch();
5070 if ( mSensorData.contains( sensorName ) )
5072 if ( expiration <= 0 || ( timestamp - mSensorData[sensorName].lastTimestamp.toMSecsSinceEpoch() ) < expiration )
5074 return mSensorData[sensorName].lastValue;
5083 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.
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.
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.
@ WKT_PREFERRED
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
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.
QString toWkt(WktVariant variant=WKT1_GDAL, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
Qgis::DistanceUnit mapUnits
Contains information about the context in which a coordinate transform is executed.
void readSettings()
Reads the context's state from application settings.
void writeXml(QDomElement &element, const QgsReadWriteContext &context) const
Writes the context's state to a DOM element.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context, QStringList &missingTransforms)
Reads the context's state from a DOM element.
Abstract base class for spatial data provider implementations.
@ ParallelThreadLoading
Skip credentials if the provided one are not valid, let the provider be invalid, avoiding to block th...
@ 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 ...
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...
@ WMSOnlineResource
Alias.
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.
static QgsStyle * defaultStyle()
Returns default application-wide style.
void triggerIconRebuild()
Triggers emission of the rebuildIconPreviews() signal.
static QColor decodeColor(const QString &str)
static QString encodeColor(const QColor &color)
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 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.