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.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Oct 21 19:46:16 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003