Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

klocale.cpp

Go to the documentation of this file.
00001 #include <qregexp.h>
00002 
00003 #include "kdebug.h"
00004 
00005 #include "klocale.h"
00006 
00007 QString i18n(const char *text)
00008 {
00009   return QString( text );
00010 }
00011 
00012 QString i18n(const char *,const char *text)
00013 {
00014   return QString( text );
00015 }
00016 
00017 inline void put_it_in( QChar *buffer, uint& index, const QString &s )
00018 {
00019   for ( uint l = 0; l < s.length(); l++ )
00020     buffer[index++] = s.at( l );
00021 }
00022 
00023 inline void put_it_in( QChar *buffer, uint& index, int number )
00024 {
00025   buffer[index++] = number / 10 + '0';
00026   buffer[index++] = number % 10 + '0';
00027 }
00028 
00029 static int readInt(const QString &str, uint &pos)
00030 {
00031   if (!str.at(pos).isDigit()) return -1;
00032   int result = 0;
00033   for (; str.length() > pos && str.at(pos).isDigit(); pos++)
00034     {
00035       result *= 10;
00036       result += str.at(pos).digitValue();
00037     }
00038 
00039   return result;
00040 }
00041 
00042 QString KLocale::formatTime(const QTime &pTime, bool includeSecs) const
00043 {
00044   const QString rst = timeFormat();
00045 
00046   // only "pm/am" here can grow, the rest shrinks, but
00047   // I'm rather safe than sorry
00048   QChar *buffer = new QChar[rst.length() * 3 / 2 + 30];
00049 
00050   uint index = 0;
00051   bool escape = false;
00052   int number = 0;
00053 
00054   for ( uint format_index = 0; format_index < rst.length(); format_index++ )
00055     {
00056       if ( !escape )
00057         {
00058           if ( rst.at( format_index ).unicode() == '%' )
00059             escape = true;
00060           else
00061             buffer[index++] = rst.at( format_index );
00062         }
00063       else
00064         {
00065           switch ( rst.at( format_index ).unicode() )
00066             {
00067             case '%':
00068               buffer[index++] = '%';
00069               break;
00070             case 'H':
00071               put_it_in( buffer, index, pTime.hour() );
00072               break;
00073             case 'I':
00074               put_it_in( buffer, index, ( pTime.hour() + 11) % 12 + 1 );
00075               break;
00076             case 'M':
00077               put_it_in( buffer, index, pTime.minute() );
00078               break;
00079             case 'S':
00080               if (includeSecs)
00081                 put_it_in( buffer, index, pTime.second() );
00082               else
00083                 {
00084                   // we remove the seperator sign before the seconds and
00085                   // assume that works everywhere
00086                   --index;
00087                   break;
00088                 }
00089               break;
00090             case 'k':
00091               number = pTime.hour();
00092             case 'l':
00093               // to share the code
00094               if ( rst.at( format_index ).unicode() == 'l' )
00095                 number = (pTime.hour() + 11) % 12 + 1;
00096               if ( number / 10 )
00097                 buffer[index++] = number / 10 + '0';
00098               buffer[index++] = number % 10 + '0';
00099               break;
00100             case 'p':
00101               {
00102                 QString s;
00103                 if ( pTime.hour() >= 12 )
00104                   put_it_in( buffer, index, i18n("pm") );
00105                 else
00106                   put_it_in( buffer, index, i18n("am") );
00107                 break;
00108               }
00109             default:
00110               buffer[index++] = rst.at( format_index );
00111               break;
00112             }
00113           escape = false;
00114         }
00115     }
00116   QString ret( buffer, index );
00117   delete [] buffer;
00118   return ret;
00119 }    
00120 
00121 QString KLocale::formatDate(const QDate &pDate, bool shortFormat) const
00122 {
00123   const QString rst = shortFormat?dateFormatShort():dateFormat();
00124 
00125   // I'm rather safe than sorry
00126   QChar *buffer = new QChar[rst.length() * 3 / 2 + 50];
00127 
00128   unsigned int index = 0;
00129   bool escape = false;
00130   int number = 0;
00131 
00132   for ( uint format_index = 0; format_index < rst.length(); ++format_index )
00133     {
00134       if ( !escape )
00135         {
00136           if ( rst.at( format_index ).unicode() == '%' )
00137             escape = true;
00138           else
00139             buffer[index++] = rst.at( format_index );
00140         }
00141       else
00142         {
00143           switch ( rst.at( format_index ).unicode() )
00144             {
00145             case '%':
00146               buffer[index++] = '%';
00147               break;
00148             case 'Y':
00149               put_it_in( buffer, index, pDate.year() / 100 );
00150             case 'y':
00151               put_it_in( buffer, index, pDate.year() % 100 );
00152               break;
00153             case 'n':
00154               number = pDate.month();
00155             case 'e':
00156               // to share the code
00157               if ( rst.at( format_index ).unicode() == 'e' )
00158                 number = pDate.day();
00159               if ( number / 10 )
00160                 buffer[index++] = number / 10 + '0';
00161               buffer[index++] = number % 10 + '0';
00162               break;
00163             case 'm':
00164               put_it_in( buffer, index, pDate.month() );
00165               break;
00166             case 'b':
00167               put_it_in( buffer, index, monthName(pDate.month(), true) );
00168               break;
00169             case 'B':
00170               put_it_in( buffer, index, monthName(pDate.month(), false) );
00171               break;
00172             case 'd':
00173               put_it_in( buffer, index, pDate.day() );
00174               break;
00175             case 'a':
00176               put_it_in( buffer, index, weekDayName(pDate.dayOfWeek(), true) );
00177               break;
00178             case 'A':
00179               put_it_in( buffer, index, weekDayName(pDate.dayOfWeek(), false) );
00180               break;
00181             default:
00182               buffer[index++] = rst.at( format_index );
00183               break;
00184             }
00185           escape = false;
00186         }
00187     }
00188   QString ret( buffer, index );
00189   delete [] buffer;
00190   return ret;
00191 }
00192 
00193 QString KLocale::formatDateTime(const QDateTime &pDateTime,
00194                                 bool shortFormat,
00195                                 bool includeSeconds) const
00196 {
00197   return i18n("concatenation of dates and time", "%1 %2")
00198     .arg( formatDate( pDateTime.date(), shortFormat ) )
00199     .arg( formatTime( pDateTime.time(), includeSeconds ) );
00200 }
00201 
00202 QString KLocale::formatDateTime(const QDateTime &pDateTime) const
00203 {
00204   return formatDateTime(pDateTime, true);
00205 }
00206 
00207 QDate KLocale::readDate(const QString &intstr, bool* ok) const
00208 {
00209   QDate date;
00210   date = readDate(intstr, true, ok);
00211   if (date.isValid()) return date;
00212   return readDate(intstr, false, ok);
00213 }
00214 
00215 QDate KLocale::readDate(const QString &intstr, bool shortFormat, bool* ok) const
00216 {
00217   QString fmt = (shortFormat ? dateFormatShort() : dateFormat()).simplifyWhiteSpace();
00218   return readDate( intstr, fmt, ok );
00219 }
00220 
00221 QDate KLocale::readDate(const QString &intstr, const QString &fmt, bool* ok) const
00222 {
00223   //kdDebug(173) << "KLocale::readDate intstr=" << intstr << " fmt=" << fmt << endl;
00224   QString str = intstr.simplifyWhiteSpace().lower();
00225   int day = -1, month = -1;
00226   // allow the year to be omitted if not in the format
00227   int year = QDate::currentDate().year();
00228   uint strpos = 0;
00229   uint fmtpos = 0;
00230 
00231   while (fmt.length() > fmtpos || str.length() > strpos)
00232     {
00233       if ( !(fmt.length() > fmtpos && str.length() > strpos) )
00234         goto error;
00235 
00236       QChar c = fmt.at(fmtpos++);
00237 
00238       if (c != '%') {
00239         if (c.isSpace())
00240           strpos++;
00241         else if (c != str.at(strpos++))
00242           goto error;
00243         continue;
00244       }
00245 
00246       // remove space at the begining
00247       if (str.length() > strpos && str.at(strpos).isSpace())
00248         strpos++;
00249 
00250       c = fmt.at(fmtpos++);
00251       switch (c)
00252       {
00253         case 'a':
00254         case 'A':
00255           // this will just be ignored
00256           { // Cristian Tache: porting to Win: Block added because of "j" redefinition
00257           for (int j = 1; j < 8; j++) {
00258             QString s = weekDayName(j, c == 'a').lower();
00259             int len = s.length();
00260             if (str.mid(strpos, len) == s)
00261               strpos += len;
00262           }
00263           break;
00264         }
00265         case 'b':
00266         case 'B':
00267           { // Cristian Tache: porting to Win: Block added because of "j" redefinition
00268           for (int j = 1; j < 13; j++) {
00269             QString s = monthName(j, c == 'b').lower();
00270             int len = s.length();
00271             if (str.mid(strpos, len) == s) {
00272               month = j;
00273               strpos += len;
00274             }
00275           }
00276           break;
00277         }
00278         case 'd':
00279         case 'e':
00280           day = readInt(str, strpos);
00281           if (day < 1 || day > 31)
00282             goto error;
00283 
00284           break;
00285 
00286         case 'n':
00287         case 'm':
00288           month = readInt(str, strpos);
00289           if (month < 1 || month > 12)
00290             goto error;
00291 
00292           break;
00293 
00294         case 'Y':
00295         case 'y':
00296           year = readInt(str, strpos);
00297           if (year < 0)
00298             goto error;
00299           // Qt treats a year in the range 0-100 as 1900-1999.
00300           // It is nicer for the user if we treat 0-68 as 2000-2068
00301           if (year < 69)
00302             year += 2000;
00303           else if (c == 'y')
00304             year += 1900;
00305 
00306           break;
00307         }
00308     }
00309   //kdDebug(173) << "KLocale::readDate day=" << day << " month=" << month << " year=" << year << endl;
00310   if ( year != -1 && month != -1 && day != -1 )
00311   {
00312     if (ok) *ok = true;
00313     return QDate(year, month, day);
00314   }
00315  error:
00316   if (ok) *ok = false;
00317   return QDate(); // invalid date
00318 }
00319 
00320 QTime KLocale::readTime(const QString &intstr, bool *ok) const
00321 {
00322   QTime _time;
00323   _time = readTime(intstr, true, ok);
00324   if (_time.isValid()) return _time;
00325   return readTime(intstr, false, ok);
00326 }
00327 
00328 QTime KLocale::readTime(const QString &intstr, bool seconds, bool *ok) const
00329 {
00330   QString str = intstr.simplifyWhiteSpace().lower();
00331   QString Format = timeFormat().simplifyWhiteSpace();
00332   if (!seconds)
00333     Format.replace(QRegExp(QString::fromLatin1(".%S")), QString::null);
00334 
00335   int hour = -1, minute = -1, second = seconds ? -1 : 0; // don't require seconds
00336   bool g_12h = false;
00337   bool pm = false;
00338   uint strpos = 0;
00339   uint Formatpos = 0;
00340 
00341   while (Format.length() > Formatpos || str.length() > strpos)
00342     {
00343       if ( !(Format.length() > Formatpos && str.length() > strpos) ) goto error;
00344 
00345       QChar c = Format.at(Formatpos++);
00346 
00347       if (c != '%')
00348         {
00349           if (c.isSpace())
00350             strpos++;
00351           else if (c != str.at(strpos++))
00352             goto error;
00353           continue;
00354         }
00355 
00356       // remove space at the begining
00357       if (str.length() > strpos && str.at(strpos).isSpace())
00358         strpos++;
00359 
00360       c = Format.at(Formatpos++);
00361       switch (c)
00362         {
00363         case 'p':
00364           {
00365             QString s;
00366             s = i18n("pm").lower();
00367             int len = s.length();
00368             if (str.mid(strpos, len) == s)
00369               {
00370                 pm = true;
00371                 strpos += len;
00372               }
00373             else
00374               {
00375                 s = i18n("am").lower();
00376                 len = s.length();
00377                 if (str.mid(strpos, len) == s) {
00378                   pm = false;
00379                   strpos += len;
00380                 }
00381                 else
00382                   goto error;
00383               }
00384           }
00385           break;
00386 
00387         case 'k':
00388         case 'H':
00389           g_12h = false;
00390           hour = readInt(str, strpos);
00391           if (hour < 0 || hour > 23)
00392             goto error;
00393 
00394           break;
00395 
00396         case 'l':
00397         case 'I':
00398           g_12h = true;
00399           hour = readInt(str, strpos);
00400           if (hour < 1 || hour > 12)
00401             goto error;
00402 
00403           break;
00404 
00405         case 'M':
00406           minute = readInt(str, strpos);
00407           if (minute < 0 || minute > 59)
00408             goto error;
00409 
00410           break;
00411 
00412         case 'S':
00413           second = readInt(str, strpos);
00414           if (second < 0 || second > 59)
00415             goto error;
00416 
00417           break;
00418         }
00419     }
00420   if (g_12h)
00421     {
00422       hour %= 12;
00423       if (pm) hour += 12;
00424     }
00425 
00426   if (ok) *ok = true;
00427   return QTime(hour, minute, second);
00428 
00429  error:
00430   if (ok) *ok = false;
00431   return QTime(-1, -1, -1); // return invalid date if it didn't work
00432   // This will be removed in the near future, since it gives a warning on stderr.
00433   // The presence of the bool* (since KDE-3.0) removes the need for an invalid QTime.
00434 }
00435 
00436 bool KLocale::use12Clock() const
00437 {
00438   return false;
00439 }
00440 
00441 bool KLocale::weekStartsMonday() const
00442 {
00443   return true;
00444 }
00445 
00446 QString KLocale::weekDayName(int i,bool shortName) const
00447 {
00448   if ( shortName )
00449     switch ( i )
00450       {
00451       case 1:  return i18n("Monday", "Mon");
00452       case 2:  return i18n("Tuesday", "Tue");
00453       case 3:  return i18n("Wednesday", "Wed");
00454       case 4:  return i18n("Thursday", "Thu");
00455       case 5:  return i18n("Friday", "Fri");
00456       case 6:  return i18n("Saturday", "Sat");
00457       case 7:  return i18n("Sunday", "Sun");
00458       }
00459   else
00460     switch ( i )
00461       {
00462       case 1:  return i18n("Monday");
00463       case 2:  return i18n("Tuesday");
00464       case 3:  return i18n("Wednesday");
00465       case 4:  return i18n("Thursday");
00466       case 5:  return i18n("Friday");
00467       case 6:  return i18n("Saturday");
00468       case 7:  return i18n("Sunday");
00469       }
00470 
00471   return QString::null;
00472 }
00473 
00474 QString KLocale::monthName(int i,bool shortName) const
00475 {
00476   if ( shortName )
00477     switch ( i )
00478       {
00479       case 1:   return i18n("January", "Jan");
00480       case 2:   return i18n("February", "Feb");
00481       case 3:   return i18n("March", "Mar");
00482       case 4:   return i18n("April", "Apr");
00483       case 5:   return i18n("May short", "May");
00484       case 6:   return i18n("June", "Jun");
00485       case 7:   return i18n("July", "Jul");
00486       case 8:   return i18n("August", "Aug");
00487       case 9:   return i18n("September", "Sep");
00488       case 10:  return i18n("October", "Oct");
00489       case 11:  return i18n("November", "Nov");
00490       case 12:  return i18n("December", "Dec");
00491       }
00492   else
00493     switch (i)
00494       {
00495       case 1:   return i18n("January");
00496       case 2:   return i18n("February");
00497       case 3:   return i18n("March");
00498       case 4:   return i18n("April");
00499       case 5:   return i18n("May long", "May");
00500       case 6:   return i18n("June");
00501       case 7:   return i18n("July");
00502       case 8:   return i18n("August");
00503       case 9:   return i18n("September");
00504       case 10:  return i18n("October");
00505       case 11:  return i18n("November");
00506       case 12:  return i18n("December");
00507       }
00508 
00509   return QString::null;
00510 }
00511 
00512 QString KLocale::country() const
00513 {
00514   return QString::null;
00515 }
00516 
00517 QString KLocale::dateFormat() const
00518 {
00519   return "%A %d %B %Y";
00520 }
00521 
00522 QString KLocale::dateFormatShort() const
00523 {
00524   return "%d.%m.%Y";
00525 }
00526 
00527 QString KLocale::timeFormat() const
00528 {
00529   return "%H:%M:%S";
00530 }

Generated on Sat Nov 5 16:17:12 2005 for OPIE by  doxygen 1.4.2