From 6572c9bd46109c00b56fa870647a724b71b51ead Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Tue, 13 Dec 2022 10:34:45 +1000 Subject: [PATCH] Add QGIS_PROTECT_QOBJECT_THREAD_ACCESS macro Either shows a warning when a qobject function is accessed from a thread which the object doesn't have affinity with, OR causes a fatal error if the AGGRESSIVE_SAFE_MODE cmake flag is set. We should ensure this macro is present for all qobject methods which may potentially be called from threads --- CMakeLists.txt | 2 + cmake_templates/qgsconfig.h.in | 2 + src/core/qgsthreadingutils.h | 10 + src/core/vector/qgsvectorlayer.cpp | 439 ++++++++++++++++++++++++++++- 4 files changed, 448 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d240c37bcb1..5908098cc09 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -692,6 +692,8 @@ else() set(QGISDEBUG FALSE) endif() +set (AGGRESSIVE_SAFE_MODE FALSE CACHE BOOL "Forces a aggressive safe mode where issues like unsafe thread access will resort in fatal exceptions") + if(MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8 /std:c++17") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /utf-8 /std:c++17") diff --git a/cmake_templates/qgsconfig.h.in b/cmake_templates/qgsconfig.h.in index b6002acd035..46fb5780be7 100644 --- a/cmake_templates/qgsconfig.h.in +++ b/cmake_templates/qgsconfig.h.in @@ -90,6 +90,8 @@ #cmakedefine QGISDEBUG +#cmakedefine AGGRESSIVE_SAFE_MODE + #cmakedefine HAVE_QUICK #cmakedefine HAVE_QT5SERIALPORT diff --git a/src/core/qgsthreadingutils.h b/src/core/qgsthreadingutils.h index ad22244e0a1..63cc8b56129 100644 --- a/src/core/qgsthreadingutils.h +++ b/src/core/qgsthreadingutils.h @@ -19,6 +19,7 @@ #define SIP_NO_FILE #include "qgis_core.h" +#include "qgsconfig.h" #include "qgsfeedback.h" @@ -26,6 +27,15 @@ #include #include +#ifdef AGGRESSIVE_SAFE_MODE +#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS if ( QThread::currentThread() != thread() ) {qFatal( "%s", QStringLiteral("%2 (%1:%3) is run from a different thread than the object %4 lives in [0x%5 vs 0x%6]" ).arg( QString( __FILE__ ), QString( __FUNCTION__ ), QString::number( __LINE__ ), objectName() ).arg( reinterpret_cast< qint64 >( QThread::currentThread() ), 0, 16 ).arg( reinterpret_cast< qint64 >( thread() ), 0, 16 ).toLocal8Bit().constData() ); } +#elif defined(QGISDEBUG) +#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS if ( QThread::currentThread() != thread() ) {qWarning() << QStringLiteral("%2 (%1:%3) is run from a different thread than the object %4 lives in [0x%5 vs 0x%6]" ).arg( QString( __FILE__ ), QString( __FUNCTION__ ), QString::number( __LINE__ ), objectName() ).arg( reinterpret_cast< qint64 >( QThread::currentThread() ), 0, 16 ).arg( reinterpret_cast< qint64 >( thread() ), 0, 16 ).toLocal8Bit().constData(); } +#else +#define QGIS_PROTECT_QOBJECT_THREAD_ACCESS do {} while(false); +#endif + + /** * \ingroup core * \brief Provides threading utilities for QGIS. diff --git a/src/core/vector/qgsvectorlayer.cpp b/src/core/vector/qgsvectorlayer.cpp index 831605cebf4..89d9b15cb06 100644 --- a/src/core/vector/qgsvectorlayer.cpp +++ b/src/core/vector/qgsvectorlayer.cpp @@ -84,6 +84,7 @@ #include "qgsvectorlayerprofilegenerator.h" #include "qgsprofilerequest.h" #include "qgssymbollayerutils.h" +#include "qgsthreadingutils.h" #include #include @@ -261,6 +262,8 @@ QgsVectorLayer::~QgsVectorLayer() QgsVectorLayer *QgsVectorLayer::clone() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QgsVectorLayer::LayerOptions options; // We get the data source string from the provider when // possible because some providers may have changed it @@ -366,6 +369,8 @@ QgsVectorLayer *QgsVectorLayer::clone() const QString QgsVectorLayer::storageType() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( mDataProvider ) { return mDataProvider->storageType(); @@ -376,6 +381,8 @@ QString QgsVectorLayer::storageType() const QString QgsVectorLayer::capabilitiesString() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( mDataProvider ) { return mDataProvider->capabilitiesString(); @@ -385,16 +392,22 @@ QString QgsVectorLayer::capabilitiesString() const bool QgsVectorLayer::isSqlQuery() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return mDataProvider && mDataProvider->isSqlQuery(); } Qgis::VectorLayerTypeFlags QgsVectorLayer::vectorLayerTypeFlags() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return mDataProvider ? mDataProvider->vectorLayerTypeFlags() : Qgis::VectorLayerTypeFlags(); } QString QgsVectorLayer::dataComment() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( mDataProvider ) { return mDataProvider->dataComment(); @@ -404,16 +417,22 @@ QString QgsVectorLayer::dataComment() const QgsCoordinateReferenceSystem QgsVectorLayer::sourceCrs() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return crs(); } QString QgsVectorLayer::sourceName() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return name(); } void QgsVectorLayer::reload() { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( mDataProvider ) { mDataProvider->reloadData(); @@ -423,6 +442,8 @@ void QgsVectorLayer::reload() QgsMapLayerRenderer *QgsVectorLayer::createMapRenderer( QgsRenderContext &rendererContext ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return new QgsVectorLayerRenderer( this, rendererContext ); } @@ -450,6 +471,8 @@ void QgsVectorLayer::drawVertexMarker( double x, double y, QPainter &p, Qgis::Ve void QgsVectorLayer::select( QgsFeatureId fid ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + mSelectedFeatureIds.insert( fid ); mPreviousSelectedFeatureIds.clear(); @@ -458,6 +481,8 @@ void QgsVectorLayer::select( QgsFeatureId fid ) void QgsVectorLayer::select( const QgsFeatureIds &featureIds ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + mSelectedFeatureIds.unite( featureIds ); mPreviousSelectedFeatureIds.clear(); @@ -466,6 +491,8 @@ void QgsVectorLayer::select( const QgsFeatureIds &featureIds ) void QgsVectorLayer::deselect( const QgsFeatureId fid ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + mSelectedFeatureIds.remove( fid ); mPreviousSelectedFeatureIds.clear(); @@ -474,6 +501,8 @@ void QgsVectorLayer::deselect( const QgsFeatureId fid ) void QgsVectorLayer::deselect( const QgsFeatureIds &featureIds ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + mSelectedFeatureIds.subtract( featureIds ); mPreviousSelectedFeatureIds.clear(); @@ -482,6 +511,8 @@ void QgsVectorLayer::deselect( const QgsFeatureIds &featureIds ) void QgsVectorLayer::selectByRect( QgsRectangle &rect, Qgis::SelectBehavior behavior ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + // normalize the rectangle rect.normalize(); @@ -504,6 +535,8 @@ void QgsVectorLayer::selectByRect( QgsRectangle &rect, Qgis::SelectBehavior beha void QgsVectorLayer::selectByExpression( const QString &expression, Qgis::SelectBehavior behavior, QgsExpressionContext *context ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QgsFeatureIds newSelection; std::optional< QgsExpressionContext > defaultContext; @@ -569,6 +602,8 @@ void QgsVectorLayer::selectByExpression( const QString &expression, Qgis::Select void QgsVectorLayer::selectByIds( const QgsFeatureIds &ids, Qgis::SelectBehavior behavior ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QgsFeatureIds newSelection; switch ( behavior ) @@ -599,6 +634,8 @@ void QgsVectorLayer::selectByIds( const QgsFeatureIds &ids, Qgis::SelectBehavior void QgsVectorLayer::modifySelection( const QgsFeatureIds &selectIds, const QgsFeatureIds &deselectIds ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QgsFeatureIds intersectingIds = selectIds & deselectIds; if ( !intersectingIds.isEmpty() ) { @@ -614,6 +651,8 @@ void QgsVectorLayer::modifySelection( const QgsFeatureIds &selectIds, const QgsF void QgsVectorLayer::invertSelection() { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QgsFeatureIds ids = allFeatureIds(); ids.subtract( mSelectedFeatureIds ); selectByIds( ids ); @@ -621,11 +660,15 @@ void QgsVectorLayer::invertSelection() void QgsVectorLayer::selectAll() { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + selectByIds( allFeatureIds() ); } void QgsVectorLayer::invertSelectionInRectangle( QgsRectangle &rect ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + // normalize the rectangle rect.normalize(); @@ -655,6 +698,8 @@ void QgsVectorLayer::invertSelectionInRectangle( QgsRectangle &rect ) void QgsVectorLayer::removeSelection() { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( mSelectedFeatureIds.isEmpty() ) return; @@ -665,6 +710,8 @@ void QgsVectorLayer::removeSelection() void QgsVectorLayer::reselect() { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( mPreviousSelectedFeatureIds.isEmpty() || !mSelectedFeatureIds.empty() ) return; @@ -673,26 +720,36 @@ void QgsVectorLayer::reselect() QgsVectorDataProvider *QgsVectorLayer::dataProvider() { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return mDataProvider; } const QgsVectorDataProvider *QgsVectorLayer::dataProvider() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return mDataProvider; } QgsMapLayerTemporalProperties *QgsVectorLayer::temporalProperties() { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return mTemporalProperties; } QgsMapLayerElevationProperties *QgsVectorLayer::elevationProperties() { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return mElevationProperties; } QgsAbstractProfileGenerator *QgsVectorLayer::createProfileGenerator( const QgsProfileRequest &request ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QgsProfileRequest modifiedRequest( request ); modifiedRequest.expressionContext().appendScope( createExpressionContextScope() ); return new QgsVectorLayerProfileGenerator( this, modifiedRequest ); @@ -700,6 +757,8 @@ QgsAbstractProfileGenerator *QgsVectorLayer::createProfileGenerator( const QgsPr void QgsVectorLayer::setProviderEncoding( const QString &encoding ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( isValid() && mDataProvider && mDataProvider->encoding() != encoding ) { mDataProvider->setEncoding( encoding ); @@ -709,6 +768,8 @@ void QgsVectorLayer::setProviderEncoding( const QString &encoding ) void QgsVectorLayer::setDiagramRenderer( QgsDiagramRenderer *r ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + delete mDiagramRenderer; mDiagramRenderer = r; emit rendererChanged(); @@ -717,16 +778,22 @@ void QgsVectorLayer::setDiagramRenderer( QgsDiagramRenderer *r ) QgsWkbTypes::GeometryType QgsVectorLayer::geometryType() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return QgsWkbTypes::geometryType( mWkbType ); } QgsWkbTypes::Type QgsVectorLayer::wkbType() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return mWkbType; } QgsRectangle QgsVectorLayer::boundingBoxOfSelected() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !isValid() || !isSpatial() || mSelectedFeatureIds.isEmpty() || !mDataProvider ) //no selected features { return QgsRectangle( 0, 0, 0, 0 ); @@ -786,16 +853,22 @@ QgsRectangle QgsVectorLayer::boundingBoxOfSelected() const bool QgsVectorLayer::labelsEnabled() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return mLabelsEnabled && static_cast< bool >( mLabeling ); } void QgsVectorLayer::setLabelsEnabled( bool enabled ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + mLabelsEnabled = enabled; } bool QgsVectorLayer::diagramsEnabled() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !mDiagramRenderer || !mDiagramLayerSettings ) return false; @@ -809,6 +882,8 @@ bool QgsVectorLayer::diagramsEnabled() const long long QgsVectorLayer::featureCount( const QString &legendKey ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !mSymbolFeatureCounted ) return -1; @@ -817,6 +892,8 @@ long long QgsVectorLayer::featureCount( const QString &legendKey ) const QgsFeatureIds QgsVectorLayer::symbolFeatureIds( const QString &legendKey ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !mSymbolFeatureCounted ) return QgsFeatureIds(); @@ -824,6 +901,8 @@ QgsFeatureIds QgsVectorLayer::symbolFeatureIds( const QString &legendKey ) const } QgsVectorLayerFeatureCounter *QgsVectorLayer::countSymbolFeatures( bool storeSymbolFids ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( ( mSymbolFeatureCounted || mFeatureCounter ) && !( storeSymbolFids && mSymbolFeatureIdMap.isEmpty() ) ) return mFeatureCounter; @@ -859,6 +938,8 @@ QgsVectorLayerFeatureCounter *QgsVectorLayer::countSymbolFeatures( bool storeSym void QgsVectorLayer::updateExtents( bool force ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + // do not update extent by default when trust project option is activated if ( force || !mReadExtentFromXml || ( mReadExtentFromXml && mXmlExtent.isNull() ) ) mValidExtent = false; @@ -866,12 +947,16 @@ void QgsVectorLayer::updateExtents( bool force ) void QgsVectorLayer::setExtent( const QgsRectangle &r ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QgsMapLayer::setExtent( r ); mValidExtent = true; } void QgsVectorLayer::updateDefaultValues( QgsFeatureId fid, QgsFeature feature ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !mDefaultValueOnUpdateFields.isEmpty() ) { if ( !feature.isValid() ) @@ -891,6 +976,8 @@ void QgsVectorLayer::updateDefaultValues( QgsFeatureId fid, QgsFeature feature ) QgsRectangle QgsVectorLayer::extent() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QgsRectangle rect; rect.setMinimal(); @@ -984,11 +1071,15 @@ QgsRectangle QgsVectorLayer::extent() const QgsRectangle QgsVectorLayer::sourceExtent() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return extent(); } QString QgsVectorLayer::subsetString() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !isValid() || !mDataProvider ) { QgsDebugMsgLevel( QStringLiteral( "invoked with invalid layer or null mDataProvider" ), 3 ); @@ -999,6 +1090,8 @@ QString QgsVectorLayer::subsetString() const bool QgsVectorLayer::setSubsetString( const QString &subset ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !isValid() || !mDataProvider ) { QgsDebugMsgLevel( QStringLiteral( "invoked with invalid layer or null mDataProvider or while editing" ), 3 ); @@ -1032,6 +1125,8 @@ bool QgsVectorLayer::setSubsetString( const QString &subset ) bool QgsVectorLayer::simplifyDrawingCanbeApplied( const QgsRenderContext &renderContext, QgsVectorSimplifyMethod::SimplifyHint simplifyHint ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( isValid() && mDataProvider && !mEditBuffer && ( isSpatial() && geometryType() != QgsWkbTypes::PointGeometry ) && ( mSimplifyMethod.simplifyHints() & simplifyHint ) && renderContext.useRenderingOptimization() ) { double maximumSimplificationScale = mSimplifyMethod.maximumScale(); @@ -1044,11 +1139,15 @@ bool QgsVectorLayer::simplifyDrawingCanbeApplied( const QgsRenderContext &render QgsConditionalLayerStyles *QgsVectorLayer::conditionalStyles() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return mConditionalStyles; } QgsFeatureIterator QgsVectorLayer::getFeatures( const QgsFeatureRequest &request ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !isValid() || !mDataProvider ) return QgsFeatureIterator(); @@ -1057,6 +1156,8 @@ QgsFeatureIterator QgsVectorLayer::getFeatures( const QgsFeatureRequest &request QgsGeometry QgsVectorLayer::getGeometry( QgsFeatureId fid ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QgsFeature feature; getFeatures( QgsFeatureRequest( fid ).setFlags( QgsFeatureRequest::SubsetOfAttributes ) ).nextFeature( feature ); if ( feature.isValid() ) @@ -1067,6 +1168,8 @@ QgsGeometry QgsVectorLayer::getGeometry( QgsFeatureId fid ) const bool QgsVectorLayer::addFeature( QgsFeature &feature, Flags ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !isValid() || !mEditBuffer || !mDataProvider ) return false; @@ -1093,6 +1196,8 @@ bool QgsVectorLayer::addFeature( QgsFeature &feature, Flags ) bool QgsVectorLayer::updateFeature( QgsFeature &updatedFeature, bool skipDefaultValues ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !mEditBuffer || !mDataProvider ) { return false; @@ -1151,6 +1256,8 @@ bool QgsVectorLayer::updateFeature( QgsFeature &updatedFeature, bool skipDefault bool QgsVectorLayer::insertVertex( double x, double y, QgsFeatureId atFeatureId, int beforeVertex ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !isValid() || !mEditBuffer || !mDataProvider ) return false; @@ -1164,6 +1271,8 @@ bool QgsVectorLayer::insertVertex( double x, double y, QgsFeatureId atFeatureId, bool QgsVectorLayer::insertVertex( const QgsPoint &point, QgsFeatureId atFeatureId, int beforeVertex ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !isValid() || !mEditBuffer || !mDataProvider ) return false; @@ -1177,6 +1286,8 @@ bool QgsVectorLayer::insertVertex( const QgsPoint &point, QgsFeatureId atFeature bool QgsVectorLayer::moveVertex( double x, double y, QgsFeatureId atFeatureId, int atVertex ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !isValid() || !mEditBuffer || !mDataProvider ) return false; @@ -1190,6 +1301,8 @@ bool QgsVectorLayer::moveVertex( double x, double y, QgsFeatureId atFeatureId, i bool QgsVectorLayer::moveVertex( const QgsPoint &p, QgsFeatureId atFeatureId, int atVertex ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !isValid() || !mEditBuffer || !mDataProvider ) return false; @@ -1203,6 +1316,8 @@ bool QgsVectorLayer::moveVertex( const QgsPoint &p, QgsFeatureId atFeatureId, in Qgis::VectorEditResult QgsVectorLayer::deleteVertex( QgsFeatureId featureId, int vertex ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !isValid() || !mEditBuffer || !mDataProvider ) return Qgis::VectorEditResult::InvalidLayer; @@ -1217,6 +1332,8 @@ Qgis::VectorEditResult QgsVectorLayer::deleteVertex( QgsFeatureId featureId, int bool QgsVectorLayer::deleteSelectedFeatures( int *deletedCount, QgsVectorLayer::DeleteContext *context ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !isValid() || !mDataProvider || !( mDataProvider->capabilities() & QgsVectorDataProvider::DeleteFeatures ) ) { return false; @@ -1261,11 +1378,15 @@ static const QgsPointSequence vectorPointXY2pointSequence( const QVector &ring, QgsFeatureId *featureId ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return addRing( vectorPointXY2pointSequence( ring ), featureId ); } Qgis::GeometryOperationResult QgsVectorLayer::addRing( const QgsPointSequence &ring, QgsFeatureId *featureId ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !isValid() || !mEditBuffer || !mDataProvider ) return Qgis::GeometryOperationResult::LayerNotEditable; @@ -1289,6 +1410,8 @@ Qgis::GeometryOperationResult QgsVectorLayer::addRing( const QgsPointSequence &r Qgis::GeometryOperationResult QgsVectorLayer::addRing( QgsCurve *ring, QgsFeatureId *featureId ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !isValid() || !mEditBuffer || !mDataProvider ) { delete ring; @@ -1327,6 +1450,8 @@ Qgis::GeometryOperationResult QgsVectorLayer::addRing( QgsCurve *ring, QgsFeatur Qgis::GeometryOperationResult QgsVectorLayer::addPart( const QList &points ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QgsPointSequence pts; pts.reserve( points.size() ); for ( QList::const_iterator it = points.constBegin(); it != points.constEnd() ; ++it ) @@ -1339,12 +1464,16 @@ Qgis::GeometryOperationResult QgsVectorLayer::addPart( const QList & #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) Qgis::GeometryOperationResult QgsVectorLayer::addPart( const QVector &points ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return addPart( vectorPointXY2pointSequence( points ) ); } #endif Qgis::GeometryOperationResult QgsVectorLayer::addPart( const QgsPointSequence &points ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !isValid() || !mEditBuffer || !mDataProvider ) return Qgis::GeometryOperationResult::LayerNotEditable; @@ -1371,6 +1500,8 @@ Qgis::GeometryOperationResult QgsVectorLayer::addPart( const QgsPointSequence &p Qgis::GeometryOperationResult QgsVectorLayer::addPart( QgsCurve *ring ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !isValid() || !mEditBuffer || !mDataProvider ) return Qgis::GeometryOperationResult::LayerNotEditable; @@ -1398,6 +1529,8 @@ Qgis::GeometryOperationResult QgsVectorLayer::addPart( QgsCurve *ring ) // TODO QGIS 4.0 -- this should return Qgis::GeometryOperationResult, not int int QgsVectorLayer::translateFeature( QgsFeatureId featureId, double dx, double dy ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !isValid() || !mEditBuffer || !mDataProvider ) return static_cast< int >( Qgis::GeometryOperationResult::LayerNotEditable ); @@ -1411,11 +1544,15 @@ int QgsVectorLayer::translateFeature( QgsFeatureId featureId, double dx, double Qgis::GeometryOperationResult QgsVectorLayer::splitParts( const QVector &splitLine, bool topologicalEditing ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return splitParts( vectorPointXY2pointSequence( splitLine ), topologicalEditing ); } Qgis::GeometryOperationResult QgsVectorLayer::splitParts( const QgsPointSequence &splitLine, bool topologicalEditing ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !isValid() || !mEditBuffer || !mDataProvider ) return Qgis::GeometryOperationResult::LayerNotEditable; @@ -1425,11 +1562,15 @@ Qgis::GeometryOperationResult QgsVectorLayer::splitParts( const QgsPointSequence Qgis::GeometryOperationResult QgsVectorLayer::splitFeatures( const QVector &splitLine, bool topologicalEditing ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return splitFeatures( vectorPointXY2pointSequence( splitLine ), topologicalEditing ); } Qgis::GeometryOperationResult QgsVectorLayer::splitFeatures( const QgsPointSequence &splitLine, bool topologicalEditing ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QgsLineString splitLineString( splitLine ); QgsPointSequence topologyTestPoints; bool preserveCircular = false; @@ -1438,6 +1579,8 @@ Qgis::GeometryOperationResult QgsVectorLayer::splitFeatures( const QgsPointSeque Qgis::GeometryOperationResult QgsVectorLayer::splitFeatures( const QgsCurve *curve, QgsPointSequence &topologyTestPoints, bool preserveCircular, bool topologicalEditing ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !isValid() || !mEditBuffer || !mDataProvider ) return Qgis::GeometryOperationResult::LayerNotEditable; @@ -1447,6 +1590,8 @@ Qgis::GeometryOperationResult QgsVectorLayer::splitFeatures( const QgsCurve *cur int QgsVectorLayer::addTopologicalPoints( const QgsGeometry &geom ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !isValid() || !mEditBuffer || !mDataProvider ) return -1; @@ -1456,11 +1601,15 @@ int QgsVectorLayer::addTopologicalPoints( const QgsGeometry &geom ) int QgsVectorLayer::addTopologicalPoints( const QgsPointXY &p ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return addTopologicalPoints( QgsPoint( p ) ); } int QgsVectorLayer::addTopologicalPoints( const QgsPoint &p ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !isValid() || !mEditBuffer || !mDataProvider ) return -1; @@ -1470,6 +1619,8 @@ int QgsVectorLayer::addTopologicalPoints( const QgsPoint &p ) int QgsVectorLayer::addTopologicalPoints( const QgsPointSequence &ps ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !mValid || !mEditBuffer || !mDataProvider ) return -1; @@ -1479,6 +1630,8 @@ int QgsVectorLayer::addTopologicalPoints( const QgsPointSequence &ps ) void QgsVectorLayer::setLabeling( QgsAbstractVectorLayerLabeling *labeling ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( mLabeling == labeling ) return; @@ -1488,6 +1641,8 @@ void QgsVectorLayer::setLabeling( QgsAbstractVectorLayerLabeling *labeling ) bool QgsVectorLayer::startEditing() { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( project() && project()->transactionMode() == Qgis::TransactionMode::BufferedGroups ) return project()->startEditing( this ); @@ -1523,17 +1678,23 @@ bool QgsVectorLayer::startEditing() void QgsVectorLayer::setTransformContext( const QgsCoordinateTransformContext &transformContext ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( mDataProvider ) mDataProvider->setTransformContext( transformContext ); } QgsFeatureSource::SpatialIndexPresence QgsVectorLayer::hasSpatialIndex() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return mDataProvider ? mDataProvider->hasSpatialIndex() : QgsFeatureSource::SpatialIndexUnknown; } bool QgsVectorLayer::accept( QgsStyleEntityVisitorInterface *visitor ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( mRenderer ) if ( !mRenderer->accept( visitor ) ) return false; @@ -1547,6 +1708,8 @@ bool QgsVectorLayer::accept( QgsStyleEntityVisitorInterface *visitor ) const bool QgsVectorLayer::readXml( const QDomNode &layer_node, QgsReadWriteContext &context ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QgsDebugMsgLevel( QStringLiteral( "Datasource in QgsVectorLayer::readXml: %1" ).arg( mDataSource.toLocal8Bit().data() ), 3 ); //process provider key @@ -1673,6 +1836,8 @@ bool QgsVectorLayer::readXml( const QDomNode &layer_node, QgsReadWriteContext &c void QgsVectorLayer::setDataSourcePrivate( const QString &dataSource, const QString &baseName, const QString &provider, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QgsWkbTypes::GeometryType geomType = geometryType(); mDataSource = dataSource; @@ -1756,6 +1921,8 @@ void QgsVectorLayer::setDataSourcePrivate( const QString &dataSource, const QStr QString QgsVectorLayer::loadDefaultStyle( bool &resultFlag ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + // first try to load a user-defined default style - this should always take precedence QString styleXml = QgsMapLayer::loadDefaultStyle( resultFlag ); @@ -1808,6 +1975,8 @@ QString QgsVectorLayer::loadDefaultStyle( bool &resultFlag ) bool QgsVectorLayer::setDataProvider( QString const &provider, const QgsDataProvider::ProviderOptions &options, QgsDataProvider::ReadFlags flags ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + mProviderKey = provider; delete mDataProvider; @@ -1959,6 +2128,8 @@ bool QgsVectorLayer::writeXml( QDomNode &layer_node, QDomDocument &document, const QgsReadWriteContext &context ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + // first get the layer element so that we can append the type attribute QDomElement mapLayerNode = layer_node.toElement(); @@ -2037,6 +2208,8 @@ bool QgsVectorLayer::writeXml( QDomNode &layer_node, QString QgsVectorLayer::encodedSource( const QString &source, const QgsReadWriteContext &context ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QString src( source ); // TODO: what about postgres, mysql and others, they should not go through writePath() @@ -2122,6 +2295,8 @@ QString QgsVectorLayer::encodedSource( const QString &source, const QgsReadWrite QString QgsVectorLayer::decodedSource( const QString &source, const QString &provider, const QgsReadWriteContext &context ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QString src( source ); if ( provider == QLatin1String( "spatialite" ) ) @@ -2219,6 +2394,8 @@ QString QgsVectorLayer::decodedSource( const QString &source, const QString &pro void QgsVectorLayer::resolveReferences( QgsProject *project ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QgsMapLayer::resolveReferences( project ); mJoinBuffer->resolveReferences( project ); } @@ -2227,6 +2404,8 @@ void QgsVectorLayer::resolveReferences( QgsProject *project ) bool QgsVectorLayer::readSymbology( const QDomNode &layerNode, QString &errorMessage, QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( categories.testFlag( Fields ) ) { if ( !mExpressionFieldBuffer ) @@ -2522,6 +2701,8 @@ bool QgsVectorLayer::readSymbology( const QDomNode &layerNode, QString &errorMes bool QgsVectorLayer::readStyle( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + bool result = true; emit readCustomSymbology( node.toElement(), errorMessage ); @@ -2738,6 +2919,8 @@ bool QgsVectorLayer::readStyle( const QDomNode &node, QString &errorMessage, bool QgsVectorLayer::writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QDomElement layerElement = node.toElement(); writeCommonStyle( layerElement, doc, context, categories ); @@ -2934,6 +3117,8 @@ bool QgsVectorLayer::writeSymbology( QDomNode &node, QDomDocument &doc, QString bool QgsVectorLayer::writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QDomElement mapLayerNode = node.toElement(); emit writeCustomSymbology( mapLayerNode, doc, errorMessage ); @@ -3019,6 +3204,8 @@ bool QgsVectorLayer::writeStyle( QDomNode &node, QDomDocument &doc, QString &err bool QgsVectorLayer::readSld( const QDomNode &node, QString &errorMessage ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + // get the Name element QDomElement nameElem = node.firstChildElement( QStringLiteral( "Name" ) ); if ( nameElem.isNull() ) @@ -3049,6 +3236,8 @@ bool QgsVectorLayer::readSld( const QDomNode &node, QString &errorMessage ) bool QgsVectorLayer::writeSld( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QVariantMap &props ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + Q_UNUSED( errorMessage ) QVariantMap localProps = QVariantMap( props ); @@ -3087,6 +3276,8 @@ bool QgsVectorLayer::writeSld( QDomNode &node, QDomDocument &doc, QString &error bool QgsVectorLayer::changeGeometry( QgsFeatureId fid, QgsGeometry &geom, bool skipDefaultValue ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !mEditBuffer || !mDataProvider ) { return false; @@ -3111,6 +3302,8 @@ bool QgsVectorLayer::changeGeometry( QgsFeatureId fid, QgsGeometry &geom, bool s bool QgsVectorLayer::changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue, bool skipDefaultValues ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + bool result = false; switch ( fields().fieldOrigin( field ) ) @@ -3142,6 +3335,8 @@ bool QgsVectorLayer::changeAttributeValue( QgsFeatureId fid, int field, const QV bool QgsVectorLayer::changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues, bool skipDefaultValues ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + bool result = true; QgsAttributeMap newValuesJoin; @@ -3203,6 +3398,8 @@ bool QgsVectorLayer::changeAttributeValues( QgsFeatureId fid, const QgsAttribute bool QgsVectorLayer::addAttribute( const QgsField &field ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !mEditBuffer || !mDataProvider ) return false; @@ -3211,6 +3408,8 @@ bool QgsVectorLayer::addAttribute( const QgsField &field ) void QgsVectorLayer::removeFieldAlias( int attIndex ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( attIndex < 0 || attIndex >= fields().count() ) return; @@ -3227,6 +3426,8 @@ void QgsVectorLayer::removeFieldAlias( int attIndex ) bool QgsVectorLayer::renameAttribute( int index, const QString &newName ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( index < 0 || index >= fields().count() ) return false; @@ -3266,6 +3467,8 @@ bool QgsVectorLayer::renameAttribute( int index, const QString &newName ) void QgsVectorLayer::setFieldAlias( int attIndex, const QString &aliasString ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( attIndex < 0 || attIndex >= fields().count() ) return; @@ -3279,6 +3482,8 @@ void QgsVectorLayer::setFieldAlias( int attIndex, const QString &aliasString ) QString QgsVectorLayer::attributeAlias( int index ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( index < 0 || index >= fields().count() ) return QString(); @@ -3287,6 +3492,8 @@ QString QgsVectorLayer::attributeAlias( int index ) const QString QgsVectorLayer::attributeDisplayName( int index ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( index >= 0 && index < mFields.count() ) return mFields.at( index ).displayName(); else @@ -3295,11 +3502,15 @@ QString QgsVectorLayer::attributeDisplayName( int index ) const QgsStringMap QgsVectorLayer::attributeAliases() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return mAttributeAliasMap; } QSet QgsVectorLayer::excludeAttributesWms() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QSet excludeList; QMap< QString, QgsField::ConfigurationFlags >::const_iterator flagsIt = mFieldConfigurationFlags.constBegin(); for ( ; flagsIt != mFieldConfigurationFlags.constEnd(); ++flagsIt ) @@ -3314,6 +3525,8 @@ QSet QgsVectorLayer::excludeAttributesWms() const void QgsVectorLayer::setExcludeAttributesWms( const QSet &att ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QMap< QString, QgsField::ConfigurationFlags >::iterator flagsIt = mFieldConfigurationFlags.begin(); for ( ; flagsIt != mFieldConfigurationFlags.end(); ++flagsIt ) { @@ -3324,6 +3537,8 @@ void QgsVectorLayer::setExcludeAttributesWms( const QSet &att ) QSet QgsVectorLayer::excludeAttributesWfs() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QSet excludeList; QMap< QString, QgsField::ConfigurationFlags >::const_iterator flagsIt = mFieldConfigurationFlags.constBegin(); for ( ; flagsIt != mFieldConfigurationFlags.constEnd(); ++flagsIt ) @@ -3338,6 +3553,8 @@ QSet QgsVectorLayer::excludeAttributesWfs() const void QgsVectorLayer::setExcludeAttributesWfs( const QSet &att ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QMap< QString, QgsField::ConfigurationFlags >::iterator flagsIt = mFieldConfigurationFlags.begin(); for ( ; flagsIt != mFieldConfigurationFlags.end(); ++flagsIt ) { @@ -3348,6 +3565,8 @@ void QgsVectorLayer::setExcludeAttributesWfs( const QSet &att ) bool QgsVectorLayer::deleteAttribute( int index ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( index < 0 || index >= fields().count() ) return false; @@ -3365,6 +3584,8 @@ bool QgsVectorLayer::deleteAttribute( int index ) bool QgsVectorLayer::deleteAttributes( const QList &attrs ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + bool deleted = false; // Remove multiple occurrences of same attribute @@ -3385,6 +3606,8 @@ bool QgsVectorLayer::deleteAttributes( const QList &attrs ) bool QgsVectorLayer::deleteFeatureCascade( QgsFeatureId fid, QgsVectorLayer::DeleteContext *context ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !mEditBuffer ) return false; @@ -3454,6 +3677,8 @@ bool QgsVectorLayer::deleteFeatureCascade( QgsFeatureId fid, QgsVectorLayer::Del bool QgsVectorLayer::deleteFeature( QgsFeatureId fid, QgsVectorLayer::DeleteContext *context ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !mEditBuffer ) return false; @@ -3469,6 +3694,8 @@ bool QgsVectorLayer::deleteFeature( QgsFeatureId fid, QgsVectorLayer::DeleteCont bool QgsVectorLayer::deleteFeatures( const QgsFeatureIds &fids, QgsVectorLayer::DeleteContext *context ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + bool res = true; if ( ( context && context->cascade ) || mJoinBuffer->containsJoins() ) @@ -3493,11 +3720,15 @@ bool QgsVectorLayer::deleteFeatures( const QgsFeatureIds &fids, QgsVectorLayer:: QgsFields QgsVectorLayer::fields() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return mFields; } QgsAttributeList QgsVectorLayer::primaryKeyAttributes() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QgsAttributeList pkAttributesList; if ( !mDataProvider ) return pkAttributesList; @@ -3515,6 +3746,8 @@ QgsAttributeList QgsVectorLayer::primaryKeyAttributes() const long long QgsVectorLayer::featureCount() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !mDataProvider ) return static_cast< long long >( Qgis::FeatureCountState::UnknownCount ); return mDataProvider->featureCount() + @@ -3523,6 +3756,8 @@ long long QgsVectorLayer::featureCount() const QgsFeatureSource::FeatureAvailability QgsVectorLayer::hasFeatures() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + const QgsFeatureIds deletedFeatures( mEditBuffer && ! mDataProvider->transaction() ? mEditBuffer->deletedFeatureIds() : QgsFeatureIds() ); const QgsFeatureMap addedFeatures( mEditBuffer && ! mDataProvider->transaction() ? mEditBuffer->addedFeatures() : QgsFeatureMap() ); @@ -3542,6 +3777,8 @@ QgsFeatureSource::FeatureAvailability QgsVectorLayer::hasFeatures() const bool QgsVectorLayer::commitChanges( bool stopEditing ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( project() && project()->transactionMode() == Qgis::TransactionMode::BufferedGroups ) return project()->commitChanges( mCommitErrors, stopEditing, this ); @@ -3616,11 +3853,15 @@ bool QgsVectorLayer::commitChanges( bool stopEditing ) QStringList QgsVectorLayer::commitErrors() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return mCommitErrors; } bool QgsVectorLayer::rollBack( bool deleteBuffer ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( project() && project()->transactionMode() == Qgis::TransactionMode::BufferedGroups ) return project()->rollBack( mCommitErrors, deleteBuffer, this ); @@ -3673,16 +3914,22 @@ bool QgsVectorLayer::rollBack( bool deleteBuffer ) int QgsVectorLayer::selectedFeatureCount() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return mSelectedFeatureIds.size(); } const QgsFeatureIds &QgsVectorLayer::selectedFeatureIds() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return mSelectedFeatureIds; } QgsFeatureList QgsVectorLayer::selectedFeatures() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QgsFeatureList features; features.reserve( mSelectedFeatureIds.count() ); QgsFeature f; @@ -3699,6 +3946,8 @@ QgsFeatureList QgsVectorLayer::selectedFeatures() const QgsFeatureIterator QgsVectorLayer::getSelectedFeatures( QgsFeatureRequest request ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( mSelectedFeatureIds.isEmpty() ) return QgsFeatureIterator(); @@ -3715,6 +3964,8 @@ QgsFeatureIterator QgsVectorLayer::getSelectedFeatures( QgsFeatureRequest reques bool QgsVectorLayer::addFeatures( QgsFeatureList &features, Flags ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !mEditBuffer || !mDataProvider ) return false; @@ -3739,12 +3990,16 @@ bool QgsVectorLayer::addFeatures( QgsFeatureList &features, Flags ) void QgsVectorLayer::setCoordinateSystem() { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + // if layer is not spatial, it has not CRS! setCrs( ( isSpatial() && mDataProvider ) ? mDataProvider->crs() : QgsCoordinateReferenceSystem() ); } QString QgsVectorLayer::displayField() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QgsExpression exp( displayExpression() ); if ( exp.isField() ) { @@ -3756,6 +4011,8 @@ QString QgsVectorLayer::displayField() const void QgsVectorLayer::setDisplayExpression( const QString &displayExpression ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( mDisplayExpression == displayExpression ) return; @@ -3765,6 +4022,8 @@ void QgsVectorLayer::setDisplayExpression( const QString &displayExpression ) QString QgsVectorLayer::displayExpression() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !mDisplayExpression.isEmpty() || mFields.isEmpty() ) { return mDisplayExpression; @@ -3785,22 +4044,30 @@ QString QgsVectorLayer::displayExpression() const bool QgsVectorLayer::isEditable() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return ( mEditBuffer && mDataProvider ); } bool QgsVectorLayer::isSpatial() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QgsWkbTypes::GeometryType t = geometryType(); return t != QgsWkbTypes::NullGeometry && t != QgsWkbTypes::UnknownGeometry; } bool QgsVectorLayer::isReadOnly() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return mDataSourceReadOnly || mReadOnly; } bool QgsVectorLayer::setReadOnly( bool readonly ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + // exit if the layer is in editing mode if ( readonly && mEditBuffer ) return false; @@ -3816,6 +4083,8 @@ bool QgsVectorLayer::setReadOnly( bool readonly ) bool QgsVectorLayer::supportsEditing() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( ! mDataProvider ) return false; @@ -3827,12 +4096,16 @@ bool QgsVectorLayer::supportsEditing() const bool QgsVectorLayer::isModified() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + emit beforeModifiedCheck(); return mEditBuffer && mEditBuffer->isModified(); } bool QgsVectorLayer::isAuxiliaryField( int index, int &srcIndex ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + bool auxiliaryField = false; srcIndex = -1; @@ -3852,6 +4125,8 @@ bool QgsVectorLayer::isAuxiliaryField( int index, int &srcIndex ) const void QgsVectorLayer::setRenderer( QgsFeatureRenderer *r ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + // we must allow setting a renderer if our geometry type is unknown // as this allows the renderer to be correctly set even for layers // with broken sources @@ -3888,6 +4163,8 @@ void QgsVectorLayer::setRenderer( QgsFeatureRenderer *r ) void QgsVectorLayer::addFeatureRendererGenerator( QgsFeatureRendererGenerator *generator ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( generator ) { mRendererGenerators << generator; @@ -3896,6 +4173,8 @@ void QgsVectorLayer::addFeatureRendererGenerator( QgsFeatureRendererGenerator *g void QgsVectorLayer::removeFeatureRendererGenerator( const QString &id ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + for ( int i = mRendererGenerators.count() - 1; i >= 0; --i ) { if ( mRendererGenerators.at( i )->id() == id ) @@ -3908,6 +4187,8 @@ void QgsVectorLayer::removeFeatureRendererGenerator( const QString &id ) QList QgsVectorLayer::featureRendererGenerators() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QList< const QgsFeatureRendererGenerator * > res; for ( const QgsFeatureRendererGenerator *generator : mRendererGenerators ) res << generator; @@ -3916,6 +4197,8 @@ QList QgsVectorLayer::featureRendererGenera void QgsVectorLayer::beginEditCommand( const QString &text ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !mDataProvider ) { return; @@ -3932,6 +4215,8 @@ void QgsVectorLayer::beginEditCommand( const QString &text ) void QgsVectorLayer::endEditCommand() { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !mDataProvider ) { return; @@ -3952,6 +4237,8 @@ void QgsVectorLayer::endEditCommand() void QgsVectorLayer::destroyEditCommand() { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !mDataProvider ) { return; @@ -3974,22 +4261,29 @@ void QgsVectorLayer::destroyEditCommand() bool QgsVectorLayer::addJoin( const QgsVectorLayerJoinInfo &joinInfo ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return mJoinBuffer->addJoin( joinInfo ); } - bool QgsVectorLayer::removeJoin( const QString &joinLayerId ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return mJoinBuffer->removeJoin( joinLayerId ); } const QList< QgsVectorLayerJoinInfo > QgsVectorLayer::vectorJoins() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return mJoinBuffer->vectorJoins(); } int QgsVectorLayer::addExpressionField( const QString &exp, const QgsField &fld ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + emit beforeAddingExpressionField( fld.name() ); mExpressionFieldBuffer->addExpression( exp, fld ); updateFields(); @@ -4000,6 +4294,8 @@ int QgsVectorLayer::addExpressionField( const QString &exp, const QgsField &fld void QgsVectorLayer::removeExpressionField( int index ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + emit beforeRemovingExpressionField( index ); int oi = mFields.fieldOriginIndex( index ); mExpressionFieldBuffer->removeExpression( oi ); @@ -4009,6 +4305,8 @@ void QgsVectorLayer::removeExpressionField( int index ) QString QgsVectorLayer::expressionField( int index ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( mFields.fieldOrigin( index ) != QgsFields::OriginExpression ) return QString(); @@ -4021,12 +4319,16 @@ QString QgsVectorLayer::expressionField( int index ) const void QgsVectorLayer::updateExpressionField( int index, const QString &exp ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + int oi = mFields.fieldOriginIndex( index ); mExpressionFieldBuffer->updateExpression( oi, exp ); } void QgsVectorLayer::updateFields() { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !mDataProvider ) return; @@ -4152,9 +4454,10 @@ void QgsVectorLayer::updateFields() } - QVariant QgsVectorLayer::defaultValue( int index, const QgsFeature &feature, QgsExpressionContext *context ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( index < 0 || index >= mFields.count() || !mDataProvider ) return QVariant(); @@ -4201,6 +4504,8 @@ QVariant QgsVectorLayer::defaultValue( int index, const QgsFeature &feature, Qgs void QgsVectorLayer::setDefaultValueDefinition( int index, const QgsDefaultValue &definition ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( index < 0 || index >= mFields.count() ) return; @@ -4217,6 +4522,8 @@ void QgsVectorLayer::setDefaultValueDefinition( int index, const QgsDefaultValue QgsDefaultValue QgsVectorLayer::defaultValueDefinition( int index ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( index < 0 || index >= mFields.count() ) return QgsDefaultValue(); else @@ -4225,6 +4532,8 @@ QgsDefaultValue QgsVectorLayer::defaultValueDefinition( int index ) const QSet QgsVectorLayer::uniqueValues( int index, int limit ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QSet uniqueValues; if ( !mDataProvider ) { @@ -4333,6 +4642,8 @@ QSet QgsVectorLayer::uniqueValues( int index, int limit ) const QStringList QgsVectorLayer::uniqueStringsMatching( int index, const QString &substring, int limit, QgsFeedback *feedback ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QStringList results; if ( !mDataProvider ) { @@ -4434,6 +4745,8 @@ QStringList QgsVectorLayer::uniqueStringsMatching( int index, const QString &sub QVariant QgsVectorLayer::minimumValue( int index ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QVariant minimum; minimumOrMaximumValue( index, &minimum, nullptr ); return minimum; @@ -4441,6 +4754,8 @@ QVariant QgsVectorLayer::minimumValue( int index ) const QVariant QgsVectorLayer::maximumValue( int index ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QVariant maximum; minimumOrMaximumValue( index, nullptr, &maximum ); return maximum; @@ -4448,11 +4763,15 @@ QVariant QgsVectorLayer::maximumValue( int index ) const void QgsVectorLayer::minimumAndMaximumValue( int index, QVariant &minimum, QVariant &maximum ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + minimumOrMaximumValue( index, &minimum, &maximum ); } void QgsVectorLayer::minimumOrMaximumValue( int index, QVariant *minimum, QVariant *maximum ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( minimum ) *minimum = QVariant(); if ( maximum ) @@ -4567,6 +4886,8 @@ void QgsVectorLayer::minimumOrMaximumValue( int index, QVariant *minimum, QVaria void QgsVectorLayer::createEditBuffer() { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( mEditBuffer ) clearEditBuffer(); @@ -4601,6 +4922,8 @@ void QgsVectorLayer::createEditBuffer() void QgsVectorLayer::clearEditBuffer() { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + delete mEditBuffer; mEditBuffer = nullptr; } @@ -4609,6 +4932,8 @@ QVariant QgsVectorLayer::aggregate( QgsAggregateCalculator::Aggregate aggregate, const QgsAggregateCalculator::AggregateParameters ¶meters, QgsExpressionContext *context, bool *ok, QgsFeatureIds *fids, QgsFeedback *feedback, QString *error ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( ok ) *ok = false; if ( error ) @@ -4659,6 +4984,8 @@ QVariant QgsVectorLayer::aggregate( QgsAggregateCalculator::Aggregate aggregate, void QgsVectorLayer::setFeatureBlendMode( QPainter::CompositionMode featureBlendMode ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( mFeatureBlendMode == featureBlendMode ) return; @@ -4669,11 +4996,15 @@ void QgsVectorLayer::setFeatureBlendMode( QPainter::CompositionMode featureBlend QPainter::CompositionMode QgsVectorLayer::featureBlendMode() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return mFeatureBlendMode; } void QgsVectorLayer::readSldLabeling( const QDomNode &node ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + setLabeling( nullptr ); // start with no labeling setLabelsEnabled( false ); @@ -4883,6 +5214,8 @@ void QgsVectorLayer::readSldLabeling( const QDomNode &node ) bool QgsVectorLayer::readSldTextSymbolizer( const QDomNode &node, QgsPalLayerSettings &settings ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( node.localName() != QLatin1String( "TextSymbolizer" ) ) { QgsDebugMsgLevel( QStringLiteral( "Not a TextSymbolizer element: %1" ).arg( node.localName() ), 3 ); @@ -5219,11 +5552,15 @@ bool QgsVectorLayer::readSldTextSymbolizer( const QDomNode &node, QgsPalLayerSet QgsEditFormConfig QgsVectorLayer::editFormConfig() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return mEditFormConfig; } void QgsVectorLayer::setEditFormConfig( const QgsEditFormConfig &editFormConfig ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( mEditFormConfig == editFormConfig ) return; @@ -5234,6 +5571,8 @@ void QgsVectorLayer::setEditFormConfig( const QgsEditFormConfig &editFormConfig QgsAttributeTableConfig QgsVectorLayer::attributeTableConfig() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QgsAttributeTableConfig config = mAttributeTableConfig; if ( config.isEmpty() ) @@ -5244,6 +5583,8 @@ QgsAttributeTableConfig QgsVectorLayer::attributeTableConfig() const void QgsVectorLayer::setAttributeTableConfig( const QgsAttributeTableConfig &attributeTableConfig ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( mAttributeTableConfig != attributeTableConfig ) { mAttributeTableConfig = attributeTableConfig; @@ -5253,16 +5594,22 @@ void QgsVectorLayer::setAttributeTableConfig( const QgsAttributeTableConfig &att QgsExpressionContext QgsVectorLayer::createExpressionContext() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return QgsExpressionContext( QgsExpressionContextUtils::globalProjectLayerScopes( this ) ); } QgsExpressionContextScope *QgsVectorLayer::createExpressionContextScope() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return QgsExpressionContextUtils::layerScope( this ); } void QgsVectorLayer::setDiagramLayerSettings( const QgsDiagramLayerSettings &s ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( !mDiagramLayerSettings ) mDiagramLayerSettings = new QgsDiagramLayerSettings(); *mDiagramLayerSettings = s; @@ -5270,6 +5617,8 @@ void QgsVectorLayer::setDiagramLayerSettings( const QgsDiagramLayerSettings &s ) QString QgsVectorLayer::htmlMetadata() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QgsLayerMetadataFormatter htmlFormatter( metadata() ); QString myMetadata = QStringLiteral( "\n\n" ); @@ -5406,28 +5755,38 @@ QString QgsVectorLayer::htmlMetadata() const void QgsVectorLayer::invalidateSymbolCountedFlag() { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + mSymbolFeatureCounted = false; } void QgsVectorLayer::onFeatureCounterCompleted() { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + onSymbolsCounted(); mFeatureCounter = nullptr; } void QgsVectorLayer::onFeatureCounterTerminated() { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + mFeatureCounter = nullptr; } void QgsVectorLayer::onJoinedFieldsChanged() { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + // some of the fields of joined layers have changed -> we need to update this layer's fields too updateFields(); } void QgsVectorLayer::onFeatureDeleted( QgsFeatureId fid ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( mEditCommandActive || mCommitChangesActive ) { mDeletedFids << fid; @@ -5443,11 +5802,15 @@ void QgsVectorLayer::onFeatureDeleted( QgsFeatureId fid ) void QgsVectorLayer::onRelationsLoaded() { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + mEditFormConfig.onRelationsLoaded(); } void QgsVectorLayer::onSymbolsCounted() { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( mFeatureCounter ) { mSymbolFeatureCounted = true; @@ -5459,38 +5822,50 @@ void QgsVectorLayer::onSymbolsCounted() QList QgsVectorLayer::referencingRelations( int idx ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return QgsProject::instance()->relationManager()->referencingRelations( this, idx ); } QList QgsVectorLayer::weakRelations() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return mWeakRelations; } void QgsVectorLayer::setWeakRelations( const QList &relations ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + mWeakRelations = relations; } int QgsVectorLayer::listStylesInDatabase( QStringList &ids, QStringList &names, QStringList &descriptions, QString &msgError ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return QgsProviderRegistry::instance()->listStyles( mProviderKey, mDataSource, ids, names, descriptions, msgError ); } QString QgsVectorLayer::getStyleFromDatabase( const QString &styleId, QString &msgError ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return QgsProviderRegistry::instance()->getStyleById( mProviderKey, mDataSource, styleId, msgError ); } bool QgsVectorLayer::deleteStyleFromDatabase( const QString &styleId, QString &msgError ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return QgsProviderRegistry::instance()->deleteStyleById( mProviderKey, mDataSource, styleId, msgError ); } - void QgsVectorLayer::saveStyleToDatabase( const QString &name, const QString &description, bool useAsDefault, const QString &uiFileContent, QString &msgError, QgsMapLayer::StyleCategories categories ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS QString sldStyle, qmlStyle; QDomDocument qmlDocument, sldDocument; @@ -5514,15 +5889,17 @@ void QgsVectorLayer::saveStyleToDatabase( const QString &name, const QString &de description, uiFileContent, useAsDefault, msgError ); } - - QString QgsVectorLayer::loadNamedStyle( const QString &theURI, bool &resultFlag, QgsMapLayer::StyleCategories categories ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return loadNamedStyle( theURI, resultFlag, false, categories ); } bool QgsVectorLayer::loadAuxiliaryLayer( const QgsAuxiliaryStorage &storage, const QString &key ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + bool rc = false; QString joinKey = mAuxiliaryLayerKey; @@ -5552,6 +5929,8 @@ bool QgsVectorLayer::loadAuxiliaryLayer( const QgsAuxiliaryStorage &storage, con void QgsVectorLayer::setAuxiliaryLayer( QgsAuxiliaryLayer *alayer ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + mAuxiliaryLayerKey.clear(); if ( mAuxiliaryLayer ) @@ -5575,16 +5954,22 @@ void QgsVectorLayer::setAuxiliaryLayer( QgsAuxiliaryLayer *alayer ) const QgsAuxiliaryLayer *QgsVectorLayer::auxiliaryLayer() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return mAuxiliaryLayer.get(); } QgsAuxiliaryLayer *QgsVectorLayer::auxiliaryLayer() { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return mAuxiliaryLayer.get(); } QString QgsVectorLayer::loadNamedStyle( const QString &theURI, bool &resultFlag, bool loadFromLocalDB, QgsMapLayer::StyleCategories categories ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QgsDataSourceUri dsUri( theURI ); QString returnMessage; QString qml, errorMsg; @@ -5620,6 +6005,8 @@ QString QgsVectorLayer::loadNamedStyle( const QString &theURI, bool &resultFlag, QSet QgsVectorLayer::dependencies() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( mDataProvider ) return mDataProvider->dependencies() + mDependencies; return mDependencies; @@ -5627,6 +6014,8 @@ QSet QgsVectorLayer::dependencies() const void QgsVectorLayer::emitDataChanged() { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( mDataChangedFired ) return; @@ -5639,6 +6028,8 @@ void QgsVectorLayer::emitDataChanged() void QgsVectorLayer::onAfterCommitChangesDependency() { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + mDataChangedFired = true; reload(); mDataChangedFired = false; @@ -5646,6 +6037,8 @@ void QgsVectorLayer::onAfterCommitChangesDependency() bool QgsVectorLayer::setDependencies( const QSet &oDeps ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QSet deps; const auto constODeps = oDeps; for ( const QgsMapLayerDependency &dep : constODeps ) @@ -5700,6 +6093,8 @@ bool QgsVectorLayer::setDependencies( const QSet &oDeps ) QgsFieldConstraints::Constraints QgsVectorLayer::fieldConstraints( int fieldIndex ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( fieldIndex < 0 || fieldIndex >= mFields.count() || !mDataProvider ) return QgsFieldConstraints::Constraints(); @@ -5716,6 +6111,8 @@ QgsFieldConstraints::Constraints QgsVectorLayer::fieldConstraints( int fieldInde QMap< QgsFieldConstraints::Constraint, QgsFieldConstraints::ConstraintStrength> QgsVectorLayer::fieldConstraintsAndStrength( int fieldIndex ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QMap< QgsFieldConstraints::Constraint, QgsFieldConstraints::ConstraintStrength > m; if ( fieldIndex < 0 || fieldIndex >= mFields.count() ) @@ -5737,6 +6134,8 @@ QMap< QgsFieldConstraints::Constraint, QgsFieldConstraints::ConstraintStrength> void QgsVectorLayer::setFieldConstraint( int index, QgsFieldConstraints::Constraint constraint, QgsFieldConstraints::ConstraintStrength strength ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( index < 0 || index >= mFields.count() ) return; @@ -5754,6 +6153,8 @@ void QgsVectorLayer::setFieldConstraint( int index, QgsFieldConstraints::Constra void QgsVectorLayer::removeFieldConstraint( int index, QgsFieldConstraints::Constraint constraint ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( index < 0 || index >= mFields.count() ) return; @@ -5771,6 +6172,8 @@ void QgsVectorLayer::removeFieldConstraint( int index, QgsFieldConstraints::Cons QString QgsVectorLayer::constraintExpression( int index ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( index < 0 || index >= mFields.count() ) return QString(); @@ -5779,6 +6182,8 @@ QString QgsVectorLayer::constraintExpression( int index ) const QString QgsVectorLayer::constraintDescription( int index ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( index < 0 || index >= mFields.count() ) return QString(); @@ -5787,6 +6192,8 @@ QString QgsVectorLayer::constraintDescription( int index ) const void QgsVectorLayer::setConstraintExpression( int index, const QString &expression, const QString &description ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( index < 0 || index >= mFields.count() ) return; @@ -5803,6 +6210,8 @@ void QgsVectorLayer::setConstraintExpression( int index, const QString &expressi void QgsVectorLayer::setFieldConfigurationFlags( int index, QgsField::ConfigurationFlags flags ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( index < 0 || index >= mFields.count() ) return; @@ -5812,6 +6221,8 @@ void QgsVectorLayer::setFieldConfigurationFlags( int index, QgsField::Configurat void QgsVectorLayer::setFieldConfigurationFlag( int index, QgsField::ConfigurationFlag flag, bool active ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( index < 0 || index >= mFields.count() ) return; QgsField::ConfigurationFlags flags = mFields.at( index ).configurationFlags(); @@ -5821,6 +6232,7 @@ void QgsVectorLayer::setFieldConfigurationFlag( int index, QgsField::Configurati QgsField::ConfigurationFlags QgsVectorLayer::fieldConfigurationFlags( int index ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS if ( index < 0 || index >= mFields.count() ) return QgsField::ConfigurationFlag::None; @@ -5830,6 +6242,8 @@ QgsField::ConfigurationFlags QgsVectorLayer::fieldConfigurationFlags( int index void QgsVectorLayer::setEditorWidgetSetup( int index, const QgsEditorWidgetSetup &setup ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( index < 0 || index >= mFields.count() ) return; @@ -5842,6 +6256,7 @@ void QgsVectorLayer::setEditorWidgetSetup( int index, const QgsEditorWidgetSetup QgsEditorWidgetSetup QgsVectorLayer::editorWidgetSetup( int index ) const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS if ( index < 0 || index >= mFields.count() ) return QgsEditorWidgetSetup(); @@ -5851,6 +6266,8 @@ QgsEditorWidgetSetup QgsVectorLayer::editorWidgetSetup( int index ) const QgsAbstractVectorLayerLabeling *QgsVectorLayer::readLabelingFromCustomProperties() { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QgsAbstractVectorLayerLabeling *labeling = nullptr; if ( customProperty( QStringLiteral( "labeling" ) ).toString() == QLatin1String( "pal" ) ) { @@ -5877,11 +6294,15 @@ QgsAbstractVectorLayerLabeling *QgsVectorLayer::readLabelingFromCustomProperties bool QgsVectorLayer::allowCommit() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return mAllowCommit; } void QgsVectorLayer::setAllowCommit( bool allowCommit ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + if ( mAllowCommit == allowCommit ) return; @@ -5891,21 +6312,29 @@ void QgsVectorLayer::setAllowCommit( bool allowCommit ) QgsGeometryOptions *QgsVectorLayer::geometryOptions() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return mGeometryOptions.get(); } void QgsVectorLayer::setReadExtentFromXml( bool readExtentFromXml ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + mReadExtentFromXml = readExtentFromXml; } bool QgsVectorLayer::readExtentFromXml() const { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + return mReadExtentFromXml; } void QgsVectorLayer::onDirtyTransaction( const QString &sql, const QString &name ) { + QGIS_PROTECT_QOBJECT_THREAD_ACCESS + QgsTransaction *tr = dataProvider()->transaction(); if ( tr && mEditBuffer ) {