Skip to content

Commit

Permalink
[FEATURE] Add numeric formatter "fraction" style
Browse files Browse the repository at this point in the history
This style represents decimal numbers as vulgar fractions, e.g.
"3/4" instead of 0.75.

Options include using Unicode superscript and subscript characters
for nicer typography, e.g. ¹⁷/₂₃ (this is the default mode, disabling
this option uses the "17/23" format). An option also exists for
using dedicated unicode characters for specific fractions (where
a unicode character exists), e.g. ½ or ¾

Ultimately this allows for creation of scalebars with fractional
representations of distances, e.g. 0 ----- ½ ----- 1 km
(instead of 0 ------ 0.5 ------ 1km)

Fixes #21289

Sponsored by SLYR
  • Loading branch information
nyalldawson committed Mar 23, 2020
1 parent ab04656 commit 78d445e
Show file tree
Hide file tree
Showing 15 changed files with 1,054 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/numericformats/qgsfractionnumericformat.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/


class QgsFractionNumericFormat : QgsNumericFormat
{
%Docstring
A numeric formatter which returns a vulgar fractional representation of a decimal value (e.g. "1/2" instead of 0.5).

.. versionadded:: 3.14
%End

%TypeHeaderCode
#include "qgsfractionnumericformat.h"
%End
public:

QgsFractionNumericFormat();
%Docstring
Default constructor
%End

virtual QString id() const;

virtual QString visibleName() const;

virtual int sortKey();

virtual QString formatDouble( double value, const QgsNumericFormatContext &context ) const;

virtual QgsNumericFormat *clone() const /Factory/;

virtual QgsNumericFormat *create( const QVariantMap &configuration, const QgsReadWriteContext &context ) const /Factory/;

virtual QVariantMap configuration( const QgsReadWriteContext &context ) const;

virtual double suggestSampleValue() const;


bool useDedicatedUnicodeCharacters() const;
%Docstring
Returns ``True`` if dedicated unicode characters should be used, when the are available for the
particular fraction (e.g. ½, ¼).

.. seealso:: :py:func:`setUseDedicatedUnicodeCharacters`

.. seealso:: :py:func:`useUnicodeSuperSubscript`
%End

void setUseDedicatedUnicodeCharacters( bool enabled );
%Docstring
Sets whether dedicated unicode characters should be used, when the are available for the
particular fraction (e.g. ½, ¼).

.. seealso:: :py:func:`useDedicatedUnicodeCharacters`

.. seealso:: :py:func:`setUseUnicodeSuperSubscript`
%End

bool useUnicodeSuperSubscript() const;
%Docstring
Returns ``True`` if unicode superscript and subscript characters should be used, (e.g. "⁶/₇").

.. seealso:: :py:func:`setUseUnicodeSuperSubscript`

.. seealso:: :py:func:`useDedicatedUnicodeCharacters`
%End

void setUseUnicodeSuperSubscript( bool enabled );
%Docstring
Sets whether unicode superscript and subscript characters should be used, (e.g. "⁶/₇").

.. seealso:: :py:func:`useUnicodeSuperSubscript`

.. seealso:: :py:func:`setUseDedicatedUnicodeCharacters`
%End

bool showThousandsSeparator() const;
%Docstring
Returns ``True`` if the thousands grouping separator will be shown.

.. seealso:: :py:func:`setShowThousandsSeparator`
%End

void setShowThousandsSeparator( bool show );
%Docstring
Sets whether the thousands grouping separator will be shown.

.. seealso:: :py:func:`showThousandsSeparator`
%End

bool showPlusSign() const;
%Docstring
Returns ``True`` if a leading plus sign will be shown for positive values.

.. seealso:: :py:func:`setShowPlusSign`
%End

void setShowPlusSign( bool show );
%Docstring
Sets whether a leading plus sign will be shown for positive values.

.. seealso:: :py:func:`showPlusSign`
%End

QChar thousandsSeparator() const;
%Docstring
Returns any override for the thousands separator character. If an invalid QChar is returned,
then the QGIS locale separator is used instead.

.. seealso:: :py:func:`setThousandsSeparator`
%End

void setThousandsSeparator( QChar character );
%Docstring
Sets an override ``character`` for the thousands separator character. If an invalid QChar is set,
then the QGIS locale separator is used instead.

.. seealso:: :py:func:`thousandsSeparator`
%End

static bool doubleToVulgarFraction( const double value, unsigned long long &numerator /Out/, unsigned long long &denominator /Out/, int &sign /Out/, const double tolerance = 1e-10 );
%Docstring
Converts a double ``value`` to a vulgar fraction (e.g. ⅓, ¼, etc) by attempting to calculate
the corresponding ``numerator`` and ``denominator``, within the specified ``tolerance``.

This method is based of Richard's algorithm (1981) from "Continued Fractions without Tears" (University of Minnesota).

:param value: input value to convert
:param denominator: will be set to the calculated fraction denominator
:param sign: will be set to the sign of the result (as -1 or +1 values)
:param tolerance: acceptable tolerance. Larger values will give "nicer" fractions.

:return: - ``True`` if ``value`` was successfully converted to a fraction
- numerator: will be set to calculated fraction numerator
%End

static QString toUnicodeSuperscript( const QString &input );
%Docstring
Converts numbers in an ``input`` string to unicode superscript equivalents.

.. seealso:: :py:func:`toUnicodeSubscript`
%End

static QString toUnicodeSubscript( const QString &input );
%Docstring
Converts numbers in an ``input`` string to unicode subscript equivalents.

.. seealso:: :py:func:`toUnicodeSuperscript`
%End

protected:

virtual void setConfiguration( const QVariantMap &configuration, const QgsReadWriteContext &context );
%Docstring
Sets the format's ``configuration``.
%End

};

/************************************************************************
* This file has been generated automatically from *
* *
* src/core/numericformats/qgsfractionnumericformat.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ This is an abstract base class and will always need to be subclassed.
sipType = sipType_QgsCurrencyNumericFormat;
else if ( dynamic_cast< QgsBasicNumericFormat * >( sipCpp ) )
sipType = sipType_QgsBasicNumericFormat;
else if ( dynamic_cast< QgsFractionNumericFormat * >( sipCpp ) )
sipType = sipType_QgsFractionNumericFormat;
else
sipType = NULL;
%End
Expand Down
1 change: 1 addition & 0 deletions python/core/core_auto.sip
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,7 @@
%Include auto_generated/numericformats/qgsbearingnumericformat.sip
%Include auto_generated/numericformats/qgscurrencynumericformat.sip
%Include auto_generated/numericformats/qgsfallbacknumericformat.sip
%Include auto_generated/numericformats/qgsfractionnumericformat.sip
%Include auto_generated/numericformats/qgsnumericformat.sip
%Include auto_generated/numericformats/qgsnumericformatregistry.sip
%Include auto_generated/numericformats/qgspercentagenumericformat.sip
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
************************************************************************/



class QgsNumericFormatWidget : QgsPanelWidget
{
%Docstring
Expand Down Expand Up @@ -231,6 +232,33 @@ Constructor for QgsScientificNumericFormatWidget, initially showing the specifie
};



class QgsFractionNumericFormatWidget : QgsNumericFormatWidget
{
%Docstring
A widget which allow control over the properties of a :py:class:`QgsFractionNumericFormat`.

.. versionadded:: 3.14
%End

%TypeHeaderCode
#include "qgsnumericformatwidget.h"
%End
public:

QgsFractionNumericFormatWidget( const QgsNumericFormat *format, QWidget *parent /TransferThis/ = 0 );
%Docstring
Constructor for QgsFractionNumericFormatWidget, initially showing the specified ``format``.
%End
~QgsFractionNumericFormatWidget();

virtual void setFormat( QgsNumericFormat *format );


virtual QgsNumericFormat *format() /Factory/;


};
/************************************************************************
* This file has been generated automatically from *
* *
Expand Down
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ SET(QGIS_CORE_SRCS
numericformats/qgsbearingnumericformat.cpp
numericformats/qgscurrencynumericformat.cpp
numericformats/qgsfallbacknumericformat.cpp
numericformats/qgsfractionnumericformat.cpp
numericformats/qgsnumericformat.cpp
numericformats/qgsnumericformatregistry.cpp
numericformats/qgspercentagenumericformat.cpp
Expand Down Expand Up @@ -1184,6 +1185,7 @@ SET(QGIS_CORE_HDRS
numericformats/qgsbearingnumericformat.h
numericformats/qgscurrencynumericformat.h
numericformats/qgsfallbacknumericformat.h
numericformats/qgsfractionnumericformat.h
numericformats/qgsnumericformat.h
numericformats/qgsnumericformatregistry.h
numericformats/qgspercentagenumericformat.h
Expand Down
Loading

0 comments on commit 78d445e

Please sign in to comment.