void kMyMoneyEdit::theTextChanged(const QString & theText) { QString d = QLocale().decimalPoint(); QString l_text = theText; QString nsign, psign; #if 0 KLocale * l = KLocale::global(); if (l->negativeMonetarySignPosition() == KLocale::ParensAround || l->positiveMonetarySignPosition() == KLocale::ParensAround) { nsign = psign = '('; } else { nsign = l->negativeSign(); psign = l->positiveSign(); } #else nsign = "-"; psign = ""; #endif int i = 0; if (isEnabled()) { QValidator::State state = m_edit->validator()->validate(l_text, i); if (state == QValidator::Intermediate) { if (l_text.length() == 1) { if (l_text != d && l_text != nsign && l_text != psign) state = QValidator::Invalid; } } if (state == QValidator::Invalid) m_edit->setText(previousText); else { previousText = l_text; emit textChanged(m_edit->text()); m_resetButton->setEnabled(true); } } }
double DoubleSpinBox::valueFromText( const QString & text ) const { DoubleSpinbox_qDebug() << Q_FUNC_INFO << "text = " << text; KLocale * locale = KGlobal::locale(); // Fetch the characters that we don't want to discard const QString exclude = locale->decimalSymbol() + locale->thousandsSeparator() + locale->positiveSign() + locale->negativeSign(); QString textToStrip( text ); QString numberToRead = textToStrip.remove( QRegExp("[^"+exclude+"\\d]") ); bool ok; double value = locale->readNumber( numberToRead, &ok ); if (!ok) { DoubleSpinbox_qDebug() << Q_FUNC_INFO << "numberToRead = |" << numberToRead << "| NOT OK"; value = 0; } DoubleSpinbox_qDebug() << Q_FUNC_INFO << "numberToRead = " << numberToRead << ", value = " << value; if ( value > maximum() ) { value = maximum(); } else if ( value < minimum() ) { value = minimum(); } if ( std::abs(value) < m_minAbsValue*0.9999 ) { value = 0.0; } double multiplier = 1.0; //updateSuffix( value ); QString textForSuffix( text ); if ( textForSuffix.length() != 0 ) { if ( textForSuffix.endsWith( m_unit, false ) ) { textForSuffix = textForSuffix.remove( textForSuffix.length() - m_unit.length(), m_unit.length() ); } textForSuffix.stripWhiteSpace(); QChar siExp = textForSuffix[ textForSuffix.length()-1 ]; DoubleSpinbox_qDebug() << Q_FUNC_INFO << "SI exp = " << siExp; if ( siExp.isLetter() || siExp.isSymbol() ) { multiplier = CNItem::getMultiplier( QString(siExp) ); } else { multiplier = 1; } } DoubleSpinbox_qDebug() << Q_FUNC_INFO << "multiplier = " << multiplier; //value /= Item::getMultiplier( value ); value *= multiplier; DoubleSpinbox_qDebug() << Q_FUNC_INFO << "value = " << value; return value; }
/* * The code of the following function is taken from kdeui/knumvalidator.cpp * and adjusted to always use the monetary symbols defined in the KDE System Settings */ QValidator::State kMyMoneyMoneyValidator::validate(QString & input, int & _p) const { QString s = input; // TODO: port this to kf5 #if 0 KLocale * l = KLocale::global(); // ok, we have to re-format the number to have: // 1. decimalSymbol == '.' // 2. negativeSign == '-' // 3. positiveSign == <empty> // 4. thousandsSeparator() == <empty> (we don't check that there // are exactly three decimals between each separator): QString d = l->monetaryDecimalSymbol(), n = l->negativeSign(), p = l->positiveSign(), t = l->monetaryThousandsSeparator(); // first, delete p's and t's: if (!p.isEmpty()) for (int idx = s.indexOf(p) ; idx >= 0 ; idx = s.indexOf(p, idx)) s.remove(idx, p.length()); if (!t.isEmpty()) for (int idx = s.indexOf(t) ; idx >= 0 ; idx = s.indexOf(t, idx)) s.remove(idx, t.length()); // then, replace the d's and n's if ((!n.isEmpty() && n.indexOf('.') != -1) || (!d.isEmpty() && d.indexOf('-') != -1)) { // make sure we don't replace something twice: qWarning() << "KDoubleValidator: decimal symbol contains '-' or " "negative sign contains '.' -> improve algorithm" << endl; return Invalid; } if (!d.isEmpty() && d != ".") for (int idx = s.indexOf(d) ; idx >= 0 ; idx = s.indexOf(d, idx + 1)) s.replace(idx, d.length(), "."); if (!n.isEmpty() && n != "-") for (int idx = s.indexOf(n) ; idx >= 0 ; idx = s.indexOf(n, idx + 1)) s.replace(idx, n.length(), "-"); // Take care of monetary parens around the value if selected via // the locale settings. // If the lead-in or lead-out paren is present, remove it // before passing the string to the QDoubleValidator if (l->negativeMonetarySignPosition() == KLocale::ParensAround || l->positiveMonetarySignPosition() == KLocale::ParensAround) { QRegExp regExp("^(\\()?([\\d-\\.]*)(\\))?$"); if (s.indexOf(regExp) != -1) { s = regExp.cap(2); } } // check for non numeric values (QDoubleValidator allows an 'e', we don't) QRegExp nonNumeric("[^\\d-\\.]+"); if (s.indexOf(nonNumeric) != -1) return Invalid; // check for minus sign trailing the number QRegExp trailingMinus("^([^-]*)\\w*-$"); if (s.indexOf(trailingMinus) != -1) { s = QString("-%1").arg(trailingMinus.cap(1)); } // check for the maximum allowed number of decimal places int decPos = s.indexOf('.'); if (decPos != -1) { if (decimals() == 0) return Invalid; if (((int)(s.length()) - decPos) > decimals()) return Invalid; } // If we have just a single minus sign, we are done if (s == QString("-")) return Acceptable; QValidator::State rc = QDoubleValidator::validate(s, _p); if (rc == Acceptable) { // If the numeric value is acceptable, we check if the parens // are ok. If only the lead-in is present, the return value // is intermediate, if only the lead-out is present then it // definitely is invalid. Nevertheless, we check for parens // only, if the locale settings have it enabled. if (l->negativeMonetarySignPosition() == KLocale::ParensAround || l->positiveMonetarySignPosition() == KLocale::ParensAround) { int tmp = input.count('(') - input.count(')'); if (tmp > 0) rc = Intermediate; else if (tmp < 0) rc = Invalid; } } return rc; #else return Acceptable; #endif }