~ubuntu-branches/ubuntu/breezy/koffice/breezy-security

« back to all changes in this revision

Viewing changes to kspread/valueformatter.cc

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2005-10-11 14:49:50 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051011144950-lwpngbifzp8nk0ds
Tags: 1:1.4.1-0ubuntu7
* SECURITY UPDATE: fix heap based buffer overflow in the RTF importer of KWord
* Opening specially crafted RTF files in KWord can cause
  execution of abitrary code.
* Add kubuntu_01_rtfimport_heap_overflow.diff
* References:
  CAN-2005-2971
  CESA-2005-005
  http://www.koffice.org/security/advisory-20051011-1.txt

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* This file is part of the KDE project
 
2
   Copyright 2004 Tomas Mecir <mecirt@gmail.com>
 
3
   Copyright (C) 1998-2004 KSpread Team <koffice-devel@mail.kde.org>
 
4
 
 
5
   This library is free software; you can redistribute it and/or
 
6
   modify it under the terms of the GNU Library General Public
 
7
   License as published by the Free Software Foundation; either
 
8
   version 2 of the License, or (at your option) any later version.
 
9
 
 
10
   This library is distributed in the hope that it will be useful,
 
11
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
   Library General Public License for more details.
 
14
 
 
15
   You should have received a copy of the GNU Library General Public License
 
16
   along with this library; see the file COPYING.LIB.  If not, write to
 
17
   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
18
   Boston, MA 02111-1307, USA.
 
19
*/
 
20
 
 
21
#include "valueformatter.h"
 
22
 
 
23
#include "kspread_cell.h"
 
24
#include "kspread_locale.h"
 
25
#include "kspread_util.h"
 
26
#include "valueconverter.h"
 
27
 
 
28
#include <kcalendarsystem.h>
 
29
#include <kdebug.h>
 
30
#include <klocale.h>
 
31
 
 
32
#include <float.h>
 
33
#include <math.h>
 
34
 
 
35
using namespace KSpread;
 
36
 
 
37
ValueFormatter::ValueFormatter (ValueConverter *conv) : converter( conv )
 
38
{
 
39
}
 
40
 
 
41
QString ValueFormatter::formatText (KSpreadCell *cell, FormatType fmtType)
 
42
{
 
43
  if (cell->hasError ())
 
44
    return errorFormat (cell);
 
45
 
 
46
  QString str;
 
47
  
 
48
  KSpreadFormat::FloatFormat floatFormat =
 
49
      cell->floatFormat (cell->column(), cell->row());
 
50
  int precision = cell->precision (cell->column(), cell->row());
 
51
  QString prefix = cell->prefix (cell->column(), cell->row());
 
52
  QString postfix = cell->postfix (cell->column(), cell->row());
 
53
 
 
54
  return formatText (cell->value(), fmtType, precision,
 
55
      floatFormat, prefix, postfix);
 
56
}
 
57
 
 
58
QString ValueFormatter::formatText (const KSpreadValue &value,
 
59
    FormatType fmtType, int precision, KSpreadFormat::FloatFormat floatFormat,
 
60
    const QString &prefix, const QString &postfix)
 
61
{
 
62
  //if we have an array, use its first element
 
63
  if (value.isArray())
 
64
    return formatText (value.element (0, 0), fmtType, precision,
 
65
        floatFormat, prefix, postfix);
 
66
 
 
67
  QString str;
 
68
  
 
69
  //step 1: determine formatting that will be used
 
70
  fmtType = determineFormatting (value, fmtType);
 
71
  
 
72
  //step 2: format the value !
 
73
  
 
74
  //text
 
75
  if (fmtType == Text_format)
 
76
  {
 
77
    str = converter->asString (value).asString();
 
78
    if (!str.isEmpty() && str[0]=='\'' )
 
79
      str = str.mid(1);
 
80
  }
 
81
  
 
82
  //date
 
83
  else if (formatIsDate (fmtType))
 
84
    str = dateFormat (value.asDate(), fmtType);
 
85
    
 
86
  //time
 
87
  else if (formatIsTime (fmtType))
 
88
    str = timeFormat (value.asDateTime(), fmtType);
 
89
    
 
90
  //fraction
 
91
  else if (formatIsFraction (fmtType))
 
92
    str = fractionFormat (value.asFloat(), fmtType);
 
93
 
 
94
  //another
 
95
  else
 
96
  {
 
97
    QChar decimal_point = converter->locale()->decimalSymbol()[0];
 
98
    if ( decimal_point.isNull() )
 
99
      decimal_point = '.';
 
100
 
 
101
    //some cell parameters ...
 
102
    double v = converter->asFloat (value).asFloat();
 
103
 
 
104
    // Always unsigned ?
 
105
    if ((floatFormat == KSpreadCell::AlwaysUnsigned) && (v < 0.0))
 
106
      v *= -1.0;
 
107
 
 
108
    // Make a string out of it.
 
109
    str = createNumberFormat (v, precision, fmtType,
 
110
        (floatFormat == KSpreadCell::AlwaysSigned));
 
111
 
 
112
    // Remove trailing zeros and the decimal point if necessary
 
113
    // unless the number has no decimal point
 
114
    if (precision == -1)
 
115
      removeTrailingZeros (str, decimal_point);
 
116
  }
 
117
    
 
118
  if (!prefix.isEmpty())
 
119
    str = prefix + ' ' + str;
 
120
 
 
121
  if( !postfix.isEmpty())
 
122
    str += ' ' + postfix;
 
123
  
 
124
  //kdDebug() << "ValueFormatter says: " << str << endl;
 
125
  return str;
 
126
}
 
127
 
 
128
FormatType ValueFormatter::determineFormatting (const KSpreadValue &value,
 
129
    FormatType fmtType)
 
130
{
 
131
  //if the cell value is a string, then we want to display it as-is,
 
132
  //no matter what, same if the cell is empty
 
133
  if (value.isString () || (value.format() == KSpreadValue::fmt_None))
 
134
    return Text_format;
 
135
  //same if we're supposed to display string, no matter what we actually got
 
136
  if (fmtType == Text_format)
 
137
    return Text_format;
 
138
  
 
139
  //now, everything depends on whether the formatting is Generic or not
 
140
  if (fmtType == Generic_format)
 
141
  {
 
142
    //here we decide based on value's format...
 
143
    KSpreadValue::Format fmt = value.format();
 
144
    switch (fmt) {
 
145
      case KSpreadValue::fmt_None:
 
146
        fmtType = Text_format;
 
147
      break;
 
148
      case KSpreadValue::fmt_Boolean:
 
149
        fmtType = Text_format;
 
150
      break;
 
151
      case KSpreadValue::fmt_Number:
 
152
        if (value.asFloat() > 1e+10)
 
153
          fmtType = Scientific_format;
 
154
        else
 
155
          fmtType = Number_format;
 
156
      break;
 
157
      case KSpreadValue::fmt_Percent:
 
158
        fmtType = Percentage_format;
 
159
      break;
 
160
      case KSpreadValue::fmt_Money:
 
161
        fmtType = Money_format;
 
162
      break;
 
163
      case KSpreadValue::fmt_DateTime:
 
164
        fmtType = TextDate_format;
 
165
      break;
 
166
      case KSpreadValue::fmt_Date:
 
167
        fmtType = ShortDate_format;
 
168
      break;
 
169
      case KSpreadValue::fmt_Time:
 
170
        fmtType = Time_format;
 
171
      break;
 
172
      case KSpreadValue::fmt_String:
 
173
        //this should never happen
 
174
        fmtType = Text_format;
 
175
      break;
 
176
    };
 
177
    return fmtType;
 
178
  }
 
179
  else
 
180
  {
 
181
    //we'll mostly want to use the given formatting, the only exception
 
182
    //being Boolean values
 
183
    
 
184
    //TODO: is this correct? We may also want to convert bools to 1s and 0s
 
185
    //if we want to display a number...
 
186
    
 
187
    //TODO: what to do about Custom formatting? We don't support it as of now,
 
188
    //  but we'll have it ... one day, that is ...
 
189
    if (value.isBoolean())
 
190
      return Text_format;
 
191
    else
 
192
      return fmtType;
 
193
  }
 
194
}
 
195
 
 
196
 
 
197
void ValueFormatter::removeTrailingZeros (QString &str, QChar decimal_point)
 
198
{
 
199
  if (str.find (decimal_point) < 0)
 
200
    //no decimal point -> nothing to do
 
201
    return;
 
202
  
 
203
  int start = 0;
 
204
  int cslen = converter->locale()->currencySymbol().length();
 
205
  if (str.find ('%') != -1)
 
206
    start = 2;
 
207
  else if (str.find (converter->locale()->currencySymbol()) ==
 
208
      ((int) (str.length() - cslen)))
 
209
    start = cslen + 1;
 
210
  else if ((start = str.find ('E')) != -1)
 
211
    start = str.length() - start;
 
212
  else
 
213
    start = 0;
 
214
 
 
215
  int i = str.length() - start;
 
216
  bool bFinished = FALSE;
 
217
  while ( !bFinished && i > 0 )
 
218
  {
 
219
    QChar ch = str[i - 1];
 
220
    if (ch == '0')
 
221
      str.remove (--i,1);
 
222
    else
 
223
    {
 
224
      bFinished = TRUE;
 
225
      if (ch == decimal_point)
 
226
        str.remove (--i, 1);
 
227
    }
 
228
  }
 
229
}
 
230
 
 
231
QString ValueFormatter::createNumberFormat ( double value, int precision,
 
232
    FormatType fmt, bool alwaysSigned)
 
233
{
 
234
  // if precision is -1, ask for a huge number of decimals, we'll remove
 
235
  // the zeros later. Is 8 ok ?
 
236
  int p = (precision == -1) ? 8 : precision;
 
237
  QString localizedNumber;
 
238
  int pos = 0;
 
239
  
 
240
  //multiply value by 100 for percentage format
 
241
  if (fmt == Percentage_format)
 
242
    value *= 100;
 
243
 
 
244
  // this will avoid displaying negative zero, i.e "-0.0000"
 
245
  if( fabs( value ) < DBL_EPSILON ) value = 0.0;
 
246
 
 
247
  // round the number, based on desired precision if not scientific is chosen 
 
248
  //(scientific has relative precision)
 
249
  if( fmt != Scientific_format )
 
250
  {
 
251
    double m[] = { 1, 10, 100, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10 };
 
252
    double mm = (p > 10) ? pow(10.0,p) : m[p];
 
253
    bool neg = value < 0;
 
254
    value = floor( fabs(value)*mm + 0.5 ) / mm;
 
255
    if( neg ) value = -value;
 
256
  }
 
257
 
 
258
  QChar decimal_point;
 
259
  switch (fmt)
 
260
  {
 
261
    case Number_format:
 
262
      localizedNumber = converter->locale()->formatNumber(value, p);
 
263
      break;
 
264
    case Percentage_format:
 
265
      localizedNumber = converter->locale()->formatNumber (value, p)+ " %";
 
266
      break;
 
267
    case Money_format:
 
268
      localizedNumber = converter->locale()->formatMoney (value, 
 
269
          converter->locale()->currencySymbol(), p );
 
270
      break;
 
271
    case Scientific_format:
 
272
      decimal_point = converter->locale()->decimalSymbol()[0];
 
273
      localizedNumber = QString::number (value, 'E', p);
 
274
      if ((pos = localizedNumber.find ('.')) != -1)
 
275
        localizedNumber = localizedNumber.replace (pos, 1, decimal_point);
 
276
      break;
 
277
    default :
 
278
      //other formatting?
 
279
      kdDebug(36001)<<"Wrong usage of ValueFormatter::createNumberFormat\n";
 
280
      break;
 
281
  }
 
282
 
 
283
  //prepend positive sign if needed
 
284
  if (alwaysSigned && value >= 0 )
 
285
    if (converter->locale()->positiveSign().isEmpty())
 
286
      localizedNumber='+'+localizedNumber;
 
287
 
 
288
  return localizedNumber;
 
289
}
 
290
 
 
291
QString ValueFormatter::fractionFormat (double value, FormatType fmtType)
 
292
{
 
293
  double result = value - floor(value);
 
294
  int index;
 
295
  int limit = 0;
 
296
 
 
297
  /* return w/o fraction part if not necessary */
 
298
  if (result == 0)
 
299
    return QString::number(value);
 
300
 
 
301
  switch (fmtType) {
 
302
  case fraction_half:
 
303
    index = 2;
 
304
    break;
 
305
  case fraction_quarter:
 
306
    index = 4;
 
307
    break;
 
308
  case fraction_eighth:
 
309
    index = 8;
 
310
    break;
 
311
  case fraction_sixteenth:
 
312
    index = 16;
 
313
    break;
 
314
  case fraction_tenth:
 
315
    index = 10;
 
316
    break;
 
317
  case fraction_hundredth:
 
318
    index = 100;
 
319
    break;
 
320
  case fraction_one_digit:
 
321
    index = 3;
 
322
    limit = 9;
 
323
    break;
 
324
  case fraction_two_digits:
 
325
    index = 4;
 
326
    limit = 99;
 
327
    break;
 
328
  case fraction_three_digits:
 
329
    index = 5;
 
330
    limit = 999;
 
331
    break;
 
332
  default:
 
333
    kdDebug(36001) << "Error in Fraction format\n";
 
334
    return QString::number(value);
 
335
    break;
 
336
  } /* switch */
 
337
 
 
338
 
 
339
  /* handle halves, quarters, tenths, ... */
 
340
 
 
341
  if (fmtType != fraction_three_digits
 
342
    && fmtType != fraction_two_digits
 
343
    && fmtType != fraction_one_digit) {
 
344
    double calc = 0;
 
345
    int index1 = 0;
 
346
    double diff = result;
 
347
    for (int i = 1; i <= index; i++) {
 
348
      calc = i * 1.0 / index;
 
349
      if (fabs(result - calc) < diff) {
 
350
        index1 = i;
 
351
        diff = fabs(result - calc);
 
352
      }
 
353
    }
 
354
    if( index1 == 0 ) return QString("%1").arg( floor(value) );
 
355
    if( index1 == index ) return QString("%1").arg( floor(value)+1 );
 
356
    if( floor(value) == 0)
 
357
      return QString("%1/%2").arg( index1 ).arg( index );
 
358
 
 
359
    return QString("%1 %2/%3")
 
360
        .arg( floor(value) )
 
361
        .arg( index1 )
 
362
        .arg( index );
 
363
  }
 
364
 
 
365
 
 
366
  /* handle fraction_one_digit, fraction_two_digit
 
367
    * and fraction_three_digit style */
 
368
 
 
369
  double precision, denominator, numerator;
 
370
 
 
371
  do {
 
372
    double val1 = result;
 
373
    double val2 = rint(result);
 
374
    double inter2 = 1;
 
375
    double inter4, p,  q;
 
376
    inter4 = p = q = 0;
 
377
    
 
378
    precision = pow(10.0, -index);
 
379
    numerator = val2;
 
380
    denominator = 1;
 
381
    
 
382
    while (fabs(numerator/denominator - result) > precision) {
 
383
      val1 = (1 / (val1 - val2));
 
384
      val2 = rint(val1);
 
385
      p = val2 * numerator + inter2;
 
386
      q = val2 * denominator + inter4;
 
387
      inter2 = numerator;
 
388
      inter4 = denominator;
 
389
      numerator = p;
 
390
      denominator = q;
 
391
    }
 
392
    index--;
 
393
  } while (fabs(denominator) > limit);
 
394
 
 
395
  denominator = fabs(denominator);
 
396
  numerator = fabs(numerator);
 
397
 
 
398
  if (denominator == numerator)
 
399
    return QString().setNum(floor(value + 1));
 
400
  else
 
401
  {
 
402
    if ( floor(value) == 0 )
 
403
      return QString("%1/%2").arg(numerator).arg(denominator);
 
404
    else
 
405
      return QString("%1 %2/%3")
 
406
        .arg(floor(value))
 
407
        .arg(numerator)
 
408
        .arg(denominator);
 
409
  }
 
410
}
 
411
 
 
412
QString ValueFormatter::timeFormat (const QDateTime &dt, FormatType fmtType)
 
413
{
 
414
  if (fmtType == Time_format)
 
415
    return converter->locale()->formatTime(dt.time(), false);
 
416
 
 
417
  if (fmtType == SecondeTime_format)
 
418
    return converter->locale()->formatTime(dt.time(), true);
 
419
 
 
420
  int h = dt.time().hour();
 
421
  int m = dt.time().minute();
 
422
  int s = dt.time().second();
 
423
 
 
424
  QString hour = ( h < 10 ? "0" + QString::number(h) : QString::number(h) );
 
425
  QString minute = ( m < 10 ? "0" + QString::number(m) : QString::number(m) );
 
426
  QString second = ( s < 10 ? "0" + QString::number(s) : QString::number(s) );
 
427
  bool pm = (h > 12);
 
428
  QString AMPM( pm ? i18n("PM"):i18n("AM") );
 
429
 
 
430
  if (fmtType == Time_format1) {  // 9 : 01 AM
 
431
    return QString("%1:%2 %3")
 
432
      .arg((pm ? h - 12 : h),2)
 
433
      .arg(minute,2)
 
434
      .arg(AMPM);
 
435
  }
 
436
 
 
437
  if (fmtType == Time_format2) {  //9:01:05 AM
 
438
    return QString("%1:%2:%3 %4")
 
439
      .arg((pm ? h-12 : h),2)
 
440
      .arg(minute,2)
 
441
      .arg(second,2)
 
442
      .arg(AMPM);
 
443
  }
 
444
 
 
445
  if (fmtType == Time_format3) {
 
446
    return QString("%1 %2 %3 %4 %5 %6")      // 9 h 01 min 28 s
 
447
      .arg(hour,2)
 
448
      .arg(i18n("h"))
 
449
      .arg(minute,2)
 
450
      .arg(i18n("min"))
 
451
      .arg(second,2)
 
452
      .arg(i18n("s"));
 
453
  }
 
454
 
 
455
  if (fmtType == Time_format4) {  // 9:01
 
456
    return QString("%1:%2").arg(hour, 2).arg(minute, 2);
 
457
  }
 
458
 
 
459
  if (fmtType == Time_format5) {  // 9:01:12
 
460
    return QString("%1:%2:%3").arg(hour, 2).arg(minute, 2).arg(second, 2);
 
461
  }
 
462
 
 
463
  QDate d1(dt.date());
 
464
  QDate d2( 1899, 12, 31 );
 
465
  int d = d2.daysTo( d1 ) + 1;
 
466
 
 
467
  h += d * 24;
 
468
 
 
469
  if (fmtType == Time_format6)
 
470
  {  // [mm]:ss
 
471
    m += (h * 60);
 
472
    return QString("%1:%2").arg(m, 1).arg(second, 2);
 
473
  }
 
474
  if (fmtType == Time_format7) {  // [h]:mm:ss
 
475
    return QString("%1:%2:%3").arg(h, 1).arg(minute, 2).arg(second, 2);
 
476
  }
 
477
  if (fmtType == Time_format8)
 
478
  {  // [h]:mm
 
479
    m += (h * 60);
 
480
    return QString("%1:%2").arg(h, 1).arg(minute, 2);
 
481
  }
 
482
 
 
483
  return converter->locale()->formatTime( dt.time(), false );
 
484
}
 
485
 
 
486
QString ValueFormatter::dateFormat (const QDate &date, FormatType fmtType)
 
487
{
 
488
  QString tmp;
 
489
  if (fmtType == ShortDate_format) {
 
490
    tmp = converter->locale()->formatDate(date, true);
 
491
  }
 
492
  else if (fmtType == TextDate_format) {
 
493
    tmp = converter->locale()->formatDate(date, false);
 
494
  }
 
495
  else if (fmtType == date_format1) {  /*18-Feb-99 */
 
496
    tmp = QString().sprintf("%02d", date.day());
 
497
    tmp += "-" + converter->locale()->calendar()->monthString(date, true) + "-";
 
498
    tmp += QString::number(date.year()).right(2);
 
499
  }
 
500
  else if (fmtType == date_format2) {  /*18-Feb-1999 */
 
501
    tmp = QString().sprintf("%02d", date.day());
 
502
    tmp += "-" + converter->locale()->calendar()->monthString(date, true) + "-";
 
503
    tmp += QString::number(date.year());
 
504
  }
 
505
  else if (fmtType == date_format3) {  /*18-Feb */
 
506
    tmp = QString().sprintf("%02d", date.day());
 
507
    tmp += "-" + converter->locale()->calendar()->monthString(date, true);
 
508
  }
 
509
  else if (fmtType == date_format4) {  /*18-05 */
 
510
    tmp = QString().sprintf("%02d", date.day());
 
511
    tmp += "-" + QString().sprintf("%02d", date.month() );
 
512
  }
 
513
  else if (fmtType == date_format5) {  /*18/05/00 */
 
514
    tmp = QString().sprintf("%02d", date.day());
 
515
    tmp += "/" + QString().sprintf("%02d", date.month()) + "/";
 
516
    tmp += QString::number(date.year()).right(2);
 
517
  }
 
518
  else if (fmtType == date_format6) {  /*18/05/1999 */
 
519
    tmp = QString().sprintf("%02d", date.day());
 
520
    tmp += "/" + QString().sprintf("%02d", date.month()) + "/";
 
521
    tmp += QString::number(date.year());
 
522
  }
 
523
  else if (fmtType == date_format7) {  /*Feb-99 */
 
524
    tmp = converter->locale()->calendar()->monthString(date, true) + "-";
 
525
    tmp += QString::number(date.year()).right(2);
 
526
  }
 
527
  else if (fmtType == date_format8) {  /*February-99 */
 
528
    tmp = converter->locale()->calendar()->monthString(date, false) + "-";
 
529
    tmp += QString::number(date.year()).right(2);
 
530
  }
 
531
  else if (fmtType == date_format9) {  /*February-1999 */
 
532
    tmp = converter->locale()->calendar()->monthString(date, false) + "-";
 
533
    tmp += QString::number(date.year());
 
534
  }
 
535
  else if (fmtType == date_format10) {  /*F-99 */
 
536
    tmp = converter->locale()->calendar()->monthString(date, false).at(0) + "-";
 
537
    tmp += QString::number(date.year()).right(2);
 
538
  }
 
539
  else if (fmtType == date_format11) {  /*18/Feb */
 
540
    tmp = QString().sprintf("%02d", date.day()) + "/";
 
541
    tmp += converter->locale()->calendar()->monthString(date, true);
 
542
  }
 
543
  else if (fmtType == date_format12) {  /*18/02 */
 
544
    tmp = QString().sprintf("%02d", date.day()) + "/";
 
545
    tmp += QString().sprintf("%02d", date.month());
 
546
  }
 
547
  else if (fmtType == date_format13) {  /*18/Feb/1999 */
 
548
    tmp = QString().sprintf("%02d", date.day());
 
549
    tmp += "/" + converter->locale()->calendar()->monthString(date, true) + "/";
 
550
    tmp += QString::number(date.year());
 
551
  }
 
552
  else if (fmtType == date_format14) {  /*2000/Feb/18 */
 
553
    tmp = QString::number(date.year());
 
554
    tmp += "/" + converter->locale()->calendar()->monthString(date, true) + "/";
 
555
    tmp += QString().sprintf("%02d", date.day());
 
556
  }
 
557
  else if (fmtType == date_format15) {  /*2000-Feb-18 */
 
558
    tmp = QString::number(date.year());
 
559
    tmp += "-" + converter->locale()->calendar()->monthString(date, true) + "-";
 
560
    tmp += QString().sprintf("%02d", date.day());
 
561
  }
 
562
  else if (fmtType == date_format16) {  /*2000-02-18 */
 
563
    tmp = QString::number(date.year());
 
564
    tmp += "-" + QString().sprintf("%02d", date.month()) + "-";
 
565
    tmp += QString().sprintf("%02d", date.day());
 
566
  }
 
567
  else if (fmtType == date_format17) {  /*2 february 2000 */
 
568
    tmp = QString().sprintf("%d", date.day());
 
569
    tmp += " " + converter->locale()->calendar()->monthString(date, false) + " ";
 
570
    tmp += QString::number(date.year());
 
571
  }
 
572
  else if (fmtType == date_format18) {  /*02/18/1999 */
 
573
    tmp = QString().sprintf("%02d", date.month());
 
574
    tmp += "/" + QString().sprintf("%02d", date.day());
 
575
    tmp += "/" + QString::number(date.year());
 
576
  }
 
577
  else if (fmtType == date_format19) {  /*02/18/99 */
 
578
    tmp = QString().sprintf("%02d", date.month());
 
579
    tmp += "/" + QString().sprintf("%02d", date.day());
 
580
    tmp += "/" + QString::number(date.year()).right(2);
 
581
  }
 
582
  else if (fmtType == date_format20) {  /*Feb/18/99 */
 
583
    tmp = converter->locale()->calendar()->monthString(date, true);
 
584
    tmp += "/" + QString().sprintf("%02d", date.day());
 
585
    tmp += "/" + QString::number(date.year()).right(2);
 
586
  }
 
587
  else if (fmtType == date_format21) {  /*Feb/18/1999 */
 
588
    tmp = converter->locale()->calendar()->monthString(date, true);
 
589
    tmp += "/" + QString().sprintf("%02d", date.day());
 
590
    tmp += "/" + QString::number(date.year());
 
591
  }
 
592
  else if (fmtType == date_format22) {  /*Feb-1999 */
 
593
    tmp = converter->locale()->calendar()->monthString(date, true) + "-";
 
594
    tmp += QString::number(date.year());
 
595
  }
 
596
  else if (fmtType == date_format23) {  /*1999 */
 
597
    tmp = QString::number(date.year());
 
598
  }
 
599
  else if (fmtType == date_format24) {  /*99 */
 
600
    tmp = QString::number(date.year()).right(2);
 
601
  }
 
602
  else if (fmtType == date_format25) {  /*2000/02/18 */
 
603
    tmp = QString::number(date.year());
 
604
    tmp += "/" + QString().sprintf("%02d", date.month());
 
605
    tmp += "/" + QString().sprintf("%02d", date.day());
 
606
  }
 
607
  else if (fmtType == date_format26) {  /*2000/Feb/18 */
 
608
    tmp = QString::number(date.year());
 
609
    tmp += "/" + converter->locale()->calendar()->monthString(date, true);
 
610
    tmp += "/" + QString().sprintf("%02d", date.day());
 
611
  }
 
612
  else
 
613
    tmp = converter->locale()->formatDate(date, true);
 
614
 
 
615
  // Missing compared with gnumeric:
 
616
  //  "m/d/yy h:mm",    /* 20 */
 
617
  //  "m/d/yyyy h:mm",  /* 21 */
 
618
  //  "mmm/ddd/yy",    /* 12 */
 
619
  //  "mmm/ddd/yyyy",    /* 13 */
 
620
  //  "mm/ddd/yy",    /* 14 */
 
621
  //  "mm/ddd/yyyy",    /* 15 */
 
622
 
 
623
  return tmp;
 
624
}
 
625
 
 
626
QString ValueFormatter::errorFormat (KSpreadCell *cell)
 
627
{
 
628
  QString err;
 
629
  if (cell->testFlag (KSpreadCell::Flag_ParseError))
 
630
    err = "#" + i18n ("Parse") + "!";
 
631
  else if ( cell->testFlag (KSpreadCell::Flag_CircularCalculation))
 
632
    err = "#" + i18n ("Circle") + "!";
 
633
  else if ( cell->testFlag (KSpreadCell::Flag_DependancyError))
 
634
    err = "#" + i18n ("Depend") + "!";
 
635
  else
 
636
  {
 
637
    err = "####";
 
638
    kdDebug(36001) << "Unhandled error type." << endl;
 
639
  }
 
640
  return err;
 
641
}
 
642