Skip to content

Commit

Permalink
GUI localization tweaks
Browse files Browse the repository at this point in the history
Part of QEP qgis/QGIS-Enhancement-Proposals#210

Locale support for numeric input and display: revision and enhancements

Grant proposal 2021

Affected widgets/classes:

- QgisApp
- QgsDecorationGridDialog
- QgsHandleBadLayers
- QgsPointRotationItem
- QgsSnappingLayerTreeModel
- QgsStatisticalSummaryDockWidget
- QgsDirectoryParamWidget
- QgsClassificationStandardDeviation
- QgsLayoutRuler
- QgsMeshRendererScalarSettingsWidget
- QgsMeshRendererVectorSettingsWidget
- QgsMeshVariableStrokeWidthWidget
- QgsVectorLayerSaveAsDialog
- QgsProcessingNumberParameterDefinitionWidget
- QgsProcessingRangeParameterDefinitionWidget
- QgsProcessingDistanceParameterDefinitionWidget
- QgsAbstractRelationEditorWidget
- QgsCoordinateOperationWidget
- QgsDoubleValidator (added ::setMaxDecimals( int decimals ) )
- QgsExtentWidget
- QgsMapToolIdentify
- QgsPropertyAssistantWidget
- QgsRasterHistogramWidget
- QgsRendererRasterPropertiesWidget
- QgsDashSpaceWidget
- QgsDataDefinedSizeLegendWidget
- QgsGraduatedSymbolRendererWidget
- QgsGraduatedSymbolRendererWidget
  • Loading branch information
elpaso committed Jun 22, 2021
1 parent c2a1d87 commit 357177d
Show file tree
Hide file tree
Showing 41 changed files with 625 additions and 487 deletions.
20 changes: 16 additions & 4 deletions python/gui/auto_generated/qgsdoublevalidator.sip.in
Expand Up @@ -50,26 +50,38 @@ Constructor for QgsDoubleValidator.
:param parent: parent object
%End

QgsDoubleValidator( double bottom, double top, int decimal, QObject *parent );
QgsDoubleValidator( double bottom, double top, int decimals, QObject *parent );
%Docstring
Constructor for QgsDoubleValidator.

:param bottom: the minimal range limit accepted by the validator
:param top: the maximal range limit accepted by the validator
:param decimal: the number of decimals accepted by the validator
:param decimals: the number of decimals accepted by the validator
:param parent: parent object
%End

QgsDoubleValidator( int decimal, QObject *parent );
QgsDoubleValidator( int decimals, QObject *parent );
%Docstring
Constructor for QgsDoubleValidator.

:param decimal: the number of decimals accepted by the validator
:param decimals: the number of decimals accepted by the validator
:param parent: parent object

.. versionadded:: 3.16
%End

void setMaxDecimals( int maxDecimals );
%Docstring
Sets the number of decimals accepted by the validator to ``maxDecimals``.

.. warning::

setting decimals overrides any custom regular expression that was previosly set

.. versionadded:: 3.22
%End



QValidator::State validate( QString &input ) const;
%Docstring
Expand Down
34 changes: 17 additions & 17 deletions src/app/decorations/qgsdecorationgriddialog.cpp
Expand Up @@ -29,6 +29,7 @@
#include "qgsgui.h"
#include "qgslinesymbol.h"
#include "qgsmarkersymbol.h"
#include "qgsdoublevalidator.h"

QgsDecorationGridDialog::QgsDecorationGridDialog( QgsDecorationGrid &deco, QWidget *parent )
: QDialog( parent )
Expand Down Expand Up @@ -85,14 +86,13 @@ QgsDecorationGridDialog::QgsDecorationGridDialog( QgsDecorationGrid &deco, QWidg

void QgsDecorationGridDialog::updateGuiElements()
{
// blockAllSignals( true );

grpEnable->setChecked( mDeco.enabled() );

mIntervalXEdit->setText( QString::number( mDeco.gridIntervalX() ) );
mIntervalYEdit->setText( QString::number( mDeco.gridIntervalY() ) );
mOffsetXEdit->setText( QString::number( mDeco.gridOffsetX() ) );
mOffsetYEdit->setText( QString::number( mDeco.gridOffsetY() ) );
mIntervalXEdit->setValue( mDeco.gridIntervalX() );
mIntervalYEdit->setValue( mDeco.gridIntervalY() );
mOffsetXEdit->setValue( mDeco.gridOffsetX() );
mOffsetYEdit->setValue( mDeco.gridOffsetY() );

mGridTypeComboBox->setCurrentIndex( mGridTypeComboBox->findData( mDeco.gridStyle() ) );
mDrawAnnotationCheckBox->setChecked( mDeco.showGridAnnotation() );
Expand Down Expand Up @@ -121,10 +121,10 @@ void QgsDecorationGridDialog::updateDecoFromGui()
mDeco.setDirty( false );
mDeco.setEnabled( grpEnable->isChecked() );

mDeco.setGridIntervalX( mIntervalXEdit->text().toDouble() );
mDeco.setGridIntervalY( mIntervalYEdit->text().toDouble() );
mDeco.setGridOffsetX( mOffsetXEdit->text().toDouble() );
mDeco.setGridOffsetY( mOffsetYEdit->text().toDouble() );
mDeco.setGridIntervalX( mIntervalXEdit->value() );
mDeco.setGridIntervalY( mIntervalYEdit->value() );
mDeco.setGridOffsetX( mOffsetXEdit->value() );
mDeco.setGridOffsetY( mOffsetYEdit->value() );
mDeco.setGridStyle( static_cast< QgsDecorationGrid::GridStyle >( mGridTypeComboBox->currentData().toInt() ) );

mDeco.setTextFormat( mAnnotationFontButton->textFormat() );
Expand Down Expand Up @@ -213,10 +213,10 @@ void QgsDecorationGridDialog::mPbtnUpdateFromLayer_clicked()
double values[4];
if ( mDeco.getIntervalFromCurrentLayer( values ) )
{
mIntervalXEdit->setText( QString::number( values[0] ) );
mIntervalYEdit->setText( QString::number( values[1] ) );
mOffsetXEdit->setText( QString::number( values[2] ) );
mOffsetYEdit->setText( QString::number( values[3] ) );
mIntervalXEdit->setValue( values[0] );
mIntervalYEdit->setValue( values[1] );
mOffsetXEdit->setValue( values[2] );
mOffsetYEdit->setValue( values[3] );
if ( values[0] >= 1 )
mCoordinatePrecisionSpinBox->setValue( 0 );
else
Expand All @@ -231,10 +231,10 @@ void QgsDecorationGridDialog::updateInterval( bool force )
double values[4];
if ( mDeco.getIntervalFromExtent( values, true ) )
{
mIntervalXEdit->setText( QString::number( values[0] ) );
mIntervalYEdit->setText( QString::number( values[1] ) );
mOffsetXEdit->setText( QString::number( values[2] ) );
mOffsetYEdit->setText( QString::number( values[3] ) );
mIntervalXEdit->setValue( values[0] );
mIntervalYEdit->setValue( values[1] );
mOffsetXEdit->setValue( values[2] );
mOffsetYEdit->setValue( values[3] );
// also update coord. precision
// if interval >= 1, set precision=0 because we have a rounded value
// else set it to previous default of 3
Expand Down
4 changes: 2 additions & 2 deletions src/app/qgisapp.cpp
Expand Up @@ -17049,11 +17049,11 @@ QgsFeature QgisApp::duplicateFeatures( QgsMapLayer *mlayer, const QgsFeature &fe
const auto duplicatedFeatureContextLayers = duplicateFeatureContext.layers();
for ( QgsVectorLayer *chl : duplicatedFeatureContextLayers )
{
childrenInfo += ( tr( "%1 children on layer %2 duplicated" ).arg( QString::number( duplicateFeatureContext.duplicatedFeatures( chl ).size() ), chl->name() ) );
childrenInfo += ( tr( "%1 children on layer %2 duplicated" ).arg( QLocale().toString( duplicateFeatureContext.duplicatedFeatures( chl ).size() ), chl->name() ) );
}
}

visibleMessageBar()->pushMessage( tr( "%1 features on layer %2 duplicated\n%3" ).arg( QString::number( featureCount ), layer->name(), childrenInfo ), Qgis::MessageLevel::Success );
visibleMessageBar()->pushMessage( tr( "%1 features on layer %2 duplicated\n%3" ).arg( QLocale().toString( featureCount ), layer->name(), childrenInfo ), Qgis::MessageLevel::Success );

return QgsFeature();
}
Expand Down
2 changes: 1 addition & 1 deletion src/app/qgshandlebadlayers.cpp
Expand Up @@ -581,7 +581,7 @@ void QgsHandleBadLayers::autoFind()
progressDialog.setValue( i );
QChar sentenceEnd = ( name.length() > 15 ) ? QChar( 0x2026 ) : '.';
progressDialog.setLabelText( QObject::tr( "Searching for file: %1 \n [ %2 of %3 ] " ).arg( name.left( 15 ) + sentenceEnd,
QString::number( i + 1 ), QString::number( layersToFind.size() ) ) );
QLocale().toString( i + 1 ), QLocale().toString( layersToFind.size() ) ) );
progressDialog.open();

QVariantMap providerMap = QgsProviderRegistry::instance()->decodeUri( provider, dataInfo.absoluteFilePath() );
Expand Down
2 changes: 1 addition & 1 deletion src/app/qgsmaptoolselectutils.cpp
Expand Up @@ -570,7 +570,7 @@ QString QgsMapToolSelectUtils::QgsMapToolSelectMenuActions::textForChooseAll( qi
if ( featureCount < 0 )
featureCountText = tr( "Searching…" );
else
featureCountText = QString::number( featureCount );
featureCountText = QLocale().toString( featureCount );

switch ( mBehavior )
{
Expand Down
3 changes: 2 additions & 1 deletion src/app/qgspointrotationitem.cpp
Expand Up @@ -15,6 +15,7 @@

#include "qgspointrotationitem.h"
#include <QPainter>
#include <QLocale>
#include <cmath>
#include "qgsguiutils.h"

Expand Down Expand Up @@ -77,7 +78,7 @@ void QgsPointRotationItem::paint( QPainter *painter )
bufferPen.setWidthF( QgsGuiUtils::scaleIconSize( 4 ) );
QFontMetricsF fm( mFont );
QPainterPath label;
label.addText( mPixmap.width(), mPixmap.height() / 2.0 + fm.height() / 2.0, mFont, QString::number( mRotation ) );
label.addText( mPixmap.width(), mPixmap.height() / 2.0 + fm.height() / 2.0, mFont, QLocale().toString( mRotation ) );
painter->setPen( bufferPen );
painter->setBrush( Qt::NoBrush );
painter->drawPath( label );
Expand Down
6 changes: 3 additions & 3 deletions src/app/qgssnappinglayertreemodel.cpp
Expand Up @@ -626,7 +626,7 @@ QVariant QgsSnappingLayerTreeModel::data( const QModelIndex &idx, int role ) con
{
if ( role == Qt::DisplayRole )
{
return QString::number( ls.tolerance() );
return QLocale().toString( ls.tolerance() );
}

if ( role == Qt::UserRole )
Expand Down Expand Up @@ -683,7 +683,7 @@ QVariant QgsSnappingLayerTreeModel::data( const QModelIndex &idx, int role ) con
}
else
{
return QString::number( ls.minimumScale() );
return QLocale().toString( ls.minimumScale() );
}
}

Expand All @@ -703,7 +703,7 @@ QVariant QgsSnappingLayerTreeModel::data( const QModelIndex &idx, int role ) con
}
else
{
return QString::number( ls.maximumScale() );
return QLocale().toString( ls.maximumScale() );
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/app/qgsstatisticalsummarydockwidget.cpp
Expand Up @@ -264,15 +264,15 @@ void QgsStatisticalSummaryDockWidget::updateNumericStatistics()
{
double val = stats.statistic( stat );
addRow( row, QgsStatisticalSummary::displayName( stat ),
std::isnan( val ) ? QString() : QString::number( val ),
std::isnan( val ) ? QString() : QLocale().toString( val ),
stats.count() != 0 );
row++;
}

if ( mStatsActions.value( MISSING_VALUES )->isChecked() )
{
addRow( row, tr( "Missing (null) values" ),
QString::number( missingValues ),
QLocale().toString( missingValues ),
stats.count() != 0 || missingValues != 0 );
row++;
}
Expand Down
4 changes: 2 additions & 2 deletions src/core/browser/qgsdirectoryitem.cpp
Expand Up @@ -533,11 +533,11 @@ QgsDirectoryParamWidget::QgsDirectoryParamWidget( const QString &path, QWidget *
QString size;
if ( fi.size() > 1024 )
{
size = QStringLiteral( "%1 KiB" ).arg( QString::number( fi.size() / 1024.0, 'f', 1 ) );
size = QStringLiteral( "%1 KiB" ).arg( QLocale().toString( fi.size() / 1024.0, 'f', 1 ) );
}
else if ( fi.size() > 1.048576e6 )
{
size = QStringLiteral( "%1 MiB" ).arg( QString::number( fi.size() / 1.048576e6, 'f', 1 ) );
size = QStringLiteral( "%1 MiB" ).arg( QLocale().toString( fi.size() / 1.048576e6, 'f', 1 ) );
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion src/core/classification/qgsclassificationlogarithmic.cpp
Expand Up @@ -111,7 +111,7 @@ QString QgsClassificationLogarithmic::valueToLabel( double value ) const
{
if ( value <= 0 )
{
return QString::number( value );
return QLocale().toString( value );
}
else
{
Expand Down
Expand Up @@ -121,7 +121,7 @@ QString QgsClassificationStandardDeviation::labelForRange( const double lowerVal
QString QgsClassificationStandardDeviation::valueToLabel( const double value ) const
{
double normalized = ( value - mEffectiveSymmetryPoint ) / mStdDev;
return QObject::tr( " %1 Std Dev" ).arg( QString::number( normalized, 'f', 2 ) );
return QObject::tr( " %1 Std Dev" ).arg( QLocale().toString( normalized, 'f', 2 ) );
}


Expand Down
6 changes: 3 additions & 3 deletions src/gui/layout/qgslayoutruler.cpp
Expand Up @@ -137,7 +137,7 @@ void QgsLayoutRuler::paintEvent( QPaintEvent *event )

//draw large division and text
p.drawLine( pixelCoord, 0, pixelCoord, mRulerMinSize );
p.drawText( QPointF( pixelCoord + mPixelsBetweenLineAndText, mTextBaseline ), QString::number( markerPos ) );
p.drawText( QPointF( pixelCoord + mPixelsBetweenLineAndText, mTextBaseline ), QLocale().toString( markerPos ) );

//draw small divisions
drawSmallDivisions( &p, markerPos, numSmallDivisions, mmDisplay, endX );
Expand Down Expand Up @@ -186,7 +186,7 @@ void QgsLayoutRuler::paintEvent( QPaintEvent *event )
double pixelCoord = mTransform.map( QPointF( 0, beforePageCoord ) ).y();
p.drawLine( 0, pixelCoord, mRulerMinSize, pixelCoord );
//calc size of label
QString label = QString::number( beforePageCoord );
QString label = QLocale().toString( beforePageCoord );
int labelSize = mRulerFontMetrics->boundingRect( label ).width();

//draw label only if it fits in before start of next page
Expand Down Expand Up @@ -234,7 +234,7 @@ void QgsLayoutRuler::paintEvent( QPaintEvent *event )
double pixelCoord = mTransform.map( QPointF( 0, totalCoord ) ).y();
p.drawLine( 0, pixelCoord, mRulerMinSize, pixelCoord );
//calc size of label
QString label = QString::number( pageCoord );
QString label = QLocale().toString( pageCoord );
int labelSize = mRulerFontMetrics->boundingRect( label ).width();

//draw label only if it fits in before start of next page
Expand Down
37 changes: 21 additions & 16 deletions src/gui/mesh/qgsmeshrendererscalarsettingswidget.cpp
Expand Up @@ -31,6 +31,11 @@ QgsMeshRendererScalarSettingsWidget::QgsMeshRendererScalarSettingsWidget( QWidge
{
setupUi( this );

mScalarMinSpinBox->setClearValueMode( QgsDoubleSpinBox::ClearValueMode::MinimumValue );
mScalarMinSpinBox->setSpecialValueText( QString( ) );
mScalarMaxSpinBox->setClearValueMode( QgsDoubleSpinBox::ClearValueMode::MinimumValue );
mScalarMaxSpinBox->setSpecialValueText( QString( ) );

// add items to data interpolation combo box
mScalarInterpolationTypeComboBox->addItem( tr( "None" ), QgsMeshRendererScalarSettings::None );
mScalarInterpolationTypeComboBox->addItem( tr( "Neighbour Average" ), QgsMeshRendererScalarSettings::NeighbourAverage );
Expand All @@ -44,10 +49,10 @@ QgsMeshRendererScalarSettingsWidget::QgsMeshRendererScalarSettingsWidget( QWidge

// connect
connect( mScalarRecalculateMinMaxButton, &QPushButton::clicked, this, &QgsMeshRendererScalarSettingsWidget::recalculateMinMaxButtonClicked );
connect( mScalarMinLineEdit, &QLineEdit::textChanged, this, &QgsMeshRendererScalarSettingsWidget::minMaxChanged );
connect( mScalarMaxLineEdit, &QLineEdit::textChanged, this, &QgsMeshRendererScalarSettingsWidget::minMaxChanged );
connect( mScalarMinLineEdit, &QLineEdit::textEdited, this, &QgsMeshRendererScalarSettingsWidget::minMaxEdited );
connect( mScalarMaxLineEdit, &QLineEdit::textEdited, this, &QgsMeshRendererScalarSettingsWidget::minMaxEdited );
connect( mScalarMinSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, [ = ]( double ) { minMaxChanged(); } );
connect( mScalarMaxSpinBox, qOverload<double>( &QgsDoubleSpinBox::valueChanged ), this, [ = ]( double ) { minMaxChanged(); } );
connect( mScalarMinSpinBox, &QgsDoubleSpinBox::editingFinished, this, &QgsMeshRendererScalarSettingsWidget::minMaxEdited );
connect( mScalarMaxSpinBox, &QgsDoubleSpinBox::editingFinished, this, &QgsMeshRendererScalarSettingsWidget::minMaxEdited );
connect( mScalarEdgeStrokeWidthVariableRadioButton, &QRadioButton::toggled, this, &QgsMeshRendererScalarSettingsWidget::onEdgeStrokeWidthMethodChanged );

connect( mScalarColorRampShaderWidget, &QgsColorRampShaderWidget::widgetChanged, this, &QgsMeshRendererScalarSettingsWidget::widgetChanged );
Expand Down Expand Up @@ -80,7 +85,7 @@ QgsMeshRendererScalarSettings QgsMeshRendererScalarSettingsWidget::settings() co
{
QgsMeshRendererScalarSettings settings;
settings.setColorRampShader( mScalarColorRampShaderWidget->shader() );
settings.setClassificationMinimumMaximum( lineEditValue( mScalarMinLineEdit ), lineEditValue( mScalarMaxLineEdit ) );
settings.setClassificationMinimumMaximum( spinBoxValue( mScalarMinSpinBox ), spinBoxValue( mScalarMaxSpinBox ) );
settings.setOpacity( mOpacityWidget->opacity() );
settings.setDataResamplingMethod( dataIntepolationMethod() );

Expand Down Expand Up @@ -113,8 +118,8 @@ void QgsMeshRendererScalarSettingsWidget::syncToLayer( )
const double min = settings.classificationMinimum();
const double max = settings.classificationMaximum();

whileBlocking( mScalarMinLineEdit )->setText( QString::number( min ) );
whileBlocking( mScalarMaxLineEdit )->setText( QString::number( max ) );
whileBlocking( mScalarMinSpinBox )->setValue( min );
whileBlocking( mScalarMaxSpinBox )->setValue( max );
whileBlocking( mScalarColorRampShaderWidget )->setFromShader( shader );
whileBlocking( mScalarColorRampShaderWidget )->setMinimumMaximum( min, max );
whileBlocking( mOpacityWidget )->setOpacity( settings.opacity() );
Expand Down Expand Up @@ -149,27 +154,27 @@ void QgsMeshRendererScalarSettingsWidget::syncToLayer( )
onEdgeStrokeWidthMethodChanged();
}

double QgsMeshRendererScalarSettingsWidget::lineEditValue( const QLineEdit *lineEdit ) const
double QgsMeshRendererScalarSettingsWidget::spinBoxValue( const QgsDoubleSpinBox *spinBox ) const
{
if ( lineEdit->text().isEmpty() )
if ( spinBox->value() == spinBox->clearValue() )
{
return std::numeric_limits<double>::quiet_NaN();
}

return lineEdit->text().toDouble();
return spinBox->value();
}

void QgsMeshRendererScalarSettingsWidget::minMaxChanged()
{
double min = lineEditValue( mScalarMinLineEdit );
double max = lineEditValue( mScalarMaxLineEdit );
const double min = spinBoxValue( mScalarMinSpinBox );
const double max = spinBoxValue( mScalarMaxSpinBox );
mScalarColorRampShaderWidget->setMinimumMaximum( min, max );
}

void QgsMeshRendererScalarSettingsWidget::minMaxEdited()
{
double min = lineEditValue( mScalarMinLineEdit );
double max = lineEditValue( mScalarMaxLineEdit );
const double min = spinBoxValue( mScalarMinSpinBox );
const double max = spinBoxValue( mScalarMaxSpinBox );
mScalarColorRampShaderWidget->setMinimumMaximumAndClassify( min, max );
}

Expand All @@ -178,8 +183,8 @@ void QgsMeshRendererScalarSettingsWidget::recalculateMinMaxButtonClicked()
const QgsMeshDatasetGroupMetadata metadata = mMeshLayer->datasetGroupMetadata( mActiveDatasetGroup );
double min = metadata.minimum();
double max = metadata.maximum();
whileBlocking( mScalarMinLineEdit )->setText( QString::number( min ) );
whileBlocking( mScalarMaxLineEdit )->setText( QString::number( max ) );
whileBlocking( mScalarMinSpinBox )->setValue( min );
whileBlocking( mScalarMaxSpinBox )->setValue( max );
mScalarColorRampShaderWidget->setMinimumMaximumAndClassify( min, max );
}

Expand Down
2 changes: 1 addition & 1 deletion src/gui/mesh/qgsmeshrendererscalarsettingswidget.h
Expand Up @@ -67,7 +67,7 @@ class QgsMeshRendererScalarSettingsWidget : public QWidget, private Ui::QgsMeshR
void onEdgeStrokeWidthMethodChanged();

private:
double lineEditValue( const QLineEdit *lineEdit ) const;
double spinBoxValue( const QgsDoubleSpinBox *spinBox ) const;
QgsMeshRendererScalarSettings::DataResamplingMethod dataIntepolationMethod() const;

bool dataIsDefinedOnFaces() const;
Expand Down

0 comments on commit 357177d

Please sign in to comment.