Branch data Line data Source code
1 : : /***************************************************************************
2 : : qgssnappingconfig.h - QgsSnappingConfig
3 : :
4 : : ---------------------
5 : : begin : 29.8.2016
6 : : copyright : (C) 2016 by Denis Rouzaud
7 : : email : denis.rouzaud@gmail.com
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 : : #ifndef QGSPROJECTSNAPPINGSETTINGS_H
17 : : #define QGSPROJECTSNAPPINGSETTINGS_H
18 : :
19 : : #include <QHash>
20 : : #include "qgis_core.h"
21 : : #include "qgstolerance.h"
22 : :
23 : : class QDomDocument;
24 : : class QgsProject;
25 : : class QgsVectorLayer;
26 : :
27 : :
28 : : /**
29 : : * \ingroup core
30 : : * \brief This is a container for configuration of the snapping of the project
31 : : * \since QGIS 3.0
32 : : */
33 : 0 : class CORE_EXPORT QgsSnappingConfig
34 : : {
35 : : Q_GADGET
36 : :
37 : : Q_PROPERTY( QgsProject *project READ project WRITE setProject )
38 : :
39 : : public:
40 : :
41 : : /**
42 : : * SnappingMode defines on which layer the snapping is performed
43 : : */
44 : : enum SnappingMode
45 : : {
46 : : ActiveLayer = 1, //!< On the active layer
47 : : AllLayers = 2, //!< On all vector layers
48 : : AdvancedConfiguration = 3, //!< On a per layer configuration basis
49 : : };
50 : 26 : Q_ENUM( SnappingMode )
51 : :
52 : : /**
53 : : * SnappingType defines on what object the snapping is performed
54 : : * \deprecated since QGIS 3.12 use SnappingTypeFlag instead.
55 : : */
56 : : enum SnappingType
57 : : {
58 : : Vertex = 1, //!< On vertices only
59 : : VertexAndSegment = 2, //!< Both on vertices and segments
60 : : Segment = 3, //!< On segments only
61 : : };
62 : : // TODO QGIS 4: remove
63 : : // this could not be tagged with Q_DECL_DEPRECATED due to Doxygen warning
64 : : // might be fixed in newer Doxygen (does not on 1.8.15, might be ok on 1.8.16)
65 : :
66 : : /**
67 : : * SnappingTypeFlag defines on what object the snapping is performed
68 : : * \since QGIS 3.12
69 : : */
70 : : enum SnappingTypes
71 : : {
72 : : NoSnapFlag = 0, //!< No snapping
73 : : VertexFlag = 1 << 0, //!< On vertices
74 : : SegmentFlag = 1 << 1, //!< On segments
75 : : AreaFlag = 1 << 2, //!< On Area
76 : : CentroidFlag = 1 << 3, //!< On centroid
77 : : MiddleOfSegmentFlag = 1 << 4, //!< On Middle segment
78 : : LineEndpointFlag = 1 << 5, //!< Start or end points of lines, or first vertex in polygon rings only (since QGIS 3.20)
79 : : };
80 : 28 : Q_ENUM( SnappingTypes )
81 : : Q_DECLARE_FLAGS( SnappingTypeFlag, SnappingTypes )
82 : : Q_FLAG( SnappingTypeFlag )
83 : :
84 : : /**
85 : : * ScaleDependencyMode the scale dependency mode of snapping
86 : : * \since QGIS 3.14
87 : : */
88 : : enum ScaleDependencyMode
89 : : {
90 : : Disabled = 0,//!< No scale dependency
91 : : Global = 1,//!< Scale dependency using global min max range
92 : : PerLayer = 2//!< Scale dependency using min max range per layer
93 : : };
94 : : Q_ENUM( ScaleDependencyMode )
95 : :
96 : : /**
97 : : * Convenient method to returns the translated name of the enum type
98 : : * QgsSnappingConfig::SnappingTypeFlag.
99 : : *
100 : : * \since QGIS 3.12
101 : : */
102 : : static QString snappingTypeFlagToString( SnappingTypeFlag type );
103 : :
104 : : /**
105 : : * Convenient method to return an icon corresponding to the enum type
106 : : * QgsSnappingConfig::SnappingTypeFlag.
107 : : *
108 : : * \since QGIS 3.20
109 : : */
110 : : static QIcon snappingTypeFlagToIcon( SnappingTypeFlag type );
111 : :
112 : : /**
113 : : * \ingroup core
114 : : * \brief This is a container of advanced configuration (per layer) of the snapping of the project
115 : : * \since QGIS 3.0
116 : : */
117 : : class CORE_EXPORT IndividualLayerSettings
118 : : {
119 : : public:
120 : :
121 : : /**
122 : : * \brief IndividualLayerSettings
123 : : * \param enabled
124 : : * \param type
125 : : * \param tolerance
126 : : * \param units
127 : : * \deprecated since QGIS 3.12 use the method with SnappingTypeFlag instead.
128 : : */
129 : : Q_DECL_DEPRECATED IndividualLayerSettings( bool enabled, SnappingType type, double tolerance, QgsTolerance::UnitType units ) SIP_DEPRECATED;
130 : :
131 : : /**
132 : : * \brief IndividualLayerSettings
133 : : * \param enabled
134 : : * \param type
135 : : * \param tolerance
136 : : * \param units
137 : : * \param minScale 0.0 disable scale limit
138 : : * \param maxScale 0.0 disable scale limit
139 : : * \since QGIS 3.12
140 : : */
141 : : IndividualLayerSettings( bool enabled, SnappingTypeFlag type, double tolerance, QgsTolerance::UnitType units, double minScale = 0.0, double maxScale = 0.0 );
142 : :
143 : : /**
144 : : * Constructs an invalid setting
145 : : */
146 : 0 : IndividualLayerSettings() = default;
147 : :
148 : : //! Returns if settings are valid
149 : : bool valid() const;
150 : :
151 : : //! Returns if snapping is enabled
152 : : bool enabled() const;
153 : :
154 : : //! enables the snapping
155 : : void setEnabled( bool enabled );
156 : :
157 : : /**
158 : : * Returns the flags type (vertices | segments | area | centroid | middle)
159 : : * \since QGIS 3.12
160 : : */
161 : : QgsSnappingConfig::SnappingTypeFlag typeFlag() const;
162 : :
163 : : /**
164 : : * Returns the flags type (vertices | segments | area | centroid | middle)
165 : : * \deprecated since QGIS 3.12 use typeFlag instead.
166 : : */
167 : : Q_DECL_DEPRECATED QgsSnappingConfig::SnappingType type() const SIP_DEPRECATED;
168 : :
169 : : /**
170 : : * define the type of snapping
171 : : * \deprecated since QGIS 3.12 use setTypeFlag instead.
172 : : */
173 : : Q_DECL_DEPRECATED void setType( QgsSnappingConfig::SnappingType type ) SIP_DEPRECATED;
174 : :
175 : : /**
176 : : * define the type of snapping
177 : : * \since QGIS 3.12
178 : : */
179 : : void setTypeFlag( QgsSnappingConfig::SnappingTypeFlag type );
180 : :
181 : : //! Returns the tolerance
182 : : double tolerance() const;
183 : :
184 : : //! Sets the tolerance
185 : : void setTolerance( double tolerance );
186 : :
187 : : //! Returns the type of units
188 : : QgsTolerance::UnitType units() const;
189 : :
190 : : //! Sets the type of units
191 : : void setUnits( QgsTolerance::UnitType units );
192 : :
193 : : /**
194 : : * Returns minimum scale on which snapping is limited
195 : : * \since QGIS 3.14
196 : : */
197 : : double minimumScale() const;
198 : :
199 : : /**
200 : : * Sets the min scale value on which snapping is used, 0.0 disable scale limit
201 : : * \since QGIS 3.14
202 : : */
203 : : void setMinimumScale( double minScale );
204 : :
205 : : /**
206 : : * Returns max scale on which snapping is limited
207 : : * \since QGIS 3.14
208 : : */
209 : : double maximumScale() const;
210 : :
211 : : /**
212 : : * Sets the max scale value on which snapping is used, 0.0 disable scale limit
213 : : * \since QGIS 3.14
214 : : */
215 : : void setMaximumScale( double maxScale );
216 : :
217 : : /**
218 : : * Compare this configuration to other.
219 : : */
220 : : bool operator!= ( const QgsSnappingConfig::IndividualLayerSettings &other ) const;
221 : :
222 : : bool operator== ( const QgsSnappingConfig::IndividualLayerSettings &other ) const;
223 : :
224 : : private:
225 : 0 : bool mValid = false;
226 : 0 : bool mEnabled = false;
227 : 0 : SnappingTypeFlag mType = VertexFlag;
228 : 0 : double mTolerance = 0;
229 : 0 : QgsTolerance::UnitType mUnits = QgsTolerance::Pixels;
230 : 0 : double mMinimumScale = 0.0;
231 : 0 : double mMaximumScale = 0.0;
232 : : };
233 : :
234 : : /**
235 : : * Constructor with default parameters defined in global settings
236 : : */
237 : : explicit QgsSnappingConfig( QgsProject *project = nullptr );
238 : :
239 : : bool operator==( const QgsSnappingConfig &other ) const;
240 : :
241 : : //! reset to default values
242 : : void reset();
243 : :
244 : : //! Returns if snapping is enabled
245 : : bool enabled() const;
246 : :
247 : : //! enables the snapping
248 : : void setEnabled( bool enabled );
249 : :
250 : : //! Returns the mode (all layers, active layer, per layer settings)
251 : : SnappingMode mode() const;
252 : :
253 : : //! define the mode of snapping
254 : : void setMode( SnappingMode mode );
255 : :
256 : : /**
257 : : * Returns the flags type (vertices | segments | area | centroid | middle)
258 : : * \since QGIS 3.12
259 : : */
260 : : QgsSnappingConfig::SnappingTypeFlag typeFlag() const;
261 : :
262 : : /**
263 : : * Returns the flags type (vertices | segments | area | centroid | middle)
264 : : * \deprecated since QGIS 3.12 use typeFlag instead.
265 : : */
266 : : Q_DECL_DEPRECATED QgsSnappingConfig::SnappingType type() const SIP_DEPRECATED;
267 : :
268 : : /**
269 : : * define the type of snapping
270 : : * \deprecated since QGIS 3.12 use setTypeFlag instead.
271 : : */
272 : : Q_DECL_DEPRECATED void setType( QgsSnappingConfig::SnappingType type );
273 : :
274 : : /**
275 : : * define the type of snapping
276 : : * \since QGIS 3.12
277 : : */
278 : : void setTypeFlag( QgsSnappingConfig::SnappingTypeFlag type );
279 : :
280 : : //! Returns the tolerance
281 : : double tolerance() const;
282 : :
283 : : //! Sets the tolerance
284 : : void setTolerance( double tolerance );
285 : :
286 : : /**
287 : : * Returns the min scale (i.e. most \"zoomed out\" scale)
288 : : * \since QGIS 3.14
289 : : */
290 : : double minimumScale() const;
291 : :
292 : : /**
293 : : * Sets the min scale on which snapping is enabled, 0.0 disable scale limit
294 : : * \since QGIS 3.14
295 : : */
296 : : void setMinimumScale( double minScale );
297 : :
298 : : /**
299 : : * Returns the max scale (i.e. most \"zoomed in\" scale)
300 : : * \since QGIS 3.14
301 : : */
302 : : double maximumScale() const;
303 : :
304 : : /**
305 : : * Set the max scale on which snapping is enabled, 0.0 disable scale limit
306 : : * \since QGIS 3.14
307 : : */
308 : : void setMaximumScale( double maxScale );
309 : :
310 : : /**
311 : : * Set the scale dependency mode
312 : : * \since QGIS 3.14
313 : : */
314 : : void setScaleDependencyMode( ScaleDependencyMode mode );
315 : :
316 : : /**
317 : : * Returns the scale dependency mode
318 : : * \since QGIS 3.14
319 : : */
320 : : ScaleDependencyMode scaleDependencyMode() const;
321 : :
322 : : //! Returns the type of units
323 : : QgsTolerance::UnitType units() const;
324 : :
325 : : //! Sets the type of units
326 : : void setUnits( QgsTolerance::UnitType units );
327 : :
328 : : //! Returns if the snapping on intersection is enabled
329 : : bool intersectionSnapping() const;
330 : :
331 : : //! Sets if the snapping on intersection is enabled
332 : : void setIntersectionSnapping( bool enabled );
333 : :
334 : : /**
335 : : * Returns if self snapping (snapping to the currently digitized feature) is enabled
336 : : *
337 : : * \since QGIS 3.14
338 : : */
339 : : bool selfSnapping() const;
340 : :
341 : : /**
342 : : * Sets if self snapping (snapping to the currently digitized feature) is enabled
343 : : *
344 : : * \since QGIS 3.14
345 : : */
346 : : void setSelfSnapping( bool enabled );
347 : :
348 : : //! Returns individual snapping settings for all layers
349 : : #ifndef SIP_RUN
350 : : QHash<QgsVectorLayer *, QgsSnappingConfig::IndividualLayerSettings> individualLayerSettings() const;
351 : : #else
352 : : SIP_PYDICT individualLayerSettings() const;
353 : : % MethodCode
354 : : // Create the dictionary.
355 : : PyObject *d = PyDict_New();
356 : : if ( !d )
357 : : return nullptr;
358 : : // Set the dictionary elements.
359 : : QHash<QgsVectorLayer *, QgsSnappingConfig::IndividualLayerSettings> container = sipCpp->individualLayerSettings();
360 : : QHash<QgsVectorLayer *, QgsSnappingConfig::IndividualLayerSettings>::const_iterator i = container.constBegin();
361 : : while ( i != container.constEnd() )
362 : : {
363 : : QgsVectorLayer *vl = i.key();
364 : : QgsSnappingConfig::IndividualLayerSettings *ils = new QgsSnappingConfig::IndividualLayerSettings( i.value() );
365 : :
366 : : PyObject *vlobj = sipConvertFromType( vl, sipType_QgsVectorLayer, nullptr );
367 : : PyObject *ilsobj = sipConvertFromType( ils, sipType_QgsSnappingConfig_IndividualLayerSettings, Py_None );
368 : :
369 : : if ( !vlobj || !ilsobj || PyDict_SetItem( d, vlobj, ilsobj ) < 0 )
370 : : {
371 : : Py_DECREF( d );
372 : : if ( vlobj )
373 : : {
374 : : Py_DECREF( vlobj );
375 : : }
376 : : if ( ilsobj )
377 : : {
378 : : Py_DECREF( ilsobj );
379 : : }
380 : : else
381 : : {
382 : : delete ils;
383 : : }
384 : : PyErr_SetString( PyExc_StopIteration, "" );
385 : : }
386 : : Py_DECREF( vlobj );
387 : : Py_DECREF( ilsobj );
388 : : ++i;
389 : : }
390 : : sipRes = d;
391 : : % End
392 : : #endif
393 : :
394 : : //! Returns individual layer snappings settings (applied if mode is AdvancedConfiguration)
395 : : QgsSnappingConfig::IndividualLayerSettings individualLayerSettings( QgsVectorLayer *vl ) const;
396 : :
397 : : //! Sets individual layer snappings settings (applied if mode is AdvancedConfiguration)
398 : : void setIndividualLayerSettings( QgsVectorLayer *vl, const QgsSnappingConfig::IndividualLayerSettings &individualLayerSettings );
399 : :
400 : : /**
401 : : * Removes all individual layer snapping settings
402 : : *
403 : : * \since QGIS 3.16
404 : : */
405 : : void clearIndividualLayerSettings();
406 : :
407 : : /**
408 : : * Compare this configuration to other.
409 : : */
410 : : bool operator!= ( const QgsSnappingConfig &other ) const;
411 : :
412 : : /**
413 : : * Reads the configuration from the specified QGIS project document.
414 : : *
415 : : * \since QGIS 3.0
416 : : */
417 : : void readProject( const QDomDocument &doc );
418 : :
419 : : /**
420 : : * Writes the configuration to the specified QGIS project document.
421 : : *
422 : : * \since QGIS 3.0
423 : : */
424 : : void writeProject( QDomDocument &doc );
425 : :
426 : : /**
427 : : * Adds the specified layers as individual layers to the configuration
428 : : * with standard configuration.
429 : : * When implementing a long-living QgsSnappingConfig (like the one in QgsProject)
430 : : * it is best to directly feed this with information from the layer registry.
431 : : *
432 : : * \returns TRUE if changes have been done.
433 : : *
434 : : * \since QGIS 3.0
435 : : */
436 : : bool addLayers( const QList<QgsMapLayer *> &layers );
437 : :
438 : :
439 : : /**
440 : : * Removes the specified layers from the individual layer configuration.
441 : : * When implementing a long-living QgsSnappingConfig (like the one in QgsProject)
442 : : * it is best to directly feed this with information from the layer registry.
443 : : *
444 : : * \returns TRUE if changes have been done.
445 : : *
446 : : * \since QGIS 3.0
447 : : */
448 : : bool removeLayers( const QList<QgsMapLayer *> &layers );
449 : :
450 : : /**
451 : : * The project from which the snapped layers should be retrieved
452 : : *
453 : : * \since QGIS 3.0
454 : : */
455 : : QgsProject *project() const;
456 : :
457 : : /**
458 : : * The project from which the snapped layers should be retrieved
459 : : *
460 : : * \since QGIS 3.0
461 : : */
462 : : void setProject( QgsProject *project );
463 : :
464 : : private:
465 : : void readLegacySettings();
466 : :
467 : : //! associated project for this snapping configuration
468 : : QgsProject *mProject = nullptr;
469 : : bool mEnabled = false;
470 : : SnappingMode mMode = ActiveLayer;
471 : : SnappingTypeFlag mType = VertexFlag;
472 : : double mTolerance = 0.0;
473 : : ScaleDependencyMode mScaleDependencyMode = Disabled;
474 : : double mMinimumScale = 0.0;
475 : : double mMaximumScale = 0.0;
476 : : QgsTolerance::UnitType mUnits = QgsTolerance::ProjectUnits;
477 : : bool mIntersectionSnapping = false;
478 : : bool mSelfSnapping = false;
479 : :
480 : : QHash<QgsVectorLayer *, IndividualLayerSettings> mIndividualLayerSettings;
481 : :
482 : : };
483 : 0 : Q_DECLARE_OPERATORS_FOR_FLAGS( QgsSnappingConfig::SnappingTypeFlag )
484 : :
485 : : #endif // QGSPROJECTSNAPPINGSETTINGS_H
|