QGIS API Documentation  2.14.11-Essen
qgsdoublespinbox.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsdoublespinbox.cpp
3  --------------------------------------
4  Date : 09.2014
5  Copyright : (C) 2014 Denis Rouzaud
6  Email : denis.rouzaud@gmail.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 
16 #include <QLineEdit>
17 #include <QMouseEvent>
18 #include <QSettings>
19 #include <QStyle>
20 #include <QToolButton>
21 
22 #include "qgsdoublespinbox.h"
23 #include "qgsexpression.h"
24 #include "qgsapplication.h"
25 #include "qgslogger.h"
26 
28  : QDoubleSpinBox( parent )
29  , mShowClearButton( true )
30  , mClearValueMode( MinimumValue )
31  , mCustomClearValue( 0.0 )
32  , mExpressionsEnabled( true )
33 {
34  mClearButton = new QToolButton( this );
35  mClearButton->setIcon( QgsApplication::getThemeIcon( "/mIconClear.svg" ) );
36  mClearButton->setCursor( Qt::ArrowCursor );
37  mClearButton->setStyleSheet( "position: absolute; border: none; padding: 0px;" );
38  connect( mClearButton, SIGNAL( clicked() ), this, SLOT( clear() ) );
39 
40  setStyleSheet( QString( "padding-right: %1px;" ).arg( mClearButton->sizeHint().width() + 18 + frameWidth() + 1 ) );
41 
42  QSize msz = minimumSizeHint();
43  setMinimumSize( qMax( msz.width(), mClearButton->sizeHint().height() + frameWidth() * 2 + 2 ),
44  qMax( msz.height(), mClearButton->sizeHint().height() + frameWidth() * 2 + 2 ) );
45 
46  connect( this, SIGNAL( valueChanged( double ) ), this, SLOT( changed( double ) ) );
47 }
48 
50 {
51  mShowClearButton = showClearButton;
52  mClearButton->setVisible( shouldShowClearForValue( value() ) );
53 }
54 
56 {
57  mExpressionsEnabled = enabled;
58 }
59 
61 {
63  mClearButton->setVisible( shouldShowClearForValue( value() ) );
64 }
65 
67 {
68  mClearButton->setVisible( shouldShowClearForValue( value() ) );
70 }
71 
72 void QgsDoubleSpinBox::changed( double value )
73 {
74  mClearButton->setVisible( shouldShowClearForValue( value ) );
75 }
76 
78 {
79  setValue( clearValue() );
80 }
81 
82 void QgsDoubleSpinBox::setClearValue( double customValue, const QString& specialValueText )
83 {
84  mClearValueMode = CustomValue;
85  mCustomClearValue = customValue;
86 
87  if ( !specialValueText.isEmpty() )
88  {
89  double v = value();
90  clear();
91  setSpecialValueText( specialValueText );
92  setValue( v );
93  }
94 }
95 
97 {
98  mClearValueMode = mode;
99  mCustomClearValue = 0;
100 
101  if ( !clearValueText.isEmpty() )
102  {
103  double v = value();
104  clear();
105  setSpecialValueText( clearValueText );
106  setValue( v );
107  }
108 }
109 
111 {
112  if ( mClearValueMode == MinimumValue )
113  return minimum() ;
114  else if ( mClearValueMode == MaximumValue )
115  return maximum();
116  else
117  return mCustomClearValue;
118 }
119 
120 QString QgsDoubleSpinBox::stripped( const QString &originalText ) const
121 {
122  //adapted from QAbstractSpinBoxPrivate::stripped
123  //trims whitespace, prefix and suffix from spin box text
124  QString text = originalText;
125  if ( specialValueText().isEmpty() || text != specialValueText() )
126  {
127  int from = 0;
128  int size = text.size();
129  bool changed = false;
130  if ( !prefix().isEmpty() && text.startsWith( prefix() ) )
131  {
132  from += prefix().size();
133  size -= from;
134  changed = true;
135  }
136  if ( !suffix().isEmpty() && text.endsWith( suffix() ) )
137  {
138  size -= suffix().size();
139  changed = true;
140  }
141  if ( changed )
142  text = text.mid( from, size );
143  }
144 
145  text = text.trimmed();
146 
147  return text;
148 }
149 
151 {
152  if ( !mExpressionsEnabled )
153  {
154  return QDoubleSpinBox::valueFromText( text );
155  }
156 
157  QString trimmedText = stripped( text );
158  if ( trimmedText.isEmpty() )
159  {
160  return mShowClearButton ? clearValue() : value();
161  }
162 
163  return QgsExpression::evaluateToDouble( trimmedText, value() );
164 }
165 
166 QValidator::State QgsDoubleSpinBox::validate( QString &input, int &pos ) const
167 {
168  if ( !mExpressionsEnabled )
169  {
170  QValidator::State r = QDoubleSpinBox::validate( input, pos );
171  return r;
172  }
173 
174  return QValidator::Acceptable;
175 }
176 
177 int QgsDoubleSpinBox::frameWidth() const
178 {
179  return style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
180 }
181 
182 bool QgsDoubleSpinBox::shouldShowClearForValue( const double value ) const
183 {
184  if ( !mShowClearButton || !isEnabled() )
185  {
186  return false;
187  }
188  return value != clearValue();
189 }
190 
192 {
194 
195  QSize sz = mClearButton->sizeHint();
196 
197  mClearButton->move( rect().right() - frameWidth() - 18 - sz.width(),
198  ( rect().bottom() + 1 - sz.height() ) / 2 );
199 
200 }
virtual QValidator::State validate(QString &text, int &pos) const
void setStyleSheet(const QString &styleSheet)
virtual bool event(QEvent *event)
int width() const
void setCursor(const QCursor &)
virtual QSize sizeHint() const
virtual QSize minimumSizeHint() const
virtual QValidator::State validate(QString &input, int &pos) const override
virtual void resizeEvent(QResizeEvent *event) override
QStyle * style() const
static QIcon getThemeIcon(const QString &theName)
Helper to get a theme icon.
virtual int pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const=0
int size() const
virtual void setVisible(bool visible)
QgsDoubleSpinBox(QWidget *parent=nullptr)
void setIcon(const QIcon &icon)
QString text() const
virtual void clear() override
Set the current value to the value defined by the clear value.
void setShowClearButton(const bool showClearButton)
determines if the widget will show a clear button
QString prefix() const
virtual void paintEvent(QPaintEvent *event) override
QSize size() const
void setMinimumSize(const QSize &)
bool showClearButton() const
virtual double valueFromText(const QString &text) const override
void valueChanged(double d)
bool isEmpty() const
QString trimmed() const
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
QPoint pos() const
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
void setClearValue(double customValue, const QString &clearValueText=QString())
setClearValue defines the clear value as a custom value and will automatically set the clear value mo...
QString suffix() const
double value() const
double clearValue() const
returns the value used when clear() is called.
QRect rect() const
virtual void changeEvent(QEvent *event) override
void setClearValueMode(ClearValueMode mode, const QString &clearValueText=QString())
setClearValueMode defines if the clear value should be the minimum or maximum values of the widget or...
QString mid(int position, int n) const
virtual void paintEvent(QPaintEvent *event)
virtual void resizeEvent(QResizeEvent *event)
virtual void changeEvent(QEvent *event)
int height() const
int bottom() const
QString specialValueText() const
virtual double valueFromText(const QString &text) const
double minimum() const
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
static double evaluateToDouble(const QString &text, const double fallbackValue)
Attempts to evaluate a text string as an expression to a resultant double value.
double maximum() const
void setExpressionsEnabled(const bool enabled)
Sets if the widget will allow entry of simple expressions, which are evaluated and then discarded...