18 #include <QDomElement>
19 #include <QHeaderView>
32 , mTolerance( tolerance )
34 , mMinimumScale( minScale )
35 , mMaximumScale( maxScale )
73 return QgsSnappingConfig::SnappingType::VertexAndSegment;
75 return QgsSnappingConfig::SnappingType::Segment;
77 return QgsSnappingConfig::SnappingType::Vertex;
126 return mMinimumScale;
131 mMinimumScale = minScale;
136 return mMaximumScale;
141 mMaximumScale = maxScale;
146 return mValid != other.mValid
147 || mEnabled != other.mEnabled
148 || mType != other.mType
149 || mTolerance != other.mTolerance
150 || mUnits != other.mUnits
151 || mMinimumScale != other.mMinimumScale
152 || mMaximumScale != other.mMaximumScale;
157 return mValid == other.mValid
158 && mEnabled == other.mEnabled
159 && mType == other.mType
160 && mTolerance == other.mTolerance
161 && mUnits == other.mUnits
162 && mMinimumScale == other.mMinimumScale
163 && 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;
192 bool enabled =
QgsSettings().
value( QStringLiteral(
"/qgis/digitizing/default_snap_enabled" ),
false ).toBool();
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;
287 case SnappingType::Vertex:
290 case SnappingType::VertexAndSegment:
293 case SnappingType::Segment:
331 if ( mUnits ==
units )
340 return mIntersectionSnapping;
345 mIntersectionSnapping =
enabled;
350 return mSelfSnapping;
360 return mIndividualLayerSettings;
365 if ( vl && mIndividualLayerSettings.contains( vl ) )
367 return mIndividualLayerSettings.value( vl );
378 mIndividualLayerSettings.clear();
392 return mEnabled != other.mEnabled
393 || mMode != other.mMode
394 || mType != other.mType
395 || mTolerance != other.mTolerance
396 || mUnits != other.mUnits
397 || mIndividualLayerSettings != other.mIndividualLayerSettings
398 || mScaleDependencyMode != other.mScaleDependencyMode
399 || mMinimumScale != other.mMinimumScale
400 || mMaximumScale != other.mMaximumScale;
405 QDomElement snapSettingsElem = doc.firstChildElement( QStringLiteral(
"qgis" ) ).firstChildElement( QStringLiteral(
"snapping-settings" ) );
406 if ( snapSettingsElem.isNull() )
408 readLegacySettings();
412 if ( snapSettingsElem.hasAttribute( QStringLiteral(
"enabled" ) ) )
413 mEnabled = snapSettingsElem.attribute( QStringLiteral(
"enabled" ) ) == QLatin1String(
"1" );
415 if ( snapSettingsElem.hasAttribute( QStringLiteral(
"mode" ) ) )
416 mMode = (
SnappingMode )snapSettingsElem.attribute( QStringLiteral(
"mode" ) ).toInt();
418 if ( snapSettingsElem.hasAttribute( QStringLiteral(
"type" ) ) )
420 int type = snapSettingsElem.attribute( QStringLiteral(
"type" ) ).toInt();
421 QDomElement versionElem = doc.firstChildElement( QStringLiteral(
"qgis" ) );
423 bool before3_14 =
false;
424 if ( versionElem.hasAttribute( QStringLiteral(
"version" ) ) )
426 version = versionElem.attribute( QStringLiteral(
"version" ) );
427 QRegularExpression re(
"([\\d]+)\\.([\\d]+)" );
428 QRegularExpressionMatch match = re.match( version );
429 if ( match.hasMatch() )
431 if ( ( match.captured( 1 ).toInt() <= 3 ) && ( match.captured( 2 ).toInt() <= 12 ) )
458 mType =
static_cast<QgsSnappingConfig::SnappingTypeFlag
>(
type );
461 if ( snapSettingsElem.hasAttribute( QStringLiteral(
"tolerance" ) ) )
462 mTolerance = snapSettingsElem.attribute( QStringLiteral(
"tolerance" ) ).toDouble();
464 if ( snapSettingsElem.hasAttribute( QStringLiteral(
"scaleDependencyMode" ) ) )
467 if ( snapSettingsElem.hasAttribute( QStringLiteral(
"minScale" ) ) )
468 mMinimumScale = snapSettingsElem.attribute( QStringLiteral(
"minScale" ) ).toDouble();
470 if ( snapSettingsElem.hasAttribute( QStringLiteral(
"maxScale" ) ) )
471 mMaximumScale = snapSettingsElem.attribute( QStringLiteral(
"maxScale" ) ).toDouble();
473 if ( snapSettingsElem.hasAttribute( QStringLiteral(
"unit" ) ) )
476 if ( snapSettingsElem.hasAttribute( QStringLiteral(
"intersection-snapping" ) ) )
477 mIntersectionSnapping = snapSettingsElem.attribute( QStringLiteral(
"intersection-snapping" ) ) == QLatin1String(
"1" );
479 if ( snapSettingsElem.hasAttribute( QStringLiteral(
"self-snapping" ) ) )
480 mSelfSnapping = snapSettingsElem.attribute( QStringLiteral(
"self-snapping" ) ) == QLatin1String(
"1" );
483 QDomNodeList nodes = snapSettingsElem.elementsByTagName( QStringLiteral(
"individual-layer-settings" ) );
486 QDomNode node = nodes.item( 0 );
487 QDomNodeList settingNodes = node.childNodes();
488 int layerCount = settingNodes.count();
489 for (
int i = 0; i < layerCount; ++i )
491 QDomElement settingElement = settingNodes.at( i ).toElement();
492 if ( settingElement.tagName() != QLatin1String(
"layer-setting" ) )
494 QgsLogger::warning( QApplication::translate(
"QgsProjectSnappingSettings",
"Cannot read individual settings. Unexpected tag '%1'" ).arg( settingElement.tagName() ) );
498 QString layerId = settingElement.attribute( QStringLiteral(
"id" ) );
499 bool enabled = settingElement.attribute( QStringLiteral(
"enabled" ) ) == QLatin1String(
"1" );
500 QgsSnappingConfig::SnappingTypeFlag
type =
static_cast<QgsSnappingConfig::SnappingTypeFlag
>( settingElement.attribute( QStringLiteral(
"type" ) ).toInt() );
501 double tolerance = settingElement.attribute( QStringLiteral(
"tolerance" ) ).toDouble();
503 double minScale = settingElement.attribute( QStringLiteral(
"minScale" ) ).toDouble();
504 double maxScale = settingElement.attribute( QStringLiteral(
"maxScale" ) ).toDouble();
513 mIndividualLayerSettings.insert( vl, setting );
520 QDomElement snapSettingsElem = doc.createElement( QStringLiteral(
"snapping-settings" ) );
521 snapSettingsElem.setAttribute( QStringLiteral(
"enabled" ), QString::number( mEnabled ) );
522 snapSettingsElem.setAttribute( QStringLiteral(
"mode" ),
static_cast<int>( mMode ) );
523 snapSettingsElem.setAttribute( QStringLiteral(
"type" ),
static_cast<int>( mType ) );
524 snapSettingsElem.setAttribute( QStringLiteral(
"tolerance" ), mTolerance );
525 snapSettingsElem.setAttribute( QStringLiteral(
"unit" ),
static_cast<int>( mUnits ) );
526 snapSettingsElem.setAttribute( QStringLiteral(
"intersection-snapping" ), QString::number( mIntersectionSnapping ) );
527 snapSettingsElem.setAttribute( QStringLiteral(
"self-snapping" ), QString::number( mSelfSnapping ) );
528 snapSettingsElem.setAttribute( QStringLiteral(
"scaleDependencyMode" ), QString::number( mScaleDependencyMode ) );
529 snapSettingsElem.setAttribute( QStringLiteral(
"minScale" ), mMinimumScale );
530 snapSettingsElem.setAttribute( QStringLiteral(
"maxScale" ), mMaximumScale );
532 QDomElement ilsElement = doc.createElement( QStringLiteral(
"individual-layer-settings" ) );
533 QHash<QgsVectorLayer *, IndividualLayerSettings>::const_iterator layerIt = mIndividualLayerSettings.constBegin();
534 for ( ; layerIt != mIndividualLayerSettings.constEnd(); ++layerIt )
538 QDomElement layerElement = doc.createElement( QStringLiteral(
"layer-setting" ) );
539 layerElement.setAttribute( QStringLiteral(
"id" ), layerIt.key()->id() );
540 layerElement.setAttribute( QStringLiteral(
"enabled" ), QString::number( setting.
enabled() ) );
541 layerElement.setAttribute( QStringLiteral(
"type" ),
static_cast<int>( setting.
typeFlag() ) );
542 layerElement.setAttribute( QStringLiteral(
"tolerance" ), setting.
tolerance() );
543 layerElement.setAttribute( QStringLiteral(
"units" ),
static_cast<int>( setting.
units() ) );
544 layerElement.setAttribute( QStringLiteral(
"minScale" ), setting.
minimumScale() );
545 layerElement.setAttribute( QStringLiteral(
"maxScale" ), setting.
maximumScale() );
546 ilsElement.appendChild( layerElement );
548 snapSettingsElem.appendChild( ilsElement );
550 doc.firstChildElement( QStringLiteral(
"qgis" ) ).appendChild( snapSettingsElem );
555 bool changed =
false;
556 bool enabled =
QgsSettings().
value( QStringLiteral(
"/qgis/digitizing/default_snap_enabled" ),
true ).toBool();
561 const auto constLayers = layers;
576 bool changed =
false;
577 const auto constLayers = layers;
583 mIndividualLayerSettings.remove( vl );
590 void QgsSnappingConfig::readLegacySettings()
595 QString snapMode = mProject->
readEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/SnappingMode" ) );
597 mTolerance = mProject->
readDoubleEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/DefaultSnapTolerance" ), 0 );
600 mIntersectionSnapping = mProject->
readNumEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/IntersectionSnapping" ), 0 );
603 QStringList layerIdList = mProject->
readListEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/LayerSnappingList" ), QStringList() );
604 QStringList enabledList = mProject->
readListEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/LayerSnappingEnabledList" ), QStringList() );
605 QStringList toleranceList = mProject->
readListEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/LayerSnappingToleranceList" ), QStringList() );
606 QStringList toleranceUnitList = mProject->
readListEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/LayerSnappingToleranceUnitList" ), QStringList() );
607 QStringList snapToList = mProject->
readListEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/LayerSnapToList" ), QStringList() );
610 if ( layerIdList.size() != enabledList.size() ||
611 layerIdList.size() != toleranceList.size() ||
612 layerIdList.size() != toleranceUnitList.size() ||
613 layerIdList.size() != snapToList.size() )
617 if ( snapMode == QLatin1String(
"current_layer" ) )
619 else if ( snapMode == QLatin1String(
"all_layers" ) )
625 QStringList::const_iterator layerIt( layerIdList.constBegin() );
626 QStringList::const_iterator tolIt( toleranceList.constBegin() );
627 QStringList::const_iterator tolUnitIt( toleranceUnitList.constBegin() );
628 QStringList::const_iterator snapIt( snapToList.constBegin() );
629 QStringList::const_iterator enabledIt( enabledList.constBegin() );
630 for ( ; layerIt != layerIdList.constEnd(); ++layerIt, ++tolIt, ++tolUnitIt, ++snapIt, ++enabledIt )
636 QgsSnappingConfig::SnappingTypeFlag t( *snapIt == QLatin1String(
"to_vertex" ) ?
VertexFlag :
637 ( *snapIt == QLatin1String(
"to_segment" ) ?
SegmentFlag :
642 mIndividualLayerSettings.insert( vlayer, IndividualLayerSettings( *enabledIt == QLatin1String(
"enabled" ), t, tolIt->toDouble(),
static_cast<QgsTolerance::UnitType>( tolUnitIt->toInt() ), 0.0, 0.0 ) );
645 QString snapType = mProject->
readEntry( QStringLiteral(
"Digitizing" ), QStringLiteral(
"/DefaultSnapType" ), QStringLiteral(
"off" ) );
647 if ( snapType == QLatin1String(
"to segment" ) )
649 else if ( snapType == QLatin1String(
"to vertex and segment" ) )
651 else if ( snapType == QLatin1String(
"to vertex" ) )
674 return mMinimumScale;
679 mMinimumScale = minScale;
684 return mMaximumScale;
689 mMaximumScale = maxScale;
694 mScaleDependencyMode =
mode;
699 return mScaleDependencyMode;