QGIS API Documentation  2.12.0-Lyon
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 : [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 #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 
49 void QgsDoubleSpinBox::setShowClearButton( const bool showClearButton )
50 {
51  mShowClearButton = showClearButton;
52  mClearButton->setVisible( shouldShowClearForValue( value() ) );
53 }
54 
55 void QgsDoubleSpinBox::setExpressionsEnabled( const bool enabled )
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( const 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().size() == 0 || text != specialValueText() )
126  {
127  int from = 0;
128  int size = text.size();
129  bool changed = false;
130  if ( prefix().size() && text.startsWith( prefix() ) )
131  {
132  from += prefix().size();
133  size -= from;
134  changed = true;
135  }
136  if ( suffix().size() && 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 
150 double QgsDoubleSpinBox::valueFromText( const QString &text ) const
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)
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
bool showClearButton() const
QStyle * style() const
QgsDoubleSpinBox(QWidget *parent=0)
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)
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 &)
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
void move(int x, int y)
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
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)
double clearValue() const
returns the value used when clear() is called.
virtual void changeEvent(QEvent *event)
int height() const
int bottom() const
void setSpecialValueText(const QString &txt)
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...