/**************************************************************************** ** ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). ** Contact: Qt Software Information (qt-info@nokia.com) ** ** This file is part of the QtDeclarative module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the either Technology Preview License Agreement or the ** Beta Release License Agreement. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain ** additional rights. These rights are described in the Nokia Qt LGPL ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this ** package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please ** contact the sales department at qt-sales@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qnumberformat.h" QT_BEGIN_NAMESPACE QML_DEFINE_NOCREATE_TYPE(QNumberFormat) QNumberFormat::QNumberFormat(QObject *parent) : QObject(parent), _number(0), _type(Decimal), _groupingSize(0) { _locale = QLocale::system(); _groupingSeparator = _locale.groupSeparator(); _decimalSeparator = _locale.decimalPoint(); _currencySymbol = QLatin1Char('$'); } QNumberFormat::~QNumberFormat() { } void QNumberFormat::updateText() { QTime t; t.start(); static int totalTime; handleFormat(); totalTime += t.elapsed(); emit textChanged(); } void QNumberFormat::handleFormat() { // ### is extremely messy if (_format.isEmpty()) { _text = QString(QLatin1String("%1")).arg(_number, -1, 'f', -1); return; } QString inputString; // ### possible to use the following parsed data in the future int remainingLength = _format.size(); int currentIndex = _format.size()-1; int maxDigits = 0; int minDigits = 0; int decimalLength = 0; while (remainingLength > 0) { switch(_format.at(currentIndex).unicode()) { case ',': if (decimalLength && !_groupingSize) setGroupingSize(maxDigits - decimalLength); else if (!_groupingSize) setGroupingSize(maxDigits); break; case '.': if (!decimalLength) decimalLength = maxDigits; break; case '0': minDigits++; case '#': maxDigits++; break; default: break; } currentIndex--; remainingLength--; } // round given the decimal length/precision inputString = QString(QLatin1String("%1")).arg(_number, -1, 'f', decimalLength); QStringList parts = inputString.split(QLatin1Char('.')); QStringList formatParts = _format.split(QLatin1Char('.')); if (formatParts.size() > 2 || parts.size() > 2 ) return; QString formatInt = formatParts.at(0); QString formatDec; if (formatParts.size() == 2) formatDec = formatParts.at(1); QString integer = parts.at(0); QString decimal; if (parts.size() == 2) decimal = parts.at(1); QString outputDecimal = formatDecimal(formatDec, decimal); QString outputInteger = formatInteger(formatInt, integer); // insert separators if (_groupingSize) { unsigned int count = 0; for (int i = outputInteger.size()-1; i > 0; i--) { if (outputInteger.at(i).digitValue() >= 0) { if (count == _groupingSize - 1) { count = 0; outputInteger.insert(i, _groupingSeparator); } else count++; } } } if (!outputDecimal.isEmpty()) _text = outputInteger + _decimalSeparator + outputDecimal; else _text = outputInteger; } QString QNumberFormat::formatInteger(const QString &formatInt, const QString &integer) { if (formatInt.isEmpty() || integer.isEmpty()) return QString(); QString outputInteger; int formatIndex = formatInt.size()-1; //easier for carry? for (int index= integer.size()-1; index >= 0; index--) { if (formatIndex < 0) { outputInteger.push_front(integer.at(index)); } else { switch(formatInt.at(formatIndex).unicode()) { case '0': if (index > integer.size()-1) { outputInteger.push_front(QLatin1Char('0')); break; } case '#': outputInteger.push_front(integer.at(index)); break; case ',': index++; break; default: outputInteger.push_front(formatInt.at(formatIndex)); index++; break; } formatIndex--; } } while (formatIndex >= 0) { if (formatInt.at(formatIndex).unicode() != '#' && formatInt.at(formatIndex).unicode() != ',') outputInteger.push_front(formatInt.at(formatIndex)); formatIndex--; } return outputInteger; } QString QNumberFormat::formatDecimal(const QString &formatDec, const QString &decimal) { QString outputDecimal; // up to max 6 decimal places for (int index=formatDec.size()-1; index >= 0; index--) { switch(formatDec.at(index).unicode()) { case '0': outputDecimal.push_front(decimal.at(index)); break; case '#': if (decimal.at(index) != QLatin1Char('0') || outputDecimal.size() > 0) outputDecimal.push_front(decimal.at(index)); break; default: outputDecimal.push_front(formatDec.at(index)); break; } } return outputDecimal; } QT_END_NAMESPACE