QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
qgssnappingconfig.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsprojectsnappingsettings.cpp - QgsProjectSnappingSettings
3 
4  ---------------------
5  begin : 29.8.2016
6  copyright : (C) 2016 by Denis Rouzaud
7  email : [email protected]
8  ***************************************************************************
9  * *
10  * This program is free software; you can redistribute it and/or modify *
11  * it under the terms of the GNU General Public License as published by *
12  * the Free Software Foundation; either version 2 of the License, or *
13  * (at your option) any later version. *
14  * *
15  ***************************************************************************/
16 #include "qgssnappingconfig.h"
17 
18 #include <QDomElement>
19 #include <QHeaderView>
20 #include <QRegularExpression>
21 
22 #include "qgssettings.h"
23 #include "qgslogger.h"
24 #include "qgsvectorlayer.h"
25 #include "qgsproject.h"
26 #include "qgsapplication.h"
27 
28 
29 QgsSnappingConfig::IndividualLayerSettings::IndividualLayerSettings( bool enabled, SnappingTypeFlag type, double tolerance, QgsTolerance::UnitType units, double minScale, double maxScale )
30  : mValid( true )
31  , mEnabled( enabled )
32  , mType( type )
33  , mTolerance( tolerance )
34  , mUnits( units )
35  , mMinimumScale( minScale )
36  , mMaximumScale( maxScale )
37 {}
38 
40  : mValid( true )
41  , mEnabled( enabled )
42  , mTolerance( tolerance )
43  , mUnits( units )
44 {
46  setType( type );
48 }
49 
51 {
52  return mValid;
53 }
54 
56 {
57  return mEnabled;
58 }
59 
61 {
62  mEnabled = enabled;
63 }
64 
65 QgsSnappingConfig::SnappingTypeFlag QgsSnappingConfig::IndividualLayerSettings::typeFlag() const
66 {
67  return mType;
68 }
69 
71 {
72 
73  if ( ( mType & SegmentFlag ) && ( mType & VertexFlag ) )
74  return QgsSnappingConfig::SnappingType::VertexAndSegment;
75  else if ( mType & SegmentFlag )
76  return QgsSnappingConfig::SnappingType::Segment;
77  else
78  return QgsSnappingConfig::SnappingType::Vertex;
79 
80 }
81 
83 {
84  switch ( type )
85  {
86  case 1:
87  mType = VertexFlag;
88  break;
89  case 2:
90  mType = VertexFlag | SegmentFlag;
91  break;
92  case 3:
93  mType = SegmentFlag;
94  break;
95  default:
96  mType = NoSnapFlag;
97  break;
98  }
99 }
100 void QgsSnappingConfig::IndividualLayerSettings::setTypeFlag( QgsSnappingConfig::SnappingTypeFlag type )
101 {
102  mType = type;
103 }
104 
106 {
107  return mTolerance;
108 }
109 
111 {
112  mTolerance = tolerance;
113 }
114 
116 {
117  return mUnits;
118 }
119 
121 {
122  mUnits = units;
123 }
124 
126 {
127  return mMinimumScale;
128 }
129 
131 {
132  mMinimumScale = minScale;
133 }
134 
136 {
137  return mMaximumScale;
138 }
139 
141 {
142  mMaximumScale = maxScale;
143 }
144 
146 {
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;
154 }
155 
157 {
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;
165 }
166 
167 
169  : mProject( project )
170 {
171  if ( project )
172  reset();
173 }
174 
176 {
177  return mEnabled == other.mEnabled
178  && mMode == other.mMode
179  && mType == other.mType
180  && mTolerance == other.mTolerance
181  && mUnits == other.mUnits
182  && mIntersectionSnapping == other.mIntersectionSnapping
183  && mSelfSnapping == other.mSelfSnapping
184  && mIndividualLayerSettings == other.mIndividualLayerSettings
185  && mScaleDependencyMode == other.mScaleDependencyMode
186  && mMinimumScale == other.mMinimumScale
187  && mMaximumScale == other.mMaximumScale;
188 }
189 
191 {
192  // get defaults values. They are both used for standard and advanced configuration (per layer)
193  bool enabled = QgsSettings().value( QStringLiteral( "/qgis/digitizing/default_snap_enabled" ), false ).toBool();
194  SnappingMode mode = QgsSettings().enumValue( QStringLiteral( "/qgis/digitizing/default_snap_mode" ), AllLayers );
195  if ( mode == 0 )
196  {
197  // backward compatibility with QGIS 2.x
198  // could be removed in 3.4+
199  mode = AllLayers;
200  }
201  QgsSnappingConfig::SnappingTypeFlag type = QgsSettings().flagValue( QStringLiteral( "/qgis/digitizing/default_snap_type" ), VertexFlag );
202  double tolerance = QgsSettings().value( QStringLiteral( "/qgis/digitizing/default_snapping_tolerance" ), Qgis::DEFAULT_SNAP_TOLERANCE ).toDouble();
203  QgsTolerance::UnitType units = QgsSettings().enumValue( QStringLiteral( "/qgis/digitizing/default_snapping_tolerance_unit" ), Qgis::DEFAULT_SNAP_UNITS );
204 
205  // assign main (standard) config
206  mEnabled = enabled;
207  mMode = mode;
208  mType = type;
209  mTolerance = tolerance;
210  mScaleDependencyMode = Disabled;
211  mMinimumScale = 0.0;
212  mMaximumScale = 0.0;
213  // do not allow unit to be "layer" if not in advanced configuration
214  if ( mUnits == QgsTolerance::LayerUnits && mMode != AdvancedConfiguration )
215  {
217  }
218  else
219  {
220  mUnits = units;
221  }
222  mIntersectionSnapping = false;
223  mSelfSnapping = false;
224 
225  // set advanced config
226  if ( mProject )
227  {
228  mIndividualLayerSettings = QHash<QgsVectorLayer *, IndividualLayerSettings>();
229  const auto constMapLayers = mProject->mapLayers();
230  for ( QgsMapLayer *ml : constMapLayers )
231  {
232  QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( ml );
233  if ( vl )
234  {
235  mIndividualLayerSettings.insert( vl, IndividualLayerSettings( enabled, type, tolerance, units, 0.0, 0.0 ) );
236  }
237  }
238  }
239 }
240 
242 {
243  return mEnabled;
244 }
245 
246 void QgsSnappingConfig::setEnabled( bool enabled )
247 {
248  if ( mEnabled == enabled )
249  {
250  return;
251  }
252  mEnabled = enabled;
253 }
254 
256 {
257  return mMode;
258 }
259 
261 {
262  if ( mMode == mode )
263  {
264  return;
265  }
266  mMode = mode;
267 }
268 
269 QgsSnappingConfig::SnappingTypeFlag QgsSnappingConfig::typeFlag() const
270 {
271  return mType;
272 }
273 
275 {
276  if ( ( mType & SegmentFlag ) && ( mType & VertexFlag ) )
277  return QgsSnappingConfig::SnappingType::VertexAndSegment;
278  else if ( mType & SegmentFlag )
279  return QgsSnappingConfig::SnappingType::Segment;
280  else
281  return QgsSnappingConfig::SnappingType::Vertex;
282 }
283 
285 {
286  switch ( type )
287  {
288  case SnappingType::Vertex:
289  mType = VertexFlag;
290  break;
291  case SnappingType::VertexAndSegment:
292  mType = static_cast<QgsSnappingConfig::SnappingTypeFlag>( QgsSnappingConfig::VertexFlag | QgsSnappingConfig::SegmentFlag );
293  break;
294  case SnappingType::Segment:
295  mType = SegmentFlag;
296  break;
297  default:
298  mType = NoSnapFlag;
299  break;
300  }
301 }
302 void QgsSnappingConfig::setTypeFlag( QgsSnappingConfig::SnappingTypeFlag type )
303 {
304  if ( mType == type )
305  {
306  return;
307  }
308  mType = type;
309 }
310 
312 {
313  return mTolerance;
314 }
315 
316 void QgsSnappingConfig::setTolerance( double tolerance )
317 {
318  if ( mTolerance == tolerance )
319  {
320  return;
321  }
322  mTolerance = tolerance;
323 }
324 
326 {
327  return mUnits;
328 }
329 
331 {
332  if ( mUnits == units )
333  {
334  return;
335  }
336  mUnits = units;
337 }
338 
340 {
341  return mIntersectionSnapping;
342 }
343 
345 {
346  mIntersectionSnapping = enabled;
347 }
348 
350 {
351  return mSelfSnapping;
352 }
353 
355 {
356  mSelfSnapping = enabled;
357 }
358 
359 QHash<QgsVectorLayer *, QgsSnappingConfig::IndividualLayerSettings> QgsSnappingConfig::individualLayerSettings() const
360 {
361  return mIndividualLayerSettings;
362 }
363 
365 {
366  if ( vl && mIndividualLayerSettings.contains( vl ) )
367  {
368  return mIndividualLayerSettings.value( vl );
369  }
370  else
371  {
372  // return invalid settings
373  return IndividualLayerSettings();
374  }
375 }
376 
378 {
379  mIndividualLayerSettings.clear();
380 }
381 
383 {
384  if ( !vl || !vl->isSpatial() || mIndividualLayerSettings.value( vl ) == individualLayerSettings )
385  {
386  return;
387  }
388  mIndividualLayerSettings.insert( vl, individualLayerSettings );
389 }
390 
392 {
393  return mEnabled != other.mEnabled
394  || mMode != other.mMode
395  || mType != other.mType
396  || mTolerance != other.mTolerance
397  || mUnits != other.mUnits
398  || mIndividualLayerSettings != other.mIndividualLayerSettings
399  || mScaleDependencyMode != other.mScaleDependencyMode
400  || mMinimumScale != other.mMinimumScale
401  || mMaximumScale != other.mMaximumScale;
402 }
403 
404 void QgsSnappingConfig::readProject( const QDomDocument &doc )
405 {
406  QDomElement snapSettingsElem = doc.firstChildElement( QStringLiteral( "qgis" ) ).firstChildElement( QStringLiteral( "snapping-settings" ) );
407  if ( snapSettingsElem.isNull() )
408  {
409  readLegacySettings();
410  return;
411  }
412 
413  if ( snapSettingsElem.hasAttribute( QStringLiteral( "enabled" ) ) )
414  mEnabled = snapSettingsElem.attribute( QStringLiteral( "enabled" ) ) == QLatin1String( "1" );
415 
416  if ( snapSettingsElem.hasAttribute( QStringLiteral( "mode" ) ) )
417  mMode = ( SnappingMode )snapSettingsElem.attribute( QStringLiteral( "mode" ) ).toInt();
418 
419  if ( snapSettingsElem.hasAttribute( QStringLiteral( "type" ) ) )
420  {
421  int type = snapSettingsElem.attribute( QStringLiteral( "type" ) ).toInt();
422  QDomElement versionElem = doc.firstChildElement( QStringLiteral( "qgis" ) );
423  QString version;
424  bool before3_14 = false;
425  if ( versionElem.hasAttribute( QStringLiteral( "version" ) ) )
426  {
427  version = versionElem.attribute( QStringLiteral( "version" ) );
428  QRegularExpression re( "([\\d]+)\\.([\\d]+)" );
429  QRegularExpressionMatch match = re.match( version );
430  if ( match.hasMatch() )
431  {
432  if ( ( match.captured( 1 ).toInt() <= 3 ) && ( match.captured( 2 ).toInt() <= 12 ) )
433  before3_14 = true;
434  }
435  }
436  if ( before3_14 )
437  {
438  // BEFORE 3.12:
439  // 1 = vertex
440  // 2 = vertexandsegment
441  // 3 = segment
442  switch ( type )
443  {
444  case 1:
445  mType = VertexFlag;
446  break;
447  case 2:
448  mType = static_cast<QgsSnappingConfig::SnappingTypeFlag>( QgsSnappingConfig::VertexFlag | QgsSnappingConfig::SegmentFlag );
449  break;
450  case 3:
451  mType = SegmentFlag;
452  break;
453  default:
454  mType = NoSnapFlag;
455  break;
456  }
457  }
458  else
459  mType = static_cast<QgsSnappingConfig::SnappingTypeFlag>( type );
460  }
461 
462  if ( snapSettingsElem.hasAttribute( QStringLiteral( "tolerance" ) ) )
463  mTolerance = snapSettingsElem.attribute( QStringLiteral( "tolerance" ) ).toDouble();
464 
465  if ( snapSettingsElem.hasAttribute( QStringLiteral( "scaleDependencyMode" ) ) )
466  mScaleDependencyMode = static_cast<QgsSnappingConfig::ScaleDependencyMode>( snapSettingsElem.attribute( QStringLiteral( "scaleDependencyMode" ) ).toInt() );
467 
468  if ( snapSettingsElem.hasAttribute( QStringLiteral( "minScale" ) ) )
469  mMinimumScale = snapSettingsElem.attribute( QStringLiteral( "minScale" ) ).toDouble();
470 
471  if ( snapSettingsElem.hasAttribute( QStringLiteral( "maxScale" ) ) )
472  mMaximumScale = snapSettingsElem.attribute( QStringLiteral( "maxScale" ) ).toDouble();
473 
474  if ( snapSettingsElem.hasAttribute( QStringLiteral( "unit" ) ) )
475  mUnits = ( QgsTolerance::UnitType )snapSettingsElem.attribute( QStringLiteral( "unit" ) ).toInt();
476 
477  if ( snapSettingsElem.hasAttribute( QStringLiteral( "intersection-snapping" ) ) )
478  mIntersectionSnapping = snapSettingsElem.attribute( QStringLiteral( "intersection-snapping" ) ) == QLatin1String( "1" );
479 
480  if ( snapSettingsElem.hasAttribute( QStringLiteral( "self-snapping" ) ) )
481  mSelfSnapping = snapSettingsElem.attribute( QStringLiteral( "self-snapping" ) ) == QLatin1String( "1" );
482 
483  // do not clear the settings as they must be automatically synchronized with current layers
484  QDomNodeList nodes = snapSettingsElem.elementsByTagName( QStringLiteral( "individual-layer-settings" ) );
485  if ( nodes.count() )
486  {
487  QDomNode node = nodes.item( 0 );
488  QDomNodeList settingNodes = node.childNodes();
489  int layerCount = settingNodes.count();
490  for ( int i = 0; i < layerCount; ++i )
491  {
492  QDomElement settingElement = settingNodes.at( i ).toElement();
493  if ( settingElement.tagName() != QLatin1String( "layer-setting" ) )
494  {
495  QgsLogger::warning( QApplication::translate( "QgsProjectSnappingSettings", "Cannot read individual settings. Unexpected tag '%1'" ).arg( settingElement.tagName() ) );
496  continue;
497  }
498 
499  QString layerId = settingElement.attribute( QStringLiteral( "id" ) );
500  bool enabled = settingElement.attribute( QStringLiteral( "enabled" ) ) == QLatin1String( "1" );
501  QgsSnappingConfig::SnappingTypeFlag type = static_cast<QgsSnappingConfig::SnappingTypeFlag>( settingElement.attribute( QStringLiteral( "type" ) ).toInt() );
502  double tolerance = settingElement.attribute( QStringLiteral( "tolerance" ) ).toDouble();
503  QgsTolerance::UnitType units = ( QgsTolerance::UnitType )settingElement.attribute( QStringLiteral( "units" ) ).toInt();
504  double minScale = settingElement.attribute( QStringLiteral( "minScale" ) ).toDouble();
505  double maxScale = settingElement.attribute( QStringLiteral( "maxScale" ) ).toDouble();
506 
507  QgsMapLayer *ml = mProject->mapLayer( layerId );
508  if ( !ml || ml->type() != QgsMapLayerType::VectorLayer )
509  continue;
510 
511  QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( ml );
512 
513  IndividualLayerSettings setting = IndividualLayerSettings( enabled, type, tolerance, units, minScale, maxScale );
514  mIndividualLayerSettings.insert( vl, setting );
515  }
516  }
517 }
518 
519 void QgsSnappingConfig::writeProject( QDomDocument &doc )
520 {
521  QDomElement snapSettingsElem = doc.createElement( QStringLiteral( "snapping-settings" ) );
522  snapSettingsElem.setAttribute( QStringLiteral( "enabled" ), QString::number( mEnabled ) );
523  snapSettingsElem.setAttribute( QStringLiteral( "mode" ), static_cast<int>( mMode ) );
524  snapSettingsElem.setAttribute( QStringLiteral( "type" ), static_cast<int>( mType ) );
525  snapSettingsElem.setAttribute( QStringLiteral( "tolerance" ), mTolerance );
526  snapSettingsElem.setAttribute( QStringLiteral( "unit" ), static_cast<int>( mUnits ) );
527  snapSettingsElem.setAttribute( QStringLiteral( "intersection-snapping" ), QString::number( mIntersectionSnapping ) );
528  snapSettingsElem.setAttribute( QStringLiteral( "self-snapping" ), QString::number( mSelfSnapping ) );
529  snapSettingsElem.setAttribute( QStringLiteral( "scaleDependencyMode" ), QString::number( mScaleDependencyMode ) );
530  snapSettingsElem.setAttribute( QStringLiteral( "minScale" ), mMinimumScale );
531  snapSettingsElem.setAttribute( QStringLiteral( "maxScale" ), mMaximumScale );
532 
533  QDomElement ilsElement = doc.createElement( QStringLiteral( "individual-layer-settings" ) );
534  QHash<QgsVectorLayer *, IndividualLayerSettings>::const_iterator layerIt = mIndividualLayerSettings.constBegin();
535  for ( ; layerIt != mIndividualLayerSettings.constEnd(); ++layerIt )
536  {
537  const IndividualLayerSettings &setting = layerIt.value();
538 
539  QDomElement layerElement = doc.createElement( QStringLiteral( "layer-setting" ) );
540  layerElement.setAttribute( QStringLiteral( "id" ), layerIt.key()->id() );
541  layerElement.setAttribute( QStringLiteral( "enabled" ), QString::number( setting.enabled() ) );
542  layerElement.setAttribute( QStringLiteral( "type" ), static_cast<int>( setting.typeFlag() ) );
543  layerElement.setAttribute( QStringLiteral( "tolerance" ), setting.tolerance() );
544  layerElement.setAttribute( QStringLiteral( "units" ), static_cast<int>( setting.units() ) );
545  layerElement.setAttribute( QStringLiteral( "minScale" ), setting.minimumScale() );
546  layerElement.setAttribute( QStringLiteral( "maxScale" ), setting.maximumScale() );
547  ilsElement.appendChild( layerElement );
548  }
549  snapSettingsElem.appendChild( ilsElement );
550 
551  doc.firstChildElement( QStringLiteral( "qgis" ) ).appendChild( snapSettingsElem );
552 }
553 
554 bool QgsSnappingConfig::addLayers( const QList<QgsMapLayer *> &layers )
555 {
556  bool changed = false;
557  bool enabled = QgsSettings().value( QStringLiteral( "/qgis/digitizing/default_snap_enabled" ), true ).toBool();
558  QgsSnappingConfig::SnappingTypeFlag type = QgsSettings().enumValue( QStringLiteral( "/qgis/digitizing/default_snap_type" ), VertexFlag );
559  double tolerance = QgsSettings().value( QStringLiteral( "/qgis/digitizing/default_snapping_tolerance" ), Qgis::DEFAULT_SNAP_TOLERANCE ).toDouble();
560  QgsTolerance::UnitType units = QgsSettings().enumValue( QStringLiteral( "/qgis/digitizing/default_snapping_tolerance_unit" ), Qgis::DEFAULT_SNAP_UNITS );
561 
562  const auto constLayers = layers;
563  for ( QgsMapLayer *ml : constLayers )
564  {
565  QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( ml );
566  if ( vl && vl->isSpatial() )
567  {
568  mIndividualLayerSettings.insert( vl, IndividualLayerSettings( enabled, type, tolerance, units, 0.0, 0.0 ) );
569  changed = true;
570  }
571  }
572  return changed;
573 }
574 
575 bool QgsSnappingConfig::removeLayers( const QList<QgsMapLayer *> &layers )
576 {
577  bool changed = false;
578  const auto constLayers = layers;
579  for ( QgsMapLayer *ml : constLayers )
580  {
581  QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( ml );
582  if ( vl )
583  {
584  mIndividualLayerSettings.remove( vl );
585  changed = true;
586  }
587  }
588  return changed;
589 }
590 
591 void QgsSnappingConfig::readLegacySettings()
592 {
593  //
594  mMode = ActiveLayer;
595 
596  QString snapMode = mProject->readEntry( QStringLiteral( "Digitizing" ), QStringLiteral( "/SnappingMode" ) );
597 
598  mTolerance = mProject->readDoubleEntry( QStringLiteral( "Digitizing" ), QStringLiteral( "/DefaultSnapTolerance" ), 0 );
599  mUnits = static_cast< QgsTolerance::UnitType >( mProject->readNumEntry( QStringLiteral( "Digitizing" ), QStringLiteral( "/DefaultSnapToleranceUnit" ), QgsTolerance::ProjectUnits ) );
600 
601  mIntersectionSnapping = mProject->readNumEntry( QStringLiteral( "Digitizing" ), QStringLiteral( "/IntersectionSnapping" ), 0 );
602 
603  //read snapping settings from project
604  QStringList layerIdList = mProject->readListEntry( QStringLiteral( "Digitizing" ), QStringLiteral( "/LayerSnappingList" ), QStringList() );
605  QStringList enabledList = mProject->readListEntry( QStringLiteral( "Digitizing" ), QStringLiteral( "/LayerSnappingEnabledList" ), QStringList() );
606  QStringList toleranceList = mProject->readListEntry( QStringLiteral( "Digitizing" ), QStringLiteral( "/LayerSnappingToleranceList" ), QStringList() );
607  QStringList toleranceUnitList = mProject->readListEntry( QStringLiteral( "Digitizing" ), QStringLiteral( "/LayerSnappingToleranceUnitList" ), QStringList() );
608  QStringList snapToList = mProject->readListEntry( QStringLiteral( "Digitizing" ), QStringLiteral( "/LayerSnapToList" ), QStringList() );
609 
610  // lists must have the same size, otherwise something is wrong
611  if ( layerIdList.size() != enabledList.size() ||
612  layerIdList.size() != toleranceList.size() ||
613  layerIdList.size() != toleranceUnitList.size() ||
614  layerIdList.size() != snapToList.size() )
615  return;
616 
617  // Use snapping information from the project
618  if ( snapMode == QLatin1String( "current_layer" ) )
619  mMode = ActiveLayer;
620  else if ( snapMode == QLatin1String( "all_layers" ) )
621  mMode = AllLayers;
622  else // either "advanced" or empty (for background compatibility)
623  mMode = AdvancedConfiguration;
624 
625  // load layers, tolerances, snap type
626  QStringList::const_iterator layerIt( layerIdList.constBegin() );
627  QStringList::const_iterator tolIt( toleranceList.constBegin() );
628  QStringList::const_iterator tolUnitIt( toleranceUnitList.constBegin() );
629  QStringList::const_iterator snapIt( snapToList.constBegin() );
630  QStringList::const_iterator enabledIt( enabledList.constBegin() );
631  for ( ; layerIt != layerIdList.constEnd(); ++layerIt, ++tolIt, ++tolUnitIt, ++snapIt, ++enabledIt )
632  {
633  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mProject->mapLayer( *layerIt ) );
634  if ( !vlayer || !vlayer->isSpatial() )
635  continue;
636 
637  QgsSnappingConfig::SnappingTypeFlag t( *snapIt == QLatin1String( "to_vertex" ) ? VertexFlag :
638  ( *snapIt == QLatin1String( "to_segment" ) ? SegmentFlag :
639  static_cast<QgsSnappingConfig::SnappingTypeFlag>( QgsSnappingConfig::VertexFlag | QgsSnappingConfig::SegmentFlag )
640  )
641  );
642 
643  mIndividualLayerSettings.insert( vlayer, IndividualLayerSettings( *enabledIt == QLatin1String( "enabled" ), t, tolIt->toDouble(), static_cast<QgsTolerance::UnitType>( tolUnitIt->toInt() ), 0.0, 0.0 ) );
644  }
645 
646  QString snapType = mProject->readEntry( QStringLiteral( "Digitizing" ), QStringLiteral( "/DefaultSnapType" ), QStringLiteral( "off" ) );
647  mEnabled = true;
648  if ( snapType == QLatin1String( "to segment" ) )
649  mType = SegmentFlag;
650  else if ( snapType == QLatin1String( "to vertex and segment" ) )
651  mType = static_cast<QgsSnappingConfig::SnappingTypeFlag>( QgsSnappingConfig::VertexFlag | QgsSnappingConfig::SegmentFlag );
652  else if ( snapType == QLatin1String( "to vertex" ) )
653  mType = VertexFlag;
654  else if ( mMode != AdvancedConfiguration ) // Type is off but mode is advanced
655  {
656  mEnabled = false;
657  }
658 }
659 
661 {
662  return mProject;
663 }
664 
666 {
667  if ( mProject != project )
668  mProject = project;
669 
670  reset();
671 }
672 
674 {
675  return mMinimumScale;
676 }
677 
678 void QgsSnappingConfig::setMinimumScale( double minScale )
679 {
680  mMinimumScale = minScale;
681 }
682 
684 {
685  return mMaximumScale;
686 }
687 
688 void QgsSnappingConfig::setMaximumScale( double maxScale )
689 {
690  mMaximumScale = maxScale;
691 }
692 
694 {
695  mScaleDependencyMode = mode;
696 }
697 
699 {
700  return mScaleDependencyMode;
701 }
702 
703 
704 
705 
706 
static const double DEFAULT_SNAP_TOLERANCE
Default snapping distance tolerance.
Definition: qgis.h:189
static const QgsTolerance::UnitType DEFAULT_SNAP_UNITS
Default snapping distance units.
Definition: qgis.h:195
static void warning(const QString &msg)
Goes to qWarning.
Definition: qgslogger.cpp:122
Base class for all map layer types.
Definition: qgsmaplayer.h:85
QgsMapLayerType type
Definition: qgsmaplayer.h:92
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:99
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 class is a composition of two QSettings instances:
Definition: qgssettings.h:62
T flagValue(const QString &key, const T &defaultValue, const Section section=NoSection)
Returns the setting value for a setting based on a flag.
Definition: qgssettings.h:330
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
T enumValue(const QString &key, const T &defaultValue, const Section section=NoSection)
Returns the setting value for a setting based on an enum.
Definition: qgssettings.h:252
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.
@ SegmentFlag
On segments.
@ NoSnapFlag
No snapping.
@ VertexFlag
On vertices.
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)
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.
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.
Definition: qgstolerance.h:42
@ ProjectUnits
Map (project) units. Added in 2.8.
Definition: qgstolerance.h:48
@ LayerUnits
Layer unit value.
Definition: qgstolerance.h:44
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
Definition: qgis.h:798
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:797