QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
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  {
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 : 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  }
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 
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 }
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:126
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:263