QGIS API Documentation  3.2.0-Bonn (bc43194)
qgsspinbox.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsspinbox.cpp
3  --------------------------------------
4  Date : 09.2014
5  Copyright : (C) 2014 Denis Rouzaud
6  Email : [email protected]
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 <QLineEdit>
17 #include <QMouseEvent>
18 #include <QSettings>
19 #include <QStyle>
20 
21 #include "qgsspinbox.h"
22 #include "qgsexpression.h"
23 #include "qgsapplication.h"
24 #include "qgslogger.h"
25 #include "qgsfilterlineedit.h"
26 
27 #define CLEAR_ICON_SIZE 16
28 
29 QgsSpinBox::QgsSpinBox( QWidget *parent )
30  : QSpinBox( parent )
31 {
32  mLineEdit = new QgsSpinBoxLineEdit();
33  setLineEdit( mLineEdit );
34 
35  QSize msz = minimumSizeHint();
36  setMinimumSize( msz.width() + CLEAR_ICON_SIZE + 9 + frameWidth() * 2 + 2,
37  std::max( msz.height(), CLEAR_ICON_SIZE + frameWidth() * 2 + 2 ) );
38 
39  connect( mLineEdit, &QgsFilterLineEdit::cleared, this, &QgsSpinBox::clear );
40  connect( this, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsSpinBox::changed );
41 }
42 
44 {
45  mShowClearButton = showClearButton;
46  mLineEdit->setShowClearButton( showClearButton );
47 }
48 
49 void QgsSpinBox::setExpressionsEnabled( const bool enabled )
50 {
51  mExpressionsEnabled = enabled;
52 }
53 
54 void QgsSpinBox::changeEvent( QEvent *event )
55 {
56  QSpinBox::changeEvent( event );
57  mLineEdit->setShowClearButton( shouldShowClearForValue( value() ) );
58 }
59 
60 void QgsSpinBox::paintEvent( QPaintEvent *event )
61 {
62  mLineEdit->setShowClearButton( shouldShowClearForValue( value() ) );
63  QSpinBox::paintEvent( event );
64 }
65 
66 void QgsSpinBox::wheelEvent( QWheelEvent *event )
67 {
68  int step = singleStep();
69  if ( event->modifiers() & Qt::ControlModifier )
70  {
71  // ctrl modifier results in finer increments - 10% of usual step
72  int newStep = step / 10;
73  // step should be at least 1
74  newStep = std::max( newStep, 1 );
75 
76  setSingleStep( newStep );
77 
78  // clear control modifier before handing off event - Qt uses it for unwanted purposes
79  // (*increasing* step size, whereas QGIS UX convention is that control modifier
80  // results in finer changes!)
81  event->setModifiers( event->modifiers() & ~Qt::ControlModifier );
82  }
83  QSpinBox::wheelEvent( event );
84  setSingleStep( step );
85 }
86 
87 void QgsSpinBox::changed( int value )
88 {
89  mLineEdit->setShowClearButton( shouldShowClearForValue( value ) );
90 }
91 
93 {
94  setValue( clearValue() );
95 }
96 
97 void QgsSpinBox::setClearValue( int customValue, const QString &specialValueText )
98 {
99  mClearValueMode = CustomValue;
100  mCustomClearValue = customValue;
101 
102  if ( !specialValueText.isEmpty() )
103  {
104  int v = value();
105  clear();
106  setSpecialValueText( specialValueText );
107  setValue( v );
108  }
109 }
110 
111 void QgsSpinBox::setClearValueMode( QgsSpinBox::ClearValueMode mode, const QString &specialValueText )
112 {
113  mClearValueMode = mode;
114  mCustomClearValue = 0;
115 
116  if ( !specialValueText.isEmpty() )
117  {
118  int v = value();
119  clear();
120  setSpecialValueText( specialValueText );
121  setValue( v );
122  }
123 }
124 
125 int QgsSpinBox::clearValue() const
126 {
127  if ( mClearValueMode == MinimumValue )
128  return minimum();
129  else if ( mClearValueMode == MaximumValue )
130  return maximum();
131  else
132  return mCustomClearValue;
133 }
134 
135 void QgsSpinBox::setLineEditAlignment( Qt::Alignment alignment )
136 {
137  mLineEdit->setAlignment( alignment );
138 }
139 
140 int QgsSpinBox::valueFromText( const QString &text ) const
141 {
142  if ( !mExpressionsEnabled )
143  {
144  return QSpinBox::valueFromText( text );
145  }
146 
147  QString trimmedText = stripped( text );
148  if ( trimmedText.isEmpty() )
149  {
150  return mShowClearButton ? clearValue() : value();
151  }
152 
153  return std::round( QgsExpression::evaluateToDouble( trimmedText, value() ) );
154 }
155 
156 QValidator::State QgsSpinBox::validate( QString &input, int &pos ) const
157 {
158  if ( !mExpressionsEnabled )
159  {
160  QValidator::State r = QSpinBox::validate( input, pos );
161  return r;
162  }
163 
164  return QValidator::Acceptable;
165 }
166 
167 int QgsSpinBox::frameWidth() const
168 {
169  return style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
170 }
171 
172 bool QgsSpinBox::shouldShowClearForValue( const int value ) const
173 {
174  if ( !mShowClearButton || !isEnabled() )
175  {
176  return false;
177  }
178  return value != clearValue();
179 }
180 
181 QString QgsSpinBox::stripped( const QString &originalText ) const
182 {
183  //adapted from QAbstractSpinBoxPrivate::stripped
184  //trims whitespace, prefix and suffix from spin box text
185  QString text = originalText;
186  if ( specialValueText().isEmpty() || text != specialValueText() )
187  {
188  int from = 0;
189  int size = text.size();
190  bool changed = false;
191  if ( !prefix().isEmpty() && text.startsWith( prefix() ) )
192  {
193  from += prefix().size();
194  size -= from;
195  changed = true;
196  }
197  if ( !suffix().isEmpty() && text.endsWith( suffix() ) )
198  {
199  size -= suffix().size();
200  changed = true;
201  }
202  if ( changed )
203  text = text.mid( from, size );
204  }
205 
206  text = text.trimmed();
207 
208  return text;
209 }
void wheelEvent(QWheelEvent *event) override
Definition: qgsspinbox.cpp:66
ClearValueMode
Behavior when widget is cleared.
Definition: qgsspinbox.h:62
Reset value to maximum()
Definition: qgsspinbox.h:65
Reset value to custom value (see setClearValue() )
Definition: qgsspinbox.h:66
bool showClearButton() const
Returns whether the widget is showing a clear button.
Definition: qgsspinbox.h:87
static double evaluateToDouble(const QString &text, double fallbackValue)
Attempts to evaluate a text string as an expression to a resultant double value.
QValidator::State validate(QString &input, int &pos) const override
Definition: qgsspinbox.cpp:156
void clear() override
Sets the current value to the value defined by the clear value.
Definition: qgsspinbox.cpp:92
void setShowClearButton(bool showClearButton)
Sets whether the widget will show a clear button.
Definition: qgsspinbox.cpp:43
void setLineEditAlignment(Qt::Alignment alignment)
Set alignment in the embedded line edit widget.
Definition: qgsspinbox.cpp:135
Reset value to minimum()
Definition: qgsspinbox.h:64
QgsSpinBox(QWidget *parent=nullptr)
Constructor for QgsSpinBox.
Definition: qgsspinbox.cpp:29
void setExpressionsEnabled(bool enabled)
Sets if the widget will allow entry of simple expressions, which are evaluated and then discarded...
Definition: qgsspinbox.cpp:49
int clearValue() const
Returns the value used when clear() is called.
void paintEvent(QPaintEvent *event) override
Definition: qgsspinbox.cpp:60
#define CLEAR_ICON_SIZE
Definition: qgsspinbox.cpp:27
int valueFromText(const QString &text) const override
Definition: qgsspinbox.cpp:140
void setClearValueMode(ClearValueMode mode, const QString &clearValueText=QString())
Defines if the clear value should be the minimum or maximum values of the widget or a custom value...
Definition: qgsspinbox.cpp:111
void setClearValue(int customValue, const QString &clearValueText=QString())
Defines the clear value as a custom value and will automatically set the clear value mode to CustomVa...
Definition: qgsspinbox.cpp:97
void cleared()
Emitted when the widget is cleared.
void changeEvent(QEvent *event) override
Definition: qgsspinbox.cpp:54