diff --git a/resources/qgis_global_settings.ini b/resources/qgis_global_settings.ini index db89c2c58e8e..305ac0d7e568 100644 --- a/resources/qgis_global_settings.ini +++ b/resources/qgis_global_settings.ini @@ -9,16 +9,12 @@ digitizing\default_snap_enabled=false digitizing\default_snapping_tolerance=12.0 # Default snap to type -# 1 = Vertices only -# 2 = Vertices and segments -# 3 = Segments only -digitizing\default_snap_type=1 +# Vertex, VertexAndSegment, Segment +digitizing\default_snap_type=Vertex # Default snapping unit -# 0 = Layer units -# 1 = Pixels -# 2 = Project units -digitizing\default_snapping_tolerance_unit=1 +# LayerUnits, Pixels, ProjectUnits +digitizing\default_snapping_tolerance_unit=Pixels # Snap on invisble feature digitizing\snap_invisible_feature=false @@ -55,4 +51,3 @@ helpSearchPath=https://docs.qgis.org/$qgis_short_version/$qgis_locale/docs/user_ [providers] # Default timeout for PostgreSQL servers (seconds) PostgreSQL\default_timeout=30 - diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index 21f00cb3921d..efb207c5f37b 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -11698,7 +11698,7 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer ) mActionSelectPolygon->setEnabled( false ); mActionSelectFreehand->setEnabled( false ); mActionSelectRadius->setEnabled( false ); - mActionIdentify->setEnabled( QgsSettings().value( QStringLiteral( "/Map/identifyMode" ), 0 ).toInt() != 0 ); + mActionIdentify->setEnabled( QgsSettings().enumValue( QStringLiteral( "/Map/identifyMode" ), QgsMapToolIdentify::ActiveLayer ) != QgsMapToolIdentify::ActiveLayer ); mActionSelectByExpression->setEnabled( false ); mActionSelectByForm->setEnabled( false ); mActionLabeling->setEnabled( false ); @@ -12098,8 +12098,8 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer *layer ) mActionIdentify->setEnabled( true ); QgsSettings settings; - int identifyMode = settings.value( QStringLiteral( "Map/identifyMode" ), 0 ).toInt(); - if ( identifyMode == 0 ) + QgsMapToolIdentify::IdentifyMode identifyMode = settings.enumValue( QStringLiteral( "Map/identifyMode" ), QgsMapToolIdentify::ActiveLayer ); + if ( identifyMode == QgsMapToolIdentify::ActiveLayer ) { const QgsRasterLayer *rlayer = qobject_cast( layer ); const QgsRasterDataProvider *dprovider = rlayer->dataProvider(); diff --git a/src/app/qgsidentifyresultsdialog.cpp b/src/app/qgsidentifyresultsdialog.cpp index bada7e326420..31c72503f314 100644 --- a/src/app/qgsidentifyresultsdialog.cpp +++ b/src/app/qgsidentifyresultsdialog.cpp @@ -370,12 +370,12 @@ QgsIdentifyResultsDialog::QgsIdentifyResultsDialog( QgsMapCanvas *canvas, QWidge } // retrieve mode before on_cmbIdentifyMode_currentIndexChanged resets it on addItem - int identifyMode = mySettings.value( QStringLiteral( "Map/identifyMode" ), 0 ).toInt(); + QgsMapToolIdentify::IdentifyMode identifyMode = mySettings.enumValue( QStringLiteral( "Map/identifyMode" ), QgsMapToolIdentify::ActiveLayer ); - cmbIdentifyMode->addItem( tr( "Current layer" ), 0 ); - cmbIdentifyMode->addItem( tr( "Top down, stop at first" ), 1 ); - cmbIdentifyMode->addItem( tr( "Top down" ), 2 ); - cmbIdentifyMode->addItem( tr( "Layer selection" ), 3 ); + cmbIdentifyMode->addItem( tr( "Current layer" ), QgsMapToolIdentify::ActiveLayer ); + cmbIdentifyMode->addItem( tr( "Top down, stop at first" ), QgsMapToolIdentify::TopDownStopAtFirst ); + cmbIdentifyMode->addItem( tr( "Top down" ), QgsMapToolIdentify::TopDownAll ); + cmbIdentifyMode->addItem( tr( "Layer selection" ), QgsMapToolIdentify::LayerSelection ); cmbIdentifyMode->setCurrentIndex( cmbIdentifyMode->findData( identifyMode ) ); cbxAutoFeatureForm->setChecked( mySettings.value( QStringLiteral( "Map/identifyAutoFeatureForm" ), false ).toBool() ); diff --git a/src/app/qgsmaptooloffsetcurve.cpp b/src/app/qgsmaptooloffsetcurve.cpp index 992b54fba7ba..a370b49a3e16 100644 --- a/src/app/qgsmaptooloffsetcurve.cpp +++ b/src/app/qgsmaptooloffsetcurve.cpp @@ -645,10 +645,10 @@ QgsOffsetUserWidget::QgsOffsetUserWidget( QWidget *parent ) mOffsetSpinBox->installEventFilter( this ); connect( mOffsetSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsOffsetUserWidget::offsetChanged ); - connect( mJoinStyleComboBox, static_cast < void ( QComboBox::* )( int ) > ( &QComboBox::currentIndexChanged ), this, [ = ] { QgsSettings().setValue( QStringLiteral( "/qgis/digitizing/offset_join_style" ), mJoinStyleComboBox->currentData() ); emit offsetConfigChanged(); } ); + connect( mJoinStyleComboBox, static_cast < void ( QComboBox::* )( int ) > ( &QComboBox::currentIndexChanged ), this, [ = ] { QgsSettings().setEnumValue( QStringLiteral( "/qgis/digitizing/offset_join_style" ), ( QgsGeometry::JoinStyle )mJoinStyleComboBox->currentData().toInt() ); emit offsetConfigChanged(); } ); connect( mQuadrantSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, [ = ]( const int quadSegments ) { QgsSettings().setValue( QStringLiteral( "/qgis/digitizing/offset_quad_seg" ), quadSegments ); emit offsetConfigChanged(); } ); connect( mMiterLimitSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, [ = ]( const double & miterLimit ) { QgsSettings().setValue( QStringLiteral( "/qgis/digitizing/offset_miter_limit" ), miterLimit ); emit offsetConfigChanged(); } ); - connect( mCapStyleComboBox, static_cast < void ( QComboBox::* )( int ) > ( &QComboBox::currentIndexChanged ), this, [ = ] { QgsSettings().setValue( QStringLiteral( "/qgis/digitizing/offset_cap_style" ), mCapStyleComboBox->currentData() ); emit offsetConfigChanged(); } ); + connect( mCapStyleComboBox, static_cast < void ( QComboBox::* )( int ) > ( &QComboBox::currentIndexChanged ), this, [ = ] { QgsSettings().setEnumValue( QStringLiteral( "/qgis/digitizing/offset_cap_style" ), ( QgsGeometry::EndCapStyle ) mCapStyleComboBox->currentData().toInt() ); emit offsetConfigChanged(); } ); bool showAdvanced = s.value( QStringLiteral( "/qgis/digitizing/offset_show_advanced" ), false ).toBool(); mShowAdvancedButton->setChecked( showAdvanced ); diff --git a/src/app/qgsoptions.cpp b/src/app/qgsoptions.cpp index 6fca9cae93ed..40c111be19cd 100644 --- a/src/app/qgsoptions.cpp +++ b/src/app/qgsoptions.cpp @@ -581,9 +581,9 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QListsetChecked( !mSettings->value( QStringLiteral( "/qgis/simplifyLocal" ), true ).toBool() ); //segmentation tolerance type - mToleranceTypeComboBox->addItem( tr( "Maximum angle" ), 0 ); - mToleranceTypeComboBox->addItem( tr( "Maximum difference" ), 1 ); - int toleranceType = mSettings->value( QStringLiteral( "/qgis/segmentationToleranceType" ), "0" ).toInt(); + mToleranceTypeComboBox->addItem( tr( "Maximum angle" ), QgsAbstractGeometry::MaximumAngle ); + mToleranceTypeComboBox->addItem( tr( "Maximum difference" ), QgsAbstractGeometry::MaximumDifference ); + QgsAbstractGeometry::SegmentationToleranceType toleranceType = mSettings->enumValue( QStringLiteral( "/qgis/segmentationToleranceType" ), QgsAbstractGeometry::MaximumAngle ); int toleranceTypeIndex = mToleranceTypeComboBox->findData( toleranceType ); if ( toleranceTypeIndex != -1 ) { @@ -591,7 +591,7 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QListvalue( QStringLiteral( "/qgis/segmentationTolerance" ), "0.01745" ).toDouble(); - if ( toleranceType == 0 ) + if ( toleranceType == QgsAbstractGeometry::MaximumAngle ) { tolerance = tolerance * 180.0 / M_PI; //value shown to the user is degree, not rad } @@ -616,7 +616,7 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QListaddItem( tr( "Distance" ), ( int )QgsVectorSimplifyMethod::Distance ); mSimplifyAlgorithmComboBox->addItem( tr( "SnapToGrid" ), ( int )QgsVectorSimplifyMethod::SnapToGrid ); mSimplifyAlgorithmComboBox->addItem( tr( "Visvalingam" ), ( int )QgsVectorSimplifyMethod::Visvalingam ); - mSimplifyAlgorithmComboBox->setCurrentIndex( mSimplifyAlgorithmComboBox->findData( mSettings->value( QStringLiteral( "/qgis/simplifyAlgorithm" ), 0 ).toInt() ) ); + mSimplifyAlgorithmComboBox->setCurrentIndex( mSimplifyAlgorithmComboBox->findData( mSettings->enumValue( QStringLiteral( "/qgis/simplifyAlgorithm" ), QgsVectorSimplifyMethod::NoSimplification ) ) ); // Slightly awkard here at the settings value is true to use QImage, // but the checkbox is true to use QPixmap @@ -633,7 +633,7 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QListaddItem( tr( "Plain text, no geometry" ), QgsClipboard::AttributesOnly ); mComboCopyFeatureFormat->addItem( tr( "Plain text, WKT geometry" ), QgsClipboard::AttributesWithWKT ); mComboCopyFeatureFormat->addItem( tr( "GeoJSON" ), QgsClipboard::GeoJSON ); - mComboCopyFeatureFormat->setCurrentIndex( mComboCopyFeatureFormat->findData( mSettings->value( QStringLiteral( "/qgis/copyFeatureFormat" ), QgsClipboard::AttributesWithWKT ) ) ); + mComboCopyFeatureFormat->setCurrentIndex( mComboCopyFeatureFormat->findData( mSettings->enumValue( QStringLiteral( "/qgis/copyFeatureFormat" ), QgsClipboard::AttributesWithWKT ) ) ); leNullValue->setText( QgsApplication::nullRepresentation() ); cbxIgnoreShapeEncoding->setChecked( mSettings->value( QStringLiteral( "/qgis/ignoreShapeEncoding" ), true ).toBool() ); @@ -948,7 +948,7 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QListaddItem( tr( "Vertex" ), QgsSnappingConfig::Vertex ); mDefaultSnapModeComboBox->addItem( tr( "Vertex and segment" ), QgsSnappingConfig::VertexAndSegment ); mDefaultSnapModeComboBox->addItem( tr( "Segment" ), QgsSnappingConfig::Segment ); - mDefaultSnapModeComboBox->setCurrentIndex( mDefaultSnapModeComboBox->findData( mSettings->value( QStringLiteral( "/qgis/digitizing/default_snap_type" ), QgsSnappingConfig::Vertex ).toInt() ) ); + mDefaultSnapModeComboBox->setCurrentIndex( mDefaultSnapModeComboBox->findData( mSettings->enumValue( QStringLiteral( "/qgis/digitizing/default_snap_type" ), QgsSnappingConfig::Vertex ) ) ); mDefaultSnappingToleranceSpinBox->setValue( mSettings->value( QStringLiteral( "/qgis/digitizing/default_snapping_tolerance" ), Qgis::DEFAULT_SNAP_TOLERANCE ).toDouble() ); mSearchRadiusVertexEditSpinBox->setValue( mSettings->value( QStringLiteral( "/qgis/digitizing/search_radius_vertex_edit" ), 10 ).toDouble() ); QgsTolerance::UnitType defSnapUnits = mSettings->enumValue( QStringLiteral( "/qgis/digitizing/default_snapping_tolerance_unit" ), Qgis::DEFAULT_SNAP_UNITS ); @@ -961,7 +961,7 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QListfindText( tr( "pixels" ) ); } mDefaultSnappingToleranceComboBox->setCurrentIndex( index ); - int defRadiusUnits = mSettings->value( QStringLiteral( "/qgis/digitizing/search_radius_vertex_edit_unit" ), QgsTolerance::Pixels ).toInt(); + QgsTolerance::UnitType defRadiusUnits = mSettings->enumValue( QStringLiteral( "/qgis/digitizing/search_radius_vertex_edit_unit" ), QgsTolerance::Pixels ); if ( defRadiusUnits == QgsTolerance::ProjectUnits || defRadiusUnits == QgsTolerance::LayerUnits ) { index = mSearchRadiusVertexEditComboBox->findText( tr( "map units" ) ); @@ -974,7 +974,6 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QListsetColor( mSettings->value( QStringLiteral( "/qgis/digitizing/snap_color" ), QColor( Qt::magenta ) ).value() ); mSnappingTooltipsCheckbox->setChecked( mSettings->value( QStringLiteral( "/qgis/digitizing/snap_tooltip" ), false ).toBool() ); - mEnableSnappingOnInvisibleFeatureCheckbox->setChecked( mSettings->value( QStringLiteral( "/qgis/digitizing/snap_invisible_feature" ), false ).toBool() ); //vertex marker mMarkersOnlyForSelectedCheckBox->setChecked( mSettings->value( QStringLiteral( "/qgis/digitizing/marker_only_for_selected" ), true ).toBool() ); @@ -1012,10 +1011,10 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QListaddItem( tr( "Dock" ), "dock" ); mSnappingMainDialogComboBox->setCurrentIndex( mSnappingMainDialogComboBox->findData( mSettings->value( QStringLiteral( "/qgis/mainSnappingWidgetMode" ), "dialog" ).toString() ) ); - mOffsetJoinStyleComboBox->addItem( tr( "Round" ), 0 ); - mOffsetJoinStyleComboBox->addItem( tr( "Miter" ), 1 ); - mOffsetJoinStyleComboBox->addItem( tr( "Bevel" ), 2 ); - mOffsetJoinStyleComboBox->setCurrentIndex( mSettings->value( QStringLiteral( "/qgis/digitizing/offset_join_style" ), QgsGeometry::JoinStyleRound ).toInt() ); + mOffsetJoinStyleComboBox->addItem( tr( "Round" ), QgsGeometry::JoinStyleRound ); + mOffsetJoinStyleComboBox->addItem( tr( "Miter" ), QgsGeometry::JoinStyleMiter ); + mOffsetJoinStyleComboBox->addItem( tr( "Bevel" ), QgsGeometry::JoinStyleBevel ); + mOffsetJoinStyleComboBox->setCurrentIndex( ( int )mSettings->enumValue( QStringLiteral( "/qgis/digitizing/offset_join_style" ), QgsGeometry::JoinStyleRound ) ); mOffsetQuadSegSpinBox->setValue( mSettings->value( QStringLiteral( "/qgis/digitizing/offset_quad_seg" ), 8 ).toInt() ); mCurveOffsetMiterLimitComboBox->setValue( mSettings->value( QStringLiteral( "/qgis/digitizing/offset_miter_limit" ), 5.0 ).toDouble() ); @@ -1300,7 +1299,7 @@ void QgsOptions::saveOptions() mSettings->setValue( QStringLiteral( "/qgis/dataSourceManagerNonModal" ), mDataSourceManagerNonModal->isChecked() ); mSettings->setValue( QStringLiteral( "/qgis/checkVersion" ), cbxCheckVersion->isChecked() ); mSettings->setValue( QStringLiteral( "/qgis/dockAttributeTable" ), cbxAttributeTableDocked->isChecked() ); - mSettings->setValue( QStringLiteral( "/qgis/attributeTableBehavior" ), cmbAttrTableBehavior->currentData() ); + mSettings->setEnumValue( QStringLiteral( "/qgis/attributeTableBehavior" ), ( QgsAttributeTableFilterModel::FilterMode )cmbAttrTableBehavior->currentData().toInt() ); mSettings->setValue( QStringLiteral( "/qgis/attributeTableView" ), mAttrTableViewComboBox->currentData() ); mSettings->setValue( QStringLiteral( "/qgis/attributeTableRowCache" ), spinBoxAttrTableRowCache->value() ); mSettings->setValue( QStringLiteral( "/qgis/promptForRasterSublayers" ), cmbPromptRasterSublayers->currentIndex() ); @@ -1316,7 +1315,7 @@ void QgsOptions::saveOptions() mSettings->setValue( QStringLiteral( "/qgis/compileExpressions" ), cbxCompileExpressions->isChecked() ); mSettings->setValue( QStringLiteral( "/qgis/defaultLegendGraphicResolution" ), mLegendGraphicResolutionSpinBox->value() ); mSettings->setValue( QStringLiteral( "/qgis/mapTipsDelay" ), mMapTipsDelaySpinBox->value() ); - mSettings->setValue( QStringLiteral( "/qgis/copyFeatureFormat" ), mComboCopyFeatureFormat->currentData().toInt() ); + mSettings->setEnumValue( QStringLiteral( "/qgis/copyFeatureFormat" ), ( QgsClipboard::CopyFormat )mComboCopyFeatureFormat->currentData().toInt() ); QgisApp::instance()->setMapTipsDelay( mMapTipsDelaySpinBox->value() ); mSettings->setValue( QStringLiteral( "/qgis/new_layers_visible" ), chkAddedVisibility->isChecked() ); @@ -1337,8 +1336,8 @@ void QgsOptions::saveOptions() simplifyHints |= QgsVectorSimplifyMethod::GeometrySimplification; if ( mSimplifyDrawingSpinBox->value() > 1 ) simplifyHints |= QgsVectorSimplifyMethod::AntialiasingSimplification; } - mSettings->setValue( QStringLiteral( "/qgis/simplifyDrawingHints" ), ( int ) simplifyHints ); - mSettings->setValue( QStringLiteral( "/qgis/simplifyAlgorithm" ), mSimplifyAlgorithmComboBox->currentData().toInt() ); + mSettings->setEnumValue( QStringLiteral( "/qgis/simplifyDrawingHints" ), simplifyHints ); + mSettings->setEnumValue( QStringLiteral( "/qgis/simplifyAlgorithm" ), ( QgsVectorSimplifyMethod::SimplifyHints )mSimplifyAlgorithmComboBox->currentData().toInt() ); mSettings->setValue( QStringLiteral( "/qgis/simplifyDrawingTol" ), mSimplifyDrawingSpinBox->value() ); mSettings->setValue( QStringLiteral( "/qgis/simplifyLocal" ), !mSimplifyDrawingAtProvider->isChecked() ); mSettings->setValue( QStringLiteral( "/qgis/simplifyMaxScale" ), mSimplifyMaximumScaleComboBox->scale() ); @@ -1347,10 +1346,10 @@ void QgsOptions::saveOptions() mSettings->setValue( QStringLiteral( "/qgis/magnifier_factor_default" ), doubleSpinBoxMagnifierDefault->value() / 100 ); //curve segmentation - int segmentationType = mToleranceTypeComboBox->currentData().toInt(); - mSettings->setValue( QStringLiteral( "/qgis/segmentationToleranceType" ), segmentationType ); + QgsAbstractGeometry::SegmentationToleranceType segmentationType = ( QgsAbstractGeometry::SegmentationToleranceType )mToleranceTypeComboBox->currentData().toInt(); + mSettings->setEnumValue( QStringLiteral( "/qgis/segmentationToleranceType" ), segmentationType ); double segmentationTolerance = mSegmentationToleranceSpinBox->value(); - if ( segmentationType == 0 ) + if ( segmentationType == QgsAbstractGeometry::MaximumAngle ) { segmentationTolerance = segmentationTolerance / 180.0 * M_PI; //user sets angle tolerance in degrees, internal classes need value in rad } @@ -1479,13 +1478,13 @@ void QgsOptions::saveOptions() //default snap mode mSettings->setValue( QStringLiteral( "/qgis/digitizing/default_snap_enabled" ), mSnappingEnabledDefault->isChecked() ); - mSettings->setValue( QStringLiteral( "/qgis/digitizing/default_snap_type" ), mDefaultSnapModeComboBox->currentData().toInt() ); + mSettings->setEnumValue( QStringLiteral( "/qgis/digitizing/default_snap_type" ), ( QgsSnappingConfig::SnappingType )mDefaultSnapModeComboBox->currentData().toInt() ); mSettings->setValue( QStringLiteral( "/qgis/digitizing/default_snapping_tolerance" ), mDefaultSnappingToleranceSpinBox->value() ); mSettings->setValue( QStringLiteral( "/qgis/digitizing/search_radius_vertex_edit" ), mSearchRadiusVertexEditSpinBox->value() ); - mSettings->setValue( QStringLiteral( "/qgis/digitizing/default_snapping_tolerance_unit" ), - ( mDefaultSnappingToleranceComboBox->currentIndex() == 0 ? QgsTolerance::ProjectUnits : QgsTolerance::Pixels ) ); - mSettings->setValue( QStringLiteral( "/qgis/digitizing/search_radius_vertex_edit_unit" ), - ( mSearchRadiusVertexEditComboBox->currentIndex() == 0 ? QgsTolerance::ProjectUnits : QgsTolerance::Pixels ) ); + mSettings->setEnumValue( QStringLiteral( "/qgis/digitizing/default_snapping_tolerance_unit" ), + ( mDefaultSnappingToleranceComboBox->currentIndex() == 0 ? QgsTolerance::ProjectUnits : QgsTolerance::Pixels ) ); + mSettings->setEnumValue( QStringLiteral( "/qgis/digitizing/search_radius_vertex_edit_unit" ), + ( mSearchRadiusVertexEditComboBox->currentIndex() == 0 ? QgsTolerance::ProjectUnits : QgsTolerance::Pixels ) ); mSettings->setValue( QStringLiteral( "/qgis/digitizing/snap_color" ), mSnappingMarkerColorButton->color() ); mSettings->setValue( QStringLiteral( "/qgis/digitizing/snap_tooltip" ), mSnappingTooltipsCheckbox->isChecked() ); @@ -1512,7 +1511,7 @@ void QgsOptions::saveOptions() mSettings->setValue( QStringLiteral( "/qgis/digitizing/disable_enter_attribute_values_dialog" ), chkDisableAttributeValuesDlg->isChecked() ); mSettings->setValue( QStringLiteral( "/qgis/digitizing/validate_geometries" ), mValidateGeometries->currentIndex() ); - mSettings->setValue( QStringLiteral( "/qgis/digitizing/offset_join_style" ), mOffsetJoinStyleComboBox->currentData().toInt() ); + mSettings->setEnumValue( QStringLiteral( "/qgis/digitizing/offset_join_style" ), ( QgsGeometry::JoinStyle )mOffsetJoinStyleComboBox->currentData().toInt() ); mSettings->setValue( QStringLiteral( "/qgis/digitizing/offset_quad_seg" ), mOffsetQuadSegSpinBox->value() ); mSettings->setValue( QStringLiteral( "/qgis/digitizing/offset_miter_limit" ), mCurveOffsetMiterLimitComboBox->value() ); diff --git a/src/core/qgssettings.h b/src/core/qgssettings.h index 6baa592e525a..536ff7fb17a0 100644 --- a/src/core/qgssettings.h +++ b/src/core/qgssettings.h @@ -22,6 +22,7 @@ #include "qgis_core.h" #include "qgis.h" +#include "qgslogger.h" /** * \ingroup core @@ -224,33 +225,155 @@ class CORE_EXPORT QgsSettings : public QObject * Return the setting value for a setting based on an enum. * This forces the output to be a valid and existing entry of the enum. * Hence if the setting value is incorrect, the given default value is returned. - * If \a flag is true, the value is checked for a flag definition. + * This tries first with setting as a string (as the enum) and then as an integer value. * \note The enum needs to be declared with Q_ENUM, and flags with Q_FLAG (not Q_FLAGS). + * \see setEnumValue + * \see flagValue */ template T enumValue( const QString &key, const T &defaultValue, - const Section section = NoSection, bool flag = false ) const + const Section section = NoSection ) { + QMetaEnum metaEnum = QMetaEnum::fromType(); + Q_ASSERT( metaEnum.isValid() ); + if ( !metaEnum.isValid() ) + { + QgsDebugMsg( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ); + } + T v; - if ( !flag ) - v = static_cast( value( key, static_cast( defaultValue ), section ).toInt() ); - else - v = T( value( key, static_cast( defaultValue ), section ).toInt() ); + bool ok = false; - QMetaEnum metaEnum = QMetaEnum::fromType(); if ( metaEnum.isValid() ) { - if ( !flag && !metaEnum.valueToKey( static_cast( v ) ) ) + // read as string + QByteArray ba = value( key, metaEnum.valueToKey( defaultValue ) ).toString().toUtf8(); + const char *vs = ba.data(); + v = static_cast( metaEnum.keyToValue( vs, &ok ) ); + } + if ( !ok ) + { + // if failed, try to read as int (old behavior) + // this code shall be removed later (probably after QGIS 3.4 LTR for 3.6) + // then the method could be marked as const + v = static_cast( value( key, static_cast( defaultValue ), section ).toInt( &ok ) ); + if ( metaEnum.isValid() ) { - v = defaultValue; + if ( !ok || !metaEnum.valueToKey( static_cast( v ) ) ) + { + v = defaultValue; + } + else + { + // found setting as an integer + // convert the setting to the new form (string) + setEnumValue( key, v, section ); + } } - else if ( flag && !metaEnum.valueToKeys( static_cast( v ) ).size() ) + } + + return v; + } + + /** + * Set the value of a setting based on an enum. + * The setting will be saved as string. + * \note The enum needs to be declared with Q_ENUM, and flags with Q_FLAG (not Q_FLAGS). + * \see enumValue + * \see setFlagValue + */ + template + void setEnumValue( const QString &key, const T &value, + const Section section = NoSection ) + { + QMetaEnum metaEnum = QMetaEnum::fromType(); + Q_ASSERT( metaEnum.isValid() ); + if ( metaEnum.isValid() ) + { + setValue( key, metaEnum.valueToKey( value ), section ); + } + else + { + QgsDebugMsg( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ); + } + } + + /** + * Return the setting value for a setting based on a flag. + * This forces the output to be a valid and existing entry of the flag. + * Hence if the setting value is incorrect, the given default value is returned. + * This tries first with setting as a string (using a byte array) and then as an integer value. + * \note The flag needs to be declared with Q_FLAG (not Q_FLAGS). + * \see setFlagValue + * \see enumValue + */ + template + T flagValue( const QString &key, const T &defaultValue, + const Section section = NoSection ) + { + QMetaEnum metaEnum = QMetaEnum::fromType(); + Q_ASSERT( metaEnum.isValid() ); + if ( !metaEnum.isValid() ) + { + QgsDebugMsg( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ); + } + + T v; + bool ok = false; + + if ( metaEnum.isValid() ) + { + // read as string + QByteArray ba = value( key, metaEnum.valueToKeys( defaultValue ) ).toString().toUtf8(); + const char *vs = ba.data(); + v = static_cast( metaEnum.keysToValue( vs, &ok ) ); + } + if ( !ok ) + { + // if failed, try to read as int (old behavior) + // this code shall be removed later (probably after QGIS 3.4 LTR for 3.6) + // then the method could be marked as const + v = T( value( key, static_cast( defaultValue ), section ).toInt( &ok ) ); + if ( metaEnum.isValid() ) { - v = defaultValue; + if ( !ok || !metaEnum.valueToKeys( static_cast( v ) ).size() ) + { + v = defaultValue; + } + else + { + // found setting as an integer + // convert the setting to the new form (string) + setFlagValue( key, v, section ); + } } } + return v; } + + /** + * Set the value of a setting based on a flaf. + * The setting will be saved as string. + * \note The flag needs to be declared with Q_FLAG (not Q_FLAGS). + * \see flagValue + * \see setEnumValue + */ + template + void setFlagValue( const QString &key, const T &value, + const Section section = NoSection ) + { + QMetaEnum metaEnum = QMetaEnum::fromType(); + Q_ASSERT( metaEnum.isValid() ); + if ( metaEnum.isValid() ) + { + setValue( key, metaEnum.valueToKeys( value ), section ); + } + else + { + QgsDebugMsg( "Invalid metaenum. Enum probably misses Q_ENUM or Q_FLAG declaration." ); + } + } #endif /** diff --git a/src/core/qgssnappingconfig.cpp b/src/core/qgssnappingconfig.cpp index 5d0eead65b2d..40be284f2e7d 100644 --- a/src/core/qgssnappingconfig.cpp +++ b/src/core/qgssnappingconfig.cpp @@ -368,7 +368,7 @@ bool QgsSnappingConfig::addLayers( const QList &layers ) { bool changed = false; bool enabled = QgsSettings().value( QStringLiteral( "/qgis/digitizing/default_snap_enabled" ), true ).toBool(); - SnappingType type = ( SnappingType )QgsSettings().value( QStringLiteral( "/qgis/digitizing/default_snap_type" ), Vertex ).toInt(); + SnappingType type = QgsSettings().enumValue( QStringLiteral( "/qgis/digitizing/default_snap_type" ), Vertex ); double tolerance = QgsSettings().value( QStringLiteral( "/qgis/digitizing/default_snapping_tolerance" ), Qgis::DEFAULT_SNAP_TOLERANCE ).toDouble(); QgsTolerance::UnitType units = QgsSettings().enumValue( QStringLiteral( "/qgis/digitizing/default_snapping_tolerance_unit" ), Qgis::DEFAULT_SNAP_UNITS ); diff --git a/src/core/qgsvectorlayer.cpp b/src/core/qgsvectorlayer.cpp index 315308fe50bc..bbe1965da346 100644 --- a/src/core/qgsvectorlayer.cpp +++ b/src/core/qgsvectorlayer.cpp @@ -165,7 +165,7 @@ QgsVectorLayer::QgsVectorLayer( const QString &vectorLayerPath, // Default simplify drawing settings QgsSettings settings; - mSimplifyMethod.setSimplifyHints( settings.enumValue( QStringLiteral( "qgis/simplifyDrawingHints" ), mSimplifyMethod.simplifyHints(), QgsSettings::NoSection, true ) ); + mSimplifyMethod.setSimplifyHints( settings.flagValue( QStringLiteral( "qgis/simplifyDrawingHints" ), mSimplifyMethod.simplifyHints(), QgsSettings::NoSection ) ); mSimplifyMethod.setSimplifyAlgorithm( settings.enumValue( QStringLiteral( "qgis/simplifyAlgorithm" ), mSimplifyMethod.simplifyAlgorithm() ) ); mSimplifyMethod.setThreshold( settings.value( QStringLiteral( "qgis/simplifyDrawingTol" ), mSimplifyMethod.threshold() ).toFloat() ); mSimplifyMethod.setForceLocalOptimization( settings.value( QStringLiteral( "qgis/simplifyLocal" ), mSimplifyMethod.forceLocalOptimization() ).toBool() ); diff --git a/src/gui/layout/qgslayoutviewtooladditem.cpp b/src/gui/layout/qgslayoutviewtooladditem.cpp index a087749c9d18..749df4525ba8 100644 --- a/src/gui/layout/qgslayoutviewtooladditem.cpp +++ b/src/gui/layout/qgslayoutviewtooladditem.cpp @@ -135,7 +135,7 @@ void QgsLayoutViewToolAddItem::layoutReleaseEvent( QgsLayoutViewMouseEvent *even QgsSettings settings; settings.setValue( QStringLiteral( "LayoutDesigner/lastItemWidth" ), item->sizeWithUnits().width() ); settings.setValue( QStringLiteral( "LayoutDesigner/lastItemHeight" ), item->sizeWithUnits().height() ); - settings.setValue( QStringLiteral( "LayoutDesigner/lastSizeUnit" ), static_cast< int >( item->sizeWithUnits().units() ) ); + settings.setEnumValue( QStringLiteral( "LayoutDesigner/lastSizeUnit" ), item->sizeWithUnits().units() ); QgsGui::layoutItemGuiRegistry()->newItemAddedToLayout( mItemMetadataId, item ); diff --git a/src/gui/qgscolorwidgets.cpp b/src/gui/qgscolorwidgets.cpp index e82dbeccc38c..3f6fef5e812d 100644 --- a/src/gui/qgscolorwidgets.cpp +++ b/src/gui/qgscolorwidgets.cpp @@ -1509,7 +1509,7 @@ void QgsColorTextWidget::showMenu() //save format setting QgsSettings settings; - settings.setValue( QStringLiteral( "ColorWidgets/textWidgetFormat" ), ( int )mFormat ); + settings.setEnumValue( QStringLiteral( "ColorWidgets/textWidgetFormat" ), mFormat ); updateText(); } diff --git a/src/providers/grass/qgsgrassoptions.cpp b/src/providers/grass/qgsgrassoptions.cpp index 67d4c2a201e0..b418aea6c024 100644 --- a/src/providers/grass/qgsgrassoptions.cpp +++ b/src/providers/grass/qgsgrassoptions.cpp @@ -155,8 +155,8 @@ void QgsGrassOptions::saveOptions() QgsGrass::instance()->setModulesDebug( mModulesDebugCheckBox->isChecked() ); // Browser - settings.setValue( mImportSettingsPath + "/crsTransform", - mCrsTransformationComboBox->currentData().toInt() ); + settings.setEnumValue( mImportSettingsPath + "/crsTransform", + ( QgsRasterProjector::Precision )mCrsTransformationComboBox->currentData().toInt() ); settings.setValue( mImportSettingsPath + "/external", mImportExternalCheckBox->isChecked() ); diff --git a/src/providers/postgres/qgspostgresconn.cpp b/src/providers/postgres/qgspostgresconn.cpp index 2e6f31e65960..bda652650ecc 100644 --- a/src/providers/postgres/qgspostgresconn.cpp +++ b/src/providers/postgres/qgspostgresconn.cpp @@ -1742,7 +1742,7 @@ QgsDataSourceUri QgsPostgresConn::connUri( const QString &connName ) QString database = settings.value( key + "/database" ).toString(); bool useEstimatedMetadata = settings.value( key + "/estimatedMetadata", false ).toBool(); - int sslmode = settings.value( key + "/sslmode", QgsDataSourceUri::SslPrefer ).toInt(); + QgsDataSourceUri::SslMode sslmode = settings.enumValue( key + "/sslmode", QgsDataSourceUri::SslPrefer ); QString username; QString password; @@ -1778,11 +1778,11 @@ QgsDataSourceUri QgsPostgresConn::connUri( const QString &connName ) QgsDataSourceUri uri; if ( !service.isEmpty() ) { - uri.setConnection( service, database, username, password, ( QgsDataSourceUri::SslMode ) sslmode, authcfg ); + uri.setConnection( service, database, username, password, sslmode, authcfg ); } else { - uri.setConnection( host, port, database, username, password, ( QgsDataSourceUri::SslMode ) sslmode, authcfg ); + uri.setConnection( host, port, database, username, password, sslmode, authcfg ); } uri.setUseEstimatedMetadata( useEstimatedMetadata ); diff --git a/tests/src/app/testqgisappclipboard.cpp b/tests/src/app/testqgisappclipboard.cpp index 814919fc5bea..b321b773d97a 100644 --- a/tests/src/app/testqgisappclipboard.cpp +++ b/tests/src/app/testqgisappclipboard.cpp @@ -140,12 +140,12 @@ void TestQgisAppClipboard::copyToText() // attributes only QgsSettings settings; - settings.setValue( QStringLiteral( "/qgis/copyFeatureFormat" ), QgsClipboard::AttributesOnly ); + settings.setEnumValue( QStringLiteral( "/qgis/copyFeatureFormat" ), QgsClipboard::AttributesOnly ); QString result = mQgisApp->clipboard()->generateClipboardText(); QCOMPARE( result, QString( "int_field\tstring_field\n9\tval\n19\tval2" ) ); // attributes with WKT - settings.setValue( QStringLiteral( "/qgis/copyFeatureFormat" ), QgsClipboard::AttributesWithWKT ); + settings.setEnumValue( QStringLiteral( "/qgis/copyFeatureFormat" ), QgsClipboard::AttributesWithWKT ); result = mQgisApp->clipboard()->generateClipboardText(); QCOMPARE( result, QString( "wkt_geom\tint_field\tstring_field\nPoint (5 6)\t9\tval\nPoint (7 8)\t19\tval2" ) ); @@ -155,7 +155,7 @@ void TestQgisAppClipboard::copyToText() QCOMPARE( result, QString( "
wkt_geomint_fieldstring_field
Point (5 6)9val
Point (7 8)19val2
" ) ); // GeoJSON - settings.setValue( QStringLiteral( "/qgis/copyFeatureFormat" ), QgsClipboard::GeoJSON ); + settings.setEnumValue( QStringLiteral( "/qgis/copyFeatureFormat" ), QgsClipboard::GeoJSON ); result = mQgisApp->clipboard()->generateClipboardText(); QString expected = "{ \"type\": \"FeatureCollection\",\n \"features\":[\n" "{\n \"type\":\"Feature\",\n" diff --git a/tests/src/core/testqgssettings.cpp b/tests/src/core/testqgssettings.cpp index bda210b47d09..3da66e690e2e 100644 --- a/tests/src/core/testqgssettings.cpp +++ b/tests/src/core/testqgssettings.cpp @@ -31,6 +31,7 @@ class TestQgsSettings : public QObject private slots: void enumValue(); + void flagValue(); }; @@ -40,6 +41,7 @@ void TestQgsSettings::enumValue() // assign to inexisting value settings.setValue( QStringLiteral( "qgis/testing/my_value_for_units" ), -1 ); + settings.setValue( QStringLiteral( "qgis/testing/my_value_for_units_as_string" ), QStringLiteral( "myString" ) ); // just to be sure it really doesn't exist QVERIFY( static_cast( QgsUnitTypes::LayoutMeters ) != -1 ); @@ -50,13 +52,25 @@ void TestQgsSettings::enumValue() // enum method returns default value if current setting is incorrect QgsUnitTypes::LayoutUnit v2 = settings.enumValue( QStringLiteral( "qgis/testing/my_value_for_units" ), QgsUnitTypes::LayoutMeters ); QCOMPARE( v2, QgsUnitTypes::LayoutMeters ); + QgsUnitTypes::LayoutUnit v2s = settings.enumValue( QStringLiteral( "qgis/testing/my_value_for_units_as_string" ), QgsUnitTypes::LayoutMeters ); + QCOMPARE( v2s, QgsUnitTypes::LayoutMeters ); // test a different value than default settings.setValue( QStringLiteral( "qgis/testing/my_value_for_units" ), QgsUnitTypes::LayoutCentimeters ); QgsUnitTypes::LayoutUnit v3 = settings.enumValue( QStringLiteral( "qgis/testing/my_value_for_units" ), QgsUnitTypes::LayoutMeters ); QCOMPARE( v3, QgsUnitTypes::LayoutCentimeters ); + settings.setEnumValue( QStringLiteral( "qgis/testing/my_value_for_units" ), QgsUnitTypes::LayoutCentimeters ); + // auto conversion of old settings (int to str) + QCOMPARE( settings.value( "qgis/testing/my_value_for_units" ).toString(), QStringLiteral( "LayoutCentimeters" ) ); + QgsUnitTypes::LayoutUnit v3s = settings.enumValue( QStringLiteral( "qgis/testing/my_value_for_units" ), QgsUnitTypes::LayoutMeters ); + QCOMPARE( v3s, QgsUnitTypes::LayoutCentimeters ); + QString v3ss = settings.value( QStringLiteral( "qgis/testing/my_value_for_units" ), QStringLiteral( "myDummyValue" ) ).toString(); + QCOMPARE( v3ss, QStringLiteral( "LayoutCentimeters" ) ); +} - // test for flags +void TestQgsSettings::flagValue() +{ + QgsSettings settings; QgsMapLayerProxyModel::Filters pointAndLine = QgsMapLayerProxyModel::Filters( QgsMapLayerProxyModel::PointLayer | QgsMapLayerProxyModel::LineLayer ); QgsMapLayerProxyModel::Filters pointAndPolygon = QgsMapLayerProxyModel::Filters( QgsMapLayerProxyModel::PointLayer | QgsMapLayerProxyModel::PolygonLayer ); settings.setValue( QStringLiteral( "qgis/testing/my_value_for_a_flag" ), 1e8 ); // invalid @@ -64,8 +78,16 @@ void TestQgsSettings::enumValue() QCOMPARE( v4, pointAndLine ); settings.setValue( QStringLiteral( "qgis/testing/my_value_for_a_flag" ), static_cast( pointAndPolygon ) ); - QgsMapLayerProxyModel::Filters v5 = settings.enumValue( QStringLiteral( "qgis/testing/my_value_for_a_flag" ), pointAndLine, QgsSettings::NoSection, true ); + QgsMapLayerProxyModel::Filters v5 = settings.flagValue( QStringLiteral( "qgis/testing/my_value_for_a_flag" ), pointAndLine, QgsSettings::NoSection ); QCOMPARE( v5, pointAndPolygon ); + // auto conversion of old settings (int to str) + QCOMPARE( settings.value( "qgis/testing/my_value_for_a_flag" ).toString(), QStringLiteral( "PointLayer|PolygonLayer" ) ); + + settings.setFlagValue( QStringLiteral( "qgis/testing/my_value_for_a_flag_as_string" ), pointAndPolygon, QgsSettings::NoSection ); + QgsMapLayerProxyModel::Filters v5s = settings.flagValue( QStringLiteral( "qgis/testing/my_value_for_a_flag_as_string" ), pointAndLine, QgsSettings::NoSection ); + QCOMPARE( v5s, pointAndPolygon ); + QString v5ss = settings.value( QStringLiteral( "qgis/testing/my_value_for_a_flag_as_string" ), QStringLiteral( "myDummyString" ), QgsSettings::NoSection ).toString(); + QCOMPARE( v5ss, QStringLiteral( "PointLayer|PolygonLayer" ) ); }