18 #include <QDomElement>
19 #include <QHeaderView>
20 #include <QRegularExpression>
22 #include "qgssettingsregistrycore.h"
33 , mTolerance( tolerance )
35 , mMinimumScale( minScale )
36 , mMaximumScale( maxScale )
74 return QgsSnappingConfig::SnappingType::VertexAndSegment;
76 return QgsSnappingConfig::SnappingType::Segment;
78 return QgsSnappingConfig::SnappingType::Vertex;
127 return mMinimumScale;
132 mMinimumScale = minScale;
137 return mMaximumScale;
142 mMaximumScale = maxScale;
147 return mValid != other.mValid
148 || mEnabled != other.mEnabled
149 || mType != other.mType
150 || mTolerance != other.mTolerance
151 || mUnits != other.mUnits
152 || mMinimumScale != other.mMinimumScale
153 || mMaximumScale != other.mMaximumScale;
158 return mValid == other.mValid
159 && mEnabled == other.mEnabled
160 && mType == other.mType
161 && mTolerance == other.mTolerance
162 && mUnits == other.mUnits
163 && mMinimumScale == other.mMinimumScale
164 && mMaximumScale == other.mMaximumScale;
176 return mEnabled == other.mEnabled
177 && mMode == other.mMode
178 && mType == other.mType
179 && mTolerance == other.mTolerance
180 && mUnits == other.mUnits
181 && mIntersectionSnapping == other.mIntersectionSnapping
182 && mSelfSnapping == other.mSelfSnapping
183 && mIndividualLayerSettings == other.mIndividualLayerSettings
184 && mScaleDependencyMode == other.mScaleDependencyMode
185 && mMinimumScale == other.mMinimumScale
186 && mMaximumScale == other.mMaximumScale;
192 bool enabled = QgsSettingsRegistryCore::settingsDigitizingDefaultSnapEnabled.value();
200 QgsSnappingConfig::SnappingTypeFlag
type = QgsSettingsRegistryCore::settingsDigitizingDefaultSnapType.value();
201 double tolerance = QgsSettingsRegistryCore::settingsDigitizingDefaultSnappingTolerance.value();
221 mIntersectionSnapping =
false;
222 mSelfSnapping =
false;
227 mIndividualLayerSettings = QHash<QgsVectorLayer *, IndividualLayerSettings>();
228 const auto constMapLayers = mProject->
mapLayers();
276 return QgsSnappingConfig::SnappingType::VertexAndSegment;
278 return QgsSnappingConfig::SnappingType::Segment;
280 return QgsSnappingConfig::SnappingType::Vertex;
288 return QObject::tr(
"No Snapping" );
290 return QObject::tr(
"Vertex" );
292 return QObject::tr(
"Segment" );
294 return QObject::tr(
"Area" );
296 return QObject::tr(
"Centroid" );
298 return QObject::tr(
"Middle of Segments" );
300 return QObject::tr(
"Line Endpoints" );
331 case SnappingType::Vertex:
334 case SnappingType::VertexAndSegment:
337 case SnappingType::Segment:
375 if ( mUnits ==
units )
384 return mIntersectionSnapping;
389 mIntersectionSnapping =
enabled;
394 return mSelfSnapping;
404 return mIndividualLayerSettings;
409 if ( vl && mIndividualLayerSettings.contains( vl ) )
411 return mIndividualLayerSettings.value( vl );
422 mIndividualLayerSettings.clear();
436 return mEnabled != other.mEnabled
437 || mMode != other.mMode
438 || mType != other.mType
439 || mTolerance != other.mTolerance
440 || mUnits != other.mUnits
441 || mIndividualLayerSettings != other.mIndividualLayerSettings
442 || mScaleDependencyMode != other.mScaleDependencyMode
443 || mMinimumScale != other.mMinimumScale
444 || mMaximumScale != other.mMaximumScale;
449 QDomElement snapSettingsElem = doc.firstChildElement( QStringLiteral(
"qgis" ) ).firstChildElement( QStringLiteral(
"snapping-settings" ) );
450 if ( snapSettingsElem.isNull() )
452 readLegacySettings();
456 if ( snapSettingsElem.hasAttribute( QStringLiteral(
"enabled" ) ) )
457 mEnabled = snapSettingsElem.attribute( QStringLiteral(
"enabled" ) ) == QLatin1String(
"1" );
459 if ( snapSettingsElem.hasAttribute( QStringLiteral(
"mode" ) ) )
460 mMode =
static_cast< SnappingMode >( snapSettingsElem.attribute( QStringLiteral(
"mode" ) ).toInt() );
462 if ( snapSettingsElem.hasAttribute( QStringLiteral(
"type" ) ) )
464 int type = snapSettingsElem.attribute( QStringLiteral(
"type" ) ).toInt();
465 QDomElement versionElem = doc.firstChildElement( QStringLiteral(
"qgis" ) );
467 bool before3_14 =
false;
468 if ( versionElem.hasAttribute( QStringLiteral(
"version" ) ) )
470 version = versionElem.attribute( QStringLiteral(
"version" ) );
471 QRegularExpression re( QStringLiteral(
"([\\d]+)\\.([\\d]+)" ) );
472 QRegularExpressionMatch match = re.match( version );
473 if ( match.hasMatch() )
475 if ( ( match.captured( 1 ).toInt() <= 3 ) && ( match.captured( 2 ).toInt() <= 12 ) )
502 mType =
static_cast<QgsSnappingConfig::SnappingTypeFlag
>(
type );
505 if ( snapSettingsElem.hasAttribute( QStringLiteral(
"tolerance" ) ) )
506 mTolerance = snapSettingsElem.attribute( QStringLiteral(
"tolerance" ) ).toDouble();
508 if ( snapSettingsElem.hasAttribute( QStringLiteral(
"scaleDependencyMode" ) ) )
511 if ( snapSettingsElem.hasAttribute( QStringLiteral(
"minScale" ) ) )
512 mMinimumScale = snapSettingsElem.attribute( QStringLiteral(
"minScale" ) ).toDouble();
514 if ( snapSettingsElem.hasAttribute( QStringLiteral(
"maxScale" ) ) )
515 mMaximumScale = snapSettingsElem.attribute( QStringLiteral(
"maxScale" ) ).toDouble();
517 if ( snapSettingsElem.hasAttribute( QStringLiteral(
"unit" ) ) )
518 mUnits =
static_cast< QgsTolerance::UnitType >( snapSettingsElem.attribute( QStringLiteral(
"unit" ) ).toInt() );
520 if ( snapSettingsElem.hasAttribute( QStringLiteral(
"intersection-snapping" ) ) )
521 mIntersectionSnapping = snapSettingsElem.attribute( QStringLiteral(
"intersection-snapping" ) ) == QLatin1String(
"1" );
523 if ( snapSettingsElem.hasAttribute( QStringLiteral(
"self-snapping" ) ) )
524 mSelfSnapping = snapSettingsElem.attribute( QStringLiteral(
"self-snapping" ) ) == QLatin1String(
"1" );
527 QDomNodeList nodes = snapSettingsElem.elementsByTagName( QStringLiteral(
"individual-layer-settings" ) );
530 QDomNode node = nodes.item( 0 );
531 QDomNodeList settingNodes = node.childNodes();
532 int layerCount = settingNodes.count();
533 for (
int i = 0; i < layerCount; ++i )
535 QDomElement settingElement = settingNodes.at( i ).toElement();
536 if ( settingElement.tagName() != QLatin1String(
"layer-setting" ) )
538 QgsLogger::warning( QApplication::translate(
"QgsProjectSnappingSettings",
"Cannot read individual settings. Unexpected tag '%1'" ).arg( settingElement.tagName() ) );
542 QString layerId = settingElement.attribute( QStringLiteral(
"id" ) );
543 bool enabled = settingElement.attribute( QStringLiteral(
"enabled" ) ) == QLatin1String(
"1" );
544 QgsSnappingConfig::SnappingTypeFlag
type =
static_cast<QgsSnappingConfig::SnappingTypeFlag
>( settingElement.attribute( QStringLiteral(
"type" ) ).toInt() );
545 double tolerance = settingElement.attribute( QStringLiteral(
"tolerance" ) ).toDouble();
547 double minScale = settingElement.attribute( QStringLiteral(
"minScale" ) ).toDouble();
548 double maxScale = settingElement.attribute( QStringLiteral(
"maxScale" ) ).toDouble();
557 mIndividualLayerSettings.insert( vl, setting );
564 QDomElement snapSettingsElem = doc.createElement( QStringLiteral(
"snapping-settings" ) );
565 snapSettingsElem.setAttribute( QStringLiteral(
"enabled" ), QString::number( mEnabled ) );
566 snapSettingsElem.setAttribute( QStringLiteral(
"mode" ),
static_cast<int>( mMode ) );
567 snapSettingsElem.setAttribute( QStringLiteral(
"type" ),
static_cast<int>( mType ) );
568 snapSettingsElem.setAttribute( QStringLiteral(
"tolerance" ), mTolerance );
569 snapSettingsElem.setAttribute( QStringLiteral(
"unit" ),
static_cast<int>( mUnits ) );
570 snapSettingsElem.setAttribute( QStringLiteral(
"intersection-snapping" ), QString::number( mIntersectionSnapping ) );
571 snapSettingsElem.setAttribute( QStringLiteral(
"self-snapping" ), QString::number( mSelfSnapping ) );
572 snapSettingsElem.setAttribute( QStringLiteral(
"scaleDependencyMode" ), QString::number( mScaleDependencyMode ) );
573 snapSettingsElem.setAttribute( QStringLiteral(
"minScale" ), mMinimumScale );
574 snapSettingsElem.setAttribute( QStringLiteral(
"maxScale" ), mMaximumScale );
576 QDomElement ilsElement = doc.createElement( QStringLiteral(
"individual-layer-settings" ) );
577 QHash<QgsVectorLayer *, IndividualLayerSettings>::const_iterator layerIt = mIndividualLayerSettings.constBegin();
578 for ( ; layerIt != mIndividualLayerSettings.constEnd(); ++layerIt )
582 QDomElement layerElement = doc.createElement( QStringLiteral(
"layer-setting" ) );
583 layerElement.setAttribute( QStringLiteral(
"id" ), layerIt.key()->id() );
584 layerElement.setAttribute( QStringLiteral(
"enabled" ), QString::number( setting.
enabled() ) );
585 layerElement.setAttribute( QStringLiteral(
"type" ),
static_cast<int>( setting.
typeFlag() ) );
586 layerElement.setAttribute( QStringLiteral(
"tolerance" ), setting.
tolerance() );
587 layerElement.setAttribute( QStringLiteral(
"units" ),
static_cast<int>( setting.
units() ) );
588 layerElement.setAttribute( QStringLiteral(
"minScale" ), setting.
minimumScale() );
589 layerElement.setAttribute( QStringLiteral(
"maxScale" ), setting.
maximumScale() );
590 ilsElement.appendChild( layerElement );
592 snapSettingsElem.appendChild( ilsElement );
594 doc.firstChildElement( QStringLiteral(
"qgis" ) ).appendChild( snapSettingsElem );
599 bool changed =
false;
600 bool enabled = QgsSettingsRegistryCore::settingsDigitizingDefaultSnapEnabled.value( QString(),
true,
true );
601 QgsSnappingConfig::SnappingTypeFlag
type = QgsSettingsRegistryCore::settingsDigitizingDefaultSnapType.value();
602 double tolerance = QgsSettingsRegistryCore::settingsDigitizingDefaultSnappingTolerance.value();
605 const auto constLayers = layers;
620 bool changed =
false;
621 const auto constLayers = layers;
627 mIndividualLayerSettings.remove( vl );
634 void QgsSnappingConfig::readLegacySettings()
639 QString snapMode = mProject->
readEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/SnappingMode" ) );
641 mTolerance = mProject->
readDoubleEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/DefaultSnapTolerance" ), 0 );
644 mIntersectionSnapping = mProject->
readNumEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/IntersectionSnapping" ), 0 );
647 QStringList layerIdList = mProject->
readListEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/LayerSnappingList" ), QStringList() );
648 QStringList enabledList = mProject->
readListEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/LayerSnappingEnabledList" ), QStringList() );
649 QStringList toleranceList = mProject->
readListEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/LayerSnappingToleranceList" ), QStringList() );
650 QStringList toleranceUnitList = mProject->
readListEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/LayerSnappingToleranceUnitList" ), QStringList() );
651 QStringList snapToList = mProject->
readListEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/LayerSnapToList" ), QStringList() );
654 if ( layerIdList.size() != enabledList.size() ||
655 layerIdList.size() != toleranceList.size() ||
656 layerIdList.size() != toleranceUnitList.size() ||
657 layerIdList.size() != snapToList.size() )
661 if ( snapMode == QLatin1String(
"current_layer" ) )
663 else if ( snapMode == QLatin1String(
"all_layers" ) )
669 QStringList::const_iterator layerIt( layerIdList.constBegin() );
670 QStringList::const_iterator tolIt( toleranceList.constBegin() );
671 QStringList::const_iterator tolUnitIt( toleranceUnitList.constBegin() );
672 QStringList::const_iterator snapIt( snapToList.constBegin() );
673 QStringList::const_iterator enabledIt( enabledList.constBegin() );
674 for ( ; layerIt != layerIdList.constEnd(); ++layerIt, ++tolIt, ++tolUnitIt, ++snapIt, ++enabledIt )
680 QgsSnappingConfig::SnappingTypeFlag t( *snapIt == QLatin1String(
"to_vertex" ) ?
VertexFlag :
681 ( *snapIt == QLatin1String(
"to_segment" ) ?
SegmentFlag :
686 mIndividualLayerSettings.insert( vlayer, IndividualLayerSettings( *enabledIt == QLatin1String(
"enabled" ), t, tolIt->toDouble(),
static_cast<QgsTolerance::UnitType>( tolUnitIt->toInt() ), 0.0, 0.0 ) );
689 QString snapType = mProject->
readEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/DefaultSnapType" ), QStringLiteral(
"off" ) );
691 if ( snapType == QLatin1String(
"to segment" ) )
693 else if ( snapType == QLatin1String(
"to vertex and segment" ) )
695 else if ( snapType == QLatin1String(
"to vertex" ) )
718 return mMinimumScale;
723 mMinimumScale = minScale;
728 return mMaximumScale;
733 mMaximumScale = maxScale;
738 mScaleDependencyMode =
mode;
743 return mScaleDependencyMode;
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static void warning(const QString &msg)
Goes to qWarning.
Base class for all map layer types.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
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_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
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.
double readDoubleEntry(const QString &scope, const QString &key, double def=0, bool *ok=nullptr) const
Reads a double from the specified scope and key.
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.
QMap< QString, QgsMapLayer * > mapLayers(const bool validOnly=false) const
Returns a map of all registered layers by layer ID.
This is a container of advanced configuration (per layer) of the snapping of the project.
double tolerance() const
Returns the tolerance.
void setEnabled(bool enabled)
enables the snapping
void setUnits(QgsTolerance::UnitType units)
Sets the type of units.
bool operator!=(const QgsSnappingConfig::IndividualLayerSettings &other) const
Compare this configuration to other.
bool valid() const
Returns if settings are valid.
IndividualLayerSettings()=default
Constructs an invalid setting.
double maximumScale() const
Returns max scale on which snapping is limited.
QgsTolerance::UnitType units() const
Returns the type of units.
void setMinimumScale(double minScale)
Sets the min scale value on which snapping is used, 0.0 disable scale limit.
void setMaximumScale(double maxScale)
Sets the max scale value on which snapping is used, 0.0 disable scale limit.
bool enabled() const
Returns if snapping is enabled.
void setTypeFlag(QgsSnappingConfig::SnappingTypeFlag type)
define the type of snapping
bool operator==(const QgsSnappingConfig::IndividualLayerSettings &other) const
Q_DECL_DEPRECATED QgsSnappingConfig::SnappingType type() const
Returns the flags type (vertices | segments | area | centroid | middle)
double minimumScale() const
Returns minimum scale on which snapping is limited.
QgsSnappingConfig::SnappingTypeFlag typeFlag() const
Returns the flags type (vertices | segments | area | centroid | middle)
Q_DECL_DEPRECATED void setType(QgsSnappingConfig::SnappingType type)
define the type of snapping
void setTolerance(double tolerance)
Sets the tolerance.
This is a container for configuration of the snapping of the project.
SnappingMode
SnappingMode defines on which layer the snapping is performed.
@ ActiveLayer
On the active layer.
@ AdvancedConfiguration
On a per layer configuration basis.
@ AllLayers
On all vector layers.
@ CentroidFlag
On centroid.
@ SegmentFlag
On segments.
@ LineEndpointFlag
Start or end points of lines, or first vertex in polygon rings only (since QGIS 3....
@ MiddleOfSegmentFlag
On Middle segment.
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 setScaleDependencyMode(ScaleDependencyMode mode)
Set the scale dependency mode.
QgsSnappingConfig(QgsProject *project=nullptr)
Constructor with default parameters defined in global settings.
void setMinimumScale(double minScale)
Sets the min scale on which snapping is enabled, 0.0 disable scale limit.
QgsTolerance::UnitType units() const
Returns the type of units.
void setUnits(QgsTolerance::UnitType units)
Sets the type of units.
bool intersectionSnapping() const
Returns if the snapping on intersection is enabled.
void setTypeFlag(QgsSnappingConfig::SnappingTypeFlag type)
define the type of snapping
void setMode(SnappingMode mode)
define the mode of snapping
ScaleDependencyMode
ScaleDependencyMode the scale dependency mode of snapping.
@ Disabled
No scale dependency.
double minimumScale() const
Returns the min scale (i.e.
double tolerance() const
Returns the tolerance.
Q_GADGET QgsProject * project
void reset()
reset to default values
Q_DECL_DEPRECATED void setType(QgsSnappingConfig::SnappingType type)
define the type of snapping
void writeProject(QDomDocument &doc)
Writes the configuration to the specified QGIS project document.
void setMaximumScale(double maxScale)
Set the max scale on which snapping is enabled, 0.0 disable scale limit.
bool selfSnapping() const
Returns if self snapping (snapping to the currently digitized feature) is enabled.
void setTolerance(double tolerance)
Sets the tolerance.
void clearIndividualLayerSettings()
Removes all individual layer snapping settings.
Q_DECL_DEPRECATED QgsSnappingConfig::SnappingType type() const
Returns the flags type (vertices | segments | area | centroid | middle)
double maximumScale() const
Returns the max scale (i.e.
void setProject(QgsProject *project)
The project from which the snapped layers should be retrieved.
SnappingMode mode() const
Returns the mode (all layers, active layer, per layer settings)
static QIcon snappingTypeFlagToIcon(SnappingTypeFlag type)
Convenient method to return an icon corresponding to the enum type QgsSnappingConfig::SnappingTypeFla...
bool operator!=(const QgsSnappingConfig &other) const
Compare this configuration to other.
QgsSnappingConfig::SnappingTypeFlag typeFlag() const
Returns the flags type (vertices | segments | area | centroid | middle)
bool operator==(const QgsSnappingConfig &other) const
SnappingType
SnappingType defines on what object the snapping is performed.
void setSelfSnapping(bool enabled)
Sets if self snapping (snapping to the currently digitized feature) is enabled.
static QString snappingTypeFlagToString(SnappingTypeFlag type)
Convenient method to returns the translated name of the enum type QgsSnappingConfig::SnappingTypeFlag...
QHash< QgsVectorLayer *, QgsSnappingConfig::IndividualLayerSettings > individualLayerSettings() const
Returns individual snapping settings for all layers.
bool removeLayers(const QList< QgsMapLayer * > &layers)
Removes the specified layers from the individual layer configuration.
ScaleDependencyMode scaleDependencyMode() const
Returns the scale dependency mode.
void setEnabled(bool enabled)
enables the snapping
bool enabled() const
Returns if snapping is enabled.
void setIndividualLayerSettings(QgsVectorLayer *vl, const QgsSnappingConfig::IndividualLayerSettings &individualLayerSettings)
Sets individual layer snappings settings (applied if mode is AdvancedConfiguration)
void setIntersectionSnapping(bool enabled)
Sets if the snapping on intersection is enabled.
UnitType
Type of unit of tolerance value from settings.
@ ProjectUnits
Map (project) units. Added in 2.8.
@ LayerUnits
Layer unit value.
Represents a vector layer which manages a vector based data sets.
bool isSpatial() const FINAL
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
#define Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_PUSH