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...
#define Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_PUSH