00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 #include "showrecordelem.h"
00022 
00023 int const ShowRecordElem::continueShowHeaders( 0 );
00024 int const ShowRecordElem::cancelShowHeaders( 1 );
00025 
00026 ShowRecordElem::ShowRecordElem ()
00027 {
00028   
00029   m_from = "???";
00030   m_subject = "???";
00031   m_size = 0;
00032   m_pItem = NULL;
00033   m_new = false;
00034   m_pFilter = NULL;
00035 }
00036 
00037 ShowRecordElem::ShowRecordElem( int number, TQString& uid, bool isNew )
00038 {
00039   
00040   m_from = "???";
00041   m_subject = "???";
00042   m_size = 0;
00043   m_pItem = NULL;
00044   m_pFilter = NULL;
00045 
00046   
00047   m_nNumber = number;
00048   m_uid = uid;
00049   m_new = isNew;
00050 }
00051 
00052 
00053 TQCString ShowRecordElem::scanHeader( const TQString& item ) const
00054 {
00055   TQCString headerline( "" );      
00056 
00057   
00058   
00059 
00060   
00061   TQString searchstring( TQString( "\r\n%1:" ).arg( item ) );
00062 
00063   
00064   int pos1 = m_header.find( searchstring, 0, false );
00065   int pos2 = m_header.find( '\r', pos1 + 2 );
00066 
00067   
00068   
00069   if( pos1 >= 0 )
00070   {
00071     headerline = m_header.mid( pos1 + searchstring.length(), pos2 - pos1 - searchstring.length() );
00072   }
00073 
00074   return headerline;
00075 }
00076 
00077 void ShowRecordElem::setHeader( const TQString& header )
00078 {
00079   
00080   m_header = header.ascii();
00081 
00082   
00083   TQCString from = scanHeader( "From" );
00084   from = from.simplifyWhiteSpace();
00085   setFrom( from );
00086 
00087   
00088   TQCString to = scanHeader( "To" );
00089   to = to.simplifyWhiteSpace();
00090   setTo (to);
00091 
00092   
00093   TQCString subject = scanHeader( "Subject" );
00094   subject = subject.simplifyWhiteSpace();
00095   setSubject( subject );
00096 
00097   
00098   TQCString date = scanHeader( "Date" );
00099   setDate( date );
00100 
00101   
00102   TQCString content = scanHeader( "Content-Type" );
00103   content = content.simplifyWhiteSpace ();
00104 
00105   
00106   int posSemicolon = content.find( ';' );
00107   if( posSemicolon != -1 )
00108   {
00109     content.remove( posSemicolon, content.length() - posSemicolon );
00110   }
00111 
00112   
00113   setContent (content);
00114 }
00115 
00116 void ShowRecordElem::setDate( const TQCString& date )
00117 {
00118   DwDateTime dwDate;      
00119                           
00120 
00121   
00122   dwDate.FromString( date );
00123   dwDate.Parse();
00124   m_unixDate.setTime_t( dwDate.AsUnixTime() );
00125 }
00126 
00127 TQString ShowRecordElem::from() const
00128 {
00129   return Codecs::decodeRFC2047( m_from );
00130 }
00131 
00132 TQString ShowRecordElem::to() const
00133 {
00134   return Codecs::decodeRFC2047( m_to );
00135 }
00136 
00137 TQString ShowRecordElem::subject() const
00138 {
00139   return Codecs::decodeRFC2047( m_subject );
00140 }
00141 
00142 TQString ShowRecordElem::date() const
00143 {
00144   return TDEGlobal::locale()->formatDateTime( m_unixDate, true, true );
00145 }
00146 
00147 TQString ShowRecordElem::strUnixTime() const
00148 {
00149   return m_unixDate.toString( TQt::ISODate );
00150 }
00151 
00152 TQString ShowRecordElem::strSize() const
00153 {
00154   return TQString( "%1" ).arg( m_size, 8 );
00155 }
00156 
00157 TQString ShowRecordElem::state() const
00158 {
00159   if( m_new )
00160     return i18n( "new" );
00161   else
00162     return i18n( "old" );
00163 }
00164 
00165 void ShowRecordElem::saveOptions( TQDomDocument& doc, TQDomElement& parent )
00166 {
00167   
00168   TQString hdr = TQString( ITEM_MESSAGE );
00169   hdr.append( "%1" );
00170   hdr = hdr.arg( m_nNumber );
00171 
00172   
00173   TQDomElement elem = doc.createElement( hdr );
00174   elem.setAttribute( ATTRIBUTE_MAIL_NUMBER, m_nNumber );
00175   elem.setAttribute( ATTRIBUTE_MAIL_SIZE, m_size );
00176   elem.setAttribute( ATTRIBUTE_MAIL_UID, m_uid );
00177 
00178   
00179   TQDomElement subelem = doc.createElement( ITEM_MAIL_HEADER );
00180   subelem.appendChild( doc.createTextNode( m_header ) );
00181 
00182   
00183   elem.appendChild( subelem );
00184 
00185   
00186   parent.appendChild( elem );
00187 }
00188 
00189 void ShowRecordElem::readOptions( TQDomElement& elem )
00190 {
00191   
00192   setNumber( elem.attribute( ATTRIBUTE_MAIL_NUMBER ).toInt() );
00193   setSize( elem.attribute( ATTRIBUTE_MAIL_SIZE ).toInt() );
00194   setUIDL( elem.attribute( ATTRIBUTE_MAIL_UID ) );
00195 
00196   
00197   TQDomElement subelem = elem.namedItem( ITEM_MAIL_HEADER ).toElement();
00198   setHeader( subelem.text() );
00199 
00200   
00201   setNew( false );
00202 }
00203 
00204 void ShowRecordElem::applyFilters ()
00205 {
00206   
00207   FilterElem* filter = Filter::matches( this );
00208 
00209   if( filter != NULL )
00210   {
00211     
00212     
00213     m_pItem->setSelected (true);
00214 
00215     
00216     setFilter( filter );
00217   }
00218 }
00219 
00220 void ShowRecordElem::setFrom( const TQCString & from )
00221 {
00222   m_from = from;
00223 }
00224 
00225 void ShowRecordElem::setTo( const TQCString & to )
00226 {
00227   m_to = to;
00228 }
00229 
00230 void ShowRecordElem::setSubject( const TQCString & subject )
00231 {
00232   m_subject = subject;
00233 }
00234 
00235 void ShowRecordElem::setContent( const TQCString& content )
00236 {
00237   m_content = content;
00238 }
00239 
00240 TQString ShowRecordElem::header( ) const
00241 {
00242   return TQString( m_header );
00243 }
00244 
00245 void ShowRecordElem::setUIDL( const TQString & uid )
00246 {
00247   m_uid = uid;
00248 }
00249 
00250 TQString ShowRecordElem::uidl( ) const
00251 {
00252   return m_uid;
00253 }
00254 
00255 void ShowRecordElem::setSize( int size )
00256 {
00257   m_size = size;
00258 }
00259 
00260 int ShowRecordElem::size( ) const
00261 {
00262   return m_size;
00263 }
00264 
00265 void ShowRecordElem::setNew( bool isnew )
00266 {
00267   m_new = isnew;
00268 }
00269 
00270 bool ShowRecordElem::isNew( ) const
00271 {
00272   return m_new;
00273 }
00274 
00275 void ShowRecordElem::setNumber( int n )
00276 {
00277   m_nNumber = n;
00278 }
00279 
00280 int ShowRecordElem::number( ) const
00281 {
00282   return m_nNumber;
00283 }
00284 
00285 TQString ShowRecordElem::content( ) const
00286 {
00287   return m_content;
00288 }
00289 
00290 void ShowRecordElem::setViewItem( ShowListViewItem* item )
00291 {
00292   m_pItem = item;
00293 }
00294 
00295 ShowListViewItem * ShowRecordElem::viewItem( ) const
00296 {
00297   return m_pItem;
00298 }
00299 
00300 void ShowRecordElem::setFilter( FilterElem* filter )
00301 {
00302   m_pFilter = filter;
00303 }
00304 
00305 bool ShowRecordElem::isSelected( ) const
00306 {
00307   if( m_pItem != NULL )
00308     return m_pItem->isSelected();
00309   else
00310     return false;
00311 }
00312 
00313 TQString ShowRecordElem::strSizePrefix( ) const
00314 {
00315   TQString size;
00316 
00317   if( m_size >= 1024 * 1024 )
00318   {
00319     
00320     size = TQString( "%L1M" ).arg( ( (double)m_size / ( 1024 * 1024 ) ), 0, 'f', 1 );
00321   }
00322   else if( m_size >= 1024 )
00323   {
00324     
00325     size = TQString( "%L1K" ).arg( ( (double)m_size / 1024 ), 0, 'f', 1 );
00326   }
00327   else
00328     
00329     size = TQString( "%L1" ).arg( m_size );
00330 
00331   return size;
00332 }
00333 
00334 TQString ShowRecordElem::decodeMailBody( TQByteArray body, bool preferHTML ) const
00335 {
00336   TQString charset;    
00337   TQString encoding;   
00338 
00339   
00340   
00341   
00342   body.resize( body.size() + 1 );
00343   body[ body.size() - 1 ] = '\0';
00344   TQCString strBody( (char *)body.data() );
00345 
00346   
00347   for( uint i = 0; i < strBody.size(); i++ )
00348     if( strBody[ i ] == '\r' )
00349       strBody.remove( i, 1 );
00350 
00351   
00352   
00353   
00354   TQString boundary = getBoundary();
00355 
00356   
00357   if( boundary == "" )
00358   {
00359     
00360 
00361     
00362     int posBlankLine = strBody.find( "\n\n" );
00363 
00364     
00365     
00366     strBody = strBody.mid( posBlankLine + 2 );
00367     while( strBody[ 0 ] == '\n')
00368       strBody.remove( 0, 1 );
00369 
00370     
00371     
00372     charset = getCharset();
00373 
00374     
00375     encoding = getTransferEncoding();
00376   }
00377   else
00378   {
00379     
00380 
00381     
00382     int posPlainFlag = strBody.find( "text/plain", 0, false );
00383     int posHTMLFlag = strBody.find( "text/html", 0, false );
00384 
00385     
00386     if( posPlainFlag != -1 || posHTMLFlag != -1 )
00387     {
00388       
00389       bool hasHTML = posHTMLFlag != -1;
00390       bool takeHTML = ( hasHTML && preferHTML ) || posPlainFlag == -1;
00391 
00392       
00393       
00394       
00395       
00396       int posInside;    
00397       while( boundary != "" )
00398       {
00399         
00400         if( takeHTML )
00401           posInside = strBody.find( "text/html", 0, false );
00402         else
00403           posInside = strBody.find( "text/plain", 0, false );
00404 
00405         
00406         int lengthBoundary = boundary.length();
00407 
00408         
00409         int beginPart = strBody.findRev( boundary.ascii(), posInside ) + lengthBoundary + 1;
00410         int lengthPart = strBody.findRev( '\n', strBody.find( boundary.ascii(), posInside ) ) - beginPart;
00411 
00412         strBody = strBody.mid( beginPart, lengthPart );
00413 
00414         
00415         
00416         int posBoundary = strBody.find( "boundary=", 0, false );
00417 
00418         if( posBoundary >= 0 )
00419         {
00420           
00421           int posFirstQuote = posBoundary + 9;
00422 
00423           
00424           int posSecondQuote = strBody.find( '"', posFirstQuote + 1 );
00425 
00426           
00427           boundary.append( strBody.mid( posFirstQuote + 1, posSecondQuote - posFirstQuote - 1 ) );
00428         }
00429         else
00430           boundary = "";
00431       }
00432 
00433       
00434       
00435 
00436       
00437       int posCharset = strBody.find( "charset=", 0, false );
00438 
00439       
00440       if( posCharset >= 0 )
00441       {
00442         
00443         int posBeginValue = posCharset + 8;
00444 
00445         
00446         int posEndValue = strBody.find( '\n', posBeginValue ) - 1;
00447 
00448         
00449         charset.append( strBody.mid( posBeginValue, posEndValue - posBeginValue + 1 ) );
00450 
00451         
00452         charset.remove( '"' );
00453         
00454         int posSemicolon = charset.find( ';' );
00455         charset = charset.left( posSemicolon );
00456       }
00457 
00458       
00459       int posEncoding = strBody.find( "Content-Transfer-Encoding:", 0, false );
00460 
00461       
00462       if( posEncoding >= 0 )
00463       {
00464         
00465         int posBeginValue = posEncoding + 26;
00466 
00467         
00468         int posEndValue = strBody.find( '\n', posBeginValue ) - 1;
00469 
00470         
00471         encoding.append( strBody.mid( posBeginValue, posEndValue - posBeginValue + 1 ) );
00472 
00473         
00474         encoding = encoding.stripWhiteSpace();
00475         encoding.remove( '"' );
00476       }
00477 
00478       
00479       
00480       if( posCharset != -1 || posEncoding != -1 )
00481       {
00482         int posBlankLine = strBody.find( "\n\n" );
00483         strBody = strBody.mid( posBlankLine + 2 );
00484         while( strBody[ 0 ] == '\n')
00485           strBody.remove( 0, 1 );
00486       }
00487     }
00488   }
00489 
00490   
00491   
00492   if( encoding == "quoted-printable" )
00493   {
00494     strBody = KCodecs::quotedPrintableDecode( strBody );
00495   }
00496 
00497   return TQString( strBody );
00498 }
00499 
00500 TQString ShowRecordElem::getBoundary( ) const
00501 {
00502   TQString boundary;
00503 
00504   
00505   if( m_content.contains( "multipart", false ) )
00506   {
00507     
00508 
00509     
00510     int posBoundary = m_header.find( "boundary=", 0, false );
00511 
00512     
00513     if( posBoundary >= 0 )
00514     {
00515       
00516       int posFirstQuote = posBoundary + 9;
00517 
00518       
00519       int posSecondQuote = m_header.find( '"', posFirstQuote + 1 );
00520 
00521       
00522       boundary.append( m_header.mid( posFirstQuote + 1, posSecondQuote - posFirstQuote - 1 ) );
00523     }
00524   }
00525 
00526   return boundary;
00527 }
00528 
00529 TQString ShowRecordElem::getCharset( ) const
00530 {
00531   TQString charset;
00532 
00533   
00534   int posCharset = m_header.find( "charset=", 0, false );
00535 
00536   
00537   if( posCharset >= 0 )
00538   {
00539     
00540     int posBeginValue = posCharset + 8;
00541 
00542     
00543     int posEndValue = m_header.find( '\r', posBeginValue ) - 1;
00544 
00545     
00546     charset.append( m_header.mid( posBeginValue, posEndValue - posBeginValue + 1 ) );
00547 
00548     
00549     charset.remove( '"' );
00550     
00551     int posSemicolon = charset.find( ';' );
00552     charset = charset.left( posSemicolon );
00553   }
00554 
00555   return TQString( charset );
00556 }
00557 
00558 TQString ShowRecordElem::getTransferEncoding( ) const
00559 {
00560   TQString encoding;
00561 
00562   
00563   int posEncoding = m_header.find( "Content-Transfer-Encoding:", 0, false );
00564 
00565   
00566   if( posEncoding >= 0 )
00567   {
00568     
00569     int posBeginValue = posEncoding + 26;
00570 
00571     
00572     int posEndValue = m_header.find( '\r', posBeginValue ) - 1;
00573 
00574     
00575     encoding.append( m_header.mid( posBeginValue, posEndValue - posBeginValue + 1 ) );
00576 
00577     
00578     encoding = encoding.stripWhiteSpace();
00579     encoding.remove( '"' );
00580   }
00581 
00582   return TQString( encoding );
00583 
00584 }
00585 
00586 int ShowRecordElem::showHeader( TQString& account )
00587 {
00588   
00589   TQString tsubject = subject();
00590   TQString tmailheader = header();
00591 
00592   
00593   ShowHeaderDialog dlg( tdeApp->mainWidget(), account, tsubject, tmailheader );
00594   int ret = dlg.exec();
00595 
00596   
00597   return ret == TQDialog::Accepted ? ShowRecordElem::continueShowHeaders : ShowRecordElem::cancelShowHeaders;
00598 }
00599 
00600