30#include "moc_qgsspinbox.cpp"
32#define CLEAR_ICON_SIZE 16
38static QChar SPECIAL_TEXT_WHEN_EMPTY = QChar( 0x2063 );
40static constexpr QChar SPECIAL_TEXT_WHEN_EMPTY = QChar( 0x2063 );
46 mLineEdit =
new QgsSpinBoxLineEdit();
49 setLineEdit( mLineEdit );
51 const QSize msz = minimumSizeHint();
55 connect(
this,
static_cast<void ( QSpinBox::* )(
int )
>( &QSpinBox::valueChanged ),
this, &QgsSpinBox::changed );
57 mLastEditTimer =
new QTimer(
this );
58 mLastEditTimer->setSingleShot(
true );
59 mLastEditTimer->setInterval( 1000 );
60 connect( mLastEditTimer, &QTimer::timeout,
this, &QgsSpinBox::onLastEditTimeout );
71 mExpressionsEnabled = enabled;
76 QSpinBox::changeEvent( event );
78 if ( event->type() == QEvent::FontChange )
80 lineEdit()->setFont( font() );
83 mLineEdit->setShowClearButton( shouldShowClearForValue( value() ) );
88 mLineEdit->setShowClearButton( shouldShowClearForValue( value() ) );
89 QSpinBox::paintEvent( event );
94 const int step = singleStep();
95 if ( event->modifiers() & Qt::ControlModifier )
98 int newStep = step / 10;
100 newStep = std::max( newStep, 1 );
102 setSingleStep( newStep );
107 event->setModifiers( event->modifiers() & ~Qt::ControlModifier );
109 QSpinBox::wheelEvent( event );
110 setSingleStep( step );
119 qApp->processEvents();
120 if ( QApplication::mouseButtons() & Qt::LeftButton )
121 QSpinBox::timerEvent( event );
126 QSpinBox::focusOutEvent( event );
130void QgsSpinBox::changed(
int value )
132 mLineEdit->setShowClearButton( shouldShowClearForValue( value ) );
133 mLastEditTimer->start();
136void QgsSpinBox::onLastEditTimeout()
138 mLastEditTimer->stop();
139 const int currentValue = value();
140 if ( !mHasEmittedEditTimeout || mLastEditTimeoutValue != currentValue )
142 mHasEmittedEditTimeout =
true;
143 mLastEditTimeoutValue = currentValue;
151 if ( mLineEdit->isNull() )
157 if ( mClearValueMode ==
CustomValue && mCustomClearValue == customValue && QAbstractSpinBox::specialValueText() == specialValueText )
163 mCustomClearValue = customValue;
165 if ( !specialValueText.isEmpty() )
167 const int v = value();
176 if ( mClearValueMode == mode && mCustomClearValue == 0 && QAbstractSpinBox::specialValueText() == specialValueText )
181 mClearValueMode = mode;
182 mCustomClearValue = 0;
184 if ( !specialValueText.isEmpty() )
186 const int v = value();
200 return mCustomClearValue;
205 mLineEdit->setAlignment( alignment );
212 QSpinBox::setSpecialValueText( SPECIAL_TEXT_WHEN_EMPTY );
213 mLineEdit->setNullValue( SPECIAL_TEXT_WHEN_EMPTY );
217 QSpinBox::setSpecialValueText( txt );
218 mLineEdit->setNullValue( txt );
224 if ( !mExpressionsEnabled )
226 return QSpinBox::valueFromText( text );
229 const QString trimmedText = stripped( text );
230 if ( trimmedText.isEmpty() )
232 return mShowClearButton ?
clearValue() : value();
243 if ( !mExpressionsEnabled )
245 const QValidator::State r = QSpinBox::validate( input, pos );
249 return QValidator::Acceptable;
254 const bool wasNull = mShowClearButton && value() ==
clearValue();
255 if ( wasNull && minimum() < 0 && maximum() > 0 && !( specialValueText().isEmpty() || specialValueText() == SPECIAL_TEXT_WHEN_EMPTY ) )
263 QSpinBox::stepBy( steps );
268 return mLastEditTimer->interval();
273 mLastEditTimer->setInterval( timeout );
276int QgsSpinBox::frameWidth()
const
278 return style()->pixelMetric( QStyle::PM_DefaultFrameWidth );
281bool QgsSpinBox::shouldShowClearForValue(
const int value )
const
283 if ( !mShowClearButton || !isEnabled() )
290QString QgsSpinBox::stripped(
const QString &originalText )
const
294 QString text = originalText;
295 if ( specialValueText().isEmpty() || text != specialValueText() )
298 if ( text.contains( SPECIAL_TEXT_WHEN_EMPTY ) )
299 text = text.replace( SPECIAL_TEXT_WHEN_EMPTY, QString() );
301 int size = text.size();
302 bool changed =
false;
303 if ( !prefix().isEmpty() && text.startsWith( prefix() ) )
305 from += prefix().size();
309 if ( !suffix().isEmpty() && text.endsWith( suffix() ) )
311 size -= suffix().size();
315 text = text.mid( from, size );
318 text = text.trimmed();
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
static Q_DECL_DEPRECATED 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.
static QgsProject * instance()
Returns the QgsProject singleton instance.
void setLineEditAlignment(Qt::Alignment alignment)
Set alignment in the embedded line edit widget.
void returnPressed()
Emitted when the Return or Enter key is used in the line edit.
ClearValueMode
Behavior when widget is cleared.
@ MaximumValue
Reset value to maximum().
@ MinimumValue
Reset value to minimum().
@ CustomValue
Reset value to custom value (see setClearValue() ).
void wheelEvent(QWheelEvent *event) override
void editingTimeout(int value)
Emitted when either:
void setShowClearButton(bool showClearButton)
Sets whether the widget will show a clear button.
void focusOutEvent(QFocusEvent *event) override
QgsSpinBox(QWidget *parent=nullptr)
Constructor for QgsSpinBox.
QValidator::State validate(QString &input, int &pos) const override
void stepBy(int steps) override
void textEdited(const QString &text)
Emitted when the the value has been manually edited via line edit.
void paintEvent(QPaintEvent *event) override
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.
int valueFromText(const QString &text) const override
void setEditingTimeoutInterval(int timeout)
Sets the timeout (in milliseconds) threshold for the editingTimeout() signal to be emitted after an e...
int editingTimeoutInterval() const
Returns the timeout (in milliseconds) threshold for the editingTimeout() signal to be emitted after a...
void timerEvent(QTimerEvent *event) override
void setClearValue(int customValue, const QString &clearValueText=QString())
Defines the clear value as a custom value and will automatically set the clear value mode to CustomVa...
void setExpressionsEnabled(bool enabled)
Sets if the widget will allow entry of simple expressions, which are evaluated and then discarded.
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 changeEvent(QEvent *event) override
void clear() override
Sets the current value to the value defined by the clear value.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.