22#include "moc_qgsdoublespinbox.cpp"
28#define CLEAR_ICON_SIZE 16
34static QChar SPECIAL_TEXT_WHEN_EMPTY = QChar( 0x2063 );
36static constexpr QChar SPECIAL_TEXT_WHEN_EMPTY = QChar( 0x2063 );
41 : QDoubleSpinBox( parent )
43 mLineEdit =
new QgsSpinBoxLineEdit();
47 setLineEdit( mLineEdit );
49 const QSize msz = minimumSizeHint();
50 setMinimumSize( msz.width() +
CLEAR_ICON_SIZE + 9 + frameWidth() * 2 + 2,
54 connect(
this,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsDoubleSpinBox::changed );
65 mExpressionsEnabled = enabled;
70 QDoubleSpinBox::changeEvent( event );
72 if ( event->type() == QEvent::FontChange )
74 lineEdit()->setFont( font() );
77 mLineEdit->setShowClearButton( shouldShowClearForValue( value() ) );
82 const double step = singleStep();
83 if ( event->modifiers() & Qt::ControlModifier )
86 double newStep = step / 10;
89 newStep = std::max( newStep, std::pow( 10.0, 0.0 - decimals() ) );
91 setSingleStep( newStep );
96 event->setModifiers( event->modifiers() & ~Qt::ControlModifier );
98 QDoubleSpinBox::wheelEvent( event );
99 setSingleStep( step );
108 qApp->processEvents();
109 if ( QApplication::mouseButtons() & Qt::LeftButton )
110 QDoubleSpinBox::timerEvent( event );
115 mLineEdit->setShowClearButton( shouldShowClearForValue( value() ) );
116 QDoubleSpinBox::paintEvent( event );
121 const bool wasNull = mShowClearButton && value() ==
clearValue();
122 if ( wasNull && minimum() < 0 && maximum() > 0 && !( specialValueText().isEmpty() || specialValueText() == SPECIAL_TEXT_WHEN_EMPTY ) )
130 QDoubleSpinBox::stepBy( steps );
133void QgsDoubleSpinBox::changed(
double value )
135 mLineEdit->setShowClearButton( shouldShowClearForValue( value ) );
141 if ( mLineEdit->isNull() )
147 if ( mClearValueMode ==
CustomValue && mCustomClearValue == customValue && QAbstractSpinBox::specialValueText() == specialValueText )
153 mCustomClearValue = customValue;
155 if ( !specialValueText.isEmpty() )
157 const double v = value();
166 if ( mClearValueMode == mode && mCustomClearValue == 0 && QAbstractSpinBox::specialValueText() == clearValueText )
171 mClearValueMode = mode;
172 mCustomClearValue = 0;
174 if ( !clearValueText.isEmpty() )
176 const double v = value();
190 return mCustomClearValue;
195 mLineEdit->setAlignment( alignment );
202 QDoubleSpinBox::setSpecialValueText( SPECIAL_TEXT_WHEN_EMPTY );
203 mLineEdit->setNullValue( SPECIAL_TEXT_WHEN_EMPTY );
207 QDoubleSpinBox::setSpecialValueText( txt );
208 mLineEdit->setNullValue( txt );
212QString QgsDoubleSpinBox::stripped(
const QString &originalText )
const
216 QString text = originalText;
217 if ( specialValueText().isEmpty() || text != specialValueText() )
220 if ( text.contains( SPECIAL_TEXT_WHEN_EMPTY ) )
221 text = text.replace( SPECIAL_TEXT_WHEN_EMPTY, QString() );
223 int size = text.size();
224 bool changed =
false;
225 if ( !prefix().isEmpty() && text.startsWith( prefix() ) )
227 from += prefix().size();
231 if ( !suffix().isEmpty() && text.endsWith( suffix() ) )
233 size -= suffix().size();
237 text = text.mid( from, size );
240 text = text.trimmed();
247 if ( !mExpressionsEnabled )
249 return QDoubleSpinBox::valueFromText( text );
252 const QString trimmedText = stripped( text );
253 if ( trimmedText.isEmpty() )
255 return mShowClearButton ?
clearValue() : value();
263 if ( !mExpressionsEnabled )
265 const QValidator::State r = QDoubleSpinBox::validate( input, pos );
269 return QValidator::Acceptable;
272int QgsDoubleSpinBox::frameWidth()
const
274 return style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
277bool QgsDoubleSpinBox::shouldShowClearForValue(
const double value )
const
279 if ( !mShowClearButton || !isEnabled() )
void paintEvent(QPaintEvent *e) override
void wheelEvent(QWheelEvent *event) override
void setLineEditAlignment(Qt::Alignment alignment)
Set alignment in the embedded line edit widget.
void stepBy(int steps) override
double valueFromText(const QString &text) const override
void setSpecialValueText(const QString &txt)
Set the special-value text to be txt If set, the spin box will display this text instead of a numeric...
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.
void changeEvent(QEvent *event) override
void clear() override
Sets the current value to the value defined by the clear value.
ClearValueMode
Behavior when widget is cleared.
@ MaximumValue
Reset value to maximum()
@ CustomValue
Reset value to custom value (see setClearValue() )
@ MinimumValue
Reset value to minimum()
QValidator::State validate(QString &input, int &pos) const override
QgsDoubleSpinBox(QWidget *parent=nullptr)
Constructor for QgsDoubleSpinBox.
void setExpressionsEnabled(bool enabled)
Sets if the widget will allow entry of simple expressions, which are evaluated and then discarded.
void setClearValue(double customValue, const QString &clearValueText=QString())
Defines the clear value as a custom value and will automatically set the clear value mode to CustomVa...
void setShowClearButton(bool showClearButton)
Sets whether the widget will show a clear button.
void timerEvent(QTimerEvent *event) override
void returnPressed()
Emitted when the Return or Enter key is used in the line edit.
static double evaluateToDouble(const QString &text, double fallbackValue)
Attempts to evaluate a text string as an expression to a resultant double value.
void cleared()
Emitted when the widget is cleared.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.