QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
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
18#include "qgis.h"
19#include "qgsapplication.h"
21#include "qgsgui.h"
22#include "qgsnumericformat.h"
26#include "qgsreadwritecontext.h"
27
28#include <QDialogButtonBox>
29#include <QPushButton>
30
31#include "moc_qgsnumericformatselectorwidget.cpp"
32
34 : QgsPanelWidget( parent )
35{
36 setupUi( this );
37
38 mCurrentFormat.reset( QgsApplication::numericFormatRegistry()->fallbackFormat() );
39
40 mPreviewFormat = std::make_unique<QgsBasicNumericFormat>();
41 mPreviewFormat->setShowThousandsSeparator( false );
42 mPreviewFormat->setShowPlusSign( false );
43 mPreviewFormat->setShowTrailingZeros( false );
44 mPreviewFormat->setNumberDecimalPlaces( 12 );
45
46 populateTypes();
47 mCategoryCombo->setCurrentIndex( mCategoryCombo->findData( mCurrentFormat->id() ) );
48
49 connect( mCategoryCombo, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsNumericFormatSelectorWidget::formatTypeChanged );
50 updateFormatWidget();
51}
52
54
56{
57 if ( !format )
58 return;
59
60 mCurrentFormat.reset( format->clone() );
61
62 const QString id = mCurrentFormat->id();
63 const int index = mCategoryCombo->findData( id );
64 if ( index < 0 )
65 {
66 whileBlocking( mCategoryCombo )->setCurrentIndex( mCategoryCombo->findData( QStringLiteral( "fallback" ) ) );
67 }
68 else
69 mCategoryCombo->setCurrentIndex( index );
70
71 updateFormatWidget();
72
73 emit changed();
74}
75
77{
78 return mCurrentFormat->clone();
79}
80
82{
83 mExpressionContextGenerator = generator;
84 if ( QgsNumericFormatWidget *w = qobject_cast<QgsNumericFormatWidget *>( stackedWidget->currentWidget() ) )
85 w->registerExpressionContextGenerator( mExpressionContextGenerator );
86}
87
88void QgsNumericFormatSelectorWidget::formatTypeChanged()
89{
90 const QString newId = mCategoryCombo->currentData().toString();
91 if ( mCurrentFormat->id() == newId )
92 {
93 return;
94 }
95
96 // keep as much of the current format's properties as possible
97 QVariantMap props = mCurrentFormat->configuration( QgsReadWriteContext() );
98 mCurrentFormat.reset( QgsApplication::numericFormatRegistry()->create( newId, props, QgsReadWriteContext() ) );
99
100 updateFormatWidget();
101 updateSampleText();
102 emit changed();
103}
104
105void QgsNumericFormatSelectorWidget::formatChanged()
106{
107 if ( QgsNumericFormatWidget *w = qobject_cast<QgsNumericFormatWidget *>( stackedWidget->currentWidget() ) )
108 mCurrentFormat.reset( w->format() );
109
110 updateSampleText();
111 emit changed();
112}
113
114void QgsNumericFormatSelectorWidget::populateTypes()
115{
116 QStringList ids = QgsApplication::numericFormatRegistry()->formats();
117
118 std::sort( ids.begin(), ids.end(), []( const QString &a, const QString &b ) -> bool {
119 if ( QgsApplication::numericFormatRegistry()->sortKey( a ) < QgsApplication::numericFormatRegistry()->sortKey( b ) )
120 return true;
121 else if ( QgsApplication::numericFormatRegistry()->sortKey( a ) > QgsApplication::numericFormatRegistry()->sortKey( b ) )
122 return false;
123 else
124 {
125 int res = QString::localeAwareCompare( QgsApplication::numericFormatRegistry()->visibleName( a ), QgsApplication::numericFormatRegistry()->visibleName( b ) );
126 if ( res < 0 )
127 return true;
128 else if ( res > 0 )
129 return false;
130 }
131 return false;
132 } );
133
134 for ( const QString &id : std::as_const( ids ) )
135 mCategoryCombo->addItem( QgsApplication::numericFormatRegistry()->visibleName( id ), id );
136}
137
138void QgsNumericFormatSelectorWidget::updateFormatWidget()
139{
140 if ( stackedWidget->currentWidget() != pageDummy )
141 {
142 // stop updating from the original widget
143 if ( QgsNumericFormatWidget *w = qobject_cast<QgsNumericFormatWidget *>( stackedWidget->currentWidget() ) )
144 disconnect( w, &QgsNumericFormatWidget::changed, this, &QgsNumericFormatSelectorWidget::formatChanged );
145 stackedWidget->removeWidget( stackedWidget->currentWidget() );
146 }
147 if ( QgsNumericFormatWidget *w = QgsGui::numericFormatGuiRegistry()->formatConfigurationWidget( mCurrentFormat.get() ) )
148 {
149 w->setFormat( mCurrentFormat->clone() );
150 stackedWidget->addWidget( w );
151 stackedWidget->setCurrentWidget( w );
152 // start receiving updates from widget
153 connect( w, &QgsNumericFormatWidget::changed, this, &QgsNumericFormatSelectorWidget::formatChanged );
154 w->registerExpressionContextGenerator( mExpressionContextGenerator );
155 }
156 else
157 {
158 stackedWidget->setCurrentWidget( pageDummy );
159 }
160
161 updateSampleText();
162}
163
164void QgsNumericFormatSelectorWidget::updateSampleText()
165{
166 const double sampleValue = mCurrentFormat->suggestSampleValue();
167 mSampleLabel->setText( QStringLiteral( "%1 %2 <b>%3</b>" ).arg( mPreviewFormat->formatDouble( sampleValue, QgsNumericFormatContext() ) ).arg( QChar( 0x2192 ) ).arg( mCurrentFormat->formatDouble( sampleValue, QgsNumericFormatContext() ) ) );
168}
169
170//
171// QgsNumericFormatSelectorDialog
172//
173
175 : QDialog( parent, fl )
176{
177 setWindowTitle( tr( "Numeric Format" ) );
178
179 mFormatWidget = new QgsNumericFormatSelectorWidget( this );
180 mFormatWidget->layout()->setContentsMargins( 0, 0, 0, 0 );
181
182 QVBoxLayout *layout = new QVBoxLayout( this );
183 layout->addWidget( mFormatWidget );
184
185 mButtonBox = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Help, Qt::Horizontal, this );
186 layout->addWidget( mButtonBox );
187
188 setLayout( layout );
190
191 connect( mButtonBox->button( QDialogButtonBox::Ok ), &QAbstractButton::clicked, this, &QDialog::accept );
192 connect( mButtonBox->button( QDialogButtonBox::Cancel ), &QAbstractButton::clicked, this, &QDialog::reject );
193}
194
196{
197 mFormatWidget->setFormat( format );
198}
199
201{
202 return mFormatWidget->format();
203}
204
206{
207 mFormatWidget->registerExpressionContextGenerator( generator );
208}
static QgsNumericFormatRegistry * numericFormatRegistry()
Gets the registry of available numeric formats.
Abstract interface for generating an expression context.
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
Definition qgsgui.cpp:221
static QgsNumericFormatGuiRegistry * numericFormatGuiRegistry()
Returns the global numeric format gui registry, used for registering the GUI widgets associated with ...
Definition qgsgui.cpp:171
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 dialog.
void setFormat(const QgsNumericFormat *format)
Sets the format to show in the dialog.
QgsNumericFormatSelectorDialog(QWidget *parent=nullptr, Qt::WindowFlags flags=QgsGuiUtils::ModalDialogFlags)
Constructor for QgsNumericFormatSelectorDialog.
void registerExpressionContextGenerator(QgsExpressionContextGenerator *generator)
Register an expression context generator class that will be used to retrieve an expression context fo...
A widget which allows choice of numeric formats and the properties of them.
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.
void registerExpressionContextGenerator(QgsExpressionContextGenerator *generator)
Register an expression context generator class that will be used to retrieve an expression context fo...
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.
Abstract base class for numeric formatters, which allow for formatting a numeric value for display.
virtual QgsNumericFormat * clone() const =0
Clones the format, returning a new object.
QgsPanelWidget(QWidget *parent=nullptr)
Base class for any widget that can be shown as an inline panel.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition qgis.h:6511