33 #include <QApplication>
37 #include <QStyleOptionSpinBox>
42 : QAbstractSpinBox(parent), m_value(0), m_singleStep(1), m_min(0), m_max(100),
43 m_displayBase(10), m_showGroupSeparator(false)
46 setInputMethodHints(Qt::ImhFormattedNumbersOnly);
77 m_cachedMinSize = QSize();
90 m_cachedMinSize = QSize();
117 setRange(min, m_max < min ? min : m_max);
127 setRange(max < m_min ? max : m_min, max);
133 m_max = max < min ? min : max;
134 setValue(qBound(m_min, m_value, m_max));
135 m_cachedMinSize = QSize();
140 return m_displayBase;
145 if (Q_UNLIKELY(base < 2 || base > 36)) {
146 qWarning(
"LongLongSpinBox::setDisplayIntegerBase: Invalid base (%d)", base);
150 if (base != m_displayBase) {
151 m_displayBase = base;
155 m_cachedMinSize = QSize();
161 if (m_displayBase == 10) {
162 str = locale().toString(val);
163 if (!m_showGroupSeparator
164 && (qAbs(val) >= 1000 || val == std::numeric_limits<qint64>::min()))
165 str.remove(locale().groupSeparator());
167 QLatin1String
prefix = val < 0 ? QLatin1String(
"-") : QLatin1String();
168 str = prefix + QString::number(val, m_displayBase);
177 int pos = lineEdit()->cursorPosition();
178 QValidator::State state = QValidator::Acceptable;
183 QValidator::State &state)
const
185 QString copy =
stripped(input, &pos);
186 state = QValidator::Acceptable;
189 if (m_max != m_min && (copy.isEmpty()
190 || (m_min < 0 && copy == QLatin1String(
"-"))
191 || (m_max >= 0 && copy == QLatin1String(
"+")))) {
192 state = QValidator::Intermediate;
193 }
else if (copy.startsWith(QLatin1Char(
'-')) && m_min >= 0) {
194 state = QValidator::Invalid;
197 if (m_displayBase == 10) {
198 num = locale().toLongLong(copy, &ok);
199 if (!ok && copy.contains(locale().groupSeparator())
200 && (m_max >= 1000 || m_min <= - 1000)) {
201 QString copy2 = copy;
202 copy2.remove(locale().groupSeparator());
203 num = locale().toLongLong(copy2, &ok);
206 num = copy.toLongLong(&ok, m_displayBase);
210 state = QValidator::Invalid;
211 }
else if (num >= m_min && num <= m_max) {
212 state = QValidator::Acceptable;
213 }
else if (m_max == m_min) {
214 state = QValidator::Invalid;
216 if ((num >= 0 && num > m_max) || (num < 0 && num < m_min))
217 state = QValidator::Invalid;
219 state = QValidator::Intermediate;
223 if (state != QValidator::Acceptable)
224 num = m_max > 0 ? m_min : m_max;
226 input = m_prefix + copy + m_suffix;
233 QValidator::State state;
240 if (!isGroupSeparatorShown())
241 input.remove(locale().groupSeparator());
248 if (specialValueText().size() == 0 || text != specialValueText()) {
250 int size = text.size();
251 bool changed =
false;
252 if (m_prefix.size() && text.startsWith(m_prefix)) {
253 from += m_prefix.size();
257 if (m_suffix.size() && text.endsWith(m_suffix)) {
262 text = text.mid(from, size);
265 const int s = text.size();
266 text = text.trimmed();
268 (*pos) -= (s - text.size());
270 return text.toString();
275 const bool specialValue = specialValueText().size() > 0;
276 const QString newText = specialValue ? specialValueText() :
278 if (newText == lineEdit()->displayText())
281 const bool empty = lineEdit()->text().isEmpty();
282 int cursor = lineEdit()->cursorPosition();
283 int selsize = lineEdit()->selectedText().size();
284 const QSignalBlocker blocker(lineEdit());
285 lineEdit()->setText(newText);
288 cursor = qBound(m_prefix.size(), cursor, lineEdit()->displayText().size() - m_suffix.size());
291 lineEdit()->setSelection(cursor, selsize);
293 lineEdit()->setCursorPosition(empty ? m_prefix.size() : cursor);
301 QAbstractSpinBox::StepEnabled enabled;
303 enabled |= StepDownEnabled;
305 enabled |= StepUpEnabled;
311 setValue(qBound(m_min, m_value + steps, m_max));
316 QAbstractSpinBox::setLineEdit(edit);
324 if (keyboardTracking()) {
326 int pos = lineEdit()->cursorPosition();
327 QValidator::State state =
validate(tmp, pos);
328 if (state == QValidator::Acceptable) {
337 if (m_cachedMinSize.isEmpty()) {
340 const QFontMetrics fm(fontMetrics());
341 int h = lineEdit()->minimumSizeHint().height();
344 QString fixedContent = m_prefix + QStringLiteral(
" ") + m_suffix;
351 w = std::max(w, fm.width(s));
353 if (specialValueText().size())
354 w = qMax(w, fm.width(specialValueText()));
358 QStyleOptionSpinBox opt;
359 initStyleOption(&opt);
362 m_cachedMinSize = style()->sizeFromContents(QStyle::CT_SpinBox, &opt, hint,
this)
363 .expandedTo(QApplication::globalStrut());
365 return m_cachedMinSize;
370 switch (event->type()) {
371 case QEvent::FontChange:
372 case QEvent::StyleChange:
373 m_cachedMinSize = QSize();
378 return QAbstractSpinBox::event(event);
void setPrefix(const QString &prefix)
void setDisplayIntegerBase(int base)
virtual QString textFromValue(qint64 val) const
void setMaximum(qint64 max)
void setMinimum(qint64 min)
void setRange(qint64 min, qint64 max)
virtual StepEnabled stepEnabled() const override
QValidator::State validate(QString &input, int &pos) const override
virtual bool event(QEvent *event) override
void lineEditChanged(const QString &t)
virtual QSize minimumSizeHint() const override
qint64 singleStep() const
void setValue(qint64 val)
void fixup(QString &str) const override
LongLongSpinBox(QWidget *parent=nullptr)
void setSuffix(const QString &suffix)
QString stripped(const QString &text, int *pos=nullptr) const
int displayIntegerBase() const
virtual void stepBy(int steps) override
void setSingleStep(qint64 val)
void valueChanged(qint64 val)
qint64 validateAndInterpret(QString &input, int &pos, QValidator::State &state) const
virtual void setLineEdit(QLineEdit *edit)
virtual qint64 valueFromText(const QString &text)
QString cleanText() const