libkdenetwork Library API Documentation

kmime_util.cpp

00001 /*
00002     kmime_util.cpp
00003 
00004     KMime, the KDE internet mail/usenet news message library.
00005     Copyright (c) 2001 the KMime authors.
00006     See file AUTHORS for details
00007 
00008     This program is free software; you can redistribute it and/or modify
00009     it under the terms of the GNU General Public License as published by
00010     the Free Software Foundation; either version 2 of the License, or
00011     (at your option) any later version.
00012     You should have received a copy of the GNU General Public License
00013     along with this program; if not, write to the Free Software Foundation,
00014     Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, US
00015 */
00016 
00017 #ifdef HAVE_CONFIG_H
00018 #include <config.h>
00019 #endif
00020 
00021 #include "kmime_util.h"
00022 
00023 #include <kmdcodec.h> // for KCodec::{quotedPrintableDe,base64{En,De}}code
00024 #include <kglobal.h>
00025 #include <klocale.h>
00026 #include <kcharsets.h>
00027 #include <kdeversion.h>
00028 #if KDE_IS_VERSION( 3, 1, 90 )
00029 #include <kcalendarsystem.h>
00030 #endif
00031 
00032 #include <qtextcodec.h>
00033 #include <qstrlist.h> // for QStrIList
00034 #include <qregexp.h>
00035 
00036 #include <stdlib.h>
00037 #include <ctype.h>
00038 #include <time.h> // for time()
00039 #include <unistd.h> // for getpid()
00040 
00041 using namespace KMime;
00042 
00043 namespace KMime {
00044 
00045 QStrIList c_harsetCache;
00046 QStrIList l_anguageCache;
00047 
00048 const char* cachedCharset(const QCString &name)
00049 {
00050   int idx=c_harsetCache.find(name.data());
00051   if(idx>-1)
00052     return c_harsetCache.at(idx);
00053 
00054   c_harsetCache.append(name.upper().data());
00055   //kdDebug() << "KNMimeBase::cachedCharset() number of cs " << c_harsetCache.count() << endl;
00056   return c_harsetCache.last();
00057 }
00058 
00059 const char* cachedLanguage(const QCString &name)
00060 {
00061   int idx=l_anguageCache.find(name.data());
00062   if(idx>-1)
00063     return l_anguageCache.at(idx);
00064 
00065   l_anguageCache.append(name.upper().data());
00066   //kdDebug() << "KNMimeBase::cachedCharset() number of cs " << c_harsetCache.count() << endl;
00067   return l_anguageCache.last();
00068 }
00069 
00070 bool isUsAscii(const QString &s)
00071 {
00072   for (uint i=0; i<s.length(); i++)
00073     if (s.at(i).latin1()<=0)    // c==0: non-latin1, c<0: non-us-ascii
00074       return false;
00075 
00076   return true;
00077 }
00078 
00079 // "(),.:;<>@[\]
00080 const uchar specialsMap[16] = {
00081   0x00, 0x00, 0x00, 0x00, // CTLs
00082   0x20, 0xCA, 0x00, 0x3A, // SPACE ... '?'
00083   0x80, 0x00, 0x00, 0x1C, // '@' ... '_'
00084   0x00, 0x00, 0x00, 0x00  // '`' ... DEL
00085 };
00086 
00087 // "(),:;<>@[\]/=?
00088 const uchar tSpecialsMap[16] = {
00089   0x00, 0x00, 0x00, 0x00, // CTLs
00090   0x20, 0xC9, 0x00, 0x3F, // SPACE ... '?'
00091   0x80, 0x00, 0x00, 0x1C, // '@' ... '_'
00092   0x00, 0x00, 0x00, 0x00  // '`' ... DEL
00093 };
00094 
00095 // all except specials, CTLs, SPACE.
00096 const uchar aTextMap[16] = {
00097   0x00, 0x00, 0x00, 0x00,
00098   0x5F, 0x35, 0xFF, 0xC5,
00099   0x7F, 0xFF, 0xFF, 0xE3,
00100   0xFF, 0xFF, 0xFF, 0xFE
00101 };
00102 
00103 // all except tspecials, CTLs, SPACE.
00104 const uchar tTextMap[16] = {
00105   0x00, 0x00, 0x00, 0x00,
00106   0x5F, 0x36, 0xFF, 0xC0,
00107   0x7F, 0xFF, 0xFF, 0xE3,
00108   0xFF, 0xFF, 0xFF, 0xFE
00109 };
00110 
00111 // none except a-zA-Z0-9!*+-/
00112 const uchar eTextMap[16] = {
00113   0x00, 0x00, 0x00, 0x00,
00114   0x40, 0x35, 0xFF, 0xC0,
00115   0x7F, 0xFF, 0xFF, 0xE0,
00116   0x7F, 0xFF, 0xFF, 0xE0
00117 };
00118 
00119 #if defined(_AIX) && defined(truncate)
00120 #undef truncate
00121 #endif
00122 
00123 QString decodeRFC2047String(const QCString &src, const char **usedCS,
00124                 const QCString &defaultCS, bool forceCS)
00125 {
00126   QCString result, str;
00127   QCString declaredCS;
00128   char *pos, *dest, *beg, *end, *mid, *endOfLastEncWord=0;
00129   char encoding = '\0';
00130   bool valid, onlySpacesSinceLastWord=false;
00131   const int maxLen=400;
00132   int i;
00133 
00134   if(src.find("=?") < 0)
00135     result = src.copy();
00136   else {
00137     result.truncate(src.length());
00138     for (pos=src.data(), dest=result.data(); *pos; pos++)
00139     {
00140       if (pos[0]!='=' || pos[1]!='?')
00141       {
00142         *dest++ = *pos;
00143         if (onlySpacesSinceLastWord)
00144           onlySpacesSinceLastWord = (pos[0]==' ' || pos[1]=='\t');
00145         continue;
00146       }
00147       beg = pos+2;
00148       end = beg;
00149       valid = TRUE;
00150       // parse charset name
00151       declaredCS="";
00152       for (i=2,pos+=2; i<maxLen && (*pos!='?'&&(ispunct(*pos)||isalnum(*pos))); i++) {
00153         declaredCS+=(*pos);
00154         pos++;
00155       }
00156       if (*pos!='?' || i<4 || i>=maxLen) valid = FALSE;
00157       else
00158       {
00159         // get encoding and check delimiting question marks
00160         encoding = toupper(pos[1]);
00161         if (pos[2]!='?' || (encoding!='Q' && encoding!='B'))
00162           valid = FALSE;
00163         pos+=3;
00164         i+=3;
00165       }
00166       if (valid)
00167       {
00168         mid = pos;
00169         // search for end of encoded part
00170         while (i<maxLen && *pos && !(*pos=='?' && *(pos+1)=='='))
00171         {
00172           i++;
00173           pos++;
00174         }
00175         end = pos+2;//end now points to the first char after the encoded string
00176         if (i>=maxLen || !*pos) valid = FALSE;
00177       }
00178 
00179       if (valid) {
00180         // cut all linear-white space between two encoded words
00181         if (onlySpacesSinceLastWord)
00182           dest=endOfLastEncWord;
00183 
00184         if (mid < pos) {
00185           str = QCString(mid, (int)(pos - mid + 1));
00186           if (encoding == 'Q')
00187           {
00188             // decode quoted printable text
00189             for (i=str.length()-1; i>=0; i--)
00190               if (str[i]=='_') str[i]=' ';
00191             str = KCodecs::quotedPrintableDecode(str);
00192           }
00193           else
00194           {
00195             str = KCodecs::base64Decode(str);
00196           }
00197           for (i=0; str[i]; i++) {
00198             *dest++ = str[i];
00199           }
00200         }
00201 
00202         endOfLastEncWord=dest;
00203         onlySpacesSinceLastWord=true;
00204 
00205         pos = end -1;
00206       }
00207       else
00208       {
00209         pos = beg - 2;
00210         *dest++ = *pos++;
00211         *dest++ = *pos;
00212       }
00213     }
00214     *dest = '\0';
00215   }
00216 
00217   //find suitable QTextCodec
00218   QTextCodec *codec=0;
00219   bool ok=true;
00220   if (forceCS || declaredCS.isEmpty()) {
00221     codec=KGlobal::charsets()->codecForName(defaultCS);
00222     (*usedCS)=cachedCharset(defaultCS);
00223   }
00224   else {
00225     codec=KGlobal::charsets()->codecForName(declaredCS, ok);
00226     if(!ok) {     //no suitable codec found => use default charset
00227       codec=KGlobal::charsets()->codecForName(defaultCS);
00228       (*usedCS)=cachedCharset(defaultCS);
00229     }
00230     else
00231       (*usedCS)=cachedCharset(declaredCS);
00232   }
00233 
00234   return codec->toUnicode(result.data(), result.length());
00235 }
00236 
00237 
00238 QCString encodeRFC2047String(const QString &src, const char *charset,
00239                  bool addressHeader, bool allow8BitHeaders)
00240 {
00241   QCString encoded8Bit, result, usedCS;
00242   unsigned int start=0,end=0;
00243   bool nonAscii=false, ok=true, useQEncoding=false;
00244   QTextCodec *codec=0;
00245 
00246   usedCS=charset;
00247   codec=KGlobal::charsets()->codecForName(usedCS, ok);
00248 
00249   if(!ok) {
00250     //no codec available => try local8Bit and hope the best ;-)
00251     usedCS=KGlobal::locale()->encoding();
00252     codec=KGlobal::charsets()->codecForName(usedCS, ok);
00253   }
00254 
00255   if (usedCS.find("8859-")>=0)  // use "B"-Encoding for non iso-8859-x charsets
00256     useQEncoding=true;
00257 
00258   encoded8Bit=codec->fromUnicode(src);
00259 
00260   if(allow8BitHeaders)
00261     return encoded8Bit;
00262 
00263   for (unsigned int i=0; i<encoded8Bit.length(); i++) {
00264     if (encoded8Bit[i]==' ')    // encoding starts at word boundaries
00265       start = i+1;
00266 
00267     // encode escape character, for japanese encodings...
00268     if (((signed char)encoded8Bit[i]<0) || (encoded8Bit[i] == '\033') ||
00269         (addressHeader && (strchr("\"()<>@,.;:\\[]=",encoded8Bit[i])!=0))) {
00270       end = start;   // non us-ascii char found, now we determine where to stop encoding
00271       nonAscii=true;
00272       break;
00273     }
00274   }
00275 
00276   if (nonAscii) {
00277     while ((end<encoded8Bit.length())&&(encoded8Bit[end]!=' '))  // we encode complete words
00278       end++;
00279 
00280     for (unsigned int x=end;x<encoded8Bit.length();x++)
00281       if (((signed char)encoded8Bit[x]<0) || (encoded8Bit[x] == '\033') ||
00282           (addressHeader && (strchr("\"()<>@,.;:\\[]=",encoded8Bit[x])!=0))) {
00283         end = encoded8Bit.length();     // we found another non-ascii word
00284 
00285       while ((end<encoded8Bit.length())&&(encoded8Bit[end]!=' '))  // we encode complete words
00286         end++;
00287     }
00288 
00289     result = encoded8Bit.left(start)+"=?"+usedCS;
00290 
00291     if (useQEncoding) {
00292       result += "?Q?";
00293 
00294       char c,hexcode;                       // implementation of the "Q"-encoding described in RFC 2047
00295       for (unsigned int i=start;i<end;i++) {
00296         c = encoded8Bit[i];
00297         if (c == ' ')       // make the result readable with not MIME-capable readers
00298           result+='_';
00299         else
00300           if (((c>='a')&&(c<='z'))||      // paranoid mode, we encode *all* special characters to avoid problems
00301               ((c>='A')&&(c<='Z'))||      // with "From" & "To" headers
00302               ((c>='0')&&(c<='9')))
00303             result+=c;
00304           else {
00305             result += "=";                 // "stolen" from KMail ;-)
00306             hexcode = ((c & 0xF0) >> 4) + 48;
00307             if (hexcode >= 58) hexcode += 7;
00308             result += hexcode;
00309             hexcode = (c & 0x0F) + 48;
00310             if (hexcode >= 58) hexcode += 7;
00311             result += hexcode;
00312           }
00313       }
00314     } else {
00315       result += "?B?"+KCodecs::base64Encode(encoded8Bit.mid(start,end-start), false);
00316     }
00317 
00318     result +="?=";
00319     result += encoded8Bit.right(encoded8Bit.length()-end);
00320   }
00321   else
00322     result = encoded8Bit;
00323 
00324   return result;
00325 }
00326 
00327 QCString uniqueString()
00328 {
00329   static char chars[] = "0123456789abcdefghijklmnopqrstuvxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
00330   time_t now;
00331   QCString ret;
00332   char p[11];
00333   int pos, ran;
00334   unsigned int timeval;
00335 
00336   p[10]='\0';
00337   now=time(0);
00338   ran=1+(int) (1000.0*rand()/(RAND_MAX+1.0));
00339   timeval=(now/ran)+getpid();
00340 
00341   for(int i=0; i<10; i++){
00342     pos=(int) (61.0*rand()/(RAND_MAX+1.0));
00343     //kdDebug(5003) << pos << endl;
00344     p[i]=chars[pos];
00345   }
00346   ret.sprintf("%d.%s", timeval, p);
00347 
00348   return ret;
00349 }
00350 
00351 
00352 QCString multiPartBoundary()
00353 {
00354   QCString ret;
00355   ret="nextPart"+uniqueString();
00356   return ret;
00357 }
00358 
00359 QCString extractHeader(const QCString &src, const char *name)
00360 {
00361   QCString n=QCString(name)+": ";
00362   int pos1=-1, pos2=0, len=src.length()-1;
00363   bool folded(false);
00364 
00365   if (n.lower() == src.left(n.length()).lower()) {
00366     pos1 = 0;
00367   } else {
00368     n.prepend("\n");
00369     pos1 = src.find(n,0,false);
00370   }
00371 
00372   if (pos1>-1) {    //there is a header with the given name
00373     pos1+=n.length(); //skip the name
00374     pos2=pos1;
00375 
00376     if (src[pos2]!='\n') {  // check if the header is not empty
00377       while(1) {
00378         pos2=src.find("\n", pos2+1);
00379         if(pos2==-1 || pos2==len || ( src[pos2+1]!=' ' && src[pos2+1]!='\t') ) //break if we reach the end of the string, honor folded lines
00380           break;
00381         else
00382           folded = true;
00383       }
00384     }
00385 
00386     if(pos2<0) pos2=len+1; //take the rest of the string
00387 
00388     if (!folded)
00389       return src.mid(pos1, pos2-pos1);
00390     else
00391       return (src.mid(pos1, pos2-pos1).replace(QRegExp("\\s*\\n\\s*")," "));
00392   }
00393   else {
00394     return QCString(0); //header not found
00395   }
00396 }
00397 
00398 
00399 QCString CRLFtoLF(const QCString &s)
00400 {
00401   QCString ret=s.copy();
00402   ret.replace(QRegExp("\\r\\n"), "\n");
00403   return ret;
00404 }
00405 
00406 
00407 QCString CRLFtoLF(const char *s)
00408 {
00409   QCString ret=s;
00410   ret.replace(QRegExp("\\r\\n"), "\n");
00411   return ret;
00412 }
00413 
00414 
00415 QCString LFtoCRLF(const QCString &s)
00416 {
00417   QCString ret=s.copy();
00418   ret.replace(QRegExp("\\n"), "\r\n");
00419   return ret;
00420 }
00421 
00422 
00423 void removeQuots(QCString &str)
00424 {
00425   bool inQuote=false;
00426 
00427   for (int i=0; i < (int)str.length(); i++) {
00428     if (str[i] == '"') {
00429       str.remove(i,1);
00430       i--;
00431       inQuote = !inQuote;
00432     } else {
00433       if (inQuote && (str[i] == '\\'))
00434         str.remove(i,1);
00435     }
00436   }
00437 }
00438 
00439 
00440 void removeQuots(QString &str)
00441 {
00442   bool inQuote=false;
00443 
00444   for (int i=0; i < (int)str.length(); i++) {
00445     if (str[i] == '"') {
00446       str.remove(i,1);
00447       i--;
00448       inQuote = !inQuote;
00449     } else {
00450       if (inQuote && (str[i] == '\\'))
00451         str.remove(i,1);
00452     }
00453   }
00454 }
00455 
00456 
00457 void addQuotes(QCString &str, bool forceQuotes)
00458 {
00459   bool needsQuotes=false;
00460   for (unsigned int i=0; i < str.length(); i++) {
00461     if (strchr("()<>@,.;:[]=\\\"",str[i])!=0)
00462       needsQuotes = true;
00463     if (str[i]=='\\' || str[i]=='\"') {
00464       str.insert(i, '\\');
00465       i++;
00466     }
00467   }
00468 
00469   if (needsQuotes || forceQuotes) {
00470     str.insert(0,'\"');
00471     str.append("\"");
00472   }
00473 }
00474 
00475 int DateFormatter::mDaylight = -1;
00476 DateFormatter::DateFormatter(FormatType fType)
00477   : mFormat( fType ), mCurrentTime( 0 )
00478 {
00479 
00480 }
00481 
00482 DateFormatter::~DateFormatter()
00483 {/*empty*/}
00484 
00485 DateFormatter::FormatType
00486 DateFormatter::getFormat() const
00487 {
00488   return mFormat;
00489 }
00490 
00491 void
00492 DateFormatter::setFormat( FormatType t )
00493 {
00494   mFormat = t;
00495 }
00496 
00497 QString
00498 DateFormatter::dateString( time_t otime , const QString& lang ,
00499                bool shortFormat, bool includeSecs ) const
00500 {
00501   switch ( mFormat ) {
00502   case Fancy:
00503     return fancy( otime );
00504     break;
00505   case Localized:
00506     return localized( otime, shortFormat, includeSecs, lang );
00507     break;
00508   case CTime:
00509     return cTime( otime );
00510     break;
00511   case Iso:
00512     return isoDate( otime );
00513     break;
00514   case Custom:
00515     return custom( otime );
00516     break;
00517   }
00518   return QString::null;
00519 }
00520 
00521 QString
00522 DateFormatter::dateString(const QDateTime& dtime, const QString& lang,
00523                bool shortFormat, bool includeSecs ) const
00524 {
00525   return DateFormatter::dateString( qdateToTimeT(dtime), lang, shortFormat, includeSecs );
00526 }
00527 
00528 QCString
00529 DateFormatter::rfc2822(time_t otime) const
00530 {
00531   QDateTime tmp;
00532   QCString  ret;
00533 
00534   tmp.setTime_t(otime);
00535 
00536   ret = tmp.toString("ddd, dd MMM yyyy hh:mm:ss ").latin1();
00537   ret += zone(otime);
00538 
00539   return ret;
00540 }
00541 
00542 QString
00543 DateFormatter::custom(time_t t) const
00544 {
00545   if ( mCustomFormat.isEmpty() )
00546     return QString::null;
00547 
00548   int z = mCustomFormat.find("Z");
00549   QDateTime d;
00550   QString ret = mCustomFormat;
00551 
00552   d.setTime_t(t);
00553   if ( z != -1 ) {
00554     ret.replace(z,1,zone(t));
00555   }
00556 
00557   ret = d.toString(ret);
00558 
00559   return ret;
00560 }
00561 
00562 void
00563 DateFormatter::setCustomFormat(const QString& format)
00564 {
00565   mCustomFormat = format;
00566   mFormat = Custom;
00567 }
00568 
00569 QString
00570 DateFormatter::getCustomFormat() const
00571 {
00572   return mCustomFormat;
00573 }
00574 
00575 
00576 QCString
00577 DateFormatter::zone(time_t otime) const
00578 {
00579   QCString ret;
00580 #if defined(HAVE_TIMEZONE) || defined(HAVE_TM_GMTOFF)
00581   struct tm *local = localtime( &otime );
00582 #endif
00583 
00584 #if defined(HAVE_TIMEZONE)
00585 
00586   //hmm, could make hours & mins static
00587   int secs = abs(timezone);
00588   int neg  = (timezone>0)?1:0;
00589   int hours = secs/3600;
00590   int mins  = (secs - hours*3600)/60;
00591 
00592   // adjust to daylight
00593   if ( local->tm_isdst > 0 ) {
00594       mDaylight = 1;
00595       if ( neg )
00596         --hours;
00597       else
00598         ++hours;
00599   } else
00600       mDaylight = 0;
00601 
00602   ret.sprintf("%c%.2d%.2d",(neg)?'-':'+', hours, mins);
00603 
00604 #elif defined(HAVE_TM_GMTOFF)
00605 
00606   int secs = abs( local->tm_gmtoff );
00607   int neg  = (local->tm_gmtoff<0)?1:0; //no, I don't know why it's backwards :o
00608   int hours = secs/3600;
00609   int mins  = (secs - hours*3600)/60;
00610 
00611   if ( local->tm_isdst > 0 )
00612       mDaylight = 1;
00613   else
00614       mDaylight = 0;
00615 
00616   ret.sprintf("%c%.2d%.2d",(neg)?'-':'+', hours, mins);
00617 
00618 #else
00619 
00620   QDateTime d1 = QDateTime::fromString( asctime(gmtime(&otime)) );
00621   QDateTime d2 = QDateTime::fromString( asctime(localtime(&otime)) );
00622   int secs = d1.secsTo(d2);
00623   int neg = (secs<0)?1:0;
00624   secs = abs(secs);
00625   int hours = secs/3600;
00626   int mins  = (secs - hours*3600)/60;
00627   // daylight should be already taken care of here
00628   ret.sprintf("%c%.2d%.2d",(neg)?'-':'+', hours, mins);
00629 
00630 #endif /* HAVE_TIMEZONE */
00631 
00632   return ret;
00633 }
00634 
00635 time_t
00636 DateFormatter::qdateToTimeT(const QDateTime& dt) const
00637 {
00638   QDateTime epoch( QDate(1970, 1,1), QTime(00,00,00) );
00639   time_t otime;
00640   time( &otime );
00641 
00642   QDateTime d1 = QDateTime::fromString( asctime(gmtime(&otime)) );
00643   QDateTime d2 = QDateTime::fromString( asctime(localtime(&otime)) );
00644   time_t drf = epoch.secsTo( dt ) - d1.secsTo( d2 );
00645 
00646   return drf;
00647 }
00648 
00649 QString
00650 DateFormatter::fancy(time_t otime) const
00651 {
00652   KLocale *locale = KGlobal::locale();
00653 
00654   if ( otime <= 0 )
00655     return i18n( "unknown" );
00656 
00657   if ( !mCurrentTime ) {
00658     time( &mCurrentTime );
00659     mDate.setTime_t( mCurrentTime );
00660   }
00661 
00662   QDateTime old;
00663   old.setTime_t( otime );
00664 
00665   // not more than an hour in the future
00666   if ( mCurrentTime + 60 * 60 >= otime ) {
00667     time_t diff = mCurrentTime - otime;
00668 
00669     if ( diff < 24 * 60 * 60 ) {
00670       if ( old.date().year() == mDate.date().year() &&
00671        old.date().dayOfYear() == mDate.date().dayOfYear() )
00672     return i18n( "Today %1" ).arg( locale->
00673                        formatTime( old.time(), true ) );
00674     }
00675     if ( diff < 2 * 24 * 60 * 60 ) {
00676       QDateTime yesterday( mDate.addDays( -1 ) );
00677       if ( old.date().year() == yesterday.date().year() &&
00678        old.date().dayOfYear() == yesterday.date().dayOfYear() )
00679     return i18n( "Yesterday %1" ).arg( locale->
00680                        formatTime( old.time(), true) );
00681     }
00682     for ( int i = 3; i < 7; i++ )
00683       if ( diff < i * 24 * 60 * 60 ) {
00684     QDateTime weekday( mDate.addDays( -i + 1 ) );
00685     if ( old.date().year() == weekday.date().year() &&
00686          old.date().dayOfYear() == weekday.date().dayOfYear() )
00687       return i18n( "1. weekday, 2. time", "%1 %2" ).
00688 #if KDE_IS_VERSION( 3, 1, 90 )
00689         arg( locale->calendar()->weekDayName( old.date() ) ).
00690 #else
00691         arg( locale->weekDayName( old.date().dayOfWeek() ) ).
00692 #endif
00693         arg( locale->formatTime( old.time(), true) );
00694       }
00695   }
00696 
00697   return locale->formatDateTime( old );
00698 
00699 }
00700 
00701 QString
00702 DateFormatter::localized(time_t otime, bool shortFormat, bool includeSecs,
00703              const QString& localeLanguage ) const
00704 {
00705   QDateTime tmp;
00706   QString ret;
00707   KLocale *locale = KGlobal::locale();
00708 
00709   tmp.setTime_t( otime );
00710 
00711 
00712   if ( !localeLanguage.isEmpty() ) {
00713     QString olang = locale->language();
00714     locale->setLanguage( localeLanguage );
00715     ret = locale->formatDateTime( tmp, shortFormat, includeSecs );
00716     locale->setLanguage( olang );
00717   } else {
00718     ret = locale->formatDateTime( tmp, shortFormat, includeSecs );
00719   }
00720 
00721   return ret;
00722 }
00723 
00724 QString
00725 DateFormatter::cTime(time_t otime) const
00726 {
00727   return QString::fromLatin1( ctime(  &otime ) ).stripWhiteSpace() ;
00728 }
00729 
00730 QString
00731 DateFormatter::isoDate(time_t otime) const
00732 {
00733   char cstr[64];
00734   strftime( cstr, 63, "%Y-%m-%d %H:%M:%S", localtime(&otime) );
00735   return QString( cstr );
00736 }
00737 
00738 
00739 void
00740 DateFormatter::reset()
00741 {
00742   mCurrentTime = 0;
00743 }
00744 
00745 QString
00746 DateFormatter::formatDate(DateFormatter::FormatType t, time_t otime,
00747               const QString& data, bool shortFormat, bool includeSecs )
00748 {
00749   DateFormatter f( t );
00750   if ( t == DateFormatter::Custom ) {
00751     f.setCustomFormat( data );
00752   }
00753   return f.dateString( otime, data, shortFormat, includeSecs );
00754 }
00755 
00756 QString
00757 DateFormatter::formatCurrentDate( DateFormatter::FormatType t, const QString& data,
00758                   bool shortFormat, bool includeSecs )
00759 {
00760   DateFormatter f( t );
00761   if ( t == DateFormatter::Custom ) {
00762     f.setCustomFormat( data );
00763   }
00764   return f.dateString( time(0), data, shortFormat, includeSecs );
00765 }
00766 
00767 QCString
00768 DateFormatter::rfc2822FormatDate( time_t t )
00769 {
00770   DateFormatter f;
00771   return f.rfc2822( t );
00772 }
00773 
00774 bool
00775 DateFormatter::isDaylight()
00776 {
00777   if ( mDaylight == -1 ) {
00778     time_t ntime = time( 0 );
00779     struct tm *local = localtime( &ntime );
00780     if ( local->tm_isdst > 0 ) {
00781       mDaylight = 1;
00782       return true;
00783     } else {
00784       mDaylight = 0;
00785       return false;
00786     }
00787   } else if ( mDaylight != 0 )
00788     return true;
00789   else
00790     return false;
00791 }
00792 
00793 } // namespace KMime
KDE Logo
This file is part of the documentation for libkdenetwork Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Jan 31 15:51:50 2007 by doxygen 1.4.2 written by Dimitri van Heesch, © 1997-2003