18#include "moc_qgssnappingconfig.cpp" 
   22#include <QRegularExpression> 
   35  , mTolerance( tolerance )
 
   37  , mMinimumScale( minScale )
 
   38  , mMaximumScale( maxScale )
 
 
  129  return mMinimumScale;
 
 
  134  mMinimumScale = minScale;
 
 
  139  return mMaximumScale;
 
 
  144  mMaximumScale = maxScale;
 
 
  149  return mValid != other.mValid
 
  150         || mEnabled != other.mEnabled
 
  151         || mType != other.mType
 
  152         || mTolerance != other.mTolerance
 
  153         || mUnits != other.mUnits
 
  154         || mMinimumScale != other.mMinimumScale
 
  155         || mMaximumScale != other.mMaximumScale;
 
 
  160  return mValid == other.mValid
 
  161         && mEnabled == other.mEnabled
 
  162         && mType == other.mType
 
  163         && mTolerance == other.mTolerance
 
  164         && mUnits == other.mUnits
 
  165         && mMinimumScale == other.mMinimumScale
 
  166         && mMaximumScale == other.mMaximumScale;
 
 
  178  return mEnabled == other.mEnabled
 
  179         && mMode == other.mMode
 
  180         && mType == other.mType
 
  181         && mTolerance == other.mTolerance
 
  182         && mUnits == other.mUnits
 
  183         && mIntersectionSnapping == other.mIntersectionSnapping
 
  184         && mSelfSnapping == other.mSelfSnapping
 
  185         && mIndividualLayerSettings == other.mIndividualLayerSettings
 
  186         && mScaleDependencyMode == other.mScaleDependencyMode
 
  187         && mMinimumScale == other.mMinimumScale
 
  188         && mMaximumScale == other.mMaximumScale;
 
 
  217  mIntersectionSnapping = 
false;
 
  218  mSelfSnapping = 
false;
 
  223    mIndividualLayerSettings = QHash<QgsVectorLayer *, IndividualLayerSettings>();
 
  224    const auto constMapLayers = mProject->
mapLayers();
 
 
  284      return QObject::tr( 
"No Snapping" );
 
  286      return QObject::tr( 
"Vertex" );
 
  288      return QObject::tr( 
"Segment" );
 
  290      return QObject::tr( 
"Area" );
 
  292      return QObject::tr( 
"Centroid" );
 
  294      return QObject::tr( 
"Middle of Segments" );
 
  296      return QObject::tr( 
"Line Endpoints" );
 
 
  371  if ( mUnits == 
units )
 
 
  380  return mIntersectionSnapping;
 
 
  385  mIntersectionSnapping = 
enabled;
 
 
  390  return mSelfSnapping;
 
 
  400  return mIndividualLayerSettings;
 
 
  405  if ( vl && mIndividualLayerSettings.contains( vl ) )
 
  407    return mIndividualLayerSettings.value( vl );
 
 
  418  mIndividualLayerSettings.clear();
 
 
  432  return mEnabled != other.mEnabled
 
  433         || mMode != other.mMode
 
  434         || mType != other.mType
 
  435         || mTolerance != other.mTolerance
 
  436         || mUnits != other.mUnits
 
  437         || mIndividualLayerSettings != other.mIndividualLayerSettings
 
  438         || mScaleDependencyMode != other.mScaleDependencyMode
 
  439         || mMinimumScale != other.mMinimumScale
 
  440         || mMaximumScale != other.mMaximumScale;
 
 
  445  const QDomElement snapSettingsElem = doc.firstChildElement( QStringLiteral( 
"qgis" ) ).firstChildElement( QStringLiteral( 
"snapping-settings" ) );
 
  446  if ( snapSettingsElem.isNull() )
 
  448    readLegacySettings();
 
  452  if ( snapSettingsElem.hasAttribute( QStringLiteral( 
"enabled" ) ) )
 
  453    mEnabled = snapSettingsElem.attribute( QStringLiteral( 
"enabled" ) ) == QLatin1String( 
"1" );
 
  455  if ( snapSettingsElem.hasAttribute( QStringLiteral( 
"mode" ) ) )
 
  456    mMode = 
static_cast< Qgis::SnappingMode >( snapSettingsElem.attribute( QStringLiteral( 
"mode" ) ).toInt() );
 
  458  if ( snapSettingsElem.hasAttribute( QStringLiteral( 
"type" ) ) )
 
  460    const int type = snapSettingsElem.attribute( QStringLiteral( 
"type" ) ).toInt();
 
  461    const QDomElement versionElem = doc.firstChildElement( QStringLiteral( 
"qgis" ) );
 
  463    bool before3_14 = 
false;
 
  464    if ( versionElem.hasAttribute( QStringLiteral( 
"version" ) ) )
 
  466      version = versionElem.attribute( QStringLiteral( 
"version" ) );
 
  467      const thread_local QRegularExpression re( QStringLiteral( 
"([\\d]+)\\.([\\d]+)" ) );
 
  468      const QRegularExpressionMatch match = re.match( version );
 
  469      if ( match.hasMatch() )
 
  471        if ( ( match.captured( 1 ).toInt() <= 3 ) && ( match.captured( 2 ).toInt() <= 12 ) )
 
  501  if ( snapSettingsElem.hasAttribute( QStringLiteral( 
"tolerance" ) ) )
 
  502    mTolerance = snapSettingsElem.attribute( QStringLiteral( 
"tolerance" ) ).toDouble();
 
  504  if ( snapSettingsElem.hasAttribute( QStringLiteral( 
"scaleDependencyMode" ) ) )
 
  507  if ( snapSettingsElem.hasAttribute( QStringLiteral( 
"minScale" ) ) )
 
  508    mMinimumScale = snapSettingsElem.attribute( QStringLiteral( 
"minScale" ) ).toDouble();
 
  510  if ( snapSettingsElem.hasAttribute( QStringLiteral( 
"maxScale" ) ) )
 
  511    mMaximumScale = snapSettingsElem.attribute( QStringLiteral( 
"maxScale" ) ).toDouble();
 
  513  if ( snapSettingsElem.hasAttribute( QStringLiteral( 
"unit" ) ) )
 
  514    mUnits = 
static_cast< Qgis::MapToolUnit >( snapSettingsElem.attribute( QStringLiteral( 
"unit" ) ).toInt() );
 
  516  if ( snapSettingsElem.hasAttribute( QStringLiteral( 
"intersection-snapping" ) ) )
 
  517    mIntersectionSnapping = snapSettingsElem.attribute( QStringLiteral( 
"intersection-snapping" ) ) == QLatin1String( 
"1" );
 
  519  if ( snapSettingsElem.hasAttribute( QStringLiteral( 
"self-snapping" ) ) )
 
  520    mSelfSnapping = snapSettingsElem.attribute( QStringLiteral( 
"self-snapping" ) ) == QLatin1String( 
"1" );
 
  523  const QDomNodeList nodes = snapSettingsElem.elementsByTagName( QStringLiteral( 
"individual-layer-settings" ) );
 
  526    const QDomNode node = nodes.item( 0 );
 
  527    const QDomNodeList settingNodes = node.childNodes();
 
  528    const int layerCount = settingNodes.count();
 
  529    for ( 
int i = 0; i < layerCount; ++i )
 
  531      const QDomElement settingElement = settingNodes.at( i ).toElement();
 
  532      if ( settingElement.tagName() != QLatin1String( 
"layer-setting" ) )
 
  534        QgsLogger::warning( QApplication::translate( 
"QgsProjectSnappingSettings", 
"Cannot read individual settings. Unexpected tag '%1'" ).arg( settingElement.tagName() ) );
 
  538      const QString layerId = settingElement.attribute( QStringLiteral( 
"id" ) );
 
  539      const bool enabled = settingElement.attribute( QStringLiteral( 
"enabled" ) ) == QLatin1String( 
"1" );
 
  541      const double tolerance = settingElement.attribute( QStringLiteral( 
"tolerance" ) ).toDouble();
 
  543      const double minScale = settingElement.attribute( QStringLiteral( 
"minScale" ) ).toDouble();
 
  544      const double maxScale = settingElement.attribute( QStringLiteral( 
"maxScale" ) ).toDouble();
 
  553      mIndividualLayerSettings.insert( vl, setting );
 
 
  560  QDomElement snapSettingsElem = doc.createElement( QStringLiteral( 
"snapping-settings" ) );
 
  561  snapSettingsElem.setAttribute( QStringLiteral( 
"enabled" ), QString::number( mEnabled ) );
 
  562  snapSettingsElem.setAttribute( QStringLiteral( 
"mode" ), 
static_cast<int>( mMode ) );
 
  563  snapSettingsElem.setAttribute( QStringLiteral( 
"type" ), 
static_cast<int>( mType ) );
 
  564  snapSettingsElem.setAttribute( QStringLiteral( 
"tolerance" ), mTolerance );
 
  565  snapSettingsElem.setAttribute( QStringLiteral( 
"unit" ), 
static_cast<int>( mUnits ) );
 
  566  snapSettingsElem.setAttribute( QStringLiteral( 
"intersection-snapping" ), QString::number( mIntersectionSnapping ) );
 
  567  snapSettingsElem.setAttribute( QStringLiteral( 
"self-snapping" ), QString::number( mSelfSnapping ) );
 
  568  snapSettingsElem.setAttribute( QStringLiteral( 
"scaleDependencyMode" ), QString::number( mScaleDependencyMode ) );
 
  569  snapSettingsElem.setAttribute( QStringLiteral( 
"minScale" ), mMinimumScale );
 
  570  snapSettingsElem.setAttribute( QStringLiteral( 
"maxScale" ), mMaximumScale );
 
  572  QDomElement ilsElement = doc.createElement( QStringLiteral( 
"individual-layer-settings" ) );
 
  573  QHash<QgsVectorLayer *, IndividualLayerSettings>::const_iterator layerIt = mIndividualLayerSettings.constBegin();
 
  574  for ( ; layerIt != mIndividualLayerSettings.constEnd(); ++layerIt )
 
  578    QDomElement layerElement = doc.createElement( QStringLiteral( 
"layer-setting" ) );
 
  579    layerElement.setAttribute( QStringLiteral( 
"id" ), layerIt.key()->id() );
 
  580    layerElement.setAttribute( QStringLiteral( 
"enabled" ), QString::number( setting.
enabled() ) );
 
  581    layerElement.setAttribute( QStringLiteral( 
"type" ), 
static_cast<int>( setting.
typeFlag() ) );
 
  582    layerElement.setAttribute( QStringLiteral( 
"tolerance" ), setting.
tolerance() );
 
  583    layerElement.setAttribute( QStringLiteral( 
"units" ), 
static_cast<int>( setting.
units() ) );
 
  584    layerElement.setAttribute( QStringLiteral( 
"minScale" ), setting.
minimumScale() );
 
  585    layerElement.setAttribute( QStringLiteral( 
"maxScale" ), setting.
maximumScale() );
 
  586    ilsElement.appendChild( layerElement );
 
  588  snapSettingsElem.appendChild( ilsElement );
 
  590  doc.firstChildElement( QStringLiteral( 
"qgis" ) ).appendChild( snapSettingsElem );
 
 
  595  bool changed = 
false;
 
  601  const auto constLayers = layers;
 
 
  616  bool changed = 
false;
 
  617  const auto constLayers = layers;
 
  623      mIndividualLayerSettings.remove( vl );
 
 
  630void QgsSnappingConfig::readLegacySettings()
 
  635  const QString snapMode = mProject->
readEntry( QStringLiteral( 
"Digitizing" ), QStringLiteral( 
"/SnappingMode" ) );
 
  637  mTolerance = mProject->
readDoubleEntry( QStringLiteral( 
"Digitizing" ), QStringLiteral( 
"/DefaultSnapTolerance" ), 0 );
 
  640  mIntersectionSnapping = mProject->
readNumEntry( QStringLiteral( 
"Digitizing" ), QStringLiteral( 
"/IntersectionSnapping" ), 0 );
 
  643  const QStringList layerIdList = mProject->
readListEntry( QStringLiteral( 
"Digitizing" ), QStringLiteral( 
"/LayerSnappingList" ), QStringList() );
 
  644  const QStringList enabledList = mProject->
readListEntry( QStringLiteral( 
"Digitizing" ), QStringLiteral( 
"/LayerSnappingEnabledList" ), QStringList() );
 
  645  const QStringList toleranceList = mProject->
readListEntry( QStringLiteral( 
"Digitizing" ), QStringLiteral( 
"/LayerSnappingToleranceList" ), QStringList() );
 
  646  const QStringList toleranceUnitList = mProject->
readListEntry( QStringLiteral( 
"Digitizing" ), QStringLiteral( 
"/LayerSnappingToleranceUnitList" ), QStringList() );
 
  647  const QStringList snapToList = mProject->
readListEntry( QStringLiteral( 
"Digitizing" ), QStringLiteral( 
"/LayerSnapToList" ), QStringList() );
 
  650  if ( layerIdList.size() != enabledList.size() ||
 
  651       layerIdList.size() != toleranceList.size() ||
 
  652       layerIdList.size() != toleranceUnitList.size() ||
 
  653       layerIdList.size() != snapToList.size() )
 
  657  if ( snapMode == QLatin1String( 
"current_layer" ) )
 
  659  else if ( snapMode == QLatin1String( 
"all_layers" ) )
 
  665  QStringList::const_iterator layerIt( layerIdList.constBegin() );
 
  666  QStringList::const_iterator tolIt( toleranceList.constBegin() );
 
  667  QStringList::const_iterator tolUnitIt( toleranceUnitList.constBegin() );
 
  668  QStringList::const_iterator snapIt( snapToList.constBegin() );
 
  669  QStringList::const_iterator enabledIt( enabledList.constBegin() );
 
  670  for ( ; layerIt != layerIdList.constEnd(); ++layerIt, ++tolIt, ++tolUnitIt, ++snapIt, ++enabledIt )
 
  682    mIndividualLayerSettings.insert( vlayer, IndividualLayerSettings( *enabledIt == QLatin1String( 
"enabled" ), t, tolIt->toDouble(), 
static_cast<Qgis::MapToolUnit>( tolUnitIt->toInt() ), 0.0, 0.0 ) );
 
  685  const QString snapType = mProject->
readEntry( QStringLiteral( 
"Digitizing" ), QStringLiteral( 
"/DefaultSnapType" ), QStringLiteral( 
"off" ) );
 
  687  if ( snapType == QLatin1String( 
"to segment" ) )
 
  689  else if ( snapType == QLatin1String( 
"to vertex and segment" ) )
 
  691  else if ( snapType == QLatin1String( 
"to vertex" ) )
 
  716  return mMinimumScale;
 
 
  721  mMinimumScale = minScale;
 
 
  726  return mMaximumScale;
 
 
  731  mMaximumScale = maxScale;
 
 
  736  mScaleDependencyMode = 
mode;
 
 
  741  return mScaleDependencyMode;
 
 
Provides global constants and enumerations for use throughout the application.
 
MapToolUnit
Type of unit of tolerance value from settings.
 
@ Project
Map (project) units.
 
SnappingType
SnappingTypeFlag defines on what object the snapping is performed.
 
@ LineEndpoint
Start or end points of lines, or first vertex in polygon rings only.
 
@ MiddleOfSegment
On Middle segment.
 
QFlags< SnappingType > SnappingTypes
Snapping types.
 
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.
 
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.
 
T valueWithDefaultOverride(const T &defaultValueOverride, const QString &dynamicKeyPart=QString()) const
Returns the settings value with a defaultValueOverride and with an optional dynamicKeyPart.
 
T value(const QString &dynamicKeyPart=QString()) const
Returns settings value.
 
static const QgsSettingsEntryBool * settingsDigitizingDefaultSnapEnabled
Settings entry digitizing default snap enabled.
 
static const QgsSettingsEntryEnumFlag< Qgis::MapToolUnit > * settingsDigitizingDefaultSnappingToleranceUnit
Settings entry digitizing default snapping tolerance unit.
 
static const QgsSettingsEntryDouble * settingsDigitizingDefaultSnappingTolerance
Settings entry digitizing default snapping tolerance.
 
static const QgsSettingsEntryEnumFlag< Qgis::SnappingMode > * settingsDigitizingDefaultSnapMode
Settings entry digitizing default snap type.
 
static const QgsSettingsEntryEnumFlag< Qgis::SnappingType > * settingsDigitizingDefaultSnapType
Settings entry digitizing default snap type.
 
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
 
bool operator!=(const QgsSnappingConfig::IndividualLayerSettings &other) const
 
void setTypeFlag(Qgis::SnappingTypes type)
define the type of snapping
 
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.
 
void setMinimumScale(double minScale)
Sets the min scale value on which snapping is used, 0.0 disable scale limit.
 
Qgis::MapToolUnit units() const
Returns the type of units.
 
void setMaximumScale(double maxScale)
Sets the max scale value on which snapping is used, 0.0 disable scale limit.
 
Q_DECL_DEPRECATED void setType(SnappingType type)
define the type of snapping
 
bool enabled() const
Returns if snapping is enabled.
 
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.
 
void setUnits(Qgis::MapToolUnit units)
Sets the type of units.
 
Qgis::SnappingTypes typeFlag() const
Returns the flags type (vertices | segments | area | centroid | middle)
 
void setTolerance(double tolerance)
Sets the tolerance.
 
Stores configuration of snapping settings for the project.
 
bool addLayers(const QList< QgsMapLayer * > &layers)
Adds the specified layers as individual layers to the configuration with standard configuration.
 
void readProject(const QDomDocument &doc)
Reads the configuration from the specified QGIS project document.
 
void 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.
 
void setUnits(Qgis::MapToolUnit units)
Sets the type of units.
 
bool intersectionSnapping() const
Returns if the snapping on intersection is enabled.
 
ScaleDependencyMode
ScaleDependencyMode the scale dependency mode of snapping.
 
@ Disabled
No scale dependency.
 
void setTypeFlag(Qgis::SnappingTypes type)
define the type of snapping
 
double minimumScale() const
Returns the min scale (i.e.
 
double tolerance() const
Returns the tolerance.
 
void setMode(Qgis::SnappingMode mode)
define the mode of snapping
 
static QIcon snappingTypeToIcon(Qgis::SnappingType type)
Convenient method to return an icon corresponding to the enum type Qgis::SnappingTypes.
 
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.
 
Qgis::SnappingTypes typeFlag() const
Returns the flags type (vertices | segments | area | centroid | middle)
 
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.
 
static QString snappingTypeToString(Qgis::SnappingType type)
Convenient method to returns the translated name of the enum type Qgis::SnappingTypes.
 
Qgis::MapToolUnit units() const
Returns the type of units.
 
bool operator!=(const QgsSnappingConfig &other) const
 
bool operator==(const QgsSnappingConfig &other) const
 
SnappingType
SnappingType defines on what object the snapping is performed.
 
@ VertexAndSegment
Both on vertices and segments.
 
@ Vertex
On vertices only.
 
@ Segment
On segments only.
 
void setSelfSnapping(bool enabled)
Sets if self snapping (snapping to the currently digitized feature) is enabled.
 
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
 
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.
 
Represents a vector layer which manages a vector based dataset.
 
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