QGIS API Documentation  2.8.2-Wien
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 
60 void QgsDoubleSpinBox::changeEvent( QEvent *event )
61 {
63  mClearButton->setVisible( shouldShowClearForValue( value() ) );
64 }
65 
66 void QgsDoubleSpinBox::paintEvent( QPaintEvent *event )
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, 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 
191 void QgsDoubleSpinBox::resizeEvent( QResizeEvent * event )
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 }