QGIS API Documentation  2.8.2-Wien
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 : 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 "qgsspinbox.h"
23 #include "qgsexpression.h"
24 #include "qgsapplication.h"
25 #include "qgslogger.h"
26 
27 QgsSpinBox::QgsSpinBox( QWidget *parent )
28  : QSpinBox( parent )
29  , mShowClearButton( true )
30  , mClearValueMode( MinimumValue )
31  , mCustomClearValue( 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( int ) ), this, SLOT( changed( int ) ) );
47 }
48 
49 void QgsSpinBox::setShowClearButton( const bool showClearButton )
50 {
51  mShowClearButton = showClearButton;
52  mClearButton->setVisible( shouldShowClearForValue( value() ) );
53 }
54 
55 void QgsSpinBox::setExpressionsEnabled( const bool enabled )
56 {
57  mExpressionsEnabled = enabled;
58 }
59 
60 void QgsSpinBox::changeEvent( QEvent *event )
61 {
62  QSpinBox::changeEvent( event );
63  mClearButton->setVisible( shouldShowClearForValue( value() ) );
64 }
65 
66 void QgsSpinBox::paintEvent( QPaintEvent *event )
67 {
68  mClearButton->setVisible( shouldShowClearForValue( value() ) );
69  QSpinBox::paintEvent( event );
70 }
71 
72 void QgsSpinBox::changed( const int& value )
73 {
74  mClearButton->setVisible( shouldShowClearForValue( value ) );
75 }
76 
78 {
79  setValue( clearValue() );
80 }
81 
82 void QgsSpinBox::setClearValue( int customValue, QString specialValueText )
83 {
84  mClearValueMode = CustomValue;
85  mCustomClearValue = customValue;
86 
87  if ( !specialValueText.isEmpty() )
88  {
89  int v = value();
90  clear();
91  setSpecialValueText( specialValueText );
92  setValue( v );
93  }
94 }
95 
96 void QgsSpinBox::setClearValueMode( QgsSpinBox::ClearValueMode mode, QString specialValueText )
97 {
98  mClearValueMode = mode;
99  mCustomClearValue = 0;
100 
101  if ( !specialValueText.isEmpty() )
102  {
103  int v = value();
104  clear();
105  setSpecialValueText( specialValueText );
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 int QgsSpinBox::valueFromText( const QString &text ) const
121 {
122  if ( !mExpressionsEnabled )
123  {
124  return QSpinBox::valueFromText( text );
125  }
126 
127  QString trimmedText = stripped( text );
128  if ( trimmedText.isEmpty() )
129  {
130  return mShowClearButton ? clearValue() : value();
131  }
132 
133  return qRound( QgsExpression::evaluateToDouble( trimmedText, value() ) );
134 }
135 
136 QValidator::State QgsSpinBox::validate( QString &input, int &pos ) const
137 {
138  if ( !mExpressionsEnabled )
139  {
140  QValidator::State r = QSpinBox::validate( input, pos );
141  return r;
142  }
143 
144  return QValidator::Acceptable;
145 }
146 
147 int QgsSpinBox::frameWidth() const
148 {
149  return style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
150 }
151 
152 bool QgsSpinBox::shouldShowClearForValue( const int value ) const
153 {
154  if ( !mShowClearButton || !isEnabled() )
155  {
156  return false;
157  }
158  return value != clearValue();
159 }
160 
161 QString QgsSpinBox::stripped( const QString &originalText ) const
162 {
163  //adapted from QAbstractSpinBoxPrivate::stripped
164  //trims whitespace, prefix and suffix from spin box text
165  QString text = originalText;
166  if ( specialValueText().size() == 0 || text != specialValueText() )
167  {
168  int from = 0;
169  int size = text.size();
170  bool changed = false;
171  if ( prefix().size() && text.startsWith( prefix() ) )
172  {
173  from += prefix().size();
174  size -= from;
175  changed = true;
176  }
177  if ( suffix().size() && text.endsWith( suffix() ) )
178  {
179  size -= suffix().size();
180  changed = true;
181  }
182  if ( changed )
183  text = text.mid( from, size );
184  }
185 
186  text = text.trimmed();
187 
188  return text;
189 }
190 
191 void QgsSpinBox::resizeEvent( QResizeEvent * event )
192 {
193  QSpinBox::resizeEvent( event );
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 }