diff --git a/python/core/qgsproject.sip b/python/core/qgsproject.sip index 61fab5ed00f..4805c221686 100644 --- a/python/core/qgsproject.sip +++ b/python/core/qgsproject.sip @@ -390,6 +390,20 @@ class QgsProject : QObject */ void setSnappingConfig( const QgsSnappingConfig& snappingConfig ); + /** + * A list of layers with which intersections should be avoided. + * + * @note Added in QGIS 3.0 + */ + QStringList avoidIntersectionsList() const; + + /** + * A list of layers with which intersections should be avoided. + * + * @note Added in QGIS 3.0 + */ + void setAvoidIntersectionsList(const QStringList& avoidIntersectionsList); + signals: //! emitted when project is being read void readProject( const QDomDocument & ); @@ -462,6 +476,13 @@ class QgsProject : QObject */ void topologicalEditingChanged(); + /** + * Emitted whenever avoidIntersectionsList has changed. + * + * @note Added in QGIS 3.0 + */ + void avoidIntersectionsListChanged(); + public slots: /** * Flag the project as dirty (modified). If this flag is set, the user will diff --git a/python/core/qgssnappingconfig.sip b/python/core/qgssnappingconfig.sip index 9beec6e7622..f6987f7b37c 100644 --- a/python/core/qgssnappingconfig.sip +++ b/python/core/qgssnappingconfig.sip @@ -41,9 +41,8 @@ class QgsSnappingConfig * @param type * @param tolerance * @param units - * @param avoidIntersection */ - IndividualLayerSettings( bool enabled, QgsSnappingConfig::SnappingType type, double tolerance, QgsTolerance::UnitType units, bool avoidIntersection = false ); + IndividualLayerSettings( bool enabled, QgsSnappingConfig::SnappingType type, double tolerance, QgsTolerance::UnitType units ); /** * Constructs an invalid setting @@ -77,12 +76,6 @@ class QgsSnappingConfig //! set the type of units void setUnits( QgsTolerance::UnitType units ); - //! return if it shall avoid intersection (polygon layers only) - bool avoidIntersection() const; - - //! set if it shall avoid intersection (polygon layers only) - void setAvoidIntersection( bool avoidIntersection ); - /** * Compare this configuration to other. */ diff --git a/src/app/qgsmaptooladdfeature.cpp b/src/app/qgsmaptooladdfeature.cpp index 33933537e57..fd4c7368de7 100644 --- a/src/app/qgsmaptooladdfeature.cpp +++ b/src/app/qgsmaptooladdfeature.cpp @@ -296,7 +296,7 @@ void QgsMapToolAddFeature::cadCanvasReleaseEvent( QgsMapMouseEvent* e ) //use always topological editing for avoidIntersection. //Otherwise, no way to guarantee the geometries don't have a small gap in between. - QStringList intersectionLayers = QgsProject::instance()->readListEntry( "Digitizing", "/AvoidIntersectionsList" ); + QStringList intersectionLayers = QgsProject::instance()->avoidIntersectionsList(); bool avoidIntersection = !intersectionLayers.isEmpty(); if ( avoidIntersection ) //try to add topological points also to background layers { diff --git a/src/app/qgssnappinglayertreemodel.cpp b/src/app/qgssnappinglayertreemodel.cpp index 8007309e5cf..337bc89f404 100644 --- a/src/app/qgssnappinglayertreemodel.cpp +++ b/src/app/qgssnappinglayertreemodel.cpp @@ -494,7 +494,7 @@ QVariant QgsSnappingLayerTreeModel::data( const QModelIndex& idx, int role ) con { if ( role == Qt::CheckStateRole && vl->geometryType() == QgsWkbTypes::PolygonGeometry ) { - if ( ls.avoidIntersection() ) + if ( mProject->avoidIntersectionsList().contains( vl->id() ) ) { return Qt::Checked; } @@ -614,20 +614,20 @@ bool QgsSnappingLayerTreeModel::setData( const QModelIndex& index, const QVarian if ( index.column() == AvoidIntersectionColumn && role == Qt::CheckStateRole ) { - QgsVectorLayer *vl = vectorLayer( index ); + QgsVectorLayer* vl = vectorLayer( index ); if ( vl ) { if ( !mIndividualLayerSettings.contains( vl ) ) return false; - QgsSnappingConfig::IndividualLayerSettings ls = mIndividualLayerSettings.value( vl ); - if ( !ls.valid() ) - return false; + QStringList avoidIntersectionsList = mProject->avoidIntersectionsList(); - ls.setAvoidIntersection( value.toInt() == Qt::Checked ); - QgsSnappingConfig config = mProject->snappingConfig(); - config.setIndividualLayerSettings( vl, ls ); - mProject->setSnappingConfig( config ); + if ( value.toInt() == Qt::Checked && !avoidIntersectionsList.contains( vl->id() ) ) + avoidIntersectionsList.append( vl->id() ); + else + avoidIntersectionsList.removeAll( vl->id() ); + + mProject->setAvoidIntersectionsList( avoidIntersectionsList ); return true; } } diff --git a/src/core/geometry/qgsgeometryeditutils.cpp b/src/core/geometry/qgsgeometryeditutils.cpp index fb657f1c359..cef714e48b8 100644 --- a/src/core/geometry/qgsgeometryeditutils.cpp +++ b/src/core/geometry/qgsgeometryeditutils.cpp @@ -241,10 +241,8 @@ QgsAbstractGeometry* QgsGeometryEditUtils::avoidIntersections( const QgsAbstract return nullptr; } - //read avoid intersections list from project properties - bool listReadOk; - QStringList avoidIntersectionsList = QgsProject::instance()->readListEntry( "Digitizing", "/AvoidIntersectionsList", QStringList(), &listReadOk ); - if ( !listReadOk ) + QStringList avoidIntersectionsList = QgsProject::instance()->avoidIntersectionsList(); + if ( avoidIntersectionsList.isEmpty() ) return nullptr; //no intersections stored in project does not mean error QList< QgsAbstractGeometry* > nearGeometries; diff --git a/src/core/qgsproject.cpp b/src/core/qgsproject.cpp index 66626849f42..a4ab11770c4 100644 --- a/src/core/qgsproject.cpp +++ b/src/core/qgsproject.cpp @@ -1002,6 +1002,17 @@ void QgsProject::loadEmbeddedNodes( QgsLayerTreeGroup *group ) } } +QStringList QgsProject::avoidIntersectionsList() const +{ + return readListEntry( "Digitizing", "/AvoidIntersectionsList", QStringList() ); +} + +void QgsProject::setAvoidIntersectionsList( const QStringList& avoidIntersectionsList ) +{ + writeEntry( "Digitizing", "/AvoidIntersectionsList", avoidIntersectionsList ); + emit avoidIntersectionsListChanged(); +} + QgsExpressionContext QgsProject::createExpressionContext() const { QgsExpressionContext context; diff --git a/src/core/qgsproject.h b/src/core/qgsproject.h index ad86946ec78..c96afaab8e2 100644 --- a/src/core/qgsproject.h +++ b/src/core/qgsproject.h @@ -80,6 +80,7 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera Q_PROPERTY( QgsCoordinateReferenceSystem crs READ crs WRITE setCrs ) Q_PROPERTY( QgsMapThemeCollection* mapThemeCollection READ mapThemeCollection ) Q_PROPERTY( QgsSnappingConfig snappingConfig READ snappingConfig WRITE setSnappingConfig NOTIFY snappingConfigChanged ) + Q_PROPERTY( QStringList avoidIntersectionsList READ avoidIntersectionsList WRITE setAvoidIntersectionsList NOTIFY avoidIntersectionsListChanged ) public: @@ -469,6 +470,20 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera */ void setSnappingConfig( const QgsSnappingConfig& snappingConfig ); + /** + * A list of layers with which intersections should be avoided. + * + * @note Added in QGIS 3.0 + */ + QStringList avoidIntersectionsList() const; + + /** + * A list of layers with which intersections should be avoided. + * + * @note Added in QGIS 3.0 + */ + void setAvoidIntersectionsList( const QStringList& avoidIntersectionsList ); + signals: //! emitted when project is being read void readProject( const QDomDocument& ); @@ -543,6 +558,13 @@ class CORE_EXPORT QgsProject : public QObject, public QgsExpressionContextGenera */ void topologicalEditingChanged(); + /** + * Emitted whenever avoidIntersectionsList has changed. + * + * @note Added in QGIS 3.0 + */ + void avoidIntersectionsListChanged(); + public slots: /** * Flag the project as dirty (modified). If this flag is set, the user will diff --git a/src/core/qgssnappingconfig.cpp b/src/core/qgssnappingconfig.cpp index c82f10caf65..3ffbaa6903c 100644 --- a/src/core/qgssnappingconfig.cpp +++ b/src/core/qgssnappingconfig.cpp @@ -30,17 +30,15 @@ QgsSnappingConfig::IndividualLayerSettings::IndividualLayerSettings() , mType( Vertex ) , mTolerance( 0 ) , mUnits( QgsTolerance::Pixels ) - , mAvoidIntersection( false ) {} -QgsSnappingConfig::IndividualLayerSettings::IndividualLayerSettings( bool enabled, SnappingType type, double tolerance, QgsTolerance::UnitType units, bool avoidIntersection ) +QgsSnappingConfig::IndividualLayerSettings::IndividualLayerSettings( bool enabled, SnappingType type, double tolerance, QgsTolerance::UnitType units ) : mValid( true ) , mEnabled( enabled ) , mType( type ) , mTolerance( tolerance ) , mUnits( units ) - , mAvoidIntersection( avoidIntersection ) {} bool QgsSnappingConfig::IndividualLayerSettings::valid() const @@ -88,24 +86,13 @@ void QgsSnappingConfig::IndividualLayerSettings::setUnits( QgsTolerance::UnitTyp mUnits = units; } -bool QgsSnappingConfig::IndividualLayerSettings::avoidIntersection() const -{ - return mAvoidIntersection; -} - -void QgsSnappingConfig::IndividualLayerSettings::setAvoidIntersection( bool avoidIntersection ) -{ - mAvoidIntersection = avoidIntersection; -} - bool QgsSnappingConfig::IndividualLayerSettings::operator !=( const QgsSnappingConfig::IndividualLayerSettings& other ) const { return mValid != other.mValid || mEnabled != other.mEnabled || mType != other.mType || mTolerance != other.mTolerance - || mUnits != other.mUnits - || mAvoidIntersection != other.mAvoidIntersection; + || mUnits != other.mUnits; } bool QgsSnappingConfig::IndividualLayerSettings::operator ==( const QgsSnappingConfig::IndividualLayerSettings& other ) const @@ -114,8 +101,7 @@ bool QgsSnappingConfig::IndividualLayerSettings::operator ==( const QgsSnappingC && mEnabled == other.mEnabled && mType == other.mType && mTolerance == other.mTolerance - && mUnits == other.mUnits - && mAvoidIntersection == other.mAvoidIntersection; + && mUnits == other.mUnits; } @@ -347,7 +333,6 @@ void QgsSnappingConfig::readProject( const QDomDocument& doc ) SnappingType type = ( SnappingType )settingElement.attribute( "type" ).toInt(); double tolerance = settingElement.attribute( "tolerance" ).toDouble(); QgsTolerance::UnitType units = ( QgsTolerance::UnitType )settingElement.attribute( "units" ).toInt(); - bool avoidIntersection = settingElement.attribute( "avoid-intersection" ) == "1"; QgsMapLayer* ml = QgsMapLayerRegistry::instance()->mapLayer( layerId ); if ( !ml || ml->type() != QgsMapLayer::VectorLayer ) @@ -355,7 +340,7 @@ void QgsSnappingConfig::readProject( const QDomDocument& doc ) QgsVectorLayer* vl = qobject_cast( ml ); - IndividualLayerSettings setting = IndividualLayerSettings( enabled, type, tolerance, units, avoidIntersection ); + IndividualLayerSettings setting = IndividualLayerSettings( enabled, type, tolerance, units ); mIndividualLayerSettings.insert( vl, setting ); } } @@ -382,7 +367,6 @@ void QgsSnappingConfig::writeProject( QDomDocument& doc ) layerElement.setAttribute( "type", ( int )setting.type() ); layerElement.setAttribute( "tolerance", setting.tolerance() ); layerElement.setAttribute( "units", ( int )setting.units() ); - layerElement.setAttribute( "avoid-intersection", QString::number( setting.avoidIntersection() ) ); ilsElement.appendChild( layerElement ); } snapSettingsElem.appendChild( ilsElement ); diff --git a/src/core/qgssnappingconfig.h b/src/core/qgssnappingconfig.h index 01ee2048a3e..f9639ea884a 100644 --- a/src/core/qgssnappingconfig.h +++ b/src/core/qgssnappingconfig.h @@ -62,9 +62,8 @@ class CORE_EXPORT QgsSnappingConfig * @param type * @param tolerance * @param units - * @param avoidIntersection */ - IndividualLayerSettings( bool enabled, QgsSnappingConfig::SnappingType type, double tolerance, QgsTolerance::UnitType units, bool avoidIntersection = false ); + IndividualLayerSettings( bool enabled, QgsSnappingConfig::SnappingType type, double tolerance, QgsTolerance::UnitType units ); /** * Constructs an invalid setting @@ -98,12 +97,6 @@ class CORE_EXPORT QgsSnappingConfig //! set the type of units void setUnits( QgsTolerance::UnitType units ); - //! return if it shall avoid intersection (polygon layers only) - bool avoidIntersection() const; - - //! set if it shall avoid intersection (polygon layers only) - void setAvoidIntersection( bool avoidIntersection ); - /** * Compare this configuration to other. */ @@ -117,7 +110,6 @@ class CORE_EXPORT QgsSnappingConfig SnappingType mType; double mTolerance; QgsTolerance::UnitType mUnits; - bool mAvoidIntersection; }; /**