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

viewmail.cpp

Go to the documentation of this file.
00001 #include "composemail.h"
00002 #include "viewmail.h"
00003 
00004 #include <libmailwrapper/settings.h>
00005 #include <libmailwrapper/abstractmail.h>
00006 #include <libmailwrapper/mailtypes.h>
00007 
00008 /* OPIE */
00009 #include <opie2/odebug.h>
00010 #include <opie2/ofiledialog.h>
00011 #include <opie2/oimagescrollview.h>
00012 #include <qpe/config.h>
00013 #include <qpe/qpeapplication.h>
00014 
00015 /* QT */
00016 #include <qtextbrowser.h>
00017 #include <qmessagebox.h>
00018 #include <qtextstream.h>
00019 #include <qaction.h>
00020 #include <qpopupmenu.h>
00021 #include <qfile.h>
00022 #include <qlayout.h>
00023 #include <qstylesheet.h>
00024 
00025 using namespace Opie::Ui;
00026 using namespace Opie::Core;
00027 
00028 AttachItem::AttachItem(QListView * parent,QListViewItem *after, const QString&mime,const QString&desc,const QString&file,
00029                        const QString&fsize,int num,const QValueList<int>&path)
00030         : QListViewItem(parent,after),_partNum(num)
00031 {
00032     _path=path;
00033     setText(0, mime);
00034     setText(1, desc);
00035     setText(2, file);
00036     setText(3, fsize);
00037 }
00038 
00039 AttachItem::AttachItem(QListViewItem * parent,QListViewItem *after, const QString&mime,const QString&desc,const QString&file,
00040                        const QString&fsize,int num,const QValueList<int>&path)
00041         : QListViewItem(parent,after),_partNum(num)
00042 {
00043     _path=path;
00044     setText(0, mime);
00045     setText(1, desc);
00046     setText(2, file);
00047     setText(3, fsize);
00048 }
00049 
00050 bool AttachItem::isParentof(const QValueList<int>&path)
00051 {
00052     /* if not set, then no parent */
00053     if (path.count()==0||_path.count()==0) return false;
00054     /* the parent must have one digit less then a child */
00055     if (path.count()!=_path.count()+1) return false;
00056     for (unsigned int i=0; i < _path.count();++i)
00057     {
00058         if (_path[i]!=path[i]) return false;
00059     }
00060     return true;
00061 }
00062 
00063 AttachItem* ViewMail::searchParent(const QValueList<int>&path)
00064 {
00065     QListViewItemIterator it( attachments );
00066     for ( ; it.current(); ++it )
00067     {
00068         AttachItem*ati = (AttachItem*)it.current();
00069         if (ati->isParentof(path)) return ati;
00070     }
00071     return 0;
00072 }
00073 
00074 AttachItem* ViewMail::lastChild(AttachItem*parent)
00075 {
00076     if (!parent) return 0;
00077     AttachItem* item = (AttachItem*)parent->firstChild();
00078     if (!item) return item;
00079     AttachItem*temp=0;
00080     while( (temp=(AttachItem*)item->nextSibling()))
00081     {
00082         item = temp;
00083     }
00084     return item;
00085 }
00086 
00087 void ViewMail::setBody(const RecBodyP&body )
00088 {
00089 
00090     m_body = body;
00091     m_mail[2] = body->Bodytext();
00092     attachbutton->setEnabled(body->Parts().count()>0);
00093     attachments->setEnabled(body->Parts().count()>0);
00094     if (body->Parts().count()==0)
00095     {
00096         return;
00097     }
00098     AttachItem * curItem=0;
00099     AttachItem * parentItem = 0;
00100     QString type=body->Description()->Type()+"/"+body->Description()->Subtype();
00101     QString desc,fsize;
00102     double s = body->Description()->Size();
00103     int w;
00104     w=0;
00105 
00106     while (s>1024)
00107     {
00108         s/=1024;
00109         ++w;
00110         if (w>=2) break;
00111     }
00112 
00113     QString q="";
00114     switch(w)
00115     {
00116     case 1:
00117         q="k";
00118         break;
00119     case 2:
00120         q="M";
00121         break;
00122     default:
00123         break;
00124     }
00125 
00126     {
00127         /* I did not found a method to make a CONTENT reset on a QTextStream
00128            so I use this construct that the stream will re-constructed in each
00129            loop. To let it work, the textstream is packed into a own area of
00130            code is it will be destructed after finishing its small job.
00131         */
00132         QTextOStream o(&fsize);
00133         if (w>0) o.precision(2); else o.precision(0);
00134         o.setf(QTextStream::fixed);
00135         o << s << " " << q << "Byte";
00136     }
00137 
00138     curItem=new AttachItem(attachments,curItem,type,"Mailbody","",fsize,-1,body->Description()->Positionlist());
00139     QString filename = "";
00140 
00141     for (unsigned int i = 0; i < body->Parts().count();++i)
00142     {
00143         filename = "";
00144         type = body->Parts()[i]->Type()+"/"+body->Parts()[i]->Subtype();
00145         part_plist_t::ConstIterator it = body->Parts()[i]->Parameters().begin();
00146         for (;it!=body->Parts()[i]->Parameters().end();++it)
00147         {
00148             odebug << it.key() << oendl;
00149             if (it.key().lower()=="name")
00150             {
00151                 filename=it.data();
00152             }
00153         }
00154         s = body->Parts()[i]->Size();
00155         w = 0;
00156         while (s>1024)
00157         {
00158             s/=1024;
00159             ++w;
00160             if (w>=2) break;
00161         }
00162         switch(w)
00163         {
00164         case 1:
00165             q="k";
00166             break;
00167         case 2:
00168             q="M";
00169             break;
00170         default:
00171             q="";
00172             break;
00173         }
00174         QTextOStream o(&fsize);
00175         if (w>0) o.precision(2); else o.precision(0);
00176         o.setf(QTextStream::fixed);
00177         o << s << " " << q << "Byte";
00178         desc = body->Parts()[i]->Description();
00179         parentItem = searchParent(body->Parts()[i]->Positionlist());
00180         if (parentItem)
00181         {
00182             AttachItem*temp = lastChild(parentItem);
00183             if (temp) curItem = temp;
00184             curItem=new AttachItem(parentItem,curItem,type,desc,filename,fsize,i,body->Parts()[i]->Positionlist());
00185             attachments->setRootIsDecorated(true);
00186             curItem = parentItem;
00187         }
00188         else
00189         {
00190             curItem=new AttachItem(attachments,curItem,type,desc,filename,fsize,i,body->Parts()[i]->Positionlist());
00191         }
00192     }
00193 }
00194 
00195 
00196 void ViewMail::slotShowHtml( bool state )
00197 {
00198     m_showHtml = state;
00199     m_lasttextpart=-2;
00200     setMainText();
00201 }
00202 
00203 void ViewMail::slotItemClicked( QListViewItem * item , const QPoint & point, int )
00204 {
00205     if (!item )
00206         return;
00207 
00208     if (  ( ( AttachItem* )item )->Partnumber() == -1 )
00209     {
00210         setMainText();
00211         return;
00212     }
00213     QPopupMenu *menu = new QPopupMenu();
00214     int ret=0;
00215 
00216     if ( item->text( 0 ).left( 5 ) == "text/" || item->text(0)=="message/rfc822" )
00217     {
00218         menu->insertItem( tr( "Show Text" ), 1 );
00219     }
00220     if (item->text(0).left(6)=="image/") {
00221         menu->insertItem(tr("Display image preview"),2);
00222     }
00223     menu->insertItem( tr( "Save Attachment" ),  0 );
00224     menu->insertSeparator(1);
00225 
00226     ret = menu->exec( point, 0 );
00227 
00228     switch(ret)
00229     {
00230     case 0:
00231         {
00232             MimeTypes types;
00233             types.insert( "all", "*" );
00234             QString str = OFileDialog::getSaveFileName( 1,
00235                           "/", item->text( 2 )  , types, 0 );
00236 
00237             if( !str.isEmpty() )
00238             {
00239                 encodedString*content = m_recMail->Wrapper()->fetchDecodedPart( m_recMail, m_body->Parts()[ ( ( AttachItem* )item )->Partnumber() ] );
00240                 if (content)
00241                 {
00242                     QFile output(str);
00243                     output.open(IO_WriteOnly);
00244                     output.writeBlock(content->Content(),content->Length());
00245                     output.close();
00246                     delete content;
00247                 }
00248             }
00249         }
00250         break ;
00251 
00252     case 2:
00253         {
00254             if (m_lastimagepart== (( AttachItem* )item )->Partnumber()) {
00255                 if (m_lastdlg) {
00256                     setUpdatesEnabled(false);
00257                     browser->hide();
00258                     m_lastdlg->show();
00259                     setUpdatesEnabled(true);
00260                     return;
00261                 }
00262             }
00263             QString tmpfile = QString("/tmp/opiemail-image-%1").arg(_icounter++);
00264             encodedString*content = m_recMail->Wrapper()->fetchDecodedPart( m_recMail, m_body->Parts()[ ( ( AttachItem* )item )->Partnumber() ] );
00265             if (content && content->Length()) {
00266                 QFile output(tmpfile);
00267                 output.open(IO_WriteOnly);
00268                 output.writeBlock(content->Content(),content->Length());
00269                 output.close();
00270                 delete content;
00271                 if (!m_PicsInline) {
00272                     MailImageDlg iview("");
00273                     iview.setName(tmpfile);
00274                     QPEApplication::execDialog(&iview);
00275                 } else {
00276                     if (!m_lastdlg) {
00277                         m_lastdlg=new Opie::MM::OImageScrollView("",browser->parentWidget(),false);
00278                         m_lastdlg->setAutoScale(true);
00279                     }
00280                     //m_lastdlg->setImage("");
00281                     m_lastdlg->setImage(tmpfile);
00282                     browser->hide();
00283                     m_lastdlg->show();
00284                 }
00285                 output.remove();
00286             } else {
00287                 QMessageBox::critical(this, tr("Reading attachment"), tr("Could not read content of attachment"));
00288             }
00289             m_lastimagepart=(( AttachItem* )item )->Partnumber();
00290         }
00291         break;
00292     case 1:
00293         if (  ( ( AttachItem* )item )->Partnumber() == -1 )
00294         {
00295             setMainText();
00296         }
00297         else
00298         {
00299             if (  m_recMail->Wrapper() != 0l )
00300             { // make sure that there is a wrapper , even after delete or simular actions
00301                 if (m_lastdlg) {
00302                     m_lastdlg->hide();
00303                     browser->show();
00304                 }
00305                 if (m_lasttextpart == ( ( AttachItem* )item )->Partnumber() ) return;
00306                 m_lasttextpart = ( ( AttachItem* )item )->Partnumber();
00307                 QString s = m_recMail->Wrapper()->fetchTextPart( m_recMail, m_body->Parts()[ ( ( AttachItem* )item )->Partnumber() ] );;
00308                 if (item->text(0).right(4)!="html") {
00309                     s = QString("<html><body>\n<font face=fixed>%1</font></body></html>").arg(QStyleSheet::convertFromPlainText(s));
00310                 }
00311                 browser->setText(s);
00312             }
00313         }
00314         break;
00315     }
00316     delete menu;
00317 }
00318 
00319 
00320 void ViewMail::setMail(const RecMailP&mail )
00321 {
00322 
00323     m_recMail = mail;
00324 
00325     m_mail[0] = mail->getFrom();
00326     m_mail[1] = mail->getSubject();
00327     m_mail[3] = mail->getStringDate();
00328     m_mail[4] = mail->Msgid();
00329 
00330     m_mail2[0] = mail->To();
00331     m_mail2[1] = mail->CC();
00332     m_mail2[2] = mail->Bcc();
00333 
00334     setCaption(tr("E-Mail by %1").arg( m_mail[0] ) );
00335     m_lasttextpart=-2;
00336     setMainText();
00337 }
00338 
00339 
00340 
00341 ViewMail::ViewMail( QWidget *parent, const char *name, WFlags fl)
00342         : ViewMailBase(parent, name, fl), _inLoop(false)
00343 {
00344     m_gotBody = false;
00345     deleted = false;
00346 
00347     connect( reply, SIGNAL(activated()), SLOT(slotReply()));
00348     connect( forward, SIGNAL(activated()), SLOT(slotForward()));
00349     connect( deleteMail, SIGNAL( activated() ),  SLOT( slotDeleteMail() ) );
00350     connect( showHtml, SIGNAL( toggled(bool) ), SLOT( slotShowHtml(bool) ) );
00351     connect( showPicsInline, SIGNAL( toggled(bool) ), SLOT( slotImageInline(bool) ) );
00352 
00353     attachments->setEnabled(m_gotBody);
00354     connect( attachments,  SIGNAL( clicked(QListViewItem*,const QPoint&, int) ), SLOT( slotItemClicked(QListViewItem*,const QPoint&, int) ) );
00355     m_lastdlg = 0;
00356     _icounter = 0;
00357     m_lastimagepart = -1;
00358     m_lasttextpart = -2;
00359 
00360     readConfig();
00361     attachments->setSorting(-1);
00362 }
00363 
00364 void ViewMail::slotImageInline(bool how)
00365 {
00366     Config cfg( "mail" );
00367     cfg.writeEntry( "showPicsInline", how);
00368     m_PicsInline = how;
00369     if (m_lastdlg&&!how) {
00370         browser->show();
00371         m_lastdlg->hide();
00372         m_lastdlg->reparent(0,QPoint(0,0),false);
00373         delete m_lastdlg;
00374         m_lastdlg = 0;
00375         m_lastimagepart = -1;
00376     }
00377 }
00378 
00379 void ViewMail::readConfig()
00380 {
00381     Config cfg( "mail" );
00382     cfg.setGroup( "Settings" );
00383     m_showHtml =  cfg.readBoolEntry( "showHtml", false );
00384     m_PicsInline = cfg.readBoolEntry( "showPicsInline", true );
00385     showPicsInline->setOn(m_PicsInline);
00386     showHtml->setOn( m_showHtml );
00387 }
00388 
00389 void ViewMail::setMainText()
00390 {
00391     QString toString;
00392     QString ccString;
00393     QString bccString;
00394     QString mailHtml;
00395 
00396     if (m_lastdlg) {
00397         m_lastdlg->hide();
00398     }
00399     browser->show();
00400     if (m_lasttextpart == -1) return;
00401     m_lasttextpart = -1;
00402     for ( QStringList::Iterator it = ( m_mail2[0] ).begin(); it != ( m_mail2[0] ).end(); ++it )
00403     {
00404         toString += (*it);
00405     }
00406     for ( QStringList::Iterator it = ( m_mail2[1] ).begin(); it != ( m_mail2[1] ).end(); ++it )
00407     {
00408         ccString += (*it);
00409     }
00410     for ( QStringList::Iterator it = ( m_mail2[2] ).begin(); it != ( m_mail2[2] ).end(); ++it )
00411     {
00412         bccString += (*it);
00413     }
00414     browser->setTextFormat(Qt::RichText);
00415     mailHtml = "<html><body>"
00416                  "<table width=\"100%\" border=\"0\"><tr bgcolor=\"#FFDD76\"><td>"
00417                  "<div align=left><b>" + deHtml(m_mail[1]) + "</b></div>"
00418                  "</td></tr><tr bgcolor=\"#EEEEE6\"><td>"
00419                  "<b>" + tr( "From" ) + ": </b><font color=#6C86C0>" + deHtml( m_mail[0] ) + "</font><br>"
00420                  "<b>" + tr(  "To" ) + ": </b><font color=#6C86C0>" + deHtml( toString ) + "</font><br><b>" +
00421                  tr( "Cc" ) + ": </b>" + deHtml( ccString ) + "<br>"
00422                  "<b>" + tr( "Date" ) + ": </b> " +  m_mail[3] +
00423                  "</td></tr></table>";
00424     if ( !m_showHtml ) {
00425         browser->setText( mailHtml+"<font face=fixed>" + QStyleSheet::convertFromPlainText(m_mail[2]) + "</font></body></html>" );
00426     } else {
00427         browser->setText(mailHtml+m_mail[2].simplifyWhiteSpace()+"</html>");
00428     }
00429     // remove later in favor of a real handling
00430     m_gotBody = true;
00431 }
00432 
00433 
00434 ViewMail::~ViewMail()
00435 {
00436     m_recMail->Wrapper()->cleanMimeCache();
00437     hide();
00438 }
00439 
00440 void ViewMail::hide()
00441 {
00442     QWidget::hide();
00443 
00444     if (_inLoop)
00445     {
00446         _inLoop = false;
00447         qApp->exit_loop();
00448 
00449     }
00450 
00451 }
00452 
00453 void ViewMail::exec()
00454 {
00455     show();
00456 
00457     if (!_inLoop)
00458     {
00459         _inLoop = true;
00460         qApp->enter_loop();
00461     }
00462 
00463 }
00464 
00465 QString ViewMail::deHtml(const QString &aString)
00466 {
00467     QString string_ = aString;
00468     string_.replace(QRegExp("&"), "&amp;");
00469     string_.replace(QRegExp("<"), "&lt;");
00470     string_.replace(QRegExp(">"), "&gt;");
00471     string_.replace(QRegExp("\\n"), "<br>");
00472     return string_;
00473 }
00474 
00475 void ViewMail::slotReply()
00476 {
00477     if (!m_gotBody)
00478     {
00479         QMessageBox::information(this, tr("Error"), tr("<p>The mail body is not yet downloaded, so you cannot reply yet."), tr("Ok"));
00480         return;
00481     }
00482 
00483     QString rtext;
00484     rtext += QString("* %1 wrote on %2:\n")        // no i18n on purpose
00485              .arg(  m_mail[0] )
00486              .arg( m_mail[3] );
00487 
00488     QString text = m_mail[2];
00489     QStringList lines = QStringList::split(QRegExp("\\n"), text);
00490     QStringList::Iterator it;
00491     for (it = lines.begin(); it != lines.end(); it++)
00492     {
00493         rtext += "> " + *it + "\n";
00494     }
00495     rtext += "\n";
00496 
00497     QString prefix;
00498     if ( m_mail[1].find(QRegExp("^Re: .*$")) != -1) prefix = "";
00499     else prefix = "Re: ";                // no i18n on purpose
00500 
00501     Settings *settings = new Settings();
00502     ComposeMail composer( settings ,this, 0, true);
00503     if (m_recMail->Replyto().isEmpty()) {
00504         composer.setTo( m_recMail->getFrom());
00505     } else {
00506         composer.setTo( m_recMail->Replyto());
00507     }
00508     composer.setSubject( prefix + m_mail[1] );
00509     composer.setMessage( rtext );
00510     composer.setInReplyTo(m_recMail->Msgid());
00511 
00512     if ( QDialog::Accepted == QPEApplication::execDialog( &composer ) )
00513     {
00514         m_recMail->Wrapper()->answeredMail(m_recMail);
00515     }
00516 }
00517 
00518 void ViewMail::slotForward()
00519 {
00520     if (!m_gotBody)
00521     {
00522         QMessageBox::information(this, tr("Error"), tr("<p>The mail body is not yet downloaded, so you cannot forward yet."), tr("Ok"));
00523         return;
00524     }
00525 
00526     QString ftext;
00527     ftext += QString("\n----- Forwarded message from %1 -----\n\n")
00528              .arg( m_mail[0] );
00529     if (!m_mail[3].isNull())
00530         ftext += QString("Date: %1\n")
00531                  .arg( m_mail[3] );
00532     if (!m_mail[0].isNull())
00533         ftext += QString("From: %1\n")
00534                  .arg( m_mail[0] );
00535     if (!m_mail[1].isNull())
00536         ftext += QString("Subject: %1\n")
00537                  .arg( m_mail[1] );
00538 
00539     ftext += QString("\n%1\n")
00540              .arg( m_mail[2]);
00541 
00542     ftext += QString("----- End forwarded message -----\n");
00543 
00544     Settings *settings = new Settings();
00545     ComposeMail composer( settings ,this, 0, true);
00546     composer.setSubject( "Fwd: " + m_mail[1] );
00547     composer.setMessage( ftext );
00548     if ( QDialog::Accepted == QPEApplication::execDialog( &composer ))
00549     {
00550     }
00551 }
00552 
00553 void ViewMail::slotDeleteMail( )
00554 {
00555     if ( QMessageBox::warning(this, tr("Delete Mail"), QString( tr("<p>Do you really want to delete this mail? <br><br>" ) + m_mail[0] + " - " + m_mail[1] ) , QMessageBox::Yes, QMessageBox::No ) == QMessageBox::Yes )
00556     {
00557         m_recMail->Wrapper()->deleteMail( m_recMail );
00558         hide();
00559         deleted = true;
00560     }
00561 }
00562 
00563 MailImageDlg::MailImageDlg(const QString&fname,QWidget *parent, const char *name, bool modal, WFlags f)
00564     : Opie::Ui::ODialog(parent,name,modal,f)
00565 {
00566     QVBoxLayout*dlglayout = new QVBoxLayout(this);
00567     dlglayout->setSpacing(2);
00568     dlglayout->setMargin(1);
00569     m_imageview = new Opie::MM::OImageScrollView(this);
00570     dlglayout->addWidget(m_imageview);
00571 }
00572 
00573 MailImageDlg::~MailImageDlg()
00574 {
00575 }
00576 
00577 void MailImageDlg::setName(const QString&fname)
00578 {
00579     m_imageview->setImage(fname);
00580 }

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