18 #include <QDomElement>
19 #include <QHeaderView>
20 #include <QRegularExpression>
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;
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 const 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 const int type = snapSettingsElem.attribute( QStringLiteral(
"type" ) ).toInt();
465 const QDomElement versionElem = doc.firstChildElement( QStringLiteral(
"qgis" ) );
467 bool before3_14 =
false;
468 if ( versionElem.hasAttribute( QStringLiteral(
"version" ) ) )
470 version = versionElem.attribute( QStringLiteral(
"version" ) );
471 const QRegularExpression re( QStringLiteral(
"([\\d]+)\\.([\\d]+)" ) );
472 const 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 const QDomNodeList nodes = snapSettingsElem.elementsByTagName( QStringLiteral(
"individual-layer-settings" ) );
530 const QDomNode node = nodes.item( 0 );
531 const QDomNodeList settingNodes = node.childNodes();
532 const int layerCount = settingNodes.count();
533 for (
int i = 0; i < layerCount; ++i )
535 const 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 const QString layerId = settingElement.attribute( QStringLiteral(
"id" ) );
543 const bool enabled = settingElement.attribute( QStringLiteral(
"enabled" ) ) == QLatin1String(
"1" );
544 const QgsSnappingConfig::SnappingTypeFlag
type =
static_cast<QgsSnappingConfig::SnappingTypeFlag
>( settingElement.attribute( QStringLiteral(
"type" ) ).toInt() );
545 const double tolerance = settingElement.attribute( QStringLiteral(
"tolerance" ) ).toDouble();
547 const double minScale = settingElement.attribute( QStringLiteral(
"minScale" ) ).toDouble();
548 const 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;
605 const auto constLayers = layers;
620 bool changed =
false;
621 const auto constLayers = layers;
627 mIndividualLayerSettings.remove( vl );
634 void QgsSnappingConfig::readLegacySettings()
639 const 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 const QStringList layerIdList = mProject->
readListEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/LayerSnappingList" ), QStringList() );
648 const QStringList enabledList = mProject->
readListEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/LayerSnappingEnabledList" ), QStringList() );
649 const QStringList toleranceList = mProject->
readListEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/LayerSnappingToleranceList" ), QStringList() );
650 const QStringList toleranceUnitList = mProject->
readListEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/LayerSnappingToleranceUnitList" ), QStringList() );
651 const 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 const 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 const 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.
bool value(const QString &dynamicKeyPart=QString(), bool useDefaultValueOverride=false, bool defaultValueOverride=false) const
Returns settings value.
double value(const QString &dynamicKeyPart=QString(), bool useDefaultValueOverride=false, double defaultValueOverride=0.0) const
Returns settings value.
T value(const QString &dynamicKeyPart=QString(), bool useDefaultValueOverride=false, const T &defaultValueOverride=T()) const
Returns settings value.
static const QgsSettingsEntryDouble settingsDigitizingDefaultSnappingTolerance
Settings entry digitizing default snapping tolerance.
static const QgsSettingsEntryBool settingsDigitizingDefaultSnapEnabled
Settings entry digitizing default snap enabled.
static const QgsSettingsEntryEnumFlag< QgsSnappingConfig::SnappingTypes > settingsDigitizingDefaultSnapType
Settings entry digitizing default snap type.
static const QgsSettingsEntryEnumFlag< QgsTolerance::UnitType > settingsDigitizingDefaultSnappingToleranceUnit
Settings entry digitizing default snapping tolerance unit.
This class is a composition of two QSettings instances:
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 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...
@ VectorLayer
Vector layer.
#define Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_PUSH