80#include <QApplication>
85#include <QTemporaryFile>
88#include <QStandardPaths>
90#include <QRegularExpression>
112 QStringList keyTokens = QStringList( scope );
113 keyTokens += key.split(
'/', Qt::SkipEmptyParts );
116 keyTokens.push_front( QStringLiteral(
"properties" ) );
119 for (
int i = 0; i < keyTokens.size(); ++i )
121 const QString keyToken = keyTokens.at( i );
125 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}])" ) );
126 if ( keyToken.contains( sInvalidRegexp ) )
128 const QString errorString = QObject::tr(
"Entry token invalid : '%1'. The token will not be saved to file." ).arg( keyToken );
156 while ( !keySequence.isEmpty() )
160 if ( keySequence.first() == currentProperty->
name() )
163 keySequence.pop_front();
165 if ( 1 == keySequence.count() )
168 return currentProperty->
find( keySequence.front() );
170 else if ( keySequence.isEmpty() )
175 return currentProperty;
177 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
179 if ( nextProperty->
isKey() )
183 else if ( nextProperty->
isValue() && 1 == keySequence.count() )
189 return currentProperty;
227 const QVariant &value,
228 bool &propertiesModified )
237 propertiesModified =
false;
238 while ( ! keySequence.isEmpty() )
242 if ( keySequence.first() == currentProperty->
name() )
245 keySequence.pop_front();
249 if ( 1 == keySequence.count() )
252 if ( !property || property->value() != value )
254 currentProperty->
setValue( keySequence.front(), value );
255 propertiesModified =
true;
258 return currentProperty;
262 else if ( keySequence.isEmpty() )
264 if ( currentProperty->
value() != value )
267 propertiesModified =
true;
270 return currentProperty;
272 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
276 if ( currentProperty )
287 if ( ( newPropertyKey = currentProperty->
addKey( keySequence.first() ) ) )
289 currentProperty = newPropertyKey;
321 while ( ! keySequence.isEmpty() )
325 if ( keySequence.first() == currentProperty->
name() )
328 keySequence.pop_front();
332 if ( 1 == keySequence.count() )
334 currentProperty->
removeKey( keySequence.front() );
339 else if ( keySequence.isEmpty() )
341 previousQgsPropertyKey->
removeKey( currentProperty->
name() );
343 else if ( ( nextProperty = currentProperty->
find( keySequence.first() ) ) )
345 previousQgsPropertyKey = currentProperty;
348 if ( currentProperty )
372 , mCapabilities( capabilities )
375 , mSnappingConfig( this )
393 mProperties.
setName( QStringLiteral(
"properties" ) );
396 mMainAnnotationLayer->setParent(
this );
410 this, [
this](
const QStringList &
layers ) { mProjectScope.reset(); emit layersWillBeRemoved( layers ); } );
412 this, [
this](
const QList<QgsMapLayer *> &
layers ) { mProjectScope.reset(); emit layersWillBeRemoved( layers ); } );
414 this, [
this](
const QString & layer ) { mProjectScope.reset(); emit layerWillBeRemoved( layer ); } );
416 this, [
this](
QgsMapLayer * layer ) { mProjectScope.reset(); emit layerWillBeRemoved( layer ); } );
418 [
this](
const QStringList &
layers ) { mProjectScope.reset(); emit layersRemoved( layers ); } );
420 [
this](
const QString & layer ) { mProjectScope.reset(); emit layerRemoved( layer ); } );
422 [
this]() { mProjectScope.reset(); emit removeAll(); } );
424 [
this](
const QList< QgsMapLayer * > &
layers ) { mProjectScope.reset(); emit layersAdded( layers ); } );
426 [
this](
QgsMapLayer * layer ) { mProjectScope.reset(); emit layerWasAdded( layer ); } );
434 [
this](
const QList<QgsMapLayer *> &
layers )
436 for ( const auto &layer : layers )
438 disconnect( layer, &QgsMapLayer::dataSourceChanged, mRelationManager, &QgsRelationManager::updateRelationsStatus );
443 [
this](
const QList<QgsMapLayer *> &layers )
445 for ( const auto &layer : layers )
447 connect( layer, &QgsMapLayer::dataSourceChanged, mRelationManager, &QgsRelationManager::updateRelationsStatus );
456 mStyleSettings->combinedStyleModel()->addDefaultStyle();
462 mIsBeingDeleted =
true;
465 releaseHandlesToProjectArchive();
466 delete mBadLayerHandler;
467 delete mRelationManager;
468 delete mLayerTreeRegistryBridge;
470 if (
this == sProject )
501 mProjectScope.reset();
512 return mMetadata.
title();
521 if ( oldEvaluateDefaultValues != newEvaluateDefaultValues )
524 for (
auto layerIt =
layers.constBegin(); layerIt !=
layers.constEnd(); ++layerIt )
526 if (
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layerIt.value() ) )
527 if ( vl->dataProvider() )
534 if ( oldTrustLayerMetadata != newTrustLayerMetadata )
537 for (
auto layerIt =
layers.constBegin(); layerIt !=
layers.constEnd(); ++layerIt )
539 if (
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layerIt.value() ) )
541 vl->setReadExtentFromXml( newTrustLayerMetadata );
546 if ( mFlags !=
flags )
561 newFlags &= ~(
static_cast< int >( flag ) );
576 return mSaveUserFull;
583 return mSaveDateTime;
604 if ( dirty && mDirtyBlockCount > 0 )
610 if ( mDirty == dirty )
621 if ( path == mHomePath )
625 mCachedHomePath.clear();
626 mProjectScope.reset();
637 const QList<QgsAttributeEditorElement *> elements = parent->
children();
645 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:formcontainers" ).arg( layerId ), container->
name() );
647 if ( !container->
children().empty() )
662 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1" ).arg( layer->layerId() ), layer->name() );
671 for (
const QgsField &field : fields )
674 if ( field.alias().isEmpty() )
675 fieldName = field.name();
677 fieldName = field.alias();
679 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:fieldaliases" ).arg( vlayer->
id() ), fieldName );
681 if ( field.editorWidgetSetup().type() == QLatin1String(
"ValueRelation" ) )
683 translationContext->
registerTranslation( QStringLiteral(
"project:layers:%1:fields:%2:valuerelationvalue" ).arg( vlayer->
id(), field.name() ), field.editorWidgetSetup().config().value( QStringLiteral(
"Value" ) ).toString() );
694 const QList<QgsLayerTreeGroup *> groupLayers = mRootGroup->
findGroups();
697 translationContext->
registerTranslation( QStringLiteral(
"project:layergroups" ), groupLayer->name() );
701 const QList<QgsRelation> &relations = mRelationManager->
relations().values();
704 translationContext->
registerTranslation( QStringLiteral(
"project:relations" ), relation.name() );
712 mDataDefinedServerProperties = properties;
719 return mDataDefinedServerProperties;
726 switch ( mTransactionMode )
747 switch ( mTransactionMode )
754 commitErrors.append( tr(
"Trying to commit changes without a layer specified. This only works if the transaction mode is buffered" ) );
763 return mEditBufferGroup.
commitChanges( commitErrors, stopEditing );
773 switch ( mTransactionMode )
780 rollbackErrors.append( tr(
"Trying to roll back changes without a layer specified. This only works if the transaction mode is buffered" ) );
783 bool success = vectorLayer->
rollBack( stopEditing );
789 return mEditBufferGroup.
rollBack( rollbackErrors, stopEditing );
799 if ( name == mFile.fileName() )
802 const QString oldHomePath =
homePath();
804 mFile.setFileName( name );
805 mCachedHomePath.clear();
806 mProjectScope.reset();
810 const QString newHomePath =
homePath();
811 if ( newHomePath != oldHomePath )
822 return mFile.fileName();
829 mOriginalPath = path;
836 return mOriginalPath;
843 return QFileInfo( mFile );
861 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
866 return QFileInfo( mFile.fileName() ).lastModified();
877 if ( mFile.fileName().isEmpty() )
880 return QFileInfo( mFile.fileName() ).absolutePath();
891 if ( mFile.fileName().isEmpty() )
894 return QFileInfo( mFile.fileName() ).absoluteFilePath();
905 storage->readProjectStorageMetadata( mFile.fileName(),
metadata );
910 return QFileInfo( mFile.fileName() ).completeBaseName();
918 const bool absolutePaths =
readBoolEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
false );
929 writeEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
true );
932 writeEntry( QStringLiteral(
"Paths" ), QStringLiteral(
"/Absolute" ),
false );
949 return mCrs3D.
isValid() ? mCrs3D : mCrs;
961 writeEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectionsEnabled" ),
crs.
isValid() ? 1 : 0 );
962 mProjectScope.reset();
976 if ( oldCrs3D != mCrs3D )
980 if ( adjustEllipsoid )
989 if ( !
crs().isValid() )
992 return readEntry( QStringLiteral(
"Measure" ), QStringLiteral(
"/Ellipsoid" ),
geoNone() );
999 if (
ellipsoid ==
readEntry( QStringLiteral(
"Measure" ), QStringLiteral(
"/Ellipsoid" ) ) )
1002 mProjectScope.reset();
1012 switch ( mCrs.
type() )
1015 QgsDebugError( QStringLiteral(
"Project has a vertical CRS set as the horizontal CRS!" ) );
1034 return mVerticalCrs;
1062 *errorMessage = QObject::tr(
"Specified CRS is a %1 CRS, not a Vertical CRS" ).arg(
qgsEnumValueToKey(
crs.
type() ) );
1067 if (
crs != mVerticalCrs )
1072 switch ( mCrs.
type() )
1075 if (
crs != oldVerticalCrs )
1078 *errorMessage = QObject::tr(
"Project CRS is a Compound CRS, specified Vertical CRS will be ignored" );
1084 if (
crs != oldVerticalCrs )
1087 *errorMessage = QObject::tr(
"Project CRS is a Geographic 3D CRS, specified Vertical CRS will be ignored" );
1093 if (
crs != oldVerticalCrs )
1096 *errorMessage = QObject::tr(
"Project CRS is a Geocentric CRS, specified Vertical CRS will be ignored" );
1105 *errorMessage = QObject::tr(
"Project CRS is a Projected 3D CRS, specified Vertical CRS will be ignored" );
1123 res = rebuildCrs3D( errorMessage );
1124 mProjectScope.reset();
1131 if ( mCrs3D != oldCrs3D )
1142 return mTransformContext;
1149 if ( context == mTransformContext )
1152 mTransformContext = context;
1153 mProjectScope.reset();
1156 for (
auto &layer : mLayerStore.get()->mapLayers() )
1158 layer->setTransformContext( context );
1167 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
1171 if ( !mIsBeingDeleted )
1180 mProjectScope.reset();
1181 mFile.setFileName( QString() );
1184 mSaveUserFull.clear();
1185 mSaveDateTime = QDateTime();
1188 mCachedHomePath.clear();
1192 mCustomVariables.clear();
1198 if ( !mSettings.
value( QStringLiteral(
"projects/anonymize_new_projects" ),
false,
QgsSettings::Core ).toBool() )
1217 mEmbeddedLayers.clear();
1218 mRelationManager->
clear();
1219 mAnnotationManager->clear();
1220 mLayoutManager->clear();
1221 m3DViewsManager->clear();
1222 mBookmarkManager->
clear();
1223 mSensorManager->
clear();
1224 mViewSettings->
reset();
1225 mTimeSettings->
reset();
1226 mElevationProperties->
reset();
1227 mDisplaySettings->
reset();
1228 mGpsSettings->
reset();
1229 mSnappingConfig.
reset();
1237 mLabelingEngineSettings->clear();
1241 releaseHandlesToProjectArchive();
1247 mStyleSettings->
reset();
1251 if ( !mIsBeingDeleted )
1259 writeEntry( QStringLiteral(
"PositionPrecision" ), QStringLiteral(
"/Automatic" ),
true );
1260 writeEntry( QStringLiteral(
"PositionPrecision" ), QStringLiteral(
"/DecimalPlaces" ), 2 );
1262 const bool defaultRelativePaths = mSettings.
value( QStringLiteral(
"/qgis/defaultProjectPathsRelative" ),
true ).toBool();
1265 int red = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_red" ), 255 ).toInt();
1266 int green = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_green" ), 255 ).toInt();
1267 int blue = mSettings.
value( QStringLiteral(
"qgis/default_canvas_color_blue" ), 255 ).toInt();
1270 red = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_red" ), 255 ).toInt();
1271 green = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_green" ), 255 ).toInt();
1272 blue = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_blue" ), 0 ).toInt();
1273 const int alpha = mSettings.
value( QStringLiteral(
"qgis/default_selection_color_alpha" ), 255 ).toInt();
1279 mRootGroup->
clear();
1280 if ( mMainAnnotationLayer )
1281 mMainAnnotationLayer->
reset();
1283 snapSingleBlocker.release();
1285 if ( !mBlockSnappingUpdates )
1290 if ( !mBlockChangeSignalsDuringClear )
1302 topQgsPropertyKey.
dump();
1335 const QDomElement propertiesElem = doc.documentElement().firstChildElement( QStringLiteral(
"properties" ) );
1337 if ( propertiesElem.isNull() )
1342 const QDomNodeList scopes = propertiesElem.childNodes();
1344 if ( propertiesElem.firstChild().isNull() )
1346 QgsDebugError( QStringLiteral(
"empty ``properties'' XML tag ... bailing" ) );
1350 if ( ! project_properties.
readXml( propertiesElem ) )
1352 QgsDebugError( QStringLiteral(
"Project_properties.readXml() failed" ) );
1366 const QDomElement ddElem = doc.documentElement().firstChildElement( QStringLiteral(
"dataDefinedServerProperties" ) );
1367 if ( !ddElem.isNull() )
1369 if ( !ddServerProperties.
readXml( ddElem, dataDefinedServerPropertyDefinitions ) )
1371 QgsDebugError( QStringLiteral(
"dataDefinedServerProperties.readXml() failed" ) );
1374 return ddServerProperties;
1381static void _getTitle(
const QDomDocument &doc, QString &title )
1383 const QDomElement titleNode = doc.documentElement().firstChildElement( QStringLiteral(
"title" ) );
1387 if ( titleNode.isNull() )
1393 if ( !titleNode.hasChildNodes() )
1399 const QDomNode titleTextNode = titleNode.firstChild();
1401 if ( !titleTextNode.isText() )
1407 const QDomText titleText = titleTextNode.toText();
1409 title = titleText.data();
1413static void readProjectFileMetadata(
const QDomDocument &doc, QString &lastUser, QString &lastUserFull, QDateTime &lastSaveDateTime )
1415 const QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"qgis" ) );
1419 QgsDebugError( QStringLiteral(
"unable to find qgis element" ) );
1423 const QDomNode qgisNode = nl.item( 0 );
1425 const QDomElement qgisElement = qgisNode.toElement();
1426 lastUser = qgisElement.attribute( QStringLiteral(
"saveUser" ), QString() );
1427 lastUserFull = qgisElement.attribute( QStringLiteral(
"saveUserFull" ), QString() );
1428 lastSaveDateTime = QDateTime::fromString( qgisElement.attribute( QStringLiteral(
"saveDateTime" ), QString() ), Qt::ISODate );
1433 const QDomNodeList nl = doc.elementsByTagName( QStringLiteral(
"qgis" ) );
1437 QgsDebugError( QStringLiteral(
" unable to find qgis element in project file" ) );
1441 const QDomNode qgisNode = nl.item( 0 );
1443 const QDomElement qgisElement = qgisNode.toElement();
1444 QgsProjectVersion projectVersion( qgisElement.attribute( QStringLiteral(
"version" ) ) );
1445 return projectVersion;
1452 return mSnappingConfig;
1471 if ( mAvoidIntersectionsMode == mode )
1474 mAvoidIntersectionsMode = mode;
1508void QgsProject::preloadProviders(
const QVector<QDomNode> ¶llelLayerNodes,
1510 QMap<QString, QgsDataProvider *> &loadedProviders,
1512 int totalProviderCount )
1517 QMap<QString, LayerToLoad> layersToLoad;
1519 for (
const QDomNode &node : parallelLayerNodes )
1523 const QDomElement layerElement = node.toElement();
1525 layerToLoad.
layerId = layerElement.namedItem( QStringLiteral(
"id" ) ).toElement().text();
1526 layerToLoad.
provider = layerElement.namedItem( QStringLiteral(
"provider" ) ).toElement().text();
1527 layerToLoad.
dataSource = layerElement.namedItem( QStringLiteral(
"datasource" ) ).toElement().text();
1538 layersToLoad.insert( layerToLoad.
layerId, layerToLoad );
1541 while ( !layersToLoad.isEmpty() )
1543 const QList<LayerToLoad> layersToAttemptInParallel = layersToLoad.values();
1544 QString layerToAttemptInMainThread;
1546 QHash<QString, QgsRunnableProviderCreator *> runnables;
1547 QThreadPool threadPool;
1550 for (
const LayerToLoad &lay : layersToAttemptInParallel )
1553 runnables.insert( lay.layerId, run );
1559 layersToLoad.remove( layId );
1562 Q_ASSERT( finishedRun );
1564 std::unique_ptr<QgsDataProvider> provider( finishedRun->
dataProvider() );
1565 Q_ASSERT( provider && provider->isValid() );
1567 loadedProviders.insert( layId, provider.release() );
1572 if ( layerToAttemptInMainThread.isEmpty() )
1573 layerToAttemptInMainThread = layId;
1577 if ( i == parallelLayerNodes.count() || !isValid )
1580 threadPool.start( run );
1584 threadPool.waitForDone();
1586 qDeleteAll( runnables );
1589 auto it = layersToLoad.find( layerToAttemptInMainThread );
1590 if ( it != layersToLoad.end() )
1592 std::unique_ptr<QgsDataProvider> provider;
1602 if ( provider && provider->isValid() )
1607 layersToLoad.erase( it );
1610 loadedProviders.insert( layerId, provider.release() );
1618void QgsProject::releaseHandlesToProjectArchive()
1623bool QgsProject::rebuildCrs3D( QString *error )
1630 else if ( !mVerticalCrs.
isValid() )
1636 switch ( mCrs.
type() )
1677bool QgsProject::_getMapLayers(
const QDomDocument &doc, QList<QDomNode> &brokenNodes,
Qgis::ProjectReadFlags flags )
1684 QDomElement layerElement = doc.documentElement().firstChildElement( QStringLiteral(
"projectlayers" ) ).firstChildElement( QStringLiteral(
"maplayer" ) );
1688 if ( layerElement.isNull() )
1698 bool returnStatus =
true;
1701 while ( ! layerElement.isNull() )
1704 layerElement = layerElement.nextSiblingElement( QStringLiteral(
"maplayer" ) );
1710 if ( depSorter.hasCycle() )
1714 if ( depSorter.hasMissingDependency() )
1715 returnStatus =
false;
1719 const QVector<QDomNode> sortedLayerNodes = depSorter.sortedLayerNodes();
1720 const int totalLayerCount = sortedLayerNodes.count();
1722 QVector<QDomNode> parallelLoading;
1723 QMap<QString, QgsDataProvider *> loadedProviders;
1728 profile.switchTask( tr(
"Load providers in parallel" ) );
1729 for (
const QDomNode &node : sortedLayerNodes )
1731 const QDomElement element = node.toElement();
1732 if ( element.attribute( QStringLiteral(
"embedded" ) ) != QLatin1String(
"1" ) )
1734 const QString layerId = node.namedItem( QStringLiteral(
"id" ) ).toElement().text();
1735 if ( !depSorter.isLayerDependent( layerId ) )
1737 const QDomNode mnl = element.namedItem( QStringLiteral(
"provider" ) );
1738 const QDomElement mne = mnl.toElement();
1739 const QString provider = mne.text();
1743 parallelLoading.append( node );
1752 if ( !parallelLoading.isEmpty() )
1753 preloadProviders( parallelLoading, context, loadedProviders, projectFlagsToLayerReadFlags(
flags, mFlags ), sortedLayerNodes.count() );
1756 int i = loadedProviders.count();
1757 for (
const QDomNode &node : std::as_const( sortedLayerNodes ) )
1759 const QDomElement element = node.toElement();
1760 const QString name =
translate( QStringLiteral(
"project:layers:%1" ).arg( node.namedItem( QStringLiteral(
"id" ) ).toElement().text() ), node.namedItem( QStringLiteral(
"layername" ) ).toElement().text() );
1761 if ( !name.isNull() )
1762 emit
loadingLayer( tr(
"Loading layer %1" ).arg( name ) );
1764 profile.switchTask( name );
1765 if ( element.attribute( QStringLiteral(
"embedded" ) ) == QLatin1String(
"1" ) )
1767 createEmbeddedLayer( element.attribute( QStringLiteral(
"id" ) ),
readPath( element.attribute( QStringLiteral(
"project" ) ) ), brokenNodes,
true,
flags );
1775 QString layerId = element.namedItem( QStringLiteral(
"id" ) ).toElement().text();
1777 if ( !addLayer( element, brokenNodes, context,
flags, loadedProviders.take( layerId ) ) )
1779 returnStatus =
false;
1782 if ( !messages.isEmpty() )
1791 return returnStatus;
1794bool QgsProject::addLayer(
const QDomElement &layerElem,
1795 QList<QDomNode> &brokenNodes,
1802 const QString type = layerElem.attribute( QStringLiteral(
"type" ) );
1804 std::unique_ptr<QgsMapLayer>
mapLayer;
1812 QgsDebugError( QStringLiteral(
"Unknown layer type \"%1\"" ).arg( type ) );
1816 switch ( layerType )
1819 mapLayer = std::make_unique<QgsVectorLayer>();
1823 mapLayer = std::make_unique<QgsRasterLayer>();
1827 mapLayer = std::make_unique<QgsMeshLayer>();
1831 mapLayer = std::make_unique<QgsVectorTileLayer>();
1835 mapLayer = std::make_unique<QgsPointCloudLayer>();
1839 mapLayer = std::make_unique<QgsTiledSceneLayer>();
1844 const QString
typeName = layerElem.attribute( QStringLiteral(
"name" ) );
1852 mapLayer = std::make_unique<QgsAnnotationLayer>( QString(), options );
1859 mapLayer = std::make_unique<QgsGroupLayer>( QString(), options );
1866 QgsDebugError( QStringLiteral(
"Unable to create layer" ) );
1874 const QString layerId { layerElem.namedItem( QStringLiteral(
"id" ) ).toElement().text() };
1875 Q_ASSERT( ! layerId.isEmpty() );
1881 profile.switchTask( tr(
"Load layer source" ) );
1888 if ( vl->dataProvider() )
1895 profile.switchTask( tr(
"Add layer to project" ) );
1896 QList<QgsMapLayer *> newLayers;
1908 vLayer->joinBuffer()->resolveReferences(
this );
1917 brokenNodes.push_back( layerElem );
1920 const bool wasEditable = layerElem.attribute( QStringLiteral(
"editable" ), QStringLiteral(
"0" ) ).toInt();
1932 if ( ! layerWasStored )
1937 return layerIsValid;
1944 mFile.setFileName( filename );
1945 mCachedHomePath.clear();
1946 mProjectScope.reset();
1955 const QString filename = mFile.fileName();
1960 QTemporaryFile inDevice;
1961 if ( !inDevice.open() )
1963 setError( tr(
"Unable to open %1" ).arg( inDevice.fileName() ) );
1969 if ( !storage->readProject( filename, &inDevice, context ) )
1971 QString err = tr(
"Unable to open %1" ).arg( filename );
1972 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
1973 if ( !messages.isEmpty() )
1974 err += QStringLiteral(
"\n\n" ) + messages.last().message();
1978 returnValue = unzip( inDevice.fileName(),
flags );
1984 returnValue = unzip( mFile.fileName(),
flags );
1989 const QFileInfo finfo( mFile.fileName() );
1990 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( QStringLiteral(
"%1_attachments.zip" ).arg( finfo.completeBaseName() ) );
1991 if ( QFile( attachmentsZip ).exists() )
1993 std::unique_ptr<QgsArchive> archive(
new QgsArchive() );
1994 if ( archive->unzip( attachmentsZip ) )
1996 releaseHandlesToProjectArchive();
1997 mArchive = std::move( archive );
2000 returnValue = readProjectFile( mFile.fileName(),
flags );
2006 mFile.setFileName( filename );
2007 mCachedHomePath.clear();
2008 mProjectScope.reset();
2013 mTranslator.reset(
nullptr );
2025 ScopedIntIncrementor snapSignalBlock( &mBlockSnappingUpdates );
2027 QFile projectFile( filename );
2035 if ( QFile( QStringLiteral(
"%1/%2.qm" ).arg( QFileInfo( projectFile.fileName() ).absolutePath(), localeFileName ) ).exists() )
2037 mTranslator.reset(
new QTranslator() );
2038 ( void )mTranslator->load( localeFileName, QFileInfo( projectFile.fileName() ).absolutePath() );
2041 profile.switchTask( tr(
"Reading project file" ) );
2042 std::unique_ptr<QDomDocument> doc(
new QDomDocument( QStringLiteral(
"qgis" ) ) );
2044 if ( !projectFile.open( QIODevice::ReadOnly | QIODevice::Text ) )
2046 projectFile.close();
2048 setError( tr(
"Unable to open %1" ).arg( projectFile.fileName() ) );
2053 QTextStream textStream( &projectFile );
2054#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
2055 textStream.setCodec(
"UTF-8" );
2057 QString projectString = textStream.readAll();
2058 projectFile.close();
2060 for (
int i = 0; i < 32; i++ )
2062 if ( i == 9 || i == 10 || i == 13 )
2066 projectString.replace( QChar( i ), QStringLiteral(
"%1%2%1" ).arg(
FONTMARKER_CHR_FIX, QString::number( i ) ) );
2072 if ( !doc->setContent( projectString, &errorMsg, &line, &column ) )
2074 const QString errorString = tr(
"Project file read error in file %1: %2 at line %3 column %4" )
2075 .arg( projectFile.fileName(), errorMsg ).arg( line ).arg( column );
2077 setError( errorString );
2082 projectFile.close();
2090 profile.switchTask( tr(
"Updating project file" ) );
2091 if ( thisVersion > fileVersion )
2093 const bool isOlderMajorVersion = fileVersion.
majorVersion() < thisVersion.majorVersion();
2095 if ( isOlderMajorVersion )
2098 "version of qgis (saved in " + fileVersion.
text() +
2100 "). Problems may occur." );
2111 projectFile.updateRevision( thisVersion );
2113 else if ( fileVersion > thisVersion )
2116 "version of qgis (saved in " + fileVersion.
text() +
2118 "). Problems may occur." );
2124 profile.switchTask( tr(
"Creating auxiliary storage" ) );
2125 const QString
fileName = mFile.fileName();
2132 std::unique_ptr<QgsAuxiliaryStorage> aStorage = std::move( mAuxiliaryStorage );
2133 std::unique_ptr<QgsArchive> archive = std::move( mArchive );
2137 mBlockChangeSignalsDuringClear =
true;
2139 mBlockChangeSignalsDuringClear =
false;
2144 releaseHandlesToProjectArchive();
2146 mAuxiliaryStorage = std::move( aStorage );
2147 mArchive = std::move( archive );
2150 mCachedHomePath.clear();
2151 mProjectScope.reset();
2152 mSaveVersion = fileVersion;
2155 profile.switchTask( tr(
"Reading properties" ) );
2164 dump_( mProperties );
2169 _getTitle( *doc, oldTitle );
2171 readProjectFileMetadata( *doc, mSaveUser, mSaveUserFull, mSaveDateTime );
2173 const QDomNodeList homePathNl = doc->elementsByTagName( QStringLiteral(
"homePath" ) );
2174 if ( homePathNl.count() > 0 )
2176 const QDomElement homePathElement = homePathNl.at( 0 ).toElement();
2177 const QString
homePath = homePathElement.attribute( QStringLiteral(
"path" ) );
2187 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorGreenPart" ), 255 ),
2188 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorBluePart" ), 255 ) );
2191 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorGreenPart" ), 255 ),
2192 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorBluePart" ), 255 ),
2193 readNumEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorAlphaPart" ), 255 ) );
2197 const QString distanceUnitString =
readEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/DistanceUnits" ), QString() );
2198 if ( !distanceUnitString.isEmpty() )
2201 const QString areaUnitString =
readEntry( QStringLiteral(
"Measurement" ), QStringLiteral(
"/AreaUnits" ), QString() );
2202 if ( !areaUnitString.isEmpty() )
2211 if (
readNumEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectionsEnabled" ), 0 ) )
2214 const QDomNode srsNode = doc->documentElement().namedItem( QStringLiteral(
"projectCrs" ) );
2215 if ( !srsNode.isNull() )
2217 projectCrs.
readXml( srsNode );
2222 const QString projCrsString =
readEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCRSProj4String" ) );
2223 const long currentCRS =
readNumEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCRSID" ), -1 );
2224 const QString authid =
readEntry( QStringLiteral(
"SpatialRefSys" ), QStringLiteral(
"/ProjectCrs" ) );
2227 const bool isUserAuthId = authid.startsWith( QLatin1String(
"USER:" ), Qt::CaseInsensitive );
2228 if ( !authid.isEmpty() && !isUserAuthId )
2232 if ( !projectCrs.
isValid() && currentCRS >= 0 )
2238 if ( !projCrsString.isEmpty() && ( authid.isEmpty() || isUserAuthId ) && ( !projectCrs.
isValid() || projectCrs.
toProj() != projCrsString ) )
2255 const QDomNode verticalCrsNode = doc->documentElement().namedItem( QStringLiteral(
"verticalCrs" ) );
2256 if ( !verticalCrsNode.isNull() )
2264 QStringList datumErrors;
2265 if ( !mTransformContext.
readXml( doc->documentElement(), context, datumErrors ) && !datumErrors.empty() )
2272 const QDomNode elevationShadingNode = doc->documentElement().namedItem( QStringLiteral(
"elevation-shading-renderer" ) );
2273 if ( !elevationShadingNode.isNull() )
2275 mElevationShadingRenderer.
readXml( elevationShadingNode.toElement(), context );
2282 const QStringList variableNames =
readListEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableNames" ) );
2283 const QStringList variableValues =
readListEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableValues" ) );
2285 mCustomVariables.clear();
2286 if ( variableNames.length() == variableValues.length() )
2288 for (
int i = 0; i < variableNames.length(); ++i )
2290 mCustomVariables.insert( variableNames.at( i ), variableValues.at( i ) );
2295 QgsMessageLog::logMessage( tr(
"Project Variables Invalid" ), tr(
"The project contains invalid variable settings." ) );
2303 QDomElement element = doc->documentElement().firstChildElement( QStringLiteral(
"projectMetadata" ) );
2305 if ( !element.isNull() )
2314 if ( mMetadata.
title().isEmpty() && !oldTitle.isEmpty() )
2322 element = doc->documentElement().firstChildElement( QStringLiteral(
"transaction" ) );
2323 if ( !element.isNull() )
2330 element = doc->documentElement().firstChildElement( QStringLiteral(
"autotransaction" ) );
2331 if ( ! element.isNull() )
2333 mTransactionMode =
static_cast<Qgis::TransactionMode>( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() );
2338 profile.switchTask( tr(
"Loading layer tree" ) );
2341 QDomElement layerTreeElem = doc->documentElement().firstChildElement( QStringLiteral(
"layer-tree-group" ) );
2342 if ( !layerTreeElem.isNull() )
2354 mLayerTreeRegistryBridge->
setEnabled(
false );
2357 profile.switchTask( tr(
"Reading map layers" ) );
2359 loadProjectFlags( doc.get() );
2361 QList<QDomNode> brokenNodes;
2362 const bool clean = _getMapLayers( *doc, brokenNodes,
flags );
2367 QgsDebugError( QStringLiteral(
"Unable to get map layers from project file." ) );
2369 if ( !brokenNodes.isEmpty() )
2371 QgsDebugError(
"there are " + QString::number( brokenNodes.size() ) +
" broken layers" );
2379 mMainAnnotationLayer->
readLayerXml( doc->documentElement().firstChildElement( QStringLiteral(
"main-annotation-layer" ) ), context );
2383 profile.switchTask( tr(
"Loading embedded layers" ) );
2384 loadEmbeddedNodes( mRootGroup,
flags );
2388 profile.switchTask( tr(
"Resolving layer references" ) );
2389 QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
2390 for ( QMap<QString, QgsMapLayer *>::iterator it =
layers.begin(); it !=
layers.end(); ++it )
2392 it.value()->resolveReferences(
this );
2396 mLayerTreeRegistryBridge->
setEnabled(
true );
2399 profile.switchTask( tr(
"Resolving references" ) );
2410 if ( !layerTreeElem.isNull() )
2416 const QDomElement layerTreeCanvasElem = doc->documentElement().firstChildElement( QStringLiteral(
"layer-tree-canvas" ) );
2417 if ( !layerTreeCanvasElem.isNull( ) )
2425 const QStringList requiredLayerIds =
readListEntry( QStringLiteral(
"RequiredLayers" ), QStringLiteral(
"Layers" ) );
2426 for (
const QString &layerId : requiredLayerIds )
2433 const QStringList disabledLayerIds =
readListEntry( QStringLiteral(
"Identify" ), QStringLiteral(
"/disabledLayers" ) );
2434 for (
const QString &layerId : disabledLayerIds )
2447 QString styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Marker" ) );
2448 if ( !styleName.isEmpty() )
2453 styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Line" ) );
2454 if ( !styleName.isEmpty() )
2459 styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Fill" ) );
2460 if ( !styleName.isEmpty() )
2465 styleName =
readEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/ColorRamp" ) );
2466 if ( !styleName.isEmpty() )
2476 double opacity = 1.0;
2479 double alpha =
readDoubleEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/AlphaInt" ), 255, &ok );
2481 opacity = alpha / 255.0;
2482 double newOpacity =
readDoubleEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Opacity" ), 1.0, &ok );
2484 opacity = newOpacity;
2488 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Marker" ) );
2489 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Line" ) );
2490 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Fill" ) );
2491 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/ColorRamp" ) );
2492 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/RandomColors" ) );
2493 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/AlphaInt" ) );
2494 removeEntry( QStringLiteral(
"DefaultStyles" ), QStringLiteral(
"/Opacity" ) );
2502 profile.switchTask( tr(
"Storing original layer properties" ) );
2508 profile.switchTask( tr(
"Loading map themes" ) );
2511 mMapThemeCollection->readXml( *doc );
2513 profile.switchTask( tr(
"Loading label settings" ) );
2514 mLabelingEngineSettings->readSettingsFromProject(
this );
2516 const QDomElement labelEngineSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"labelEngineSettings" ) );
2517 mLabelingEngineSettings->readXml( labelEngineSettingsElement, context );
2519 mLabelingEngineSettings->resolveReferences(
this );
2523 profile.switchTask( tr(
"Loading annotations" ) );
2526 mAnnotationManager->readXml( doc->documentElement(), context );
2530 mAnnotationManager->readXmlAndUpgradeToAnnotationLayerItems( doc->documentElement(), context, mMainAnnotationLayer, mTransformContext );
2534 profile.switchTask( tr(
"Loading layouts" ) );
2535 mLayoutManager->readXml( doc->documentElement(), *doc );
2540 profile.switchTask( tr(
"Loading 3D Views" ) );
2541 m3DViewsManager->readXml( doc->documentElement(), *doc );
2544 profile.switchTask( tr(
"Loading bookmarks" ) );
2545 mBookmarkManager->
readXml( doc->documentElement(), *doc );
2547 profile.switchTask( tr(
"Loading sensors" ) );
2548 mSensorManager->
readXml( doc->documentElement(), *doc );
2551 QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
2552 for ( QMap<QString, QgsMapLayer *>::iterator it = existingMaps.begin(); it != existingMaps.end(); ++it )
2554 it.value()->setDependencies( it.value()->dependencies() );
2557 profile.switchTask( tr(
"Loading snapping settings" ) );
2561 profile.switchTask( tr(
"Loading view settings" ) );
2564 const QStringList scales =
readListEntry( QStringLiteral(
"Scales" ), QStringLiteral(
"/ScalesList" ) );
2565 QVector<double> res;
2566 for (
const QString &scale : scales )
2568 const QStringList parts = scale.split(
':' );
2569 if ( parts.size() != 2 )
2573 const double denominator = QLocale().toDouble( parts[1], &ok );
2580 const QDomElement viewSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectViewSettings" ) );
2581 if ( !viewSettingsElement.isNull() )
2582 mViewSettings->
readXml( viewSettingsElement, context );
2585 profile.switchTask( tr(
"Loading style properties" ) );
2586 const QDomElement styleSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectStyleSettings" ) );
2587 if ( !styleSettingsElement.isNull() )
2590 mStyleSettings->
readXml( styleSettingsElement, context,
flags );
2594 profile.switchTask( tr(
"Loading temporal settings" ) );
2595 const QDomElement timeSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectTimeSettings" ) );
2596 if ( !timeSettingsElement.isNull() )
2597 mTimeSettings->
readXml( timeSettingsElement, context );
2600 profile.switchTask( tr(
"Loading elevation properties" ) );
2601 const QDomElement elevationPropertiesElement = doc->documentElement().firstChildElement( QStringLiteral(
"ElevationProperties" ) );
2602 if ( !elevationPropertiesElement.isNull() )
2603 mElevationProperties->
readXml( elevationPropertiesElement, context );
2606 profile.switchTask( tr(
"Loading display settings" ) );
2608 const QDomElement displaySettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectDisplaySettings" ) );
2609 if ( !displaySettingsElement.isNull() )
2610 mDisplaySettings->
readXml( displaySettingsElement, context );
2613 profile.switchTask( tr(
"Loading GPS settings" ) );
2615 const QDomElement gpsSettingsElement = doc->documentElement().firstChildElement( QStringLiteral(
"ProjectGpsSettings" ) );
2616 if ( !gpsSettingsElement.isNull() )
2617 mGpsSettings->
readXml( gpsSettingsElement, context );
2621 profile.switchTask( tr(
"Updating variables" ) );
2623 profile.switchTask( tr(
"Updating CRS" ) );
2627 if ( mCrs3D != oldCrs3D )
2632 profile.switchTask( tr(
"Reading external settings" ) );
2636 profile.switchTask( tr(
"Updating interface" ) );
2638 snapSignalBlock.release();
2639 if ( !mBlockSnappingUpdates )
2650 QgsDebugMsgLevel( QStringLiteral(
"Project save user: %1" ).arg( mSaveUser ), 2 );
2651 QgsDebugMsgLevel( QStringLiteral(
"Project save user: %1" ).arg( mSaveUserFull ), 2 );
2660 const QString newFileName( QStringLiteral(
"%1/%2.qgs" ).arg( QFileInfo( projectFile.fileName() ).absolutePath(), localeFileName ) );
2675 const QMap<QString, QgsMapLayer *> loadedLayers =
mapLayers();
2676 for (
auto it = loadedLayers.constBegin(); it != loadedLayers.constEnd(); ++it )
2678 if ( it.value()->isValid() && it.value()->customProperty( QStringLiteral(
"_layer_was_editable" ) ).toBool() )
2680 if (
QgsVectorLayer *vl = qobject_cast< QgsVectorLayer * >( it.value() ) )
2682 it.value()->removeCustomProperty( QStringLiteral(
"_layer_was_editable" ) );
2694 const auto constChildren = group->
children();
2700 if ( childGroup->
customProperty( QStringLiteral(
"embedded" ) ).toInt() )
2703 const QString projectPath =
readPath( childGroup->
customProperty( QStringLiteral(
"embedded_project" ) ).toString() );
2704 childGroup->
setCustomProperty( QStringLiteral(
"embedded_project" ), projectPath );
2708 QList<QgsLayerTreeNode *> clonedChildren;
2709 const QList<QgsLayerTreeNode *> constChildren = newGroup->
children();
2710 clonedChildren.reserve( constChildren.size() );
2712 clonedChildren << newGroupChild->clone();
2720 loadEmbeddedNodes( childGroup,
flags );
2725 if ( child->customProperty( QStringLiteral(
"embedded" ) ).toInt() )
2727 QList<QDomNode> brokenNodes;
2730 valid = valid &&
false;
2745 return mCustomVariables;
2752 if ( variables == mCustomVariables )
2756 QStringList variableNames;
2757 QStringList variableValues;
2759 QVariantMap::const_iterator it = variables.constBegin();
2760 for ( ; it != variables.constEnd(); ++it )
2762 variableNames << it.key();
2763 variableValues << it.value().toString();
2766 writeEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableNames" ), variableNames );
2767 writeEntry( QStringLiteral(
"Variables" ), QStringLiteral(
"/variableValues" ), variableValues );
2769 mCustomVariables = variables;
2770 mProjectScope.reset();
2779 *mLabelingEngineSettings = settings;
2787 return *mLabelingEngineSettings;
2794 mProjectScope.reset();
2795 return mLayerStore.get();
2802 return mLayerStore.get();
2809 QList<QgsVectorLayer *>
layers;
2810 const QStringList layerIds =
readListEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsList" ), QStringList() );
2811 const auto constLayerIds = layerIds;
2812 for (
const QString &layerId : constLayerIds )
2825 list.reserve(
layers.size() );
2827 list << layer->id();
2828 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsList" ), list );
2850 if ( mProjectScope )
2852 std::unique_ptr< QgsExpressionContextScope > projectScope = std::make_unique< QgsExpressionContextScope >( *mProjectScope );
2859 projectScope->addFunction( QStringLiteral(
"sensor_data" ),
new GetSensorData(
sensorManager()->sensorsData() ) );
2861 return projectScope.release();
2864 mProjectScope = std::make_unique< QgsExpressionContextScope >( QObject::tr(
"Project" ) );
2868 QVariantMap::const_iterator it = vars.constBegin();
2870 for ( ; it != vars.constEnd(); ++it )
2872 mProjectScope->setVariable( it.key(), it.value(),
true );
2876 if ( projectPath.isEmpty() )
2877 projectPath = mOriginalPath;
2878 const QString projectFolder = QFileInfo( projectPath ).path();
2879 const QString projectFilename = QFileInfo( projectPath ).fileName();
2880 const QString projectBasename =
baseName();
2917 QVariantMap keywords;
2919 for (
auto it = metadataKeywords.constBegin(); it != metadataKeywords.constEnd(); ++it )
2921 keywords.insert( it.key(), it.value() );
2926 QVariantList layersIds;
2928 const QMap<QString, QgsMapLayer *> layersInProject = mLayerStore->mapLayers();
2929 layersIds.reserve( layersInProject.count() );
2930 layers.reserve( layersInProject.count() );
2931 for (
auto it = layersInProject.constBegin(); it != layersInProject.constEnd(); ++it )
2933 layersIds << it.value()->id();
2939 mProjectScope->addFunction( QStringLiteral(
"project_color" ),
new GetNamedProjectColor(
this ) );
2940 mProjectScope->addFunction( QStringLiteral(
"project_color_object" ),
new GetNamedProjectColorObject(
this ) );
2945void QgsProject::onMapLayersAdded(
const QList<QgsMapLayer *> &layers )
2949 const QMap<QString, QgsMapLayer *> existingMaps =
mapLayers();
2951 const auto constLayers =
layers;
2954 if ( ! layer->isValid() )
2957 if (
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer ) )
2960 if ( vlayer->dataProvider() )
2968 for ( QMap<QString, QgsMapLayer *>::const_iterator it = existingMaps.cbegin(); it != existingMaps.cend(); ++it )
2970 const QSet<QgsMapLayerDependency> deps = it.value()->dependencies();
2971 if ( deps.contains( layer->id() ) )
2974 it.value()->setDependencies( deps );
2979 updateTransactionGroups();
2985void QgsProject::onMapLayersRemoved(
const QList<QgsMapLayer *> &layers )
2993void QgsProject::cleanTransactionGroups(
bool force )
2997 bool changed =
false;
2998 for ( QMap< QPair< QString, QString>,
QgsTransactionGroup *>::Iterator tg = mTransactionGroups.begin(); tg != mTransactionGroups.end(); )
3000 if ( tg.value()->isEmpty() || force )
3003 tg = mTransactionGroups.erase( tg );
3015void QgsProject::updateTransactionGroups()
3019 mEditBufferGroup.
clear();
3021 switch ( mTransactionMode )
3025 cleanTransactionGroups(
true );
3030 cleanTransactionGroups(
true );
3033 cleanTransactionGroups(
false );
3037 bool tgChanged =
false;
3038 const auto constLayers =
mapLayers().values();
3041 if ( ! layer->isValid() )
3044 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
3048 switch ( mTransactionMode )
3065 mTransactionGroups.insert( qMakePair( key, connString ), tg );
3075 mEditBufferGroup.
addLayer( vlayer );
3091 context.setProjectTranslator(
this );
3093 QList<QDomNode> brokenNodes;
3094 if ( addLayer( layerNode.toElement(), brokenNodes, context ) )
3098 const QVector<QgsVectorLayer *> vectorLayers = layers<QgsVectorLayer *>();
3102 layer->resolveReferences(
this );
3104 if ( layer->isValid() && layer->customProperty( QStringLiteral(
"_layer_was_editable" ) ).toBool() )
3106 layer->startEditing();
3107 layer->removeCustomProperty( QStringLiteral(
"_layer_was_editable" ) );
3119 mFile.setFileName( filename );
3120 mCachedHomePath.clear();
3128 mProjectScope.reset();
3134 const QString storageFilePath { storage->filePath( mFile.fileName() ) };
3135 if ( storageFilePath.isEmpty() )
3141 const QString tempPath = QStandardPaths::standardLocations( QStandardPaths::TempLocation ).at( 0 );
3142 const QString tmpZipFilename( tempPath + QDir::separator() + QUuid::createUuid().toString() );
3144 if ( !zip( tmpZipFilename ) )
3147 QFile tmpZipFile( tmpZipFilename );
3148 if ( !tmpZipFile.open( QIODevice::ReadOnly ) )
3150 setError( tr(
"Unable to read file %1" ).arg( tmpZipFilename ) );
3155 if ( !storage->writeProject( mFile.fileName(), &tmpZipFile, context ) )
3157 QString err = tr(
"Unable to save project to storage %1" ).arg( mFile.fileName() );
3158 QList<QgsReadWriteContext::ReadWriteMessage> messages = context.
takeMessages();
3159 if ( !messages.isEmpty() )
3160 err += QStringLiteral(
"\n\n" ) + messages.last().message();
3166 QFile::remove( tmpZipFilename );
3173 return zip( mFile.fileName() );
3179 const bool asOk = saveAuxiliaryStorage();
3180 const bool writeOk = writeProjectFile( mFile.fileName() );
3181 bool attachmentsOk =
true;
3182 if ( !mArchive->files().isEmpty() )
3184 const QFileInfo finfo( mFile.fileName() );
3185 const QString attachmentsZip = finfo.absoluteDir().absoluteFilePath( QStringLiteral(
"%1_attachments.zip" ).arg( finfo.completeBaseName() ) );
3186 attachmentsOk = mArchive->zip( attachmentsZip );
3190 if ( ( !asOk || !attachmentsOk ) && writeOk )
3192 QStringList errorMessage;
3195 const QString err = mAuxiliaryStorage->errorString();
3196 errorMessage.append( tr(
"Unable to save auxiliary storage ('%1')" ).arg( err ) );
3198 if ( !attachmentsOk )
3200 errorMessage.append( tr(
"Unable to save attachments archive" ) );
3202 setError( errorMessage.join(
'\n' ) );
3205 return asOk && writeOk && attachmentsOk;
3209bool QgsProject::writeProjectFile(
const QString &filename )
3213 QFile projectFile( filename );
3219 const QFileInfo myFileInfo( projectFile );
3220 if ( myFileInfo.exists() && !myFileInfo.isWritable() )
3222 setError( tr(
"%1 is not writable. Please adjust permissions (if possible) and try again." )
3223 .arg( projectFile.fileName() ) );
3231 QDomImplementation::setInvalidDataPolicy( QDomImplementation::DropInvalidChars );
3233 const QDomDocumentType documentType =
3234 QDomImplementation().createDocumentType( QStringLiteral(
"qgis" ), QStringLiteral(
"http://mrcc.com/qgis.dtd" ),
3235 QStringLiteral(
"SYSTEM" ) );
3236 std::unique_ptr<QDomDocument> doc(
new QDomDocument( documentType ) );
3238 QDomElement qgisNode = doc->createElement( QStringLiteral(
"qgis" ) );
3239 qgisNode.setAttribute( QStringLiteral(
"projectname" ),
title() );
3240 qgisNode.setAttribute( QStringLiteral(
"version" ),
Qgis::version() );
3242 if ( !mSettings.
value( QStringLiteral(
"projects/anonymize_saved_projects" ),
false,
QgsSettings::Core ).toBool() )
3246 qgisNode.setAttribute( QStringLiteral(
"saveUser" ), newSaveUser );
3247 qgisNode.setAttribute( QStringLiteral(
"saveUserFull" ), newSaveUserFull );
3248 mSaveUser = newSaveUser;
3249 mSaveUserFull = newSaveUserFull;
3250 mSaveDateTime = QDateTime::currentDateTime();
3251 qgisNode.setAttribute( QStringLiteral(
"saveDateTime" ), mSaveDateTime.toString( Qt::ISODate ) );
3256 mSaveUserFull.clear();
3257 mSaveDateTime = QDateTime();
3259 doc->appendChild( qgisNode );
3262 QDomElement homePathNode = doc->createElement( QStringLiteral(
"homePath" ) );
3263 homePathNode.setAttribute( QStringLiteral(
"path" ), mHomePath );
3264 qgisNode.appendChild( homePathNode );
3267 QDomElement titleNode = doc->createElement( QStringLiteral(
"title" ) );
3268 qgisNode.appendChild( titleNode );
3270 QDomElement transactionNode = doc->createElement( QStringLiteral(
"transaction" ) );
3271 transactionNode.setAttribute( QStringLiteral(
"mode" ),
qgsEnumValueToKey( mTransactionMode ) );
3272 qgisNode.appendChild( transactionNode );
3274 QDomElement flagsNode = doc->createElement( QStringLiteral(
"projectFlags" ) );
3276 qgisNode.appendChild( flagsNode );
3278 const QDomText titleText = doc->createTextNode(
title() );
3279 titleNode.appendChild( titleText );
3283 QDomElement srsNode = doc->createElement( QStringLiteral(
"projectCrs" ) );
3285 qgisNode.appendChild( srsNode );
3288 QDomElement verticalSrsNode = doc->createElement( QStringLiteral(
"verticalCrs" ) );
3289 mVerticalCrs.
writeXml( verticalSrsNode, *doc );
3290 qgisNode.appendChild( verticalSrsNode );
3293 QDomElement elevationShadingNode = doc->createElement( QStringLiteral(
"elevation-shading-renderer" ) );
3294 mElevationShadingRenderer.
writeXml( elevationShadingNode, context );
3295 qgisNode.appendChild( elevationShadingNode );
3302 clonedRoot->
writeXml( qgisNode, context );
3306 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/AvoidIntersectionsMode" ),
static_cast<int>( mAvoidIntersectionsMode ) );
3314 QDomElement annotationLayerNode = doc->createElement( QStringLiteral(
"main-annotation-layer" ) );
3315 mMainAnnotationLayer->
writeLayerXml( annotationLayerNode, *doc, context );
3316 qgisNode.appendChild( annotationLayerNode );
3320 QDomElement projectLayersNode = doc->createElement( QStringLiteral(
"projectlayers" ) );
3322 QMap<QString, QgsMapLayer *>::ConstIterator li =
layers.constBegin();
3323 while ( li !=
layers.end() )
3329 const QHash< QString, QPair< QString, bool> >::const_iterator emIt = mEmbeddedLayers.constFind( ml->
id() );
3330 if ( emIt == mEmbeddedLayers.constEnd() )
3332 QDomElement maplayerElem;
3338 maplayerElem = doc->createElement( QStringLiteral(
"maplayer" ) );
3342 maplayerElem.setAttribute( QStringLiteral(
"editable" ), QStringLiteral(
"1" ) );
3346 QDomDocument document;
3349 maplayerElem = document.firstChildElement();
3353 QgsDebugError( QStringLiteral(
"Could not restore layer properties for layer %1" ).arg( ml->
id() ) );
3359 projectLayersNode.appendChild( maplayerElem );
3365 if ( emIt.value().second )
3367 QDomElement mapLayerElem = doc->createElement( QStringLiteral(
"maplayer" ) );
3368 mapLayerElem.setAttribute( QStringLiteral(
"embedded" ), 1 );
3369 mapLayerElem.setAttribute( QStringLiteral(
"project" ),
writePath( emIt.value().first ) );
3370 mapLayerElem.setAttribute( QStringLiteral(
"id" ), ml->
id() );
3371 projectLayersNode.appendChild( mapLayerElem );
3378 qgisNode.appendChild( projectLayersNode );
3380 QDomElement layerOrderNode = doc->createElement( QStringLiteral(
"layerorder" ) );
3382 for (
QgsMapLayer *layer : constCustomLayerOrder )
3384 QDomElement mapLayerElem = doc->createElement( QStringLiteral(
"layer" ) );
3385 mapLayerElem.setAttribute( QStringLiteral(
"id" ), layer->id() );
3386 layerOrderNode.appendChild( mapLayerElem );
3388 qgisNode.appendChild( layerOrderNode );
3390 mLabelingEngineSettings->writeSettingsToProject(
this );
3392 QDomElement labelEngineSettingsElement = doc->createElement( QStringLiteral(
"labelEngineSettings" ) );
3393 mLabelingEngineSettings->writeXml( *doc, labelEngineSettingsElement, context );
3394 qgisNode.appendChild( labelEngineSettingsElement );
3397 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorRedPart" ), mBackgroundColor.red() );
3398 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorGreenPart" ), mBackgroundColor.green() );
3399 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/CanvasColorBluePart" ), mBackgroundColor.blue() );
3401 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorRedPart" ), mSelectionColor.red() );
3402 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorGreenPart" ), mSelectionColor.green() );
3403 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorBluePart" ), mSelectionColor.blue() );
3404 writeEntry( QStringLiteral(
"Gui" ), QStringLiteral(
"/SelectionColorAlphaPart" ), mSelectionColor.alpha() );
3411 dump_( mProperties );
3414 QgsDebugMsgLevel( QStringLiteral(
"there are %1 property scopes" ).arg(
static_cast<int>( mProperties.
count() ) ), 2 );
3419 mProperties.
writeXml( QStringLiteral(
"properties" ), qgisNode, *doc );
3422 QDomElement ddElem = doc->createElement( QStringLiteral(
"dataDefinedServerProperties" ) );
3423 mDataDefinedServerProperties.
writeXml( ddElem, dataDefinedServerPropertyDefinitions() );
3424 qgisNode.appendChild( ddElem );
3426 mMapThemeCollection->writeXml( *doc );
3428 mTransformContext.
writeXml( qgisNode, context );
3430 QDomElement metadataElem = doc->createElement( QStringLiteral(
"projectMetadata" ) );
3432 qgisNode.appendChild( metadataElem );
3435 const QDomElement annotationsElem = mAnnotationManager->writeXml( *doc, context );
3436 qgisNode.appendChild( annotationsElem );
3440 const QDomElement layoutElem = mLayoutManager->writeXml( *doc );
3441 qgisNode.appendChild( layoutElem );
3445 const QDomElement views3DElem = m3DViewsManager->writeXml( *doc );
3446 qgisNode.appendChild( views3DElem );
3450 const QDomElement bookmarkElem = mBookmarkManager->
writeXml( *doc );
3451 qgisNode.appendChild( bookmarkElem );
3455 const QDomElement sensorElem = mSensorManager->
writeXml( *doc );
3456 qgisNode.appendChild( sensorElem );
3460 const QDomElement viewSettingsElem = mViewSettings->
writeXml( *doc, context );
3461 qgisNode.appendChild( viewSettingsElem );
3465 const QDomElement styleSettingsElem = mStyleSettings->
writeXml( *doc, context );
3466 qgisNode.appendChild( styleSettingsElem );
3470 const QDomElement timeSettingsElement = mTimeSettings->
writeXml( *doc, context );
3471 qgisNode.appendChild( timeSettingsElement );
3475 const QDomElement elevationPropertiesElement = mElevationProperties->
writeXml( *doc, context );
3476 qgisNode.appendChild( elevationPropertiesElement );
3480 const QDomElement displaySettingsElem = mDisplaySettings->
writeXml( *doc, context );
3481 qgisNode.appendChild( displaySettingsElem );
3485 const QDomElement gpsSettingsElem = mGpsSettings->
writeXml( *doc, context );
3486 qgisNode.appendChild( gpsSettingsElem );
3495 QFile backupFile( QStringLiteral(
"%1~" ).arg( filename ) );
3497 ok &= backupFile.open( QIODevice::WriteOnly | QIODevice::Truncate );
3498 ok &= projectFile.open( QIODevice::ReadOnly );
3501 while ( ok && !projectFile.atEnd() )
3503 ba = projectFile.read( 10240 );
3504 ok &= backupFile.write( ba ) == ba.size();
3507 projectFile.close();
3512 setError( tr(
"Unable to create backup file %1" ).arg( backupFile.fileName() ) );
3517 struct utimbuf tb = {
static_cast<time_t
>( fi.lastRead().toSecsSinceEpoch() ),
static_cast<time_t
>( fi.lastModified().toSecsSinceEpoch() ) };
3518 utime( backupFile.fileName().toUtf8().constData(), &tb );
3521 if ( !projectFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
3523 projectFile.close();
3526 setError( tr(
"Unable to save to file %1" ).arg( projectFile.fileName() ) );
3530 QTemporaryFile tempFile;
3531 bool ok = tempFile.open();
3534 QTextStream projectFileStream( &tempFile );
3535 doc->save( projectFileStream, 2 );
3536 ok &= projectFileStream.pos() > -1;
3538 ok &= tempFile.seek( 0 );
3541 while ( ok && !tempFile.atEnd() )
3543 ba = tempFile.read( 10240 );
3544 ok &= projectFile.write( ba ) == ba.size();
3547 ok &= projectFile.error() == QFile::NoError;
3549 projectFile.close();
3556 setError( tr(
"Unable to save to file %1. Your project "
3557 "may be corrupted on disk. Try clearing some space on the volume and "
3558 "check file permissions before pressing save again." )
3559 .arg( projectFile.fileName() ) );
3573 bool propertiesModified;
3574 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3576 if ( propertiesModified )
3586 bool propertiesModified;
3587 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3589 if ( propertiesModified )
3599 bool propertiesModified;
3600 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3602 if ( propertiesModified )
3612 bool propertiesModified;
3613 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3615 if ( propertiesModified )
3625 bool propertiesModified;
3626 const bool success =
addKey_( scope, key, &mProperties, value, propertiesModified );
3628 if ( propertiesModified )
3636 const QStringList &def,
3648 value =
property->value();
3650 const bool valid = QMetaType::Type::QStringList == value.userType();
3656 return value.toStringList();
3679 value =
property->value();
3681 const bool valid = value.canConvert( QMetaType::Type::QString );
3686 return value.toString();
3705 value =
property->value();
3708 const bool valid = value.canConvert( QMetaType::Type::Int );
3717 return value.toInt();
3732 const QVariant value =
property->value();
3734 const bool valid = value.canConvert( QMetaType::Type::Double );
3739 return value.toDouble();
3756 const QVariant value =
property->value();
3758 const bool valid = value.canConvert( QMetaType::Type::Bool );
3763 return value.toBool();
3775 if (
findKey_( scope, key, mProperties ) )
3781 return !
findKey_( scope, key, mProperties );
3790 QStringList entries;
3792 if ( foundProperty )
3809 QStringList entries;
3811 if ( foundProperty )
3826 dump_( mProperties );
3846 filePath = storage->filePath( mFile.fileName() );
3873void QgsProject::setError(
const QString &errorMessage )
3877 mErrorMessage = errorMessage;
3884 return mErrorMessage;
3887void QgsProject::clearError()
3891 setError( QString() );
3898 delete mBadLayerHandler;
3899 mBadLayerHandler = handler;
3906 const QHash< QString, QPair< QString, bool > >::const_iterator it = mEmbeddedLayers.find(
id );
3907 if ( it == mEmbeddedLayers.constEnd() )
3911 return it.value().first;
3921 static QString sPrevProjectFilePath;
3922 static QDateTime sPrevProjectFileTimestamp;
3923 static QDomDocument sProjectDocument;
3925 QString qgsProjectFile = projectFilePath;
3927 if ( projectFilePath.endsWith( QLatin1String(
".qgz" ), Qt::CaseInsensitive ) )
3929 archive.
unzip( projectFilePath );
3933 const QDateTime projectFileTimestamp = QFileInfo( projectFilePath ).lastModified();
3935 if ( projectFilePath != sPrevProjectFilePath || projectFileTimestamp != sPrevProjectFileTimestamp )
3937 sPrevProjectFilePath.clear();
3939 QFile projectFile( qgsProjectFile );
3940 if ( !projectFile.open( QIODevice::ReadOnly ) )
3945 if ( !sProjectDocument.setContent( &projectFile ) )
3950 sPrevProjectFilePath = projectFilePath;
3951 sPrevProjectFileTimestamp = projectFileTimestamp;
3955 bool useAbsolutePaths =
true;
3957 const QDomElement propertiesElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral(
"properties" ) );
3958 if ( !propertiesElem.isNull() )
3960 const QDomElement absElem = propertiesElem.firstChildElement( QStringLiteral(
"Paths" ) ).firstChildElement( QStringLiteral(
"Absolute" ) );
3961 if ( !absElem.isNull() )
3963 useAbsolutePaths = absElem.text().compare( QLatin1String(
"true" ), Qt::CaseInsensitive ) == 0;
3968 if ( !useAbsolutePaths )
3973 const QDomElement projectLayersElem = sProjectDocument.documentElement().firstChildElement( QStringLiteral(
"projectlayers" ) );
3974 if ( projectLayersElem.isNull() )
3979 QDomElement mapLayerElem = projectLayersElem.firstChildElement( QStringLiteral(
"maplayer" ) );
3980 while ( ! mapLayerElem.isNull() )
3983 const QString
id = mapLayerElem.firstChildElement( QStringLiteral(
"id" ) ).text();
3984 if (
id == layerId )
3987 if ( mapLayerElem.attribute( QStringLiteral(
"embedded" ) ) == QLatin1String(
"1" ) )
3992 mEmbeddedLayers.insert( layerId, qMakePair( projectFilePath, saveFlag ) );
3994 if ( addLayer( mapLayerElem, brokenNodes, embeddedContext,
flags ) )
4000 mEmbeddedLayers.remove( layerId );
4004 mapLayerElem = mapLayerElem.nextSiblingElement( QStringLiteral(
"maplayer" ) );
4014 QString qgsProjectFile = projectFilePath;
4016 if ( projectFilePath.endsWith( QLatin1String(
".qgz" ), Qt::CaseInsensitive ) )
4018 archive.
unzip( projectFilePath );
4023 QFile projectFile( qgsProjectFile );
4024 if ( !projectFile.open( QIODevice::ReadOnly ) )
4029 QDomDocument projectDocument;
4030 if ( !projectDocument.setContent( &projectFile ) )
4042 QDomElement layerTreeElem = projectDocument.documentElement().firstChildElement( QStringLiteral(
"layer-tree-group" ) );
4043 if ( !layerTreeElem.isNull() )
4053 if ( !group || group->
customProperty( QStringLiteral(
"embedded" ) ).toBool() )
4066 newGroup->
setCustomProperty( QStringLiteral(
"embedded_project" ), projectFilePath );
4069 mLayerTreeRegistryBridge->
setEnabled(
false );
4070 initializeEmbeddedSubtree( projectFilePath, newGroup,
flags );
4071 mLayerTreeRegistryBridge->
setEnabled(
true );
4074 const auto constFindLayerIds = newGroup->
findLayerIds();
4075 for (
const QString &layerId : constFindLayerIds )
4092 const auto constChildren = group->
children();
4096 child->setCustomProperty( QStringLiteral(
"embedded" ), 1 );
4105 QList<QDomNode> brokenNodes;
4129 writeEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/TopologicalEditing" ), ( enabled ? 1 : 0 ) );
4137 return readNumEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/TopologicalEditing" ), 0 );
4144 if ( mDistanceUnits == unit )
4147 mDistanceUnits = unit;
4156 if ( mAreaUnits == unit )
4169 if ( !mCachedHomePath.isEmpty() )
4170 return mCachedHomePath;
4174 if ( !mHomePath.isEmpty() )
4176 const QFileInfo homeInfo( mHomePath );
4177 if ( !homeInfo.isRelative() )
4179 mCachedHomePath = mHomePath;
4189 const QString storagePath { storage->filePath(
fileName() ) };
4190 if ( ! storagePath.isEmpty() && QFileInfo::exists( storagePath ) )
4192 mCachedHomePath = QFileInfo( storagePath ).path();
4193 return mCachedHomePath;
4197 mCachedHomePath = pfi.path();
4198 return mCachedHomePath;
4201 if ( !pfi.exists() )
4203 mCachedHomePath = mHomePath;
4207 if ( !mHomePath.isEmpty() )
4210 mCachedHomePath = QDir::cleanPath( pfi.path() +
'/' + mHomePath );
4214 mCachedHomePath = pfi.canonicalPath();
4216 return mCachedHomePath;
4231 return mRelationManager;
4238 return mLayoutManager.get();
4245 return mLayoutManager.get();
4252 return m3DViewsManager.get();
4259 return m3DViewsManager.get();
4266 return mBookmarkManager;
4273 return mBookmarkManager;
4280 return mSensorManager;
4287 return mSensorManager;
4294 return mViewSettings;
4301 return mViewSettings;
4308 return mStyleSettings;
4316 return mStyleSettings;
4323 return mTimeSettings;
4330 return mTimeSettings;
4337 return mElevationProperties;
4344 return mElevationProperties;
4351 return mDisplaySettings;
4358 return mDisplaySettings;
4365 return mGpsSettings;
4372 return mGpsSettings;
4386 return mMapThemeCollection.get();
4393 return mAnnotationManager.get();
4400 return mAnnotationManager.get();
4407 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
4408 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
4413 if (
layers.contains( it.value() ) )
4414 it.value()->setFlags( it.value()->flags() &
~QgsMapLayer::Identifiable );
4430 for (
const QString &layerId : layerIds )
4448 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
4482 updateTransactionGroups();
4489 return mTransactionMode;
4500 const auto constLayers =
mapLayers().values();
4503 if ( layer->isEditable() )
4505 QgsLogger::warning( tr(
"Transaction mode can be changed only if all layers are not editable." ) );
4511 updateTransactionGroups();
4520 return mTransactionGroups;
4533 return mLayerStore->count();
4540 return mLayerStore->validCount();
4548 return mLayerStore->mapLayer( layerId );
4555 return mLayerStore->mapLayersByName( layerName );
4562 QList<QgsMapLayer *>
layers;
4563 const auto constMapLayers { mLayerStore->mapLayers() };
4564 for (
const auto &l : constMapLayers )
4566 if ( ! l->serverProperties()->shortName().isEmpty() )
4568 if ( l->serverProperties()->shortName() == shortName )
4571 else if ( l->name() == shortName )
4587 if ( !archive->unzip( filename ) )
4589 setError( tr(
"Unable to unzip file '%1'" ).arg( filename ) );
4594 if ( archive->projectFile().isEmpty() )
4596 setError( tr(
"Zip archive does not provide a project file" ) );
4601 releaseHandlesToProjectArchive();
4602 mArchive = std::move( archive );
4619 setError( tr(
"Cannot read unzipped qgs project file" ) + QStringLiteral(
": " ) +
error() );
4629bool QgsProject::zip(
const QString &filename )
4637 const QString
baseName = QFileInfo( filename ).baseName();
4638 const QString qgsFileName = QStringLiteral(
"%1.qgs" ).arg(
baseName );
4639 QFile qgsFile( QDir( archive->dir() ).filePath( qgsFileName ) );
4641 bool writeOk =
false;
4642 if ( qgsFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
4644 writeOk = writeProjectFile( qgsFile.fileName() );
4651 setError( tr(
"Unable to write temporary qgs file" ) );
4656 const QFileInfo info( qgsFile );
4658 const QString asFileName = info.path() + QDir::separator() + info.completeBaseName() + asExt;
4660 bool auxiliaryStorageSavedOk =
true;
4661 if ( ! saveAuxiliaryStorage( asFileName ) )
4663 const QString err = mAuxiliaryStorage->errorString();
4664 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 ) );
4665 auxiliaryStorageSavedOk =
false;
4668 if ( !mArchive->exists() )
4670 releaseHandlesToProjectArchive();
4672 mArchive->unzip( mFile.fileName() );
4675 const QString auxiliaryStorageFile =
static_cast<QgsProjectArchive *
>( mArchive.get() )->auxiliaryStorageFile();
4676 if ( ! auxiliaryStorageFile.isEmpty() )
4678 archive->
addFile( auxiliaryStorageFile );
4687 if ( QFile::exists( asFileName ) )
4689 archive->addFile( asFileName );
4694 archive->addFile( qgsFile.fileName() );
4697 const QStringList &
files = mArchive->files();
4698 for (
const QString &file :
files )
4700 if ( !file.endsWith( QLatin1String(
".qgs" ), Qt::CaseInsensitive ) && !file.endsWith( asExt, Qt::CaseInsensitive ) )
4702 archive->addFile( file );
4708 if ( !archive->zip( filename ) )
4710 setError( tr(
"Unable to perform zip" ) );
4714 return auxiliaryStorageSavedOk && zipOk;
4725 const QList<QgsMapLayer *> &layers,
4727 bool takeOwnership )
4731 const QList<QgsMapLayer *> myResultList { mLayerStore->addMapLayers(
layers, takeOwnership ) };
4732 if ( !myResultList.isEmpty() )
4735 for (
auto &l : myResultList )
4745 if ( mAuxiliaryStorage )
4760 mProjectScope.reset();
4762 return myResultList;
4768 bool takeOwnership )
4772 QList<QgsMapLayer *> addedLayers;
4773 addedLayers =
addMapLayers( QList<QgsMapLayer *>() << layer, addToLegend, takeOwnership );
4774 return addedLayers.isEmpty() ? nullptr : addedLayers[0];
4777void QgsProject::removeAuxiliaryLayer(
const QgsMapLayer *ml )
4784 const QgsVectorLayer *vl = qobject_cast<const QgsVectorLayer *>( ml );
4796 for (
const auto &layerId : layerIds )
4797 removeAuxiliaryLayer( mLayerStore->mapLayer( layerId ) );
4799 mProjectScope.reset();
4800 mLayerStore->removeMapLayers( layerIds );
4807 for (
const auto &layer :
layers )
4808 removeAuxiliaryLayer( layer );
4810 mProjectScope.reset();
4811 mLayerStore->removeMapLayers(
layers );
4818 removeAuxiliaryLayer( mLayerStore->mapLayer( layerId ) );
4819 mProjectScope.reset();
4820 mLayerStore->removeMapLayer( layerId );
4827 removeAuxiliaryLayer( layer );
4828 mProjectScope.reset();
4829 mLayerStore->removeMapLayer( layer );
4836 mProjectScope.reset();
4837 return mLayerStore->takeMapLayer( layer );
4844 return mMainAnnotationLayer;
4851 if ( mLayerStore->count() == 0 )
4854 ScopedIntIncrementor snapSingleBlocker( &mBlockSnappingUpdates );
4855 mProjectScope.reset();
4856 mLayerStore->removeAllMapLayers();
4858 snapSingleBlocker.release();
4860 if ( !mBlockSnappingUpdates )
4868 const QMap<QString, QgsMapLayer *>
layers = mLayerStore->mapLayers();
4869 QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin();
4870 for ( ; it !=
layers.constEnd(); ++it )
4872 it.value()->reload();
4881 return validOnly ? mLayerStore->validMapLayers() : mLayerStore->mapLayers();
4888 return mTransactionGroups.value( qMakePair( providerKey, connString ) );
4895 return &mEditBufferGroup;
4906 if ( mSettings.
value( QStringLiteral(
"/projections/unknownCrsBehavior" ), QStringLiteral(
"NoAction" ),
QgsSettings::App ).toString() == QStringLiteral(
"UseProjectCrs" )
4907 || mSettings.
value( QStringLiteral(
"/projections/unknownCrsBehavior" ), 0,
QgsSettings::App ).toString() == QLatin1String(
"2" ) )
4915 const QString layerDefaultCrs = mSettings.
value( QStringLiteral(
"/Projections/layerDefaultCrs" ),
geoEpsgCrsAuthId() ).toString();
4936bool QgsProject::saveAuxiliaryStorage(
const QString &filename )
4942 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
4947 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( it.value() );
4955 if ( !mAuxiliaryStorage->exists( *
this ) && empty )
4959 else if ( !filename.isEmpty() )
4961 return mAuxiliaryStorage->saveAs( filename );
4965 return mAuxiliaryStorage->saveAs( *
this );
4978 return sPropertyDefinitions;
4991 return mAuxiliaryStorage.get();
4998 return mAuxiliaryStorage.get();
5005 const QDir archiveDir( mArchive->dir() );
5006 QTemporaryFile tmpFile( archiveDir.filePath(
"XXXXXX_" + nameTemplate ),
this );
5007 tmpFile.setAutoRemove(
false );
5009 mArchive->addFile( tmpFile.fileName() );
5010 return tmpFile.fileName();
5017 QStringList attachments;
5019 const QStringList files = mArchive->files();
5020 attachments.reserve( files.size() );
5021 for (
const QString &file : files )
5023 if ( QFileInfo( file ).baseName() !=
baseName )
5025 attachments.append( file );
5035 return mArchive->removeFile( path );
5042 return QStringLiteral(
"attachment:///%1" ).arg( QFileInfo( attachedFile ).
fileName() );
5049 if ( identifier.startsWith( QLatin1String(
"attachment:///" ) ) )
5051 return QDir( mArchive->dir() ).absoluteFilePath( identifier.mid( 14 ) );
5072 mProjectScope.reset();
5086 for ( QMap<QString, QgsMapLayer *>::const_iterator it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5100 const QMap<QString, QgsMapLayer *> &projectLayers =
mapLayers();
5101 for ( QMap<QString, QgsMapLayer *>::const_iterator it = projectLayers.constBegin(); it != projectLayers.constEnd(); ++it )
5106 if (
layers.contains( it.value() ) )
5107 it.value()->setFlags( it.value()->flags() &
~QgsMapLayer::Removable );
5118 QStringList customColors;
5119 QStringList customColorLabels;
5121 QgsNamedColorList::const_iterator colorIt = colors.constBegin();
5122 for ( ; colorIt != colors.constEnd(); ++colorIt )
5125 const QString label = ( *colorIt ).second;
5126 customColors.append( color );
5127 customColorLabels.append( label );
5129 writeEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Colors" ), customColors );
5130 writeEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Labels" ), customColorLabels );
5131 mProjectScope.reset();
5139 if ( mBackgroundColor == color )
5142 mBackgroundColor = color;
5150 return mBackgroundColor;
5157 if ( mSelectionColor == color )
5160 mSelectionColor = color;
5168 return mSelectionColor;
5205 translationContext.setFileName( QStringLiteral(
"%1/%2.ts" ).arg(
absolutePath(),
baseName() ) );
5209 translationContext.writeTsFile( locale );
5212QString
QgsProject::translate(
const QString &context,
const QString &sourceText,
const char *disambiguation,
int n )
const
5221 QString result = mTranslator->translate( context.toUtf8(), sourceText.toUtf8(), disambiguation, n );
5223 if ( result.isEmpty() )
5237 for (
auto it =
layers.constBegin(); it !=
layers.constEnd(); ++it )
5242 if ( !( ( *it )->accept( visitor ) ) )
5251 if ( !mLayoutManager->accept( visitor ) )
5254 if ( !mAnnotationManager->accept( visitor ) )
5262 return mElevationShadingRenderer;
5265void QgsProject::loadProjectFlags(
const QDomDocument *doc )
5269 QDomElement element = doc->documentElement().firstChildElement( QStringLiteral(
"projectFlags" ) );
5271 if ( !element.isNull() )
5278 element = doc->documentElement().firstChildElement( QStringLiteral(
"evaluateDefaultValues" ) );
5279 if ( !element.isNull() )
5281 if ( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
5286 element = doc->documentElement().firstChildElement( QStringLiteral(
"trust" ) );
5287 if ( !element.isNull() )
5289 if ( element.attribute( QStringLiteral(
"active" ), QStringLiteral(
"0" ) ).toInt() == 1 )
5305 const QString projectFunctions =
readEntry( QStringLiteral(
"ExpressionFunctions" ), QStringLiteral(
"/pythonCode" ), QString() );
5306 if ( !projectFunctions.isEmpty() )
5326QHash< QString, QColor > loadColorsFromProject(
const QgsProject *project )
5328 QHash< QString, QColor > colors;
5331 QStringList colorStrings = project->
readListEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Colors" ) );
5332 const QStringList colorLabels = project->
readListEntry( QStringLiteral(
"Palette" ), QStringLiteral(
"/Labels" ) );
5336 for ( QStringList::iterator it = colorStrings.begin();
5337 it != colorStrings.end(); ++it )
5341 if ( colorLabels.length() > colorIndex )
5343 label = colorLabels.at( colorIndex );
5346 colors.insert( label.toLower(), color );
5354GetNamedProjectColor::GetNamedProjectColor(
const QgsProject *project )
5360 mColors = loadColorsFromProject( project );
5363GetNamedProjectColor::GetNamedProjectColor(
const QHash<QString, QColor> &colors )
5371 const QString colorName = values.at( 0 ).toString().toLower();
5372 if ( mColors.contains( colorName ) )
5374 return QStringLiteral(
"%1,%2,%3" ).arg( mColors.value( colorName ).red() ).arg( mColors.value( colorName ).green() ).arg( mColors.value( colorName ).blue() );
5382 return new GetNamedProjectColor( mColors );
5385GetNamedProjectColorObject::GetNamedProjectColorObject(
const QgsProject *project )
5391 mColors = loadColorsFromProject( project );
5394GetNamedProjectColorObject::GetNamedProjectColorObject(
const QHash<QString, QColor> &colors )
5402 const QString colorName = values.at( 0 ).toString().toLower();
5403 if ( mColors.contains( colorName ) )
5405 return mColors.value( colorName );
5413 return new GetNamedProjectColorObject( mColors );
5418GetSensorData::GetSensorData(
const QMap<QString, QgsAbstractSensor::SensorData> &sensorData )
5421 QStringLiteral(
"Sensors" ) )
5422 , mSensorData( sensorData )
5428 const QString sensorName = values.at( 0 ).toString();
5429 const int expiration = values.at( 1 ).toInt();
5430 const qint64 timestamp = QDateTime::currentMSecsSinceEpoch();
5431 if ( mSensorData.contains( sensorName ) )
5433 if ( expiration <= 0 || ( timestamp - mSensorData[sensorName].lastTimestamp.toMSecsSinceEpoch() ) < expiration )
5435 return mSensorData[sensorName].lastValue;
5444 return new GetSensorData( mSensorData );
@ DontLoad3DViews
Skip loading 3D views.
@ DontStoreOriginalStyles
Skip the initial XML style storage for layers. Useful for minimising project load times in non-intera...
@ ForceReadOnlyLayers
Open layers in a read-only mode.
@ TrustLayerMetadata
Trust layer metadata. Improves project read time. Do not use it if layers' extent is not fixed during...
@ DontUpgradeAnnotations
Don't upgrade old annotation items to QgsAnnotationItem.
@ DontLoadLayouts
Don't load print layouts. Improves project read time if layouts are not required, and allows projects...
@ DontResolveLayers
Don't resolve layer paths (i.e. don't load any layer content). Dramatically improves project read tim...
static QString version()
Version string.
QFlags< ProjectCapability > ProjectCapabilities
Flags which control project capabilities.
QFlags< ProjectReadFlag > ProjectReadFlags
Project load flags.
DistanceUnit
Units of distance.
FilePathType
File path types.
TransactionMode
Transaction mode.
@ AutomaticGroups
Automatic transactional editing means that on supported datasources (postgres and geopackage database...
@ BufferedGroups
Buffered transactional editing means that all editable layers in the buffered transaction group are t...
@ Disabled
Edits are buffered locally and sent to the provider when toggling layer editing mode.
@ SquareMeters
Square meters.
@ Critical
Critical/error message.
@ Success
Used for reporting a successful operation.
PythonEmbeddedMode
Authorisation to run Python Embedded in projects.
@ Always
Python embedded is always run.
@ Ask
User is prompt before running.
@ SessionOnly
Only during this session.
@ Compound
Compound (horizontal + vertical) CRS.
@ Projected
Projected CRS.
@ DerivedProjected
Derived projected CRS.
@ Engineering
Engineering CRS.
@ Geographic3d
3D geopraphic CRS
@ Geographic2d
2D geographic CRS
@ Geocentric
Geocentric CRS.
AvoidIntersectionsMode
Flags which control how intersections of pre-existing feature are handled when digitizing new feature...
@ AvoidIntersectionsLayers
Overlap with features from a specified list of layers when digitizing new features not allowed.
@ AllowIntersections
Overlap with any feature allowed when digitizing new features.
ProjectFlag
Flags which control the behavior of QgsProjects.
@ RememberLayerEditStatusBetweenSessions
If set, then any layers set to be editable will be stored in the project and immediately made editabl...
@ EvaluateDefaultValuesOnProviderSide
If set, default values for fields will be evaluated on the provider side when features from the proje...
@ TrustStoredLayerStatistics
If set, then layer statistics (such as the layer extent) will be read from values stored in the proje...
QFlags< DataProviderReadFlag > DataProviderReadFlags
Flags which control data provider construction.
LayerType
Types of layers that can be added to a map.
@ Group
Composite group layer. Added in QGIS 3.24.
@ Plugin
Plugin based layer.
@ TiledScene
Tiled scene layer. Added in QGIS 3.34.
@ Annotation
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
@ VectorTile
Vector tile layer. Added in QGIS 3.14.
@ Mesh
Mesh layer. Added in QGIS 3.2.
@ PointCloud
Point cloud layer. Added in QGIS 3.18.
@ SkipCredentialsRequest
Skip credentials if the provided one are not valid, let the provider be invalid, avoiding to block th...
@ ParallelThreadLoading
Provider is created in a parallel thread than the one where it will live.
QFlags< ProjectFlag > ProjectFlags
@ Preferred
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
virtual bool readXml(const QDomElement &collectionElem, const QgsPropertiesDefinition &definitions)
Reads property collection state from an XML element.
virtual bool writeXml(QDomElement &collectionElem, const QgsPropertiesDefinition &definitions) const
Writes the current state of the property collection into an XML element.
Represents a map layer containing a set of georeferenced annotations, e.g.
void resolveReferences(QgsProject *project) override
Resolve references to other layers (kept as layer IDs after reading XML) into layer objects.
void setTransformContext(const QgsCoordinateTransformContext &context) override
Sets the coordinate transform context to transformContext.
void reset()
Resets the annotation layer to a default state, and clears all items from it.
bool isEmpty() const
Returns true if the annotation layer is empty and contains no annotations.
Manages storage of a set of QgsAnnotation annotation objects.
static QgsApplication * instance()
Returns the singleton instance of the QgsApplication.
static QgsProjectStorageRegistry * projectStorageRegistry()
Returns registry of available project storage implementations.
static const QgsSettingsEntryString * settingsLocaleUserLocale
Settings entry locale user locale.
static QgsRuntimeProfiler * profiler()
Returns the application runtime profiler.
void collectTranslatableObjects(QgsTranslationContext *translationContext)
Emits the signal to collect all the strings of .qgs to be included in ts file.
static QgsPluginLayerRegistry * pluginLayerRegistry()
Returns the application's plugin layer registry, used for managing plugin layer types.
void requestForTranslatableObjects(QgsTranslationContext *translationContext)
Emitted when project strings which require translation are being collected for inclusion in a ....
static QString userFullName()
Returns the user's operating system login account full display name.
static QString userLoginName()
Returns the user's operating system login account name.
Class allowing to manage the zip/unzip actions.
void addFile(const QString &filename)
Add a new file to this archive.
This is a container for attribute editors, used to group them visually in the attribute form if it is...
QList< QgsAttributeEditorElement * > children() const
Gets a list of the children elements of this container.
This is an abstract base class for any elements of a drag and drop form.
QString name() const
Returns the name of this element.
QgsFields auxiliaryFields() const
Returns a list of all auxiliary fields currently managed by the layer.
bool save()
Commits changes and starts editing then.
Class providing some utility methods to manage auxiliary storage.
static QString extension()
Returns the extension used for auxiliary databases.
static bool deleteTable(const QgsDataSourceUri &uri)
Removes a table from the auxiliary storage.
Manages storage of a set of bookmarks.
bool readXml(const QDomElement &element, const QDomDocument &doc)
Reads the manager's state from a DOM element, restoring all bookmarks present in the XML document.
void clear()
Removes and deletes all bookmarks from the manager.
QDomElement writeXml(QDomDocument &doc) const
Returns a DOM element representing the state of the manager.
static QColor colorFromString(const QString &string)
Decodes a string into a color value.
static QString colorToString(const QColor &color)
Encodes a color into a string value.
This class represents a coordinate reference system (CRS).
static QgsCoordinateReferenceSystem fromOgcWmsCrs(const QString &ogcCrs)
Creates a CRS from a given OGC WMS-format Coordinate Reference System string.
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
bool hasVerticalAxis() const
Returns true if the CRS has a vertical axis.
QString toProj() const
Returns a Proj string representation of this CRS.
bool readXml(const QDomNode &node)
Restores state from the given DOM node.
static QgsCoordinateReferenceSystem createCompoundCrs(const QgsCoordinateReferenceSystem &horizontalCrs, const QgsCoordinateReferenceSystem &verticalCrs, QString &error)
Given a horizontal and vertical CRS, attempts to create a compound CRS from them.
QString ellipsoidAcronym() const
Returns the ellipsoid acronym for the ellipsoid used by the CRS.
QString projectionAcronym() const
Returns the projection acronym for the projection used by the CRS.
QgsCoordinateReferenceSystem verticalCrs() const
Returns the vertical CRS associated with this CRS object.
static QgsCoordinateReferenceSystem fromProj(const QString &proj)
Creates a CRS from a proj style formatted string.
QString toWkt(Qgis::CrsWktVariant variant=Qgis::CrsWktVariant::Wkt1Gdal, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
bool writeXml(QDomNode &node, QDomDocument &doc) const
Stores state to the given Dom node in the given document.
static QgsCoordinateReferenceSystem fromSrsId(long srsId)
Creates a CRS from a specified QGIS SRS ID.
Qgis::CrsType type() const
Returns the type of the CRS.
Qgis::DistanceUnit mapUnits
Contains information about the context in which a coordinate transform is executed.
void readSettings()
Reads the context's state from application settings.
void writeXml(QDomElement &element, const QgsReadWriteContext &context) const
Writes the context's state to a DOM element.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context, QStringList &missingTransforms)
Reads the context's state from a DOM element.
Abstract base class for spatial data provider implementations.
@ EvaluateDefaultValues
Evaluate default values on provider side when calling QgsVectorDataProvider::defaultValue( int index ...
Class for storing the component parts of a RDBMS data source URI (e.g.
This class can render elevation shading on an image with different methods (eye dome lighting,...
void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const
Writes configuration on a DOM element.
void readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads configuration from a DOM element.
Single scope for storing variables and functions for use within a QgsExpressionContext.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
A abstract base class for defining QgsExpression functions.
An expression node for expression functions.
Class for parsing and evaluation of expressions (formerly called "search strings").
Encapsulate a field in an attribute table or data source.
Container of fields for a vector layer.
Stores global configuration for labeling engine.
Class used to work with layer dependencies stored in a XML project or layer definition file.
Layer tree group node serves as a container for layers and further groups.
void resolveReferences(const QgsProject *project, bool looseMatching=false) override
Calls resolveReferences() on child tree nodes.
QgsLayerTreeGroup * findGroup(const QString &name)
Find group node with specified name.
QList< QgsLayerTreeGroup * > findGroups(bool recursive=false) const
Find group layer nodes.
QString name() const override
Returns the group's name.
QStringList findLayerIds() const
Find layer IDs used in all layer nodes.
void insertChildNodes(int index, const QList< QgsLayerTreeNode * > &nodes)
Insert existing nodes at specified position.
void readChildrenFromXml(QDomElement &element, const QgsReadWriteContext &context)
Read children from XML and append them to the group.
QgsLayerTreeGroup * clone() const override
Returns a clone of the group.
QList< QgsLayerTreeLayer * > findLayers() const
Find all layer nodes.
QgsLayerTreeLayer * findLayer(QgsMapLayer *layer) const
Find layer node representing the map layer.
Layer tree node points to a map layer.
void resolveReferences(const QgsProject *project, bool looseMatching=false) override
Resolves reference to layer from stored layer ID (if it has not been resolved already)
This class is a base class for nodes in a layer tree.
QList< QgsLayerTreeNode * > abandonChildren()
Removes the children, disconnect all the forwarded and external signals and sets their parent to null...
void setCustomProperty(const QString &key, const QVariant &value)
Sets a custom property for the node. Properties are stored in a map and saved in project file.
virtual void writeXml(QDomElement &parentElement, const QgsReadWriteContext &context)=0
Write layer tree to XML.
QList< QgsLayerTreeNode * > children()
Gets list of children of the node. Children are owned by the parent.
void removeCustomProperty(const QString &key)
Remove a custom property from layer. Properties are stored in a map and saved in project file.
QVariant customProperty(const QString &key, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer. Properties are stored in a map and saved in project file.
void setItemVisibilityChecked(bool checked)
Check or uncheck a node (independently of its ancestors or children)
Listens to the updates in map layer registry and does changes in layer tree.
void setEnabled(bool enabled)
static void replaceChildrenOfEmbeddedGroups(QgsLayerTreeGroup *group)
Remove subtree of embedded groups and replaces it with a custom property embedded-visible-layers.
static void storeOriginalLayersProperties(QgsLayerTreeGroup *group, const QDomDocument *doc)
Stores in a layer's originalXmlProperties the layer properties information.
static void updateEmbeddedGroupsProjectPath(QgsLayerTreeGroup *group, const QgsProject *project)
Updates an embedded group from a project.
static bool readOldLegend(QgsLayerTreeGroup *root, const QDomElement &legendElem)
Try to load layer tree from.
Namespace with helper functions for layer tree operations.
void readLayerOrderFromXml(const QDomElement &doc)
Load the layer order from an XML element.
static QgsLayerTreeLayer * toLayer(QgsLayerTreeNode *node)
Cast node to a layer.
void clear()
Clear any information from this layer tree.
static bool isLayer(const QgsLayerTreeNode *node)
Check whether the node is a valid layer node.
static bool isGroup(QgsLayerTreeNode *node)
Check whether the node is a valid group node.
static QgsLayerTreeGroup * toGroup(QgsLayerTreeNode *node)
Cast node to a group.
QList< QgsMapLayer * > customLayerOrder() const
The order in which layers will be rendered on the canvas.
QgsLayerTree * clone() const override
Create a copy of the node. Returns new instance.
Manages storage of a set of layouts.
static void warning(const QString &msg)
Goes to qWarning.
static Qgis::LayerType typeFromString(const QString &string, bool &ok)
Returns the map layer type corresponding a string value.
A storage object for map layers, in which the layers are owned by the store and have their lifetime b...
void layersWillBeRemoved(const QStringList &layerIds)
Emitted when one or more layers are about to be removed from the store.
void layerWillBeRemoved(const QString &layerId)
Emitted when a layer is about to be removed from the store.
void layersRemoved(const QStringList &layerIds)
Emitted after one or more layers were removed from the store.
void allLayersRemoved()
Emitted when all layers are removed, before layersWillBeRemoved() and layerWillBeRemoved() signals ar...
void layerRemoved(const QString &layerId)
Emitted after a layer was removed from the store.
void layerWasAdded(QgsMapLayer *layer)
Emitted when a layer was added to the store.
QgsMapLayer * mapLayer(const QString &id) const
Retrieve a pointer to a layer by layer id.
void layersAdded(const QList< QgsMapLayer * > &layers)
Emitted when one or more layers were added to the store.
Base class for all map layer types.
QFlags< ReadFlag > ReadFlags
QString source() const
Returns the source for the layer.
QString providerType() const
Returns the provider type (provider key) for this layer.
void removeCustomProperty(const QString &key)
Remove a custom property from layer.
void configChanged()
Emitted whenever the configuration is changed.
static Qgis::DataProviderReadFlags providerReadFlags(const QDomNode &layerNode, QgsMapLayer::ReadFlags layerReadFlags)
Returns provider read flag deduced from layer read flags layerReadFlags and a dom node layerNode that...
QgsCoordinateReferenceSystem crs
QString originalXmlProperties() const
Returns the XML properties of the original layer as they were when the layer was first read from the ...
Q_INVOKABLE void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
virtual bool isEditable() const
Returns true if the layer can be edited.
bool writeLayerXml(QDomElement &layerElement, QDomDocument &document, const QgsReadWriteContext &context) const
Stores state in DOM node.
@ Identifiable
If the layer is identifiable using the identify map tool and as a WMS layer.
@ Removable
If the layer can be removed from the project. The layer will not be removable from the legend menu en...
@ FlagReadExtentFromXml
Read extent from xml and skip get extent from provider.
@ FlagTrustLayerMetadata
Trust layer metadata. Improves layer load time by skipping expensive checks like primary key unicity,...
@ FlagForceReadOnly
Force open as read only.
@ FlagDontResolveLayers
Don't resolve layer paths or create data providers for layers.
bool readLayerXml(const QDomElement &layerElement, QgsReadWriteContext &context, QgsMapLayer::ReadFlags flags=QgsMapLayer::ReadFlags(), QgsDataProvider *preloadedProvider=nullptr)
Sets state from DOM document.
void setCrs(const QgsCoordinateReferenceSystem &srs, bool emitSignal=true)
Sets layer's spatial reference system.
Container class that allows storage of map themes consisting of visible map layers and layer styles.
Manages storage of a set of views.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Resolves relative paths into absolute paths and vice versa.
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
Class allowing to manage the zip/unzip actions on project file.
QString projectFile() const
Returns the current .qgs project file or an empty string if there's none.
QString auxiliaryStorageFile() const
Returns the current .qgd auxiliary storage file or an empty string if there's none.
bool unzip(const QString &zipFilename) override
Clear the current content of this archive and unzip.
Interface for classes that handle missing layer files when reading project file.
virtual void handleBadLayers(const QList< QDomNode > &layers)
This method will be called whenever the project tries to load layers which cannot be accessed.
Contains settings and properties relating to how a QgsProject should display values such as map coord...
void reset()
Resets the settings to a default state.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads the settings's state from a DOM element.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Returns a DOM element representing the settings.
Contains elevation properties for a QgsProject.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads the property state from a DOM element.
void reset()
Resets the properties to a default state.
QDomElement writeXml(QDomDocument &document, const QgsReadWriteContext &context) const
Returns a DOM element representing the properties.
void resolveReferences(const QgsProject *project)
Resolves reference to layers from stored layer ID.
Contains settings and properties relating to how a QgsProject should interact with a GPS device.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads the settings's state from a DOM element.
void reset()
Resets the settings to a default state.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Returns a DOM element representing the settings.
void resolveReferences(const QgsProject *project)
Resolves reference to layers from stored layer ID (if it has not been resolved already)
Project property key node.
QString name() const
The name of the property is used as identifier.
QgsProjectProperty * find(const QString &propertyName) const
Attempts to find a property with a matching sub-key name.
void removeKey(const QString &keyName)
Removes the specified key.
void dump(int tabs=0) const override
Dumps out the keys and values.
bool isEmpty() const
Returns true if this property contains no sub-keys.
virtual void clearKeys()
Deletes any sub-nodes from the property.
bool writeXml(const QString &nodeName, QDomElement &element, QDomDocument &document) override
Writes the property hierarchy to a specified DOM element.
void subkeyList(QStringList &entries) const
Returns any sub-keys contained by this property which themselves contain other keys.
void setName(const QString &name)
The name of the property is used as identifier.
QgsProjectPropertyKey * addKey(const QString &keyName)
Adds the specified property key as a sub-key.
QVariant value() const override
If this key has a value, it will be stored by its name in its properties.
QgsProjectPropertyValue * setValue(const QString &name, const QVariant &value)
Sets the value associated with this key.
void entryList(QStringList &entries) const
Returns any sub-keys contained by this property that do not contain other keys.
int count() const
Returns the number of sub-keys contained by this property.
bool readXml(const QDomNode &keyNode) override
Restores the property hierarchy from a specified DOM node.
An Abstract Base Class for QGIS project property hierarchys.
virtual bool isKey() const =0
Returns true if the property is a QgsProjectPropertyKey.
virtual bool isValue() const =0
Returns true if the property is a QgsProjectPropertyValue.
QgsProjectStorage * projectStorageFromUri(const QString &uri)
Returns storage implementation if the URI matches one. Returns nullptr otherwise (it is a normal file...
Abstract interface for project storage - to be implemented by various backends and registered in QgsP...
Contains settings and properties relating to how a QgsProject should handle styling.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Returns a DOM element representing the settings.
void setDefaultSymbol(Qgis::SymbolType symbolType, QgsSymbol *symbol)
Sets the project default symbol for a given type.
void reset()
Resets the settings to a default state.
void removeProjectStyle()
Removes and deletes the project style database.
void setRandomizeDefaultSymbolColor(bool randomized)
Sets whether the default symbol fill color is randomized.
void setDefaultColorRamp(QgsColorRamp *colorRamp)
Sets the project default color ramp.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context, Qgis::ProjectReadFlags flags=Qgis::ProjectReadFlags())
Reads the settings's state from a DOM element.
void setDefaultSymbolOpacity(double opacity)
Sets the default symbol opacity.
Contains temporal settings and properties for the project, this may be used when animating maps or sh...
bool readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads the settings's state from a DOM element.
void reset()
Resets the settings to a default state.
QDomElement writeXml(QDomDocument &document, const QgsReadWriteContext &context) const
Returns a DOM element representing the settings.
A class to describe the version of a project.
QString text() const
Returns a string representation of the version.
int majorVersion() const
Returns the major version number.
Contains settings and properties relating to how a QgsProject should be displayed inside map canvas,...
bool useProjectScales() const
Returns true if project mapScales() are enabled.
void reset()
Resets the settings to a default state.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads the settings's state from a DOM element.
void setMapScales(const QVector< double > &scales)
Sets the list of custom project map scales.
void setUseProjectScales(bool enabled)
Sets whether project mapScales() are enabled.
QVector< double > mapScales() const
Returns the list of custom project map scales.
void mapScalesChanged()
Emitted when the list of custom project map scales changes.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Returns a DOM element representing the settings.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
bool isZipped() const
Returns true if the project comes from a zip archive, false otherwise.
bool removeAttachedFile(const QString &path)
Removes the attached file.
QgsRelationManager * relationManager
bool write()
Writes the project to its current associated file (see fileName() ).
QgsProject(QObject *parent=nullptr, Qgis::ProjectCapabilities capabilities=Qgis::ProjectCapability::ProjectStyles)
Create a new QgsProject.
void removeMapLayer(const QString &layerId)
Remove a layer from the registry by layer ID.
Q_DECL_DEPRECATED void oldProjectVersionWarning(const QString &warning)
Emitted when an old project file is read.
Q_DECL_DEPRECATED bool evaluateDefaultValues() const
Should default values be evaluated on provider side when requested and not when committed.
Qgis::DistanceUnit distanceUnits
void layersRemoved(const QStringList &layerIds)
Emitted after one or more layers were removed from the registry.
void clear()
Clears the project, removing all settings and resetting it back to an empty, default state.
QString error() const
Returns error message from previous read/write.
Q_DECL_DEPRECATED void setUseProjectScales(bool enabled)
Sets whether project mapScales() are enabled.
void readProjectWithContext(const QDomDocument &document, QgsReadWriteContext &context)
Emitted when a project is being read.
int readNumEntry(const QString &scope, const QString &key, int def=0, bool *ok=nullptr) const
Reads an integer from the specified scope and key.
Q_DECL_DEPRECATED void setNonIdentifiableLayers(const QList< QgsMapLayer * > &layers)
Set a list of layers which should not be taken into account on map identification.
QList< QgsMapLayer * > addMapLayers(const QList< QgsMapLayer * > &mapLayers, bool addToLegend=true, bool takeOwnership=true)
Add a list of layers to the map of loaded layers.
Qgis::ProjectFlags flags() const
Returns the project's flags, which dictate the behavior of the project.
Q_DECL_DEPRECATED QFileInfo fileInfo() const
Returns QFileInfo object for the project's associated file.
QString presetHomePath() const
Returns any manual project home path setting, or an empty string if not set.
void setBackgroundColor(const QColor &color)
Sets the default background color used by default map canvases.
void setCrs(const QgsCoordinateReferenceSystem &crs, bool adjustEllipsoid=false)
Sets the project's native coordinate reference system.
QString title() const
Returns the project's title.
bool commitChanges(QStringList &commitErrors, bool stopEditing=true, QgsVectorLayer *vectorLayer=nullptr)
Attempts to commit to the underlying data provider any buffered changes made since the last to call t...
void mapThemeCollectionChanged()
Emitted when the map theme collection changes.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Qgis::FilePathType filePathStorage() const
Returns the type of paths used when storing file paths in a QGS/QGZ project file.
QString createAttachedFile(const QString &nameTemplate)
Attaches a file to the project.
Q_DECL_DEPRECATED void mapScalesChanged()
Emitted when the list of custom project map scales changes.
void readVersionMismatchOccurred(const QString &fileVersion)
Emitted when a project is read and the version of QGIS used to save the project differs from the curr...
void fileNameChanged()
Emitted when the file name of the project changes.
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
void writeMapLayer(QgsMapLayer *mapLayer, QDomElement &layerElem, QDomDocument &doc)
Emitted when a layer is being saved.
const QgsSensorManager * sensorManager() const
Returns the project's sensor manager, which manages sensors within the project.
void setSnappingConfig(const QgsSnappingConfig &snappingConfig)
The snapping configuration for this project.
void areaUnitsChanged()
Emitted when the default area units changes.
QgsPropertyCollection dataDefinedServerProperties() const
Returns the data defined properties used for overrides in user defined server parameters.
Q_DECL_DEPRECATED void nonIdentifiableLayersChanged(QStringList nonIdentifiableLayers)
Emitted when the list of layer which are excluded from map identification changes.
void layersWillBeRemoved(const QStringList &layerIds)
Emitted when one or more layers are about to be removed from the registry.
QString attachmentIdentifier(const QString &attachedFile) const
Returns an identifier for an attachment file path An attachment identifier is a string which does not...
QgsVectorLayerEditBufferGroup * editBufferGroup()
Returns the edit buffer group.
void setSelectionColor(const QColor &color)
Sets the color used to highlight selected features.
bool rollBack(QStringList &rollbackErrors, bool stopEditing=true, QgsVectorLayer *vectorLayer=nullptr)
Stops a current editing operation on vectorLayer and discards any uncommitted edits.
void snappingConfigChanged(const QgsSnappingConfig &config)
Emitted whenever the configuration for snapping has changed.
QgsPathResolver pathResolver() const
Returns path resolver object with considering whether the project uses absolute or relative paths and...
void setBadLayerHandler(QgsProjectBadLayerHandler *handler)
Change handler for missing layers.
Q_DECL_DEPRECATED void setEvaluateDefaultValues(bool evaluateDefaultValues)
Defines if default values should be evaluated on provider side when requested and not when committed.
void crsChanged()
Emitted when the crs() of the project has changed.
QString translate(const QString &context, const QString &sourceText, const char *disambiguation=nullptr, int n=-1) const override
Translates a string using the Qt QTranslator mechanism.
const QgsProjectStyleSettings * styleSettings() const
Returns the project's style settings, which contains settings and properties relating to how a QgsPro...
QgsSnappingConfig snappingConfig
const QgsProjectGpsSettings * gpsSettings() const
Returns the project's GPS settings, which contains settings and properties relating to how a QgsProje...
void setFileName(const QString &name)
Sets the file name associated with the project.
void avoidIntersectionsLayersChanged()
Emitted whenever avoidIntersectionsLayers has changed.
void setDataDefinedServerProperties(const QgsPropertyCollection &properties)
Sets the data defined properties used for overrides in user defined server parameters to properties.
void registerTranslatableObjects(QgsTranslationContext *translationContext)
Registers the objects that require translation into the translationContext.
void distanceUnitsChanged()
Emitted when the default distance units changes.
QgsAnnotationLayer * mainAnnotationLayer()
Returns the main annotation layer associated with the project.
const QgsBookmarkManager * bookmarkManager() const
Returns the project's bookmark manager, which manages bookmarks within the project.
void readMapLayer(QgsMapLayer *mapLayer, const QDomElement &layerNode)
Emitted after the basic initialization of a layer from the project file is done.
Q_DECL_DEPRECATED void setAutoTransaction(bool autoTransaction)
Transactional editing means that on supported datasources (postgres databases) the edit state of all ...
@ WMSOnlineResource
Alias.
bool startEditing(QgsVectorLayer *vectorLayer=nullptr)
Makes the layer editable.
void aboutToBeCleared()
Emitted when the project is about to be cleared.
Q_DECL_DEPRECATED void setTrustLayerMetadata(bool trust)
Sets the trust option allowing to indicate if the extent has to be read from the XML document when da...
void cleared()
Emitted when the project is cleared (and additionally when an open project is cleared just before a n...
bool setVerticalCrs(const QgsCoordinateReferenceSystem &crs, QString *errorMessage=nullptr)
Sets the project's vertical coordinate reference system.
void setLabelingEngineSettings(const QgsLabelingEngineSettings &settings)
Sets project's global labeling engine settings.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
void metadataChanged()
Emitted when the project's metadata is changed.
QString resolveAttachmentIdentifier(const QString &identifier) const
Resolves an attachment identifier to a attachment file path.
const QgsProjectElevationProperties * elevationProperties() const
Returns the project's elevation properties, which contains the project's elevation related settings.
QString absolutePath() const
Returns full absolute path to the project folder if the project is stored in a file system - derived ...
void crs3DChanged()
Emitted when the crs3D() of the project has changed.
void removeMapLayers(const QStringList &layerIds)
Remove a set of layers from the registry by layer ID.
Q_DECL_DEPRECATED void setRequiredLayers(const QSet< QgsMapLayer * > &layers)
Configures a set of map layers that are required in the project and therefore they should not get rem...
bool createEmbeddedLayer(const QString &layerId, const QString &projectFilePath, QList< QDomNode > &brokenNodes, bool saveFlag=true, Qgis::ProjectReadFlags flags=Qgis::ProjectReadFlags())
Creates a maplayer instance defined in an arbitrary project file.
QList< QgsVectorLayer * > avoidIntersectionsLayers
QString readEntry(const QString &scope, const QString &key, const QString &def=QString(), bool *ok=nullptr) const
Reads a string from the specified scope and key.
QgsExpressionContextScope * createExpressionContextScope() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
QString baseName() const
Returns the base name of the project file without the path and without extension - derived from fileN...
void ellipsoidChanged(const QString &ellipsoid)
Emitted when the project ellipsoid is changed.
QgsMapThemeCollection * mapThemeCollection
void generateTsFile(const QString &locale)
Triggers the collection strings of .qgs to be included in ts file and calls writeTsFile()
QStringList entryList(const QString &scope, const QString &key) const
Returns a list of child keys with values which exist within the the specified scope and key.
Qgis::TransactionMode transactionMode
QgsAnnotationManager * annotationManager()
Returns pointer to the project's annotation manager.
QgsProjectDisplaySettings * displaySettings
QgsProjectMetadata metadata
void projectColorsChanged()
Emitted whenever the project's color scheme has been changed.
QString saveUser() const
Returns the user name that did the last save.
QVector< T > layers() const
Returns a list of registered map layers with a specified layer type.
void setProjectColors(const QgsNamedColorList &colors)
Sets the colors for the project's color scheme (see QgsProjectColorScheme).
bool setTransactionMode(Qgis::TransactionMode transactionMode)
Set transaction mode.
QgsCoordinateTransformContext transformContext
void transactionModeChanged()
Emitted when the transaction mode has changed.
void labelingEngineSettingsChanged()
Emitted when global configuration of the labeling engine changes.
void customVariablesChanged()
Emitted whenever the expression variables stored in the project have been changed.
QgsLayerTree * layerTreeRoot() const
Returns pointer to the root (invisible) node of the project's layer tree.
bool readBoolEntry(const QString &scope, const QString &key, bool def=false, bool *ok=nullptr) const
Reads a boolean from the specified scope and key.
QgsMapLayerStore * layerStore()
Returns a pointer to the project's internal layer store.
QString originalPath() const
Returns the original path associated with the project.
void setOriginalPath(const QString &path)
Sets the original path associated with the project.
void dumpProperties() const
Dump out current project properties to stderr.
QgsElevationShadingRenderer elevationShadingRenderer() const
Returns the elevation shading renderer used for map shading.
const QgsMapViewsManager * viewsManager() const
Returns the project's views manager, which manages map views (including 3d maps) in the project.
static void setInstance(QgsProject *project)
Set the current project singleton instance to project.
int validCount() const
Returns the number of registered valid layers.
const QgsLayoutManager * layoutManager() const
Returns the project's layout manager, which manages print layouts, atlases and reports within the pro...
void elevationShadingRendererChanged()
Emitted when the map shading renderer changes.
Q_INVOKABLE QList< QgsMapLayer * > mapLayersByName(const QString &layerName) const
Retrieve a list of matching registered layers by layer name.
QgsCoordinateReferenceSystem crs3D() const
Returns the CRS to use for the project when transforming 3D data, or when z/elevation value handling ...
Q_DECL_DEPRECATED bool autoTransaction() const
Transactional editing means that on supported datasources (postgres databases) the edit state of all ...
bool accept(QgsStyleEntityVisitorInterface *visitor) const
Accepts the specified style entity visitor, causing it to visit all style entities associated with th...
QStringList attachedFiles() const
Returns a map of all attached files with identifier and real paths.
void setMetadata(const QgsProjectMetadata &metadata)
Sets the project's metadata store.
void missingDatumTransforms(const QStringList &missingTransforms)
Emitted when datum transforms stored in the project are not available locally.
QgsTransactionGroup * transactionGroup(const QString &providerKey, const QString &connString)
Returns the matching transaction group from a provider key and connection string.
QgsCoordinateReferenceSystem crs
QgsMapLayer * addMapLayer(QgsMapLayer *mapLayer, bool addToLegend=true, bool takeOwnership=true)
Add a layer to the map of loaded layers.
QStringList nonIdentifiableLayers
void setAvoidIntersectionsMode(const Qgis::AvoidIntersectionsMode mode)
Sets the avoid intersections mode.
void transactionGroupsChanged()
Emitted whenever a new transaction group has been created or a transaction group has been removed.
const QgsAuxiliaryStorage * auxiliaryStorage() const
Returns the current const auxiliary storage.
void reloadAllLayers()
Reload all registered layer's provider data caches, synchronising the layer with any changes in the d...
int count() const
Returns the number of registered layers.
void loadingLayerMessageReceived(const QString &layerName, const QList< QgsReadWriteContext::ReadWriteMessage > &messages)
Emitted when loading layers has produced some messages.
void setAreaUnits(Qgis::AreaUnit unit)
Sets the default area measurement units for the project.
void setTitle(const QString &title)
Sets the project's title.
QMap< QPair< QString, QString >, QgsTransactionGroup * > transactionGroups()
Map of transaction groups.
void setFlag(Qgis::ProjectFlag flag, bool enabled=true)
Sets whether a project flag is enabled.
QDateTime lastModified() const
Returns last modified time of the project file as returned by the file system (or other project stora...
bool loadFunctionsFromProject(bool force=false)
Loads python expression functions stored in the currrent project.
bool readLayer(const QDomNode &layerNode)
Reads the layer described in the associated DOM node.
double readDoubleEntry(const QString &scope, const QString &key, double def=0, bool *ok=nullptr) const
Reads a double from the specified scope and key.
bool writeEntry(const QString &scope, const QString &key, bool value)
Write a boolean value to the project file.
QString absoluteFilePath() const
Returns full absolute path to the project file if the project is stored in a file system - derived fr...
QDateTime lastSaveDateTime() const
Returns the date and time when the project was last saved.
void projectSaved()
Emitted when the project file has been written and closed.
Q_DECL_DEPRECATED bool trustLayerMetadata() const
Returns true if the trust option is activated, false otherwise.
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
void setEllipsoid(const QString &ellipsoid)
Sets the project's ellipsoid from a proj string representation, e.g., "WGS84".
void readProject(const QDomDocument &document)
Emitted when a project is being read.
void setTransformContext(const QgsCoordinateTransformContext &context)
Sets the project's coordinate transform context, which stores various information regarding which dat...
void layerLoaded(int i, int n)
Emitted when a layer from a projects was read.
QStringList subkeyList(const QString &scope, const QString &key) const
Returns a list of child keys which contain other keys that exist within the the specified scope and k...
bool read(const QString &filename, Qgis::ProjectReadFlags flags=Qgis::ProjectReadFlags())
Reads given project file from the given file.
QStringList readListEntry(const QString &scope, const QString &key, const QStringList &def=QStringList(), bool *ok=nullptr) const
Reads a string list from the specified scope and key.
void selectionColorChanged()
Emitted whenever the project's selection color has been changed.
const QgsLabelingEngineSettings & labelingEngineSettings() const
Returns project's global labeling engine settings.
void removeAllMapLayers()
Removes all registered layers.
Q_DECL_DEPRECATED QVector< double > mapScales() const
Returns the list of custom project map scales.
void setDirty(bool b=true)
Flag the project as dirty (modified).
void backgroundColorChanged()
Emitted whenever the project's canvas background color has been changed.
QgsLayerTreeGroup * createEmbeddedGroup(const QString &groupName, const QString &projectFilePath, const QStringList &invisibleLayers, Qgis::ProjectReadFlags flags=Qgis::ProjectReadFlags())
Create layer group instance defined in an arbitrary project file.
const QgsProjectViewSettings * viewSettings() const
Returns the project's view settings, which contains settings and properties relating to how a QgsProj...
void cleanFunctionsFromProject()
Unloads python expression functions stored in the current project and reloads local functions from th...
QgsCoordinateReferenceSystem verticalCrs() const
Returns the project's vertical coordinate reference system.
QString readPath(const QString &filename) const
Transforms a filename read from the project file to an absolute path.
void registerTranslatableContainers(QgsTranslationContext *translationContext, QgsAttributeEditorContainer *parent, const QString &layerId)
Registers the containers that require translation into the translationContext.
void setElevationShadingRenderer(const QgsElevationShadingRenderer &elevationShadingRenderer)
Sets the elevation shading renderer used for global map shading.
void setFilePathStorage(Qgis::FilePathType type)
Sets the type of paths used when storing file paths in a QGS/QGZ project file.
Q_DECL_DEPRECATED QSet< QgsMapLayer * > requiredLayers() const
Returns a set of map layers that are required in the project and therefore they should not get remove...
void transformContextChanged()
Emitted when the project transformContext() is changed.
void setTopologicalEditing(bool enabled)
Convenience function to set topological editing.
void legendLayersAdded(const QList< QgsMapLayer * > &layers)
Emitted, when a layer was added to the registry and the legend.
QVariantMap customVariables() const
A map of custom project variables.
void setAvoidIntersectionsLayers(const QList< QgsVectorLayer * > &layers)
Sets the list of layers with which intersections should be avoided.
void homePathChanged()
Emitted when the home path of the project changes.
void dirtySet()
Emitted when setDirty(true) is called.
void setCustomVariables(const QVariantMap &customVariables)
A map of custom project variables.
void writeProject(QDomDocument &document)
Emitted when the project is being written.
QgsCoordinateReferenceSystem defaultCrsForNewLayers() const
Returns the default CRS for new layers based on the settings and the current project CRS.
QString saveUserFullName() const
Returns the full user name that did the last save.
void layersAdded(const QList< QgsMapLayer * > &layers)
Emitted when one or more layers were added to the registry.
QMap< QString, QgsMapLayer * > mapLayers(const bool validOnly=false) const
Returns a map of all registered layers by layer ID.
bool isDirty() const
Returns true if the project has been modified since the last write()
QgsMapLayer * takeMapLayer(QgsMapLayer *layer)
Takes a layer from the registry.
void isDirtyChanged(bool dirty)
Emitted when the project dirty status changes.
void setDistanceUnits(Qgis::DistanceUnit unit)
Sets the default distance measurement units for the project.
Q_DECL_DEPRECATED bool useProjectScales() const
Returns true if project mapScales() are enabled.
Q_DECL_DEPRECATED void setMapScales(const QVector< double > &scales)
Sets the list of custom project map scales.
void setPresetHomePath(const QString &path)
Sets the project's home path.
void setFlags(Qgis::ProjectFlags flags)
Sets the project's flags, which dictate the behavior of the project.
QList< QgsMapLayer * > mapLayersByShortName(const QString &shortName) const
Retrieves a list of matching registered layers by layer shortName.
QgsProjectStorage * projectStorage() const
Returns pointer to project storage implementation that handles read/write of the project file.
QString layerIsEmbedded(const QString &id) const
Returns the source project file path if the layer with matching id is embedded from other project fil...
const QgsProjectTimeSettings * timeSettings() const
Returns the project's time settings, which contains the project's temporal range and other time based...
void verticalCrsChanged()
Emitted when the verticalCrs() of the project has changed.
void topologicalEditingChanged()
Emitted when the topological editing flag has changed.
bool removeEntry(const QString &scope, const QString &key)
Remove the given key from the specified scope.
QgsProjectVersion lastSaveVersion() const
Returns the QGIS version which the project was last saved using.
void avoidIntersectionsModeChanged()
Emitted whenever the avoid intersections mode has changed.
void loadingLayer(const QString &layerName)
Emitted when a layer is loaded.
A grouped map of multiple QgsProperty objects, each referenced by a integer key value.
Definition for a property.
@ String
Any string value.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
QString relativeToAbsoluteUri(const QString &providerKey, const QString &uri, const QgsReadWriteContext &context) const
Converts relative path(s) to absolute path(s) in the given provider-specific URI.
QgsProviderMetadata * providerMetadata(const QString &providerKey) const
Returns metadata of the provider or nullptr if not found.
static bool run(const QString &command, const QString &messageOnError=QString())
Execute a Python statement.
static bool isValid()
Returns true if the runner has an instance (and thus is able to run commands)
The class is used as a container of context for various read/write operations on other objects.
void setTransformContext(const QgsCoordinateTransformContext &transformContext)
Sets data coordinate transform context to transformContext.
QgsCoordinateTransformContext transformContext() const
Returns data provider coordinate transform context.
QList< QgsReadWriteContext::ReadWriteMessage > takeMessages()
Returns the stored messages and remove them.
void setProjectTranslator(QgsProjectTranslator *projectTranslator)
Sets the project translator.
void setPathResolver(const QgsPathResolver &resolver)
Sets up path resolver for conversion between relative and absolute paths.
This class manages a set of relations between layers.
void clear()
Remove any relation managed by this class.
QMap< QString, QgsRelation > relations() const
Gets access to the relations managed by this class.
Represents a relationship between two vector layers.
The QgsRunnableProviderCreator class is used when reading a project to create asynchronously provider...
void providerCreated(bool isValid, const QString &layerId)
Emitted when a provider is created with isValid set to True when the provider is valid.
QgsDataProvider * dataProvider()
Returns the created data provider.
void clear(const QString &group="startup")
clear Clear all profile data.
Expression function for use within a QgsExpressionContextScope.
Scoped object for logging of the runtime for a single operation or group of operations.
QDomElement writeXml(QDomDocument &document) const
Returns a DOM element representing the state of the manager.
void clear()
Deregisters and removes all sensors from the manager.
bool readXml(const QDomElement &element, const QDomDocument &document)
Reads the manager's state from a DOM element, restoring all sensors present in the XML document.
T value(const QString &dynamicKeyPart=QString()) const
Returns settings value.
static const QgsSettingsEntryInteger * settingsLayerParallelLoadingMaxCount
Settings entry maximum thread count used to load layer in parallel.
static const QgsSettingsEntryBool * settingsLayerParallelLoading
Settings entry whether layer are loading in parallel.
This class is a composition of two QSettings instances:
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
T enumValue(const QString &key, const T &defaultValue, const Section section=NoSection)
Returns the setting value for a setting based on an enum.
This is a container for configuration of the snapping of the project.
bool addLayers(const QList< QgsMapLayer * > &layers)
Adds the specified layers as individual layers to the configuration with standard configuration.
void readProject(const QDomDocument &doc)
Reads the configuration from the specified QGIS project document.
void reset()
reset to default values
void writeProject(QDomDocument &doc)
Writes the configuration to the specified QGIS project document.
void clearIndividualLayerSettings()
Removes all individual layer snapping settings.
bool removeLayers(const QList< QgsMapLayer * > &layers)
Removes the specified layers from the individual layer configuration.
An interface for classes which can visit style entity (e.g.
virtual bool visitExit(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor stops visiting a node.
virtual bool visitEnter(const QgsStyleEntityVisitorInterface::Node &node)
Called when the visitor starts visiting a node.
void triggerIconRebuild()
Triggers emission of the rebuildIconPreviews() signal.
static QgsStyle * defaultStyle(bool initialize=true)
Returns the default application-wide style.
bool addLayer(QgsVectorLayer *layer)
Add a layer to this transaction group.
static bool supportsTransaction(const QgsVectorLayer *layer)
Checks if the provider of a given layer supports transactions.
QString connectionString() const
Returns the connection string of the transaction.
Used for the collecting of strings from projects for translation and creation of ts files.
void registerTranslation(const QString &context, const QString &source)
Registers the source to be translated.
void setProject(QgsProject *project)
Sets the project being translated.
static Q_INVOKABLE QString toString(Qgis::DistanceUnit unit)
Returns a translated string representing a distance unit.
static Q_INVOKABLE Qgis::AreaUnit decodeAreaUnit(const QString &string, bool *ok=nullptr)
Decodes an areal unit from a string.
static Q_INVOKABLE QString encodeUnit(Qgis::DistanceUnit unit)
Encodes a distance unit to a string.
static Q_INVOKABLE Qgis::DistanceUnit decodeDistanceUnit(const QString &string, bool *ok=nullptr)
Decodes a distance unit from a string.
The edit buffer group manages a group of edit buffers.
bool commitChanges(QStringList &commitErrors, bool stopEditing=true)
Attempts to commit any changes to disk.
bool startEditing()
Start editing.
void clear()
Remove all layers from this edit buffer group.
bool rollBack(QStringList &rollbackErrors, bool stopEditing=true)
Stop editing and discard the edits.
void addLayer(QgsVectorLayer *layer)
Add a layer to this edit buffer group.
Represents a vector layer which manages a vector based data sets.
Q_INVOKABLE bool startEditing()
Makes the layer editable.
bool loadAuxiliaryLayer(const QgsAuxiliaryStorage &storage, const QString &key=QString())
Loads the auxiliary layer for this vector layer.
QgsAuxiliaryLayer * auxiliaryLayer()
Returns the current auxiliary layer.
QStringList commitErrors() const
Returns a list containing any error messages generated when attempting to commit changes to the layer...
Q_INVOKABLE bool rollBack(bool deleteBuffer=true)
Stops a current editing operation and discards any uncommitted edits.
Q_INVOKABLE bool commitChanges(bool stopEditing=true)
Attempts to commit to the underlying data provider any buffered changes made since the last to call t...
QgsEditFormConfig editFormConfig
QList< QPair< QColor, QString > > QgsNamedColorList
List of colors paired with a friendly display name identifying the color.
CORE_EXPORT bool isZipFile(const QString &filename)
Returns true if the file name is a zipped file ( i.e with a '.qgz' extension, false otherwise.
CORE_EXPORT const QStringList files(const QString &zip)
Returns the list of files within a zip file.
CONSTLATIN1STRING geoNone()
Constant that holds the string representation for "No ellips/No CRS".
T qgsEnumKeyToValue(const QString &key, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given key of an enum.
#define Q_NOWARN_DEPRECATED_POP
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
QString qgsFlagValueToKeys(const T &value, bool *returnOk=nullptr)
Returns the value for the given keys of a flag.
T qgsFlagKeysToValue(const QString &keys, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given keys of a flag.
#define Q_NOWARN_DEPRECATED_PUSH
CONSTLATIN1STRING geoEpsgCrsAuthId()
Geographic coord sys from EPSG authority.
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)
QPointer< QgsMapLayer > QgsWeakMapLayerPointer
Weak pointer for QgsMapLayer.
void _getProperties(const QDomDocument &doc, QgsProjectPropertyKey &project_properties)
Restores any optional properties found in "doc" to "properties".
QgsPropertyCollection getDataDefinedServerProperties(const QDomDocument &doc, const QgsPropertiesDefinition &dataDefinedServerPropertyDefinitions)
Returns the data defined server properties collection found in "doc" to "dataDefinedServerProperties"...
void removeKey_(const QString &scope, const QString &key, QgsProjectPropertyKey &rootProperty)
Removes a given key.
QgsProjectVersion getVersion(const QDomDocument &doc)
Returns the version string found in the given DOM document.
QStringList makeKeyTokens_(const QString &scope, const QString &key)
Takes the given scope and key and convert them to a string list of key tokens that will be used to na...
void dump_(const QgsProjectPropertyKey &topQgsPropertyKey)
QgsProjectProperty * findKey_(const QString &scope, const QString &key, QgsProjectPropertyKey &rootProperty)
Returns the property that matches the given key sequence, if any.
QgsProjectProperty * addKey_(const QString &scope, const QString &key, QgsProjectPropertyKey *rootProperty, const QVariant &value, bool &propertiesModified)
Adds the given key and value.
CORE_EXPORT QgsProjectVersion getVersion(QDomDocument const &doc)
Returns the version string found in the given DOM document.
QMap< int, QgsPropertyDefinition > QgsPropertiesDefinition
Definition of available properties.
#define FONTMARKER_CHR_FIX
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS_NON_FATAL
#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS
const QgsCoordinateReferenceSystem & crs
Qgis::DataProviderReadFlags flags
QgsDataProvider::ProviderOptions options
Setting options for loading annotation layers.
Setting options for creating vector data providers.
Single variable definition for use within a QgsExpressionContextScope.
Setting options for loading group layers.
Contains information relating to a node (i.e.