QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
qgsrangewidgetwrapper.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrangewidgetwrapper.cpp
3  --------------------------------------
4  Date : 5.1.2014
5  Copyright : (C) 2014 Matthias Kuhn
6  Email : matthias at opengis dot ch
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 
16 #include <QSettings>
17 
18 #include "qgsrangewidgetwrapper.h"
19 #include "qgsspinbox.h"
20 #include "qgsdoublespinbox.h"
21 #include "qgsvectorlayer.h"
22 
24  : QgsEditorWidgetWrapper( vl, fieldIdx, editor, parent )
25  , mIntSpinBox( nullptr )
26  , mDoubleSpinBox( nullptr )
27  , mSlider( nullptr )
28  , mDial( nullptr )
29  , mQgsSlider( nullptr )
30  , mQgsDial( nullptr )
31 {
32 }
33 
35 {
36  QWidget* editor = nullptr;
37 
38  if ( config( "Style" ).toString() == "Dial" )
39  {
40  editor = new QgsDial( parent );
41  }
42  else if ( config( "Style" ).toString() == "Slider" )
43  {
44  editor = new QgsSlider( Qt::Horizontal, parent );
45  }
46  else
47  {
48  QgsDebugMsg( QString( "%1" ).arg(( int )layer()->fields().at( fieldIdx() ).type() ) );
49  switch ( layer()->fields().at( fieldIdx() ).type() )
50  {
51  case QVariant::Double:
52  {
53  editor = new QgsDoubleSpinBox( parent );
54  break;
55  }
56  case QVariant::Int:
57  case QVariant::LongLong:
58  default:
59  editor = new QgsSpinBox( parent );
60  break;
61  }
62  }
63 
64  return editor;
65 }
66 
68 {
69  mDoubleSpinBox = qobject_cast<QDoubleSpinBox*>( editor );
70  mIntSpinBox = qobject_cast<QSpinBox*>( editor );
71  mDial = qobject_cast<QDial*>( editor );
72  mSlider = qobject_cast<QSlider*>( editor );
73  mQgsDial = qobject_cast<QgsDial*>( editor );
74  mQgsSlider = qobject_cast<QgsSlider*>( editor );
75 
76  bool allowNull = config( "AllowNull" ).toBool();
77 
78  QVariant min( config( "Min" ) );
79  QVariant max( config( "Max" ) );
80  QVariant step( config( "Step" ) );
81 
82  if ( mDoubleSpinBox )
83  {
84  // set the precision if field is integer
85  int precision = layer()->fields().at( fieldIdx() ).precision();
86  if ( precision > 0 )
87  {
88  mDoubleSpinBox->setDecimals( layer()->fields().at( fieldIdx() ).precision() );
89  }
90 
91  double minval = min.toDouble();
92  double stepval = step.toDouble();
93  QgsDoubleSpinBox* qgsWidget = dynamic_cast<QgsDoubleSpinBox*>( mDoubleSpinBox );
94  if ( qgsWidget )
95  qgsWidget->setShowClearButton( allowNull );
96  if ( allowNull )
97  {
98  if ( precision > 0 )
99  {
100  minval -= 10 ^ -precision;
101  }
102  else
103  {
104  minval -= stepval;
105  }
106  mDoubleSpinBox->setValue( minval );
107  mDoubleSpinBox->setSpecialValueText( QSettings().value( "qgis/nullValue", "NULL" ).toString() );
108  }
109  if ( min.isValid() )
110  mDoubleSpinBox->setMinimum( min.toDouble() );
111  if ( max.isValid() )
112  mDoubleSpinBox->setMaximum( max.toDouble() );
113  if ( step.isValid() )
114  mDoubleSpinBox->setSingleStep( step.toDouble() );
115  if ( config( "Suffix" ).isValid() )
116  mDoubleSpinBox->setSuffix( config( "Suffix" ).toString() );
117 
118  connect( mDoubleSpinBox, SIGNAL( valueChanged( double ) ), this, SLOT( valueChanged( double ) ) );
119  }
120 
121  if ( mIntSpinBox )
122  {
123  int minval = min.toInt();
124  int stepval = step.toInt();
125  QgsSpinBox* qgsWidget = dynamic_cast<QgsSpinBox*>( mIntSpinBox );
126  if ( qgsWidget )
127  qgsWidget->setShowClearButton( allowNull );
128  if ( allowNull )
129  {
130  minval -= stepval;
131  mIntSpinBox->setValue( minval );
132  mIntSpinBox->setSpecialValueText( QSettings().value( "qgis/nullValue", "NULL" ).toString() );
133  }
134  if ( min.isValid() )
135  mIntSpinBox->setMinimum( min.toInt() );
136  if ( max.isValid() )
137  mIntSpinBox->setMaximum( max.toInt() );
138  if ( step.isValid() )
139  mIntSpinBox->setSingleStep( step.toInt() );
140  if ( config( "Suffix" ).isValid() )
141  mIntSpinBox->setSuffix( config( "Suffix" ).toString() );
142  connect( mIntSpinBox, SIGNAL( valueChanged( int ) ), this, SLOT( valueChanged( int ) ) );
143  }
144 
145 
146  if ( mQgsDial || mQgsSlider )
147  {
148  field().convertCompatible( min );
149  field().convertCompatible( max );
150  field().convertCompatible( step );
151 
152  if ( mQgsSlider )
153  {
154  if ( min.isValid() )
155  mQgsSlider->setMinimum( min );
156  if ( max.isValid() )
157  mQgsSlider->setMaximum( max );
158  if ( step.isValid() )
159  mQgsSlider->setSingleStep( step );
160  }
161 
162  if ( mQgsDial )
163  {
164  if ( min.isValid() )
165  mQgsDial->setMinimum( min );
166  if ( max.isValid() )
167  mQgsDial->setMaximum( max );
168  if ( step.isValid() )
169  mQgsDial->setSingleStep( step );
170  }
171 
172  connect( editor, SIGNAL( valueChanged( QVariant ) ), this, SLOT( valueChangedVariant( QVariant ) ) );
173  }
174  else if ( mDial )
175  {
176  if ( min.isValid() )
177  mDial->setMinimum( min.toInt() );
178  if ( max.isValid() )
179  mDial->setMaximum( max.toInt() );
180  if ( step.isValid() )
181  mDial->setSingleStep( step.toInt() );
182  connect( mDial, SIGNAL( valueChanged( int ) ), this, SLOT( valueChanged( int ) ) );
183  }
184  else if ( mSlider )
185  {
186  if ( min.isValid() )
187  mSlider->setMinimum( min.toInt() );
188  if ( max.isValid() )
189  mSlider->setMaximum( max.toInt() );
190  if ( step.isValid() )
191  mSlider->setSingleStep( step.toInt() );
192  connect( mSlider, SIGNAL( valueChanged( int ) ), this, SLOT( valueChanged( int ) ) );
193  }
194 }
195 
197 {
198  return mSlider || mDial || mQgsDial || mQgsSlider || mIntSpinBox || mDoubleSpinBox;
199 }
200 
201 void QgsRangeWidgetWrapper::valueChangedVariant( const QVariant& v )
202 {
203  if ( v.type() == QVariant::Int )
204  valueChanged( v.toInt() );
205  if ( v.type() == QVariant::Double )
206  valueChanged( v.toDouble() );
207 }
208 
210 {
211  QVariant value;
212 
213  if ( mDoubleSpinBox )
214  {
215  value = mDoubleSpinBox->value();
216  if ( value == mDoubleSpinBox->minimum() && config( "AllowNull" ).toBool() )
217  {
218  value = QVariant( field().type() );
219  }
220  }
221  else if ( mIntSpinBox )
222  {
223  value = mIntSpinBox->value();
224  if ( value == mIntSpinBox->minimum() && config( "AllowNull" ).toBool() )
225  {
226  value = QVariant( field().type() );
227  }
228  }
229  else if ( mQgsDial )
230  {
231  value = mQgsDial->variantValue();
232  }
233  else if ( mQgsSlider )
234  {
235  value = mQgsSlider->variantValue();
236  }
237  else if ( mDial )
238  {
239  value = mDial->value();
240  }
241  else if ( mSlider )
242  {
243  value = mSlider->value();
244  }
245 
246  return value;
247 }
248 
250 {
251  if ( mDoubleSpinBox )
252  {
253  if ( value.isNull() && config( "AllowNull" ).toBool() )
254  {
255  mDoubleSpinBox->setValue( mDoubleSpinBox->minimum() );
256  }
257  else
258  {
259  mDoubleSpinBox->setValue( value.toDouble() );
260  }
261  }
262 
263  if ( mIntSpinBox )
264  {
265  if ( value.isNull() && config( "AllowNull" ).toBool() )
266  {
267  mIntSpinBox->setValue( mIntSpinBox->minimum() );
268  }
269  else
270  {
271  mIntSpinBox->setValue( value.toInt() );
272  }
273  }
274 
275  if ( mQgsDial )
276  {
277  mQgsDial->setValue( value );
278  }
279  else if ( mQgsSlider )
280  {
281  mQgsSlider->setValue( value );
282  }
283  else if ( mDial )
284  {
285  mDial->setValue( value.toInt() );
286  }
287  else if ( mSlider )
288  {
289  mSlider->setValue( value.toInt() );
290  }
291 }
void setValue(const QVariant &value)
Definition: qgsslider.cpp:65
The QgsSpinBox is a spin box with a clear button that will set the value to the defined clear value...
bool valid() const override
Return true if the widget has been properly initialized.
virtual QWidget * createWidget(QWidget *parent) override
This method should create a new widget with the provided parent.
virtual void initWidget(QWidget *editor) override
This method should initialize the editor widget with runtime data.
int precision
Definition: qgsfield.h:50
void valueChanged()
Will call the value() method to determine the emitted value.
QgsField field() const
Access the field.
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
Manages an editor widget Widget and wrapper share the same parent.
bool convertCompatible(QVariant &v) const
Converts the provided variant to a compatible format.
Definition: qgsfield.cpp:208
The QgsSpinBox is a spin box with a clear button that will set the value to the defined clear value...
Definition: qgsspinbox.h:28
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfield.cpp:422
void setShowClearButton(const bool showClearButton)
Sets whether the widget will show a clear button.
QgsFields fields() const
Returns the list of fields of this layer.
double ANALYSIS_EXPORT max(double x, double y)
Returns the maximum of two doubles or the first argument if both are equal.
void setSingleStep(double val)
void setShowClearButton(const bool showClearButton)
Sets whether the widget will show a clear button.
Definition: qgsspinbox.cpp:48
int toInt(bool *ok) const
bool isNull() const
void setDecimals(int prec)
void setSuffix(const QString &suffix)
void setValue(double val)
void setValue(const QVariant &value)
Definition: qgsdial.cpp:60
virtual void setValue(const QVariant &value) override
QgsRangeWidgetWrapper(QgsVectorLayer *vl, int fieldIdx, QWidget *editor, QWidget *parent=nullptr)
void setSpecialValueText(const QString &txt)
bool isValid() const
double toDouble(bool *ok) const
void setMinimum(double min)
QVariant variantValue() const
Definition: qgsdial.cpp:106
double ANALYSIS_EXPORT min(double x, double y)
Returns the minimum of two doubles or the first argument if both are equal.
QgsEditorWidgetConfig config() const
Returns the whole config.
int fieldIdx() const
Access the field index.
Type type() const
QgsVectorLayer * layer() const
Access the QgsVectorLayer, you are working on.
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const
Represents a vector layer which manages a vector based data sets.
void setMaximum(double max)
virtual QVariant value() const override
Will be used to access the widget&#39;s value.
QVariant variantValue() const
Definition: qgsslider.cpp:111