QGIS API Documentation 3.99.0-Master (d270888f95f)
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#include <QString>
31
32#include "moc_qgsnumericformatselectorwidget.cpp"
33
34using namespace Qt::StringLiterals;
35
37 : QgsPanelWidget( parent )
38{
39 setupUi( this );
40
41 mCurrentFormat.reset( QgsApplication::numericFormatRegistry()->fallbackFormat() );
42
43 mPreviewFormat = std::make_unique<QgsBasicNumericFormat>();
44 mPreviewFormat->setShowThousandsSeparator( false );
45 mPreviewFormat->setShowPlusSign( false );
46 mPreviewFormat->setShowTrailingZeros( false );
47 mPreviewFormat->setNumberDecimalPlaces( 12 );
48
49 populateTypes();
50 mCategoryCombo->setCurrentIndex( mCategoryCombo->findData( mCurrentFormat->id() ) );
51
52 connect( mCategoryCombo, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsNumericFormatSelectorWidget::formatTypeChanged );
53 updateFormatWidget();
54}
55
57
59{
60 if ( !format )
61 return;
62
63 mCurrentFormat.reset( format->clone() );
64
65 const QString id = mCurrentFormat->id();
66 const int index = mCategoryCombo->findData( id );
67 if ( index < 0 )
68 {
69 whileBlocking( mCategoryCombo )->setCurrentIndex( mCategoryCombo->findData( u"fallback"_s ) );
70 }
71 else
72 mCategoryCombo->setCurrentIndex( index );
73
74 updateFormatWidget();
75
76 emit changed();
77}
78
80{
81 return mCurrentFormat->clone();
82}
83
85{
86 mExpressionContextGenerator = generator;
87 if ( QgsNumericFormatWidget *w = qobject_cast<QgsNumericFormatWidget *>( stackedWidget->currentWidget() ) )
88 w->registerExpressionContextGenerator( mExpressionContextGenerator );
89}
90
91void QgsNumericFormatSelectorWidget::formatTypeChanged()
92{
93 const QString newId = mCategoryCombo->currentData().toString();
94 if ( mCurrentFormat->id() == newId )
95 {
96 return;
97 }
98
99 // keep as much of the current format's properties as possible
100 QVariantMap props = mCurrentFormat->configuration( QgsReadWriteContext() );
101 mCurrentFormat.reset( QgsApplication::numericFormatRegistry()->create( newId, props, QgsReadWriteContext() ) );
102
103 updateFormatWidget();
104 updateSampleText();
105 emit changed();
106}
107
108void QgsNumericFormatSelectorWidget::formatChanged()
109{
110 if ( QgsNumericFormatWidget *w = qobject_cast<QgsNumericFormatWidget *>( stackedWidget->currentWidget() ) )
111 mCurrentFormat.reset( w->format() );
112
113 updateSampleText();
114 emit changed();
115}
116
117void QgsNumericFormatSelectorWidget::populateTypes()
118{
119 QStringList ids = QgsApplication::numericFormatRegistry()->formats();
120
121 std::sort( ids.begin(), ids.end(), []( const QString &a, const QString &b ) -> bool {
122 if ( QgsApplication::numericFormatRegistry()->sortKey( a ) < QgsApplication::numericFormatRegistry()->sortKey( b ) )
123 return true;
124 else if ( QgsApplication::numericFormatRegistry()->sortKey( a ) > QgsApplication::numericFormatRegistry()->sortKey( b ) )
125 return false;
126 else
127 {
128 int res = QString::localeAwareCompare( QgsApplication::numericFormatRegistry()->visibleName( a ), QgsApplication::numericFormatRegistry()->visibleName( b ) );
129 if ( res < 0 )
130 return true;
131 else if ( res > 0 )
132 return false;
133 }
134 return false;
135 } );
136
137 for ( const QString &id : std::as_const( ids ) )
138 mCategoryCombo->addItem( QgsApplication::numericFormatRegistry()->visibleName( id ), id );
139}
140
141void QgsNumericFormatSelectorWidget::updateFormatWidget()
142{
143 if ( stackedWidget->currentWidget() != pageDummy )
144 {
145 // stop updating from the original widget
146 if ( QgsNumericFormatWidget *w = qobject_cast<QgsNumericFormatWidget *>( stackedWidget->currentWidget() ) )
147 disconnect( w, &QgsNumericFormatWidget::changed, this, &QgsNumericFormatSelectorWidget::formatChanged );
148 stackedWidget->removeWidget( stackedWidget->currentWidget() );
149 }
150 if ( QgsNumericFormatWidget *w = QgsGui::numericFormatGuiRegistry()->formatConfigurationWidget( mCurrentFormat.get() ) )
151 {
152 w->setFormat( mCurrentFormat->clone() );
153 stackedWidget->addWidget( w );
154 stackedWidget->setCurrentWidget( w );
155 // start receiving updates from widget
156 connect( w, &QgsNumericFormatWidget::changed, this, &QgsNumericFormatSelectorWidget::formatChanged );
157 w->registerExpressionContextGenerator( mExpressionContextGenerator );
158 }
159 else
160 {
161 stackedWidget->setCurrentWidget( pageDummy );
162 }
163
164 updateSampleText();
165}
166
167void QgsNumericFormatSelectorWidget::updateSampleText()
168{
169 const double sampleValue = mCurrentFormat->suggestSampleValue();
170 mSampleLabel->setText( u"%1 %2 <b>%3</b>"_s.arg( mPreviewFormat->formatDouble( sampleValue, QgsNumericFormatContext() ) ).arg( QChar( 0x2192 ) ).arg( mCurrentFormat->formatDouble( sampleValue, QgsNumericFormatContext() ) ) );
171}
172
173//
174// QgsNumericFormatSelectorDialog
175//
176
178 : QDialog( parent, fl )
179{
180 setWindowTitle( tr( "Numeric Format" ) );
181
182 mFormatWidget = new QgsNumericFormatSelectorWidget( this );
183 mFormatWidget->layout()->setContentsMargins( 0, 0, 0, 0 );
184
185 QVBoxLayout *layout = new QVBoxLayout( this );
186 layout->addWidget( mFormatWidget );
187
188 mButtonBox = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Help, Qt::Horizontal, this );
189 layout->addWidget( mButtonBox );
190
191 setLayout( layout );
193
194 connect( mButtonBox->button( QDialogButtonBox::Ok ), &QAbstractButton::clicked, this, &QDialog::accept );
195 connect( mButtonBox->button( QDialogButtonBox::Cancel ), &QAbstractButton::clicked, this, &QDialog::reject );
196}
197
199{
200 mFormatWidget->setFormat( format );
201}
202
204{
205 return mFormatWidget->format();
206}
207
209{
210 mFormatWidget->registerExpressionContextGenerator( generator );
211}
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:224
static QgsNumericFormatGuiRegistry * numericFormatGuiRegistry()
Returns the global numeric format gui registry, used for registering the GUI widgets associated with ...
Definition qgsgui.cpp:174
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:6804