mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-27 00:33:48 -05:00
Merge pull request #6246 from elpaso/rangeformatter
[bugfix] Range formatter for doubles and ints
This commit is contained in:
commit
5c5ef3b6de
@ -287,6 +287,7 @@
|
||||
%Include geometry/qgswkbtypes.sip
|
||||
%Include ./3d/qgs3drendererregistry.sip
|
||||
%Include ./3d/qgsabstract3drenderer.sip
|
||||
%Include fieldformatter/qgsrangefieldformatter.sip
|
||||
%Include fieldformatter/qgsdatetimefieldformatter.sip
|
||||
%Include fieldformatter/qgsfallbackfieldformatter.sip
|
||||
%Include fieldformatter/qgskeyvaluefieldformatter.sip
|
||||
|
42
python/core/fieldformatter/qgsrangefieldformatter.sip.in
Normal file
42
python/core/fieldformatter/qgsrangefieldformatter.sip.in
Normal file
@ -0,0 +1,42 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/fieldformatter/qgsrangefieldformatter.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
class QgsRangeFieldFormatter : QgsFieldFormatter
|
||||
{
|
||||
%Docstring
|
||||
Field formatter for a range (double) field with precision and locale
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsrangefieldformatter.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsRangeFieldFormatter();
|
||||
%Docstring
|
||||
Default constructor of field formatter for a range (double)field.
|
||||
%End
|
||||
|
||||
virtual QString id() const;
|
||||
|
||||
|
||||
virtual QString representValue( QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config, const QVariant &cache, const QVariant &value ) const;
|
||||
|
||||
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/fieldformatter/qgsrangefieldformatter.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
@ -117,6 +117,13 @@ Defines if the clear value should be the minimum or maximum values of the widget
|
||||
Returns the value used when clear() is called.
|
||||
|
||||
.. seealso:: :py:func:`setClearValue`
|
||||
%End
|
||||
|
||||
void setLineEditAlignment( Qt::Alignment alignment );
|
||||
%Docstring
|
||||
Set alignment in the embedded line edit widget
|
||||
|
||||
:param alignment:
|
||||
%End
|
||||
|
||||
virtual double valueFromText( const QString &text ) const;
|
||||
|
@ -117,6 +117,13 @@ Defines if the clear value should be the minimum or maximum values of the widget
|
||||
Returns the value used when clear() is called.
|
||||
|
||||
.. seealso:: :py:func:`setClearValue`
|
||||
%End
|
||||
|
||||
void setLineEditAlignment( Qt::Alignment alignment );
|
||||
%Docstring
|
||||
Set alignment in the embedded line edit widget
|
||||
|
||||
:param alignment:
|
||||
%End
|
||||
|
||||
virtual int valueFromText( const QString &text ) const;
|
||||
|
@ -473,6 +473,7 @@ SET(QGIS_CORE_SRCS
|
||||
3d/qgs3drendererregistry.cpp
|
||||
3d/qgsabstract3drenderer.cpp
|
||||
|
||||
fieldformatter/qgsrangefieldformatter.cpp
|
||||
fieldformatter/qgsdatetimefieldformatter.cpp
|
||||
fieldformatter/qgsfallbackfieldformatter.cpp
|
||||
fieldformatter/qgskeyvaluefieldformatter.cpp
|
||||
@ -1110,6 +1111,7 @@ SET(QGIS_CORE_HDRS
|
||||
3d/qgs3drendererregistry.h
|
||||
3d/qgsabstract3drenderer.h
|
||||
|
||||
fieldformatter/qgsrangefieldformatter.h
|
||||
fieldformatter/qgsdatetimefieldformatter.h
|
||||
fieldformatter/qgsfallbackfieldformatter.h
|
||||
fieldformatter/qgskeyvaluefieldformatter.h
|
||||
|
86
src/core/fieldformatter/qgsrangefieldformatter.cpp
Normal file
86
src/core/fieldformatter/qgsrangefieldformatter.cpp
Normal file
@ -0,0 +1,86 @@
|
||||
/***************************************************************************
|
||||
qgsrangefieldformatter.cpp - QgsRangeFieldFormatter
|
||||
|
||||
---------------------
|
||||
begin : 01/02/2018
|
||||
copyright : (C) 2018 by Alessandro Pasotti
|
||||
email : elpaso at itopen dot it
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include <QLocale>
|
||||
|
||||
#include "qgsrangefieldformatter.h"
|
||||
|
||||
#include "qgssettings.h"
|
||||
#include "qgsfield.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
|
||||
|
||||
QString QgsRangeFieldFormatter::id() const
|
||||
{
|
||||
return QStringLiteral( "Range" );
|
||||
}
|
||||
|
||||
QString QgsRangeFieldFormatter::representValue( QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config, const QVariant &cache, const QVariant &value ) const
|
||||
{
|
||||
Q_UNUSED( cache )
|
||||
Q_UNUSED( config )
|
||||
|
||||
if ( value.isNull() )
|
||||
{
|
||||
return QgsApplication::nullRepresentation();
|
||||
}
|
||||
|
||||
QString result;
|
||||
|
||||
// Prepare locale
|
||||
std::function<QLocale()> f_locale = [ ]
|
||||
{
|
||||
QLocale locale( QgsApplication::instance()->locale() );
|
||||
QLocale::NumberOptions options( locale.numberOptions() );
|
||||
options |= QLocale::NumberOption::OmitGroupSeparator;
|
||||
locale.setNumberOptions( options );
|
||||
return locale;
|
||||
};
|
||||
|
||||
const QgsField field = layer->fields().at( fieldIndex );
|
||||
|
||||
if ( field.type() == QVariant::Double &&
|
||||
config.contains( QStringLiteral( "Precision" ) ) &&
|
||||
value.isValid( ) )
|
||||
{
|
||||
bool ok;
|
||||
double val( value.toDouble( &ok ) );
|
||||
if ( ok )
|
||||
{
|
||||
int precision( config[ QStringLiteral( "Precision" ) ].toInt( &ok ) );
|
||||
if ( ok )
|
||||
{
|
||||
// TODO: make the format configurable!
|
||||
result = f_locale().toString( val, 'f', precision );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( field.type() == QVariant::Int &&
|
||||
value.isValid( ) )
|
||||
{
|
||||
bool ok;
|
||||
double val( value.toInt( &ok ) );
|
||||
if ( ok )
|
||||
{
|
||||
result = f_locale().toString( val );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = value.toString();
|
||||
}
|
||||
return result;
|
||||
}
|
43
src/core/fieldformatter/qgsrangefieldformatter.h
Normal file
43
src/core/fieldformatter/qgsrangefieldformatter.h
Normal file
@ -0,0 +1,43 @@
|
||||
/***************************************************************************
|
||||
qgsrangefieldformatter.h - QgsRangeFieldFormatter
|
||||
|
||||
---------------------
|
||||
begin : 01/02/2018
|
||||
copyright : (C) 2018 by Alessandro Pasotti
|
||||
email : elpaso at itopen dot it
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#ifndef QGSRANGEFIELDFORMATTER_H
|
||||
#define QGSRANGEFIELDFORMATTER_H
|
||||
|
||||
#include "qgis_core.h"
|
||||
#include "qgsfieldformatter.h"
|
||||
|
||||
/**
|
||||
* \ingroup core
|
||||
* Field formatter for a range (double) field with precision and locale
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
class CORE_EXPORT QgsRangeFieldFormatter : public QgsFieldFormatter
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Default constructor of field formatter for a range (double)field.
|
||||
*/
|
||||
QgsRangeFieldFormatter() = default;
|
||||
|
||||
QString id() const override;
|
||||
|
||||
QString representValue( QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config, const QVariant &cache, const QVariant &value ) const override;
|
||||
|
||||
};
|
||||
|
||||
#endif // QGSRANGEFIELDFORMATTER_H
|
@ -22,6 +22,7 @@
|
||||
#include "qgsrelationreferencefieldformatter.h"
|
||||
#include "qgskeyvaluefieldformatter.h"
|
||||
#include "qgslistfieldformatter.h"
|
||||
#include "qgsrangefieldformatter.h"
|
||||
#include "qgsfallbackfieldformatter.h"
|
||||
|
||||
|
||||
@ -34,6 +35,7 @@ QgsFieldFormatterRegistry::QgsFieldFormatterRegistry( QObject *parent )
|
||||
addFieldFormatter( new QgsKeyValueFieldFormatter() );
|
||||
addFieldFormatter( new QgsListFieldFormatter() );
|
||||
addFieldFormatter( new QgsDateTimeFieldFormatter() );
|
||||
addFieldFormatter( new QgsRangeFieldFormatter() );
|
||||
|
||||
mFallbackFieldFormatter = new QgsFallbackFieldFormatter();
|
||||
}
|
||||
|
@ -31,6 +31,8 @@ QgsDoubleSpinBox::QgsDoubleSpinBox( QWidget *parent )
|
||||
{
|
||||
mLineEdit = new QgsSpinBoxLineEdit();
|
||||
|
||||
// By default, group separator is off
|
||||
setLocale( QLocale( QgsApplication::locale( ) ) );
|
||||
setLineEdit( mLineEdit );
|
||||
|
||||
QSize msz = minimumSizeHint();
|
||||
@ -134,6 +136,11 @@ double QgsDoubleSpinBox::clearValue() const
|
||||
return mCustomClearValue;
|
||||
}
|
||||
|
||||
void QgsDoubleSpinBox::setLineEditAlignment( Qt::Alignment alignment )
|
||||
{
|
||||
mLineEdit->setAlignment( alignment );
|
||||
}
|
||||
|
||||
QString QgsDoubleSpinBox::stripped( const QString &originalText ) const
|
||||
{
|
||||
//adapted from QAbstractSpinBoxPrivate::stripped
|
||||
|
@ -126,6 +126,12 @@ class GUI_EXPORT QgsDoubleSpinBox : public QDoubleSpinBox
|
||||
*/
|
||||
double clearValue() const;
|
||||
|
||||
/**
|
||||
* Set alignment in the embedded line edit widget
|
||||
* \param alignment
|
||||
*/
|
||||
void setLineEditAlignment( Qt::Alignment alignment );
|
||||
|
||||
double valueFromText( const QString &text ) const override;
|
||||
QValidator::State validate( QString &input, int &pos ) const override;
|
||||
void paintEvent( QPaintEvent *e ) override;
|
||||
|
@ -47,12 +47,14 @@ QWidget *QgsRangeWidgetWrapper::createWidget( QWidget *parent )
|
||||
case QVariant::Double:
|
||||
{
|
||||
editor = new QgsDoubleSpinBox( parent );
|
||||
static_cast<QgsDoubleSpinBox *>( editor )->setLineEditAlignment( Qt::AlignRight );
|
||||
break;
|
||||
}
|
||||
case QVariant::Int:
|
||||
case QVariant::LongLong:
|
||||
default:
|
||||
editor = new QgsSpinBox( parent );
|
||||
static_cast<QgsSpinBox *>( editor )->setLineEditAlignment( Qt::AlignRight );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,6 @@ QgsSpinBox::QgsSpinBox( QWidget *parent )
|
||||
: QSpinBox( parent )
|
||||
{
|
||||
mLineEdit = new QgsSpinBoxLineEdit();
|
||||
|
||||
setLineEdit( mLineEdit );
|
||||
|
||||
QSize msz = minimumSizeHint();
|
||||
@ -133,6 +132,11 @@ int QgsSpinBox::clearValue() const
|
||||
return mCustomClearValue;
|
||||
}
|
||||
|
||||
void QgsSpinBox::setLineEditAlignment( Qt::Alignment alignment )
|
||||
{
|
||||
mLineEdit->setAlignment( alignment );
|
||||
}
|
||||
|
||||
int QgsSpinBox::valueFromText( const QString &text ) const
|
||||
{
|
||||
if ( !mExpressionsEnabled )
|
||||
|
@ -126,6 +126,12 @@ class GUI_EXPORT QgsSpinBox : public QSpinBox
|
||||
*/
|
||||
int clearValue() const;
|
||||
|
||||
/**
|
||||
* Set alignment in the embedded line edit widget
|
||||
* \param alignment
|
||||
*/
|
||||
void setLineEditAlignment( Qt::Alignment alignment );
|
||||
|
||||
int valueFromText( const QString &text ) const override;
|
||||
QValidator::State validate( QString &input, int &pos ) const override;
|
||||
|
||||
|
@ -16,7 +16,7 @@ import qgis # NOQA
|
||||
|
||||
from qgis.core import (QgsFeature, QgsProject, QgsRelation, QgsVectorLayer,
|
||||
QgsValueMapFieldFormatter, QgsValueRelationFieldFormatter,
|
||||
QgsRelationReferenceFieldFormatter, QgsSettings)
|
||||
QgsRelationReferenceFieldFormatter, QgsRangeFieldFormatter, QgsSettings)
|
||||
|
||||
from qgis.testing import start_app, unittest
|
||||
|
||||
@ -197,5 +197,62 @@ class TestQgsRelationReferenceFieldFormatter(unittest.TestCase):
|
||||
QgsProject.instance().removeAllMapLayers()
|
||||
|
||||
|
||||
class TestQgsRangeFieldFormatter(unittest.TestCase):
|
||||
|
||||
def test_representValue(self):
|
||||
|
||||
layer = QgsVectorLayer("point?field=int:integer&field=double:double",
|
||||
"layer", "memory")
|
||||
self.assertTrue(layer.isValid())
|
||||
QgsProject.instance().addMapLayers([layer])
|
||||
|
||||
fieldFormatter = QgsRangeFieldFormatter()
|
||||
|
||||
# Precision is ignored for integers
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 0, {'Precision': 1}, None, '123'), '123')
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 0, {'Precision': 1}, None, '123000'), '123000')
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 0, {'Precision': 1}, None, None), 'NULL')
|
||||
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 1}, None, None), 'NULL')
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 1}, None, '123'), '123.0')
|
||||
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 2}, None, None), 'NULL')
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 2}, None, '123000'), '123000.00')
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 2}, None, '0'), '0.00')
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 2}, None, '123'), '123.00')
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 2}, None, '0.123'), '0.12')
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 2}, None, '0.127'), '0.13')
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 3}, None, '0'), '0.000')
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 3}, None, '0.127'), '0.127')
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 3}, None, '1.27e-1'), '0.127')
|
||||
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 2}, None, '-123'), '-123.00')
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 2}, None, '-0.123'), '-0.12')
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 2}, None, '-0.127'), '-0.13')
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 3}, None, '-0.127'), '-0.127')
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 3}, None, '-1.27e-1'), '-0.127')
|
||||
|
||||
QgsSettings().setValue("locale/overrideFlag", True)
|
||||
QgsSettings().setValue("locale/userLocale", 'it')
|
||||
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 2}, None, None), 'NULL')
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 2}, None, '123000'), '123000,00')
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 2}, None, '0'), '0,00')
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 2}, None, '123'), '123,00')
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 2}, None, '0.123'), '0,12')
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 2}, None, '0.127'), '0,13')
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 3}, None, '0'), '0,000')
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 3}, None, '0.127'), '0,127')
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 3}, None, '1.27e-1'), '0,127')
|
||||
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 2}, None, '-123'), '-123,00')
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 2}, None, '-0.123'), '-0,12')
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 2}, None, '-0.127'), '-0,13')
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 3}, None, '-0.127'), '-0,127')
|
||||
self.assertEqual(fieldFormatter.representValue(layer, 1, {'Precision': 3}, None, '-1.27e-1'), '-0,127')
|
||||
|
||||
QgsProject.instance().removeAllMapLayers()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
Loading…
x
Reference in New Issue
Block a user