kspread

valueformatter.cc

00001 /* This file is part of the KDE project
00002    Copyright 2004 Tomas Mecir <mecirt@gmail.com>
00003    Copyright (C) 1998-2004 KSpread Team <koffice-devel@kde.org>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "valueformatter.h"
00022 
00023 #include "kspread_cell.h"
00024 #include "kspread_locale.h"
00025 #include "kspread_util.h"
00026 #include "valueconverter.h"
00027 
00028 #include <kcalendarsystem.h>
00029 #include <kdebug.h>
00030 #include <klocale.h>
00031 
00032 #include <float.h>
00033 #include <math.h>
00034 
00035 using namespace KSpread;
00036 
00037 ValueFormatter::ValueFormatter (ValueConverter *conv) : converter( conv )
00038 {
00039 }
00040 
00041 QString ValueFormatter::formatText (Cell *cell, FormatType fmtType)
00042 {
00043   if (cell->hasError ())
00044     return errorFormat (cell);
00045 
00046   QString str;
00047 
00048   Format::FloatFormat floatFormat =
00049       cell->format()->floatFormat (cell->column(), cell->row());
00050   int precision = cell->format()->precision (cell->column(), cell->row());
00051   QString prefix = cell->format()->prefix (cell->column(), cell->row());
00052   QString postfix = cell->format()->postfix (cell->column(), cell->row());
00053   Format::Currency currency;
00054   bool valid = cell->format()->currencyInfo(currency);
00055   QString currencySymbol = valid ? currency.symbol : QString::null;
00056 
00057   return formatText (cell->value(), fmtType, precision,
00058       floatFormat, prefix, postfix, currencySymbol);
00059 }
00060 
00061 QString ValueFormatter::formatText (const Value &value,
00062     FormatType fmtType, int precision, Format::FloatFormat floatFormat,
00063     const QString &prefix, const QString &postfix, const QString &currencySymbol)
00064 {
00065   //if we have an array, use its first element
00066   if (value.isArray())
00067     return formatText (value.element (0, 0), fmtType, precision,
00068         floatFormat, prefix, postfix, currencySymbol);
00069 
00070   QString str;
00071   
00072   //step 1: determine formatting that will be used
00073   fmtType = determineFormatting (value, fmtType);
00074   
00075   //step 2: format the value !
00076   
00077   //text
00078   if (fmtType == Text_format)
00079   {
00080     str = converter->asString (value).asString();
00081     if (!str.isEmpty() && str[0]=='\'' )
00082       str = str.mid(1);
00083   }
00084   
00085   //date
00086   else if (formatIsDate (fmtType))
00087     str = dateFormat (value.asDate(), fmtType);
00088     
00089   //time
00090   else if (formatIsTime (fmtType))
00091     str = timeFormat (value.asDateTime(), fmtType);
00092     
00093   //fraction
00094   else if (formatIsFraction (fmtType))
00095     str = fractionFormat (value.asFloat(), fmtType);
00096 
00097   //another
00098   else if (value.isInteger())
00099   {
00100     long v = value.asInteger();
00101     // Always unsigned ?
00102     if ((floatFormat == Format::AlwaysUnsigned) && (v < 0))
00103       v *= -1;
00104     str = createNumberFormat (v, fmtType,
00105         (floatFormat == Format::AlwaysSigned), currencySymbol);
00106   }
00107   else
00108   {
00109     QChar decimal_point = converter->locale()->decimalSymbol()[0];
00110     if ( decimal_point.isNull() )
00111       decimal_point = '.';
00112 
00113     //some cell parameters ...
00114     double v = converter->asFloat (value).asFloat();
00115 
00116     // Always unsigned ?
00117     if ((floatFormat == Format::AlwaysUnsigned) && (v < 0.0))
00118       v *= -1.0;
00119 
00120     // Make a string out of it.
00121     str = createNumberFormat (v, precision, fmtType,
00122         (floatFormat == Format::AlwaysSigned), currencySymbol);
00123 
00124     // Remove trailing zeros and the decimal point if necessary
00125     // unless the number has no decimal point
00126     if (precision == -1)
00127       removeTrailingZeros (str, decimal_point);
00128   }
00129 
00130   if (!prefix.isEmpty())
00131     str = prefix + ' ' + str;
00132 
00133   if( !postfix.isEmpty())
00134     str += ' ' + postfix;
00135 
00136   //kdDebug() << "ValueFormatter says: " << str << endl;
00137   return str;
00138 }
00139 
00140 FormatType ValueFormatter::determineFormatting (const Value &value,
00141     FormatType fmtType)
00142 {
00143   //if the cell value is a string, then we want to display it as-is,
00144   //no matter what, same if the cell is empty
00145   if (value.isString () || (value.format() == Value::fmt_None))
00146     return Text_format;
00147   //same if we're supposed to display string, no matter what we actually got
00148   if (fmtType == Text_format)
00149     return Text_format;
00150   
00151   //now, everything depends on whether the formatting is Generic or not
00152   if (fmtType == Generic_format)
00153   {
00154     //here we decide based on value's format...
00155     Value::Format fmt = value.format();
00156     switch (fmt) {
00157       case Value::fmt_None:
00158         fmtType = Text_format;
00159       break;
00160       case Value::fmt_Boolean:
00161         fmtType = Text_format;
00162       break;
00163       case Value::fmt_Number:
00164         if (value.asFloat() > 1e+10)
00165           fmtType = Scientific_format;
00166         else
00167           fmtType = Number_format;
00168       break;
00169       case Value::fmt_Percent:
00170         fmtType = Percentage_format;
00171       break;
00172       case Value::fmt_Money:
00173         fmtType = Money_format;
00174       break;
00175       case Value::fmt_DateTime:
00176         fmtType = TextDate_format;
00177       break;
00178       case Value::fmt_Date:
00179         fmtType = ShortDate_format;
00180       break;
00181       case Value::fmt_Time:
00182         fmtType = Time_format;
00183       break;
00184       case Value::fmt_String:
00185         //this should never happen
00186         fmtType = Text_format;
00187       break;
00188     };
00189     return fmtType;
00190   }
00191   else
00192   {
00193     //we'll mostly want to use the given formatting, the only exception
00194     //being Boolean values
00195     
00196     //TODO: is this correct? We may also want to convert bools to 1s and 0s
00197     //if we want to display a number...
00198     
00199     //TODO: what to do about Custom formatting? We don't support it as of now,
00200     //  but we'll have it ... one day, that is ...
00201     if (value.isBoolean())
00202       return Text_format;
00203     else
00204       return fmtType;
00205   }
00206 }
00207 
00208 
00209 void ValueFormatter::removeTrailingZeros (QString &str, QChar decimal_point)
00210 {
00211   if (str.find (decimal_point) < 0)
00212     //no decimal point -> nothing to do
00213     return;
00214   
00215   int start = 0;
00216   int cslen = converter->locale()->currencySymbol().length();
00217   if (str.find ('%') != -1)
00218     start = 2;
00219   else if (str.find (converter->locale()->currencySymbol()) ==
00220       ((int) (str.length() - cslen)))
00221     start = cslen + 1;
00222   else if ((start = str.find ('E')) != -1)
00223     start = str.length() - start;
00224   else
00225     start = 0;
00226 
00227   int i = str.length() - start;
00228   bool bFinished = false;
00229   while ( !bFinished && i > 0 )
00230   {
00231     QChar ch = str[i - 1];
00232     if (ch == '0')
00233       str.remove (--i,1);
00234     else
00235     {
00236       bFinished = true;
00237       if (ch == decimal_point)
00238         str.remove (--i, 1);
00239     }
00240   }
00241 }
00242 
00243 
00244 QString ValueFormatter::createNumberFormat ( long value, FormatType fmt, 
00245      bool alwaysSigned, const QString& currencySymbol)
00246 {
00247   QString number;
00248 
00249   //multiply value by 100 for percentage format
00250   if (fmt == Percentage_format)
00251     value *= 100;
00252 
00253   switch (fmt)
00254   {
00255     case Number_format:
00256     case Scientific_format:
00257       number = QString::number(value);
00258       break;
00259     case Percentage_format:
00260       number = QString::number(value) + " %";
00261       break;
00262     case Money_format:
00263       number = converter->locale()->formatMoney (value, currencySymbol.isEmpty() ? converter->locale()->currencySymbol() : currencySymbol);
00264       break;
00265     default :
00266       //other formatting?
00267       // This happens with Custom_format...
00268       kdDebug(36001)<<"Wrong usage of ValueFormatter::createNumberFormat fmt=" << fmt << "\n";
00269       break;
00270   }
00271 
00272   //prepend positive sign if needed
00273   if (alwaysSigned && value >= 0 )
00274     if (converter->locale()->positiveSign().isEmpty())
00275       number='+'+number;
00276 
00277   return number;
00278 }
00279 
00280 QString ValueFormatter::createNumberFormat ( double value, int precision,
00281     FormatType fmt, bool alwaysSigned, const QString& currencySymbol)
00282 {
00283   // if precision is -1, ask for a huge number of decimals, we'll remove
00284   // the zeros later. Is 8 ok ?
00285   int p = (precision == -1) ? 8 : precision;
00286   QString localizedNumber;
00287   int pos = 0;
00288 
00289   //multiply value by 100 for percentage format
00290   if (fmt == Percentage_format)
00291     value *= 100;
00292 
00293   // this will avoid displaying negative zero, i.e "-0.0000"
00294   if( fabs( value ) < DBL_EPSILON ) value = 0.0;
00295 
00296   // round the number, based on desired precision if not scientific is chosen 
00297   //(scientific has relative precision)
00298   if( fmt != Scientific_format )
00299   {
00300     double m[] = { 1, 10, 100, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10 };
00301     double mm = (p > 10) ? pow(10.0,p) : m[p];
00302     bool neg = value < 0;
00303     value = floor( fabs(value)*mm + 0.5 ) / mm;
00304     if( neg ) value = -value;
00305   }
00306 
00307   QChar decimal_point;
00308   switch (fmt)
00309   {
00310     case Number_format:
00311       localizedNumber = converter->locale()->formatNumber(value, p);
00312       break;
00313     case Percentage_format:
00314       localizedNumber = converter->locale()->formatNumber (value, p)+ " %";
00315       break;
00316     case Money_format:
00317       localizedNumber = converter->locale()->formatMoney (value,
00318         currencySymbol.isEmpty() ? converter->locale()->currencySymbol() : currencySymbol, p );
00319       break;
00320     case Scientific_format:
00321       decimal_point = converter->locale()->decimalSymbol()[0];
00322       localizedNumber = QString::number (value, 'E', p);
00323       if ((pos = localizedNumber.find ('.')) != -1)
00324         localizedNumber = localizedNumber.replace (pos, 1, decimal_point);
00325       break;
00326     default :
00327       //other formatting?
00328       // This happens with Custom_format...
00329       kdDebug(36001)<<"Wrong usage of ValueFormatter::createNumberFormat fmt=" << fmt << "\n";
00330       break;
00331   }
00332 
00333   //prepend positive sign if needed
00334   if (alwaysSigned && value >= 0 )
00335     if (converter->locale()->positiveSign().isEmpty())
00336       localizedNumber='+'+localizedNumber;
00337 
00338   return localizedNumber;
00339 }
00340 
00341 QString ValueFormatter::fractionFormat (double value, FormatType fmtType)
00342 {
00343   double result = value - floor(value);
00344   int index;
00345   int limit = 0;
00346 
00347   /* return w/o fraction part if not necessary */
00348   if (result == 0)
00349     return QString::number(value);
00350 
00351   switch (fmtType) {
00352   case fraction_half:
00353     index = 2;
00354     break;
00355   case fraction_quarter:
00356     index = 4;
00357     break;
00358   case fraction_eighth:
00359     index = 8;
00360     break;
00361   case fraction_sixteenth:
00362     index = 16;
00363     break;
00364   case fraction_tenth:
00365     index = 10;
00366     break;
00367   case fraction_hundredth:
00368     index = 100;
00369     break;
00370   case fraction_one_digit:
00371     index = 3;
00372     limit = 9;
00373     break;
00374   case fraction_two_digits:
00375     index = 4;
00376     limit = 99;
00377     break;
00378   case fraction_three_digits:
00379     index = 5;
00380     limit = 999;
00381     break;
00382   default:
00383     kdDebug(36001) << "Error in Fraction format\n";
00384     return QString::number(value);
00385     break;
00386   } /* switch */
00387 
00388 
00389   /* handle halves, quarters, tenths, ... */
00390 
00391   if (fmtType != fraction_three_digits
00392     && fmtType != fraction_two_digits
00393     && fmtType != fraction_one_digit) {
00394     double calc = 0;
00395     int index1 = 0;
00396     double diff = result;
00397     for (int i = 1; i <= index; i++) {
00398       calc = i * 1.0 / index;
00399       if (fabs(result - calc) < diff) {
00400         index1 = i;
00401         diff = fabs(result - calc);
00402       }
00403     }
00404     if( index1 == 0 ) return QString("%1").arg( floor(value) );
00405     if( index1 == index ) return QString("%1").arg( floor(value)+1 );
00406     if( floor(value) == 0)
00407       return QString("%1/%2").arg( index1 ).arg( index );
00408 
00409     return QString("%1 %2/%3")
00410         .arg( floor(value) )
00411         .arg( index1 )
00412         .arg( index );
00413   }
00414 
00415 
00416   /* handle fraction_one_digit, fraction_two_digit
00417     * and fraction_three_digit style */
00418 
00419   double precision, denominator, numerator;
00420 
00421   do {
00422     double val1 = result;
00423     double val2 = rint(result);
00424     double inter2 = 1;
00425     double inter4, p,  q;
00426     inter4 = p = q = 0;
00427     
00428     precision = pow(10.0, -index);
00429     numerator = val2;
00430     denominator = 1;
00431     
00432     while (fabs(numerator/denominator - result) > precision) {
00433       val1 = (1 / (val1 - val2));
00434       val2 = rint(val1);
00435       p = val2 * numerator + inter2;
00436       q = val2 * denominator + inter4;
00437       inter2 = numerator;
00438       inter4 = denominator;
00439       numerator = p;
00440       denominator = q;
00441     }
00442     index--;
00443   } while (fabs(denominator) > limit);
00444 
00445   denominator = fabs(denominator);
00446   numerator = fabs(numerator);
00447 
00448   if (denominator == numerator)
00449     return QString().setNum(floor(value + 1));
00450   else
00451   {
00452     if ( floor(value) == 0 )
00453       return QString("%1/%2").arg(numerator).arg(denominator);
00454     else
00455       return QString("%1 %2/%3")
00456         .arg(floor(value))
00457         .arg(numerator)
00458         .arg(denominator);
00459   }
00460 }
00461 
00462 QString ValueFormatter::timeFormat (const QDateTime &dt, FormatType fmtType)
00463 {
00464   if (fmtType == Time_format)
00465     return converter->locale()->formatTime(dt.time(), false);
00466 
00467   if (fmtType == SecondeTime_format)
00468     return converter->locale()->formatTime(dt.time(), true);
00469 
00470   int h = dt.time().hour();
00471   int m = dt.time().minute();
00472   int s = dt.time().second();
00473 
00474   QString hour = ( h < 10 ? "0" + QString::number(h) : QString::number(h) );
00475   QString minute = ( m < 10 ? "0" + QString::number(m) : QString::number(m) );
00476   QString second = ( s < 10 ? "0" + QString::number(s) : QString::number(s) );
00477   bool pm = (h > 12);
00478   QString AMPM( pm ? i18n("PM"):i18n("AM") );
00479 
00480   if (fmtType == Time_format1) {  // 9 : 01 AM
00481     return QString("%1:%2 %3")
00482       .arg((pm ? h - 12 : h),2)
00483       .arg(minute,2)
00484       .arg(AMPM);
00485   }
00486 
00487   if (fmtType == Time_format2) {  //9:01:05 AM
00488     return QString("%1:%2:%3 %4")
00489       .arg((pm ? h-12 : h),2)
00490       .arg(minute,2)
00491       .arg(second,2)
00492       .arg(AMPM);
00493   }
00494 
00495   if (fmtType == Time_format3) {
00496     return QString("%1 %2 %3 %4 %5 %6")      // 9 h 01 min 28 s
00497       .arg(hour,2)
00498       .arg(i18n("h"))
00499       .arg(minute,2)
00500       .arg(i18n("min"))
00501       .arg(second,2)
00502       .arg(i18n("s"));
00503   }
00504 
00505   if (fmtType == Time_format4) {  // 9:01
00506     return QString("%1:%2").arg(hour, 2).arg(minute, 2);
00507   }
00508 
00509   if (fmtType == Time_format5) {  // 9:01:12
00510     return QString("%1:%2:%3").arg(hour, 2).arg(minute, 2).arg(second, 2);
00511   }
00512 
00513   QDate d1(dt.date());
00514   QDate d2( 1899, 12, 31 );
00515   int d = d2.daysTo( d1 ) + 1;
00516 
00517   h += d * 24;
00518 
00519   if (fmtType == Time_format6)
00520   {  // [mm]:ss
00521     m += (h * 60);
00522     return QString("%1:%2").arg(m, 1).arg(second, 2);
00523   }
00524   if (fmtType == Time_format7) {  // [h]:mm:ss
00525     return QString("%1:%2:%3").arg(h, 1).arg(minute, 2).arg(second, 2);
00526   }
00527   if (fmtType == Time_format8)
00528   {  // [h]:mm
00529     m += (h * 60);
00530     return QString("%1:%2").arg(h, 1).arg(minute, 2);
00531   }
00532 
00533   return converter->locale()->formatTime( dt.time(), false );
00534 }
00535 
00536 QString ValueFormatter::dateFormat (const QDate &date, FormatType fmtType)
00537 {
00538   QString tmp;
00539   if (fmtType == ShortDate_format) {
00540     tmp = converter->locale()->formatDate(date, true);
00541   }
00542   else if (fmtType == TextDate_format) {
00543     tmp = converter->locale()->formatDate(date, false);
00544   }
00545   else if (fmtType == date_format1) {  /*18-Feb-99 */
00546     tmp = QString().sprintf("%02d", date.day());
00547     tmp += "-" + converter->locale()->calendar()->monthString(date, true) + "-";
00548     tmp += QString::number(date.year()).right(2);
00549   }
00550   else if (fmtType == date_format2) {  /*18-Feb-1999 */
00551     tmp = QString().sprintf("%02d", date.day());
00552     tmp += "-" + converter->locale()->calendar()->monthString(date, true) + "-";
00553     tmp += QString::number(date.year());
00554   }
00555   else if (fmtType == date_format3) {  /*18-Feb */
00556     tmp = QString().sprintf("%02d", date.day());
00557     tmp += "-" + converter->locale()->calendar()->monthString(date, true);
00558   }
00559   else if (fmtType == date_format4) {  /*18-05 */
00560     tmp = QString().sprintf("%02d", date.day());
00561     tmp += "-" + QString().sprintf("%02d", date.month() );
00562   }
00563   else if (fmtType == date_format5) {  /*18/05/00 */
00564     tmp = QString().sprintf("%02d", date.day());
00565     tmp += "/" + QString().sprintf("%02d", date.month()) + "/";
00566     tmp += QString::number(date.year()).right(2);
00567   }
00568   else if (fmtType == date_format6) {  /*18/05/1999 */
00569     tmp = QString().sprintf("%02d", date.day());
00570     tmp += "/" + QString().sprintf("%02d", date.month()) + "/";
00571     tmp += QString::number(date.year());
00572   }
00573   else if (fmtType == date_format7) {  /*Feb-99 */
00574     tmp = converter->locale()->calendar()->monthString(date, true) + "-";
00575     tmp += QString::number(date.year()).right(2);
00576   }
00577   else if (fmtType == date_format8) {  /*February-99 */
00578     tmp = converter->locale()->calendar()->monthString(date, false) + "-";
00579     tmp += QString::number(date.year()).right(2);
00580   }
00581   else if (fmtType == date_format9) {  /*February-1999 */
00582     tmp = converter->locale()->calendar()->monthString(date, false) + "-";
00583     tmp += QString::number(date.year());
00584   }
00585   else if (fmtType == date_format10) {  /*F-99 */
00586     tmp = converter->locale()->calendar()->monthString(date, false).at(0) + "-";
00587     tmp += QString::number(date.year()).right(2);
00588   }
00589   else if (fmtType == date_format11) {  /*18/Feb */
00590     tmp = QString().sprintf("%02d", date.day()) + "/";
00591     tmp += converter->locale()->calendar()->monthString(date, true);
00592   }
00593   else if (fmtType == date_format12) {  /*18/02 */
00594     tmp = QString().sprintf("%02d", date.day()) + "/";
00595     tmp += QString().sprintf("%02d", date.month());
00596   }
00597   else if (fmtType == date_format13) {  /*18/Feb/1999 */
00598     tmp = QString().sprintf("%02d", date.day());
00599     tmp += "/" + converter->locale()->calendar()->monthString(date, true) + "/";
00600     tmp += QString::number(date.year());
00601   }
00602   else if (fmtType == date_format14) {  /*2000/Feb/18 */
00603     tmp = QString::number(date.year());
00604     tmp += "/" + converter->locale()->calendar()->monthString(date, true) + "/";
00605     tmp += QString().sprintf("%02d", date.day());
00606   }
00607   else if (fmtType == date_format15) {  /*2000-Feb-18 */
00608     tmp = QString::number(date.year());
00609     tmp += "-" + converter->locale()->calendar()->monthString(date, true) + "-";
00610     tmp += QString().sprintf("%02d", date.day());
00611   }
00612   else if (fmtType == date_format16) {  /*2000-02-18 */
00613     tmp = QString::number(date.year());
00614     tmp += "-" + QString().sprintf("%02d", date.month()) + "-";
00615     tmp += QString().sprintf("%02d", date.day());
00616   }
00617   else if (fmtType == date_format17) {  /*2 february 2000 */
00618     tmp = QString().sprintf("%d", date.day());
00619     tmp += " " + converter->locale()->calendar()->monthString(date, false) + " ";
00620     tmp += QString::number(date.year());
00621   }
00622   else if (fmtType == date_format18) {  /*02/18/1999 */
00623     tmp = QString().sprintf("%02d", date.month());
00624     tmp += "/" + QString().sprintf("%02d", date.day());
00625     tmp += "/" + QString::number(date.year());
00626   }
00627   else if (fmtType == date_format19) {  /*02/18/99 */
00628     tmp = QString().sprintf("%02d", date.month());
00629     tmp += "/" + QString().sprintf("%02d", date.day());
00630     tmp += "/" + QString::number(date.year()).right(2);
00631   }
00632   else if (fmtType == date_format20) {  /*Feb/18/99 */
00633     tmp = converter->locale()->calendar()->monthString(date, true);
00634     tmp += "/" + QString().sprintf("%02d", date.day());
00635     tmp += "/" + QString::number(date.year()).right(2);
00636   }
00637   else if (fmtType == date_format21) {  /*Feb/18/1999 */
00638     tmp = converter->locale()->calendar()->monthString(date, true);
00639     tmp += "/" + QString().sprintf("%02d", date.day());
00640     tmp += "/" + QString::number(date.year());
00641   }
00642   else if (fmtType == date_format22) {  /*Feb-1999 */
00643     tmp = converter->locale()->calendar()->monthString(date, true) + "-";
00644     tmp += QString::number(date.year());
00645   }
00646   else if (fmtType == date_format23) {  /*1999 */
00647     tmp = QString::number(date.year());
00648   }
00649   else if (fmtType == date_format24) {  /*99 */
00650     tmp = QString::number(date.year()).right(2);
00651   }
00652   else if (fmtType == date_format25) {  /*2000/02/18 */
00653     tmp = QString::number(date.year());
00654     tmp += "/" + QString().sprintf("%02d", date.month());
00655     tmp += "/" + QString().sprintf("%02d", date.day());
00656   }
00657   else if (fmtType == date_format26) {  /*2000/Feb/18 */
00658     tmp = QString::number(date.year());
00659     tmp += "/" + converter->locale()->calendar()->monthString(date, true);
00660     tmp += "/" + QString().sprintf("%02d", date.day());
00661   }
00662   else
00663     tmp = converter->locale()->formatDate(date, true);
00664 
00665   // Missing compared with gnumeric:
00666   //  "m/d/yy h:mm",    /* 20 */
00667   //  "m/d/yyyy h:mm",  /* 21 */
00668   //  "mmm/ddd/yy",    /* 12 */
00669   //  "mmm/ddd/yyyy",    /* 13 */
00670   //  "mm/ddd/yy",    /* 14 */
00671   //  "mm/ddd/yyyy",    /* 15 */
00672 
00673   return tmp;
00674 }
00675 
00676 QString ValueFormatter::errorFormat (Cell *cell)
00677 {
00678   QString err;
00679   if (cell->testFlag (Cell::Flag_ParseError))
00680     err = "#" + i18n ("Parse") + "!";
00681   else if ( cell->testFlag (Cell::Flag_CircularCalculation))
00682     err = "#" + i18n ("Circle") + "!";
00683   else if ( cell->testFlag (Cell::Flag_DependancyError))
00684     err = "#" + i18n ("Depend") + "!";
00685   else
00686   {
00687     err = "####";
00688     kdDebug(36001) << "Unhandled error type." << endl;
00689   }
00690   return err;
00691 }
00692 
KDE Home | KDE Accessibility Home | Description of Access Keys