QGIS API Documentation  3.17.0-Master (df2c9ff931)
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"
20 #include "qgsnumericformatwidget.h"
21 #include "qgis.h"
22 #include "qgsgui.h"
24 #include "qgsreadwritecontext.h"
25 #include "qgsbasicnumericformat.h"
26 #include <mutex>
27 
28 
30  : QgsPanelWidget( parent )
31 {
32  setupUi( this );
33 
34  mCurrentFormat.reset( QgsApplication::numericFormatRegistry()->fallbackFormat() );
35 
36  mPreviewFormat = qgis::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 
78 void 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 
95 void 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 
104 void 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  {
111  return true;
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 : qgis::as_const( ids ) )
126  mCategoryCombo->addItem( QgsApplication::numericFormatRegistry()->visibleName( id ), id );
127 }
128 
129 void 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  }
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 
154 void 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 }
The class is used as a container of context for various read/write operations on other objects...
int sortKey(const QString &id) const
Returns the sorting key for the format with matching id.
Base class for widgets which allow control over the properties of QgsNumericFormat subclasses...
QStringList formats() const
Returns a list of the format IDs currently contained in the registry.
void changed()
Emitted whenever the configuration of the numeric format is changed.
virtual QgsNumericFormat * clone() const =0
Clones the format, returning a new object.
static QgsNumericFormatRegistry * numericFormatRegistry()
Gets the registry of available numeric formats.
Base class for any widget that can be shown as a inline panel.
QgsNumericFormatSelectorWidget(QWidget *parent=nullptr)
Constructor for QgsNumericFormatSelectorWidget with the specified parent widget.
A numeric formatter allows for formatting a numeric value for display, using a variety of different f...
static QgsNumericFormatGuiRegistry * numericFormatGuiRegistry()
Returns the global numeric format gui registry, used for registering the GUI widgets associated with ...
Definition: qgsgui.cpp:126
~QgsNumericFormatSelectorWidget() override
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:263
void setFormat(const QgsNumericFormat *format)
Sets the format to show in the widget.
A context for numeric formats.
void changed()
Emitted whenever the format configured55 in the widget is changed.
QString visibleName(const QString &id) const
Returns the translated, user-visible name for the format with matching id.
QgsNumericFormatWidget * formatConfigurationWidget(const QgsNumericFormat *format) const
Returns a new configuration widget for an format.
QgsNumericFormat * format() const
Returns a new format object representing the settings currently configured in the widget...