QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgsnumericformatselectorwidget.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsnumericformatselectorwidget.cpp
3 ----------------------------------
4 begin : January 2020
5 copyright : (C) 2020 by Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17#include "qgsapplication.h"
19#include "qgsnumericformat.h"
21#include "qgis.h"
22#include "qgsgui.h"
24#include "qgsreadwritecontext.h"
26#include <mutex>
27
28
30 : QgsPanelWidget( parent )
31{
32 setupUi( this );
33
34 mCurrentFormat.reset( QgsApplication::numericFormatRegistry()->fallbackFormat() );
35
36 mPreviewFormat = std::make_unique< QgsBasicNumericFormat >();
37 mPreviewFormat->setShowThousandsSeparator( false );
38 mPreviewFormat->setShowPlusSign( false );
39 mPreviewFormat->setShowTrailingZeros( false );
40 mPreviewFormat->setNumberDecimalPlaces( 12 );
41
42 populateTypes();
43 mCategoryCombo->setCurrentIndex( mCategoryCombo->findData( mCurrentFormat->id() ) );
44
45 connect( mCategoryCombo, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsNumericFormatSelectorWidget::formatTypeChanged );
46 updateFormatWidget();
47}
48
50
52{
53 if ( !format )
54 return;
55
56 mCurrentFormat.reset( format->clone() );
57
58 const QString id = mCurrentFormat->id();
59 const int index = mCategoryCombo->findData( id );
60 if ( index < 0 )
61 {
62 whileBlocking( mCategoryCombo )->setCurrentIndex( mCategoryCombo->findData( QStringLiteral( "fallback" ) ) );
63
64 }
65 else
66 mCategoryCombo->setCurrentIndex( index );
67
68 updateFormatWidget();
69
70 emit changed();
71}
72
74{
75 return mCurrentFormat->clone();
76}
77
78void QgsNumericFormatSelectorWidget::formatTypeChanged()
79{
80 const QString newId = mCategoryCombo->currentData().toString();
81 if ( mCurrentFormat->id() == newId )
82 {
83 return;
84 }
85
86 // keep as much of the current format's properties as possible
87 QVariantMap props = mCurrentFormat->configuration( QgsReadWriteContext() );
88 mCurrentFormat.reset( QgsApplication::numericFormatRegistry()->create( newId, props, QgsReadWriteContext() ) );
89
90 updateFormatWidget();
91 updateSampleText();
92 emit changed();
93}
94
95void QgsNumericFormatSelectorWidget::formatChanged()
96{
97 if ( QgsNumericFormatWidget *w = qobject_cast< QgsNumericFormatWidget * >( stackedWidget->currentWidget() ) )
98 mCurrentFormat.reset( w->format() );
99
100 updateSampleText();
101 emit changed();
102}
103
104void QgsNumericFormatSelectorWidget::populateTypes()
105{
106 QStringList ids = QgsApplication::numericFormatRegistry()->formats();
107
108 std::sort( ids.begin(), ids.end(), [ = ]( const QString & a, const QString & b )->bool
109 {
110 if ( QgsApplication::numericFormatRegistry()->sortKey( a ) < QgsApplication::numericFormatRegistry()->sortKey( b ) )
111 return true;
112 else if ( QgsApplication::numericFormatRegistry()->sortKey( a ) > QgsApplication::numericFormatRegistry()->sortKey( b ) )
113 return false;
114 else
115 {
116 int res = QString::localeAwareCompare( QgsApplication::numericFormatRegistry()->visibleName( a ), QgsApplication::numericFormatRegistry()->visibleName( b ) );
117 if ( res < 0 )
118 return true;
119 else if ( res > 0 )
120 return false;
121 }
122 return false;
123 } );
124
125 for ( const QString &id : std::as_const( ids ) )
126 mCategoryCombo->addItem( QgsApplication::numericFormatRegistry()->visibleName( id ), id );
127}
128
129void QgsNumericFormatSelectorWidget::updateFormatWidget()
130{
131 if ( stackedWidget->currentWidget() != pageDummy )
132 {
133 // stop updating from the original widget
134 if ( QgsNumericFormatWidget *w = qobject_cast< QgsNumericFormatWidget * >( stackedWidget->currentWidget() ) )
135 disconnect( w, &QgsNumericFormatWidget::changed, this, &QgsNumericFormatSelectorWidget::formatChanged );
136 stackedWidget->removeWidget( stackedWidget->currentWidget() );
137 }
138 if ( QgsNumericFormatWidget *w = QgsGui::numericFormatGuiRegistry()->formatConfigurationWidget( mCurrentFormat.get() ) )
139 {
140 w->setFormat( mCurrentFormat->clone() );
141 stackedWidget->addWidget( w );
142 stackedWidget->setCurrentWidget( w );
143 // start receiving updates from widget
144 connect( w, &QgsNumericFormatWidget::changed, this, &QgsNumericFormatSelectorWidget::formatChanged );
145 }
146 else
147 {
148 stackedWidget->setCurrentWidget( pageDummy );
149 }
150
151 updateSampleText();
152}
153
154void QgsNumericFormatSelectorWidget::updateSampleText()
155{
156 const double sampleValue = mCurrentFormat->suggestSampleValue();
157 mSampleLabel->setText( QStringLiteral( "%1 %2 <b>%3</b>" ).arg( mPreviewFormat->formatDouble( sampleValue, QgsNumericFormatContext() ) )
158 .arg( QChar( 0x2192 ) )
159 .arg( mCurrentFormat->formatDouble( sampleValue, QgsNumericFormatContext() ) ) );
160}
static QgsNumericFormatRegistry * numericFormatRegistry()
Gets the registry of available numeric formats.
static QgsNumericFormatGuiRegistry * numericFormatGuiRegistry()
Returns the global numeric format gui registry, used for registering the GUI widgets associated with ...
Definition: qgsgui.cpp:149
A context for numeric formats.
QStringList formats() const
Returns a list of the format IDs currently contained in the registry.
QgsNumericFormat * format() const
Returns a new format object representing the settings currently configured in the widget.
~QgsNumericFormatSelectorWidget() override
void changed()
Emitted whenever the format configured55 in the widget is changed.
QgsNumericFormatSelectorWidget(QWidget *parent=nullptr)
Constructor for QgsNumericFormatSelectorWidget with the specified parent widget.
void setFormat(const QgsNumericFormat *format)
Sets the format to show in the widget.
Base class for widgets which allow control over the properties of QgsNumericFormat subclasses.
void changed()
Emitted whenever the configuration of the numeric format is changed.
A numeric formatter allows for formatting a numeric value for display, using a variety of different f...
virtual QgsNumericFormat * clone() const =0
Clones the format, returning a new object.
Base class for any widget that can be shown as a inline panel.
The class is used as a container of context for various read/write operations on other objects.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:5111