-rw-r--r-- | kmicromail/libmailwrapper/abstractmail.cpp | 1 | ||||
-rw-r--r-- | kmicromail/libmailwrapper/genericwrapper.cpp | 35 | ||||
-rw-r--r-- | kmicromail/libmailwrapper/genericwrapper.h | 2 | ||||
-rw-r--r-- | kmicromail/libmailwrapper/imapwrapper.cpp | 17 | ||||
-rw-r--r-- | kmicromail/libmailwrapper/mailtypes.cpp | 20 | ||||
-rw-r--r-- | kmicromail/libmailwrapper/mailtypes.h | 4 |
6 files changed, 56 insertions, 23 deletions
diff --git a/kmicromail/libmailwrapper/abstractmail.cpp b/kmicromail/libmailwrapper/abstractmail.cpp index 8f67566..88545f8 100644 --- a/kmicromail/libmailwrapper/abstractmail.cpp +++ b/kmicromail/libmailwrapper/abstractmail.cpp @@ -1,277 +1,278 @@ // CHANGED 2004-09-31 Lutz Rogowski #include "abstractmail.h" #include "imapwrapper.h" #include "pop3wrapper.h" #include "nntpwrapper.h" #include "mhwrapper.h" #include "mailtypes.h" #include <qpe/global.h> #include <qprogressbar.h> #include <qapplication.h> #include <qmessagebox.h> #include <kdecore/kstandarddirs.h> #include <qfile.h> #include <qtextstream.h> #include <stdlib.h> #include <libetpan/mailmime_content.h> #include <libetpan/mailmime.h> using namespace Opie::Core; AbstractMail* AbstractMail::getWrapper(IMAPaccount *a) { return new IMAPwrapper(a); } AbstractMail* AbstractMail::getWrapper(POP3account *a) { return new POP3wrapper(a); } AbstractMail* AbstractMail::getWrapper(NNTPaccount *a) { return new NNTPwrapper(a); } AbstractMail* AbstractMail::getWrapper(const QString&a,const QString&name) { return new MHwrapper(a,name); } AbstractMail* AbstractMail::getWrapper(Account*a) { if (!a) return 0; switch (a->getType()) { case MAILLIB::A_IMAP: return new IMAPwrapper((IMAPaccount*)a); break; case MAILLIB::A_POP3: return new POP3wrapper((POP3account*)a); break; case MAILLIB::A_NNTP: return new NNTPwrapper((NNTPaccount*)a); break; default: return 0; } } encodedString* AbstractMail::decode_String(const encodedString*text,const QString&enc) { // odebug << "Decode string start" << oendl; char*result_text; size_t index = 0; /* reset for recursive use! */ size_t target_length = 0; result_text = 0; int mimetype = MAILMIME_MECHANISM_7BIT; if (enc.lower()=="quoted-printable") { mimetype = MAILMIME_MECHANISM_QUOTED_PRINTABLE; } else if (enc.lower()=="base64") { mimetype = MAILMIME_MECHANISM_BASE64; } else if (enc.lower()=="8bit") { mimetype = MAILMIME_MECHANISM_8BIT; } else if (enc.lower()=="binary") { mimetype = MAILMIME_MECHANISM_BINARY; } int err = mailmime_part_parse(text->Content(),text->Length(),&index,mimetype, &result_text,&target_length); encodedString* result = new encodedString(); if (err == MAILIMF_NO_ERROR) { result->setContent(result_text,target_length); } //odebug << "Decode string finished" << oendl; return result; } QString AbstractMail::convert_String(const char*text) { //size_t index = 0; char*res = 0; int err = MAILIMF_NO_ERROR; QString result(text); /* due a bug in libetpan it isn't usable this moment */ /* int err = mailmime_encoded_phrase_parse("iso-8859-1", text, strlen(text),&index, "iso-8859-1",&res);*/ //odebug << "Input: " << text << "" << oendl; if (err == MAILIMF_NO_ERROR && res && strlen(res)) { // result = QString(res); // odebug << "Res: " << res << ", length: " << strlen(res) << "" << oendl; } if (res) free(res); return result; } /* cp & paste from launcher */ QString AbstractMail::gen_attachment_id() { QFile file( "/proc/sys/kernel/random/uuid" ); if (!file.open(IO_ReadOnly ) ) return QString::null; QTextStream stream(&file); return "{" + stream.read().stripWhiteSpace() + "}"; } int AbstractMail::createMbox(const QString&,const FolderP&,const QString& ,bool) { return 0; } QString AbstractMail::defaultLocalfolder() { // QString f = getenv( "HOME" ); QString f = locateLocal( "data", "kopiemail/localmail"); // f += "/Applications/opiemail/localmail"; return f; } QString AbstractMail::draftFolder() { return QString("Drafts"); } /* temporary - will be removed when implemented in all classes */ void AbstractMail::deleteMails(const QString &,const QValueList<Opie::Core::OSmartPointer<RecMail> > &) { } void AbstractMail::deleteMailList(const QValueList<RecMailP>&target) { //qDebug("AbstractMail::deleteMailList:: Please reimplement! "); // this is currently re-implemented in pop3wrapper and imapwrapper int iii = 0; int count = target.count(); QProgressBar wid ( count ); wid.setCaption( tr("Deleting ...")); wid.show(); while (iii < count ) { Global::statusMessage(tr("Delete message %1 of %2").arg(iii).arg(count)); wid.setProgress( iii ); wid.raise(); qApp->processEvents(); RecMailP mail = (*target.at( iii )); deleteMail(mail); ++iii; } } void AbstractMail::downloadNewMails(const FolderP&fromFolder, AbstractMail*targetMail ) { //qDebug("AbstractMail::downloadNewMails %s ", fromFolder->getName().latin1()); // get local folder Account * acc = getAccount(); if ( !acc ) return; QString lfName = acc->getLocalFolder(); if ( lfName.isEmpty() ) lfName = acc->getAccountName(); // create local folder if ( !targetMail->createMbox(lfName)) { QMessageBox::critical(0,tr("Error creating new Folder"), tr("Error while creating new folder\n%1\n\nCancelling action.").arg(lfName)); return; } QValueList<RecMailP> t; listMessages(fromFolder->getName(),t,acc->getMaxMailSize() ); if ( t.count() == 0 ) { Global::statusMessage(tr("There are no new messages")); return; } QValueList<RecMailP> e; targetMail->listMessages(lfName,e,acc->getMaxMailSize() ); //qDebug("target has mails %d ", e.count()); QValueList<RecMailP> n; int iii = 0; int count = t.count(); while (iii < count ) { RecMailP r = (*t.at( iii )); bool found = false; int jjj = 0; int countE = e.count(); while (jjj < countE ) { RecMailP re = (*e.at( jjj )); if ( re->isEqual(r) ) { found = true; break; } ++jjj; } if ( !found ) { + //qDebug("AAAdate *%s* ", r->isodate.latin1() ); n.append( r ); } ++iii; } if ( n.count() == 0 ) { Global::statusMessage(tr("There are no new messages")); return; } mvcpMailList( n,lfName,targetMail,!acc->getLeaveOnServer()); Global::statusMessage(tr("Downloaded %1 messages").arg(n.count())); #if 0 QValueList<RecMailP> t; listMessages(fromFolder->getName(),t, maxSizeInKb); mvcpMailList( t,targetFolder,targetWrapper,moveit); #endif } void AbstractMail::mvcpAllMails(const FolderP&fromFolder, const QString&targetFolder,AbstractMail*targetWrapper,bool moveit, int maxSizeInKb) { QValueList<RecMailP> t; listMessages(fromFolder->getName(),t, maxSizeInKb); mvcpMailList( t,targetFolder,targetWrapper,moveit); } void AbstractMail::mvcpMailList(const QValueList<RecMailP>& t, const QString&targetFolder,AbstractMail*targetWrapper,bool moveit) { encodedString*st = 0; int iii = 0; int count = t.count(); if ( count == 0 ) return; // wel, processevents is qite strange, we need a widget for getting // Global::statusMessage(tr("Copy2 message %1").arg(iii)); displaye QProgressBar wid ( count ); wid.setCaption( tr("Copying ...")); wid.show(); while (iii < count ) { Global::statusMessage(tr("Copy message %1 of %2").arg(iii).arg(count)); wid.setProgress( iii ); wid.raise(); qApp->processEvents(); RecMailP r = (*t.at( iii )); st = fetchRawBody(r); if (st) { targetWrapper->storeMessage(st->Content(),st->Length(),targetFolder); delete st; } ++iii; } if (moveit) { deleteMailList( t ); //deleteAllMail(fromFolder); } } void AbstractMail::mvcpMail(const RecMailP&mail,const QString&targetFolder,AbstractMail*targetWrapper,bool moveit) { encodedString*st = 0; st = fetchRawBody(mail); if (st) { targetWrapper->storeMessage(st->Content(),st->Length(),targetFolder); delete st; } if (moveit) { deleteMail(mail); } } diff --git a/kmicromail/libmailwrapper/genericwrapper.cpp b/kmicromail/libmailwrapper/genericwrapper.cpp index c3a1627..d99c6a3 100644 --- a/kmicromail/libmailwrapper/genericwrapper.cpp +++ b/kmicromail/libmailwrapper/genericwrapper.cpp @@ -1,533 +1,548 @@ // CHANGED 2004-09-31 Lutz Rogowski #include "genericwrapper.h" #include <libetpan/libetpan.h> #include "mailtypes.h" #include <kconfig.h> #include <kglobal.h> #include <kstandarddirs.h> using namespace Opie::Core; Genericwrapper::Genericwrapper() : AbstractMail() { bodyCache.clear(); m_storage = 0; m_folder = 0; } Genericwrapper::~Genericwrapper() { if (m_folder) { mailfolder_free(m_folder); } if (m_storage) { mailstorage_free(m_storage); } cleanMimeCache(); } -QString Genericwrapper::parseDateTime( mailimf_date_time *date ) +const QDateTime Genericwrapper::parseDateTime( mailimf_date_time *date ) { static bool init = false ; if ( ! init ) { KConfig kon ( locateLocal( "config", "korganizerrc" ) ); kon.setGroup("Locale"); KGlobal::locale()->setIntDateFormat( (KLocale::IntDateFormat)kon.readNumEntry( "PreferredDate",0) ); QString dummy = kon.readEntry( "UserDateFormatShort","%aK %d.%m.%y" );// kon.readEntry( ""); KGlobal::locale()->setHore24Format( !kon.readBoolEntry( "PreferredTime",0 ) ); KGlobal::locale()->setDateFormatShort(dummy.replace( QRegExp("K"), QString(",") )); dummy = kon.readEntry( "UserDateFormatLong","%A %d %b %y" ); KGlobal::locale()->setDateFormat(dummy.replace( QRegExp("K"), QString(",") )); kon.setGroup("Time & Date"); KGlobal::locale()->setDaylightSaving( kon.readBoolEntry( "UseDaylightsaving", true ), kon.readNumEntry( "DaylightsavingStart", 90), kon.readNumEntry( "DaylightsavingEnd",304) ); KGlobal::locale()->setTimezone( kon.readEntry( "TimeZoneName" ," 00:00 Europe/London(UTC)") ); init = true; } QDate da (date->dt_year,date->dt_month, date->dt_day ); QTime ti ( date->dt_hour, date->dt_min, date->dt_sec ); QDateTime dt ( da ,ti ); + int addsec = -date->dt_zone*36; + //qDebug("adsec1 %d ",addsec ); + dt = dt.addSecs( addsec ); int off = KGlobal::locale()->localTimeOffset( dt ); - //dt = dt.addSecs( off*60 ); + //qDebug("adsec2 %d ",off*60 ); + + dt = dt.addSecs( off*60 ); + return dt; +#if 0 QString ret; - if ( da == QDate::currentDate () ) - ret = KGlobal::locale()->formatTime( ti,true); + if ( dt.date() == QDate::currentDate () ) + ret = KGlobal::locale()->formatTime( dt.time(),true); else { ret = KGlobal::locale()->formatDateTime( dt,true,true); } +#endif #if 0 if ( off < 0 ) ret += " -"; else ret += " +"; ret += QString::number( off / 60 ); ret += "h"; #endif #if 0 char tmp[23]; // snprintf( tmp, 23, "%02i.%02i.%04i %02i:%02i:%02i %+05i", // date->dt_day, date->dt_month, date->dt_year, date->dt_hour, date->dt_min, date->dt_sec, date->dt_zone ); snprintf( tmp, 23, "%04i-%02i-%02i %02i:%02i:%02i %+05i", date->dt_year,date->dt_month, date->dt_day, date->dt_hour, date->dt_min, date->dt_sec, date->dt_zone ); return QString( tmp ); #endif - return ret; + //return ret; } void Genericwrapper::fillSingleBody(RecPartP&target,mailmessage*,mailmime*mime) { if (!mime) { return; } mailmime_field*field = 0; mailmime_single_fields fields; memset(&fields, 0, sizeof(struct mailmime_single_fields)); if (mime->mm_mime_fields != NULL) { mailmime_single_fields_init(&fields, mime->mm_mime_fields, mime->mm_content_type); } mailmime_content*type = fields.fld_content; clistcell*current; if (!type) { target->setType("text"); target->setSubtype("plain"); } else { target->setSubtype(type->ct_subtype); switch(type->ct_type->tp_data.tp_discrete_type->dt_type) { case MAILMIME_DISCRETE_TYPE_TEXT: target->setType("text"); break; case MAILMIME_DISCRETE_TYPE_IMAGE: target->setType("image"); break; case MAILMIME_DISCRETE_TYPE_AUDIO: target->setType("audio"); break; case MAILMIME_DISCRETE_TYPE_VIDEO: target->setType("video"); break; case MAILMIME_DISCRETE_TYPE_APPLICATION: target->setType("application"); break; case MAILMIME_DISCRETE_TYPE_EXTENSION: default: if (type->ct_type->tp_data.tp_discrete_type->dt_extension) { target->setType(type->ct_type->tp_data.tp_discrete_type->dt_extension); } break; } if (type->ct_parameters) { fillParameters(target,type->ct_parameters); } } if (mime->mm_mime_fields && mime->mm_mime_fields->fld_list) { for (current=clist_begin(mime->mm_mime_fields->fld_list);current!=0;current=clist_next(current)) { field = (mailmime_field*)current->data; switch(field->fld_type) { case MAILMIME_FIELD_TRANSFER_ENCODING: target->setEncoding(getencoding(field->fld_data.fld_encoding)); break; case MAILMIME_FIELD_ID: target->setIdentifier(field->fld_data.fld_id); break; case MAILMIME_FIELD_DESCRIPTION: target->setDescription(field->fld_data.fld_description); break; default: break; } } } } void Genericwrapper::fillParameters(RecPartP&target,clist*parameters) { if (!parameters) {return;} clistcell*current=0; mailmime_parameter*param; for (current=clist_begin(parameters);current!=0;current=clist_next(current)) { param = (mailmime_parameter*)current->data; if (param) { target->addParameter(QString(param->pa_name).lower(),QString(param->pa_value)); } } } QString Genericwrapper::getencoding(mailmime_mechanism*aEnc) { QString enc="7bit"; if (!aEnc) return enc; switch(aEnc->enc_type) { case MAILMIME_MECHANISM_7BIT: enc = "7bit"; break; case MAILMIME_MECHANISM_8BIT: enc = "8bit"; break; case MAILMIME_MECHANISM_BINARY: enc = "binary"; break; case MAILMIME_MECHANISM_QUOTED_PRINTABLE: enc = "quoted-printable"; break; case MAILMIME_MECHANISM_BASE64: enc = "base64"; break; case MAILMIME_MECHANISM_TOKEN: default: if (aEnc->enc_token) { enc = QString(aEnc->enc_token); } break; } return enc; } void Genericwrapper::traverseBody(RecBodyP&target,mailmessage*message,mailmime*mime,QValueList<int>recList,unsigned int current_rec,int current_count) { if (current_rec >= 10) { ; // odebug << "too deep recursion!" << oendl; } if (!message || !mime) { return; } int r; char*data = 0; size_t len; clistiter * cur = 0; QString b; RecPartP part = new RecPart(); switch (mime->mm_type) { case MAILMIME_SINGLE: { QValueList<int>countlist = recList; countlist.append(current_count); r = mailmessage_fetch_section(message,mime,&data,&len); part->setSize(len); part->setPositionlist(countlist); b = gen_attachment_id(); part->setIdentifier(b); fillSingleBody(part,message,mime); if (part->Type()=="text" && target->Bodytext().isNull()) { encodedString*rs = new encodedString(); rs->setContent(data,len); encodedString*res = decode_String(rs,part->Encoding()); if (countlist.count()>2) { bodyCache[b]=rs; target->addPart(part); } else { delete rs; } b = QString(res->Content()); delete res; target->setBodytext(b); target->setDescription(part); } else { bodyCache[b]=new encodedString(data,len); target->addPart(part); } } break; case MAILMIME_MULTIPLE: { unsigned int ccount = 1; mailmime*cbody=0; QValueList<int>countlist = recList; for (cur = clist_begin(mime->mm_data.mm_multipart.mm_mp_list) ; cur != NULL ; cur = clist_next(cur)) { cbody = (mailmime*)clist_content(cur); if (cbody->mm_type==MAILMIME_MULTIPLE) { RecPartP targetPart = new RecPart(); targetPart->setType("multipart"); countlist.append(current_count); targetPart->setPositionlist(countlist); target->addPart(targetPart); } traverseBody(target,message, cbody,countlist,current_rec+1,ccount); if (cbody->mm_type==MAILMIME_MULTIPLE) { countlist = recList; } ++ccount; } } break; case MAILMIME_MESSAGE: { QValueList<int>countlist = recList; countlist.append(current_count); /* the own header is always at recursion 0 - we don't need that */ if (current_rec > 0) { part->setPositionlist(countlist); r = mailmessage_fetch_section(message,mime,&data,&len); part->setSize(len); part->setPositionlist(countlist); b = gen_attachment_id(); part->setIdentifier(b); part->setType("message"); part->setSubtype("rfc822"); bodyCache[b]=new encodedString(data,len); target->addPart(part); } if (mime->mm_data.mm_message.mm_msg_mime != NULL) { traverseBody(target,message,mime->mm_data.mm_message.mm_msg_mime,countlist,current_rec+1); } } break; } } RecBodyP Genericwrapper::parseMail( mailmessage * msg ) { int err = MAILIMF_NO_ERROR; mailmime_single_fields fields; /* is bound to msg and will be freed there */ mailmime * mime=0; RecBodyP body = new RecBody(); memset(&fields, 0, sizeof(struct mailmime_single_fields)); err = mailmessage_get_bodystructure(msg,&mime); QValueList<int>recList; traverseBody(body,msg,mime,recList); return body; } QString Genericwrapper::parseAddressList( mailimf_address_list *list ) { QString result( "" ); bool first = true; if (list == 0) return result; for ( clistiter *current = clist_begin( list->ad_list ); current != NULL; current = current->next ) { mailimf_address *addr = (mailimf_address *) current->data; if ( !first ) { result.append( "," ); } else { first = false; } switch ( addr->ad_type ) { case MAILIMF_ADDRESS_MAILBOX: result.append( parseMailbox( addr->ad_data.ad_mailbox ) ); break; case MAILIMF_ADDRESS_GROUP: result.append( parseGroup( addr->ad_data.ad_group ) ); break; default: ; // odebug << "Generic: unkown mailimf address type" << oendl; break; } } return result; } QString Genericwrapper::parseGroup( mailimf_group *group ) { QString result( "" ); result.append( group->grp_display_name ); result.append( ": " ); if ( group->grp_mb_list != NULL ) { result.append( parseMailboxList( group->grp_mb_list ) ); } result.append( ";" ); return result; } QString Genericwrapper::parseMailbox( mailimf_mailbox *box ) { QString result( "" ); if ( box->mb_display_name == NULL ) { result.append( box->mb_addr_spec ); } else { result.append( convert_String(box->mb_display_name).latin1() ); result.append( " <" ); result.append( box->mb_addr_spec ); result.append( ">" ); } return result; } QString Genericwrapper::parseMailboxList( mailimf_mailbox_list *list ) { QString result( "" ); bool first = true; for ( clistiter *current = clist_begin( list->mb_list ); current != NULL; current = current->next ) { mailimf_mailbox *box = (mailimf_mailbox *) current->data; if ( !first ) { result.append( "," ); } else { first = false; } result.append( parseMailbox( box ) ); } return result; } encodedString* Genericwrapper::fetchDecodedPart(const RecMailP&,const RecPartP&part) { QMap<QString,encodedString*>::ConstIterator it = bodyCache.find(part->Identifier()); if (it==bodyCache.end()) return new encodedString(); encodedString*t = decode_String(it.data(),part->Encoding()); return t; } encodedString* Genericwrapper::fetchRawPart(const RecMailP&,const RecPartP&part) { QMap<QString,encodedString*>::ConstIterator it = bodyCache.find(part->Identifier()); if (it==bodyCache.end()) return new encodedString(); encodedString*t = it.data(); return t; } QString Genericwrapper::fetchTextPart(const RecMailP&mail,const RecPartP&part) { encodedString*t = fetchDecodedPart(mail,part); QString text=t->Content(); delete t; return text; } void Genericwrapper::cleanMimeCache() { QMap<QString,encodedString*>::Iterator it = bodyCache.begin(); for (;it!=bodyCache.end();++it) { encodedString*t = it.data(); //it.setValue(0); if (t) delete t; } bodyCache.clear(); ; // odebug << "Genericwrapper: cache cleaned" << oendl; } QStringList Genericwrapper::parseInreplies(mailimf_in_reply_to * in_replies) { QStringList res; if (!in_replies || !in_replies->mid_list) return res; clistiter * current = 0; for ( current = clist_begin( in_replies->mid_list ); current != NULL; current = current->next ) { QString h((char*)current->data); while (h.length()>0 && h[0]=='<') { h.remove(0,1); } while (h.length()>0 && h[h.length()-1]=='>') { h.remove(h.length()-1,1); } if (h.length()>0) { res.append(h); } } return res; } void Genericwrapper::parseList(QValueList<Opie::Core::OSmartPointer<RecMail> > &target,mailsession*session,const QString&mailbox,bool mbox_as_to, int maxSizeInKb) { int r; mailmessage_list * env_list = 0; r = mailsession_get_messages_list(session,&env_list); if (r != MAIL_NO_ERROR) { ; // odebug << "Error message list" << oendl; return; } r = mailsession_get_envelopes_list(session, env_list); if (r != MAIL_NO_ERROR) { ; // odebug << "Error filling message list" << oendl; if (env_list) { mailmessage_list_free(env_list); } return; } mailimf_references * refs = 0; mailimf_in_reply_to * in_replies = 0; uint32_t i = 0; for(; i < carray_count(env_list->msg_tab) ; ++i) { mailmessage * msg; QBitArray mFlags(7); msg = (mailmessage*)carray_get(env_list->msg_tab, i); if (msg->msg_fields == NULL) { //; // odebug << "could not fetch envelope of message " << i << "" << oendl; continue; } RecMailP mail = new RecMail(); mail->setWrapper(this); mail_flags * flag_result = 0; r = mailmessage_get_flags(msg,&flag_result); if (r == MAIL_ERROR_NOT_IMPLEMENTED) { mFlags.setBit(FLAG_SEEN); } mailimf_single_fields single_fields; mailimf_single_fields_init(&single_fields, msg->msg_fields); mail->setMsgsize(msg->msg_size); mail->setFlags(mFlags); mail->setMbox(mailbox); mail->setNumber(msg->msg_index); if (single_fields.fld_subject) mail->setSubject( convert_String(single_fields.fld_subject->sbj_value)); if (single_fields.fld_from) mail->setFrom(parseMailboxList(single_fields.fld_from->frm_mb_list)); if (!mbox_as_to) { if (single_fields.fld_to) mail->setTo( parseAddressList( single_fields.fld_to->to_addr_list ) ); } else { mail->setTo(mailbox); } if (single_fields.fld_cc) mail->setCC( parseAddressList( single_fields.fld_cc->cc_addr_list ) ); if (single_fields.fld_bcc) mail->setBcc( parseAddressList( single_fields.fld_bcc->bcc_addr_list ) ); if (single_fields.fld_orig_date) { - mail->setDate( parseDateTime( single_fields.fld_orig_date->dt_date_time ) ); - char tmp[23]; - struct mailimf_date_time* date = single_fields.fld_orig_date->dt_date_time; - snprintf( tmp, 23, "%04i-%02i-%02i %02i:%02i:%02i %05i", - date->dt_year,date->dt_month, date->dt_day, date->dt_hour, date->dt_min, date->dt_sec, date->dt_zone ); + QDateTime dt = Genericwrapper::parseDateTime( single_fields.fld_orig_date->dt_date_time ); + QString ret; + if ( dt.date() == QDate::currentDate () ) + ret = KGlobal::locale()->formatTime( dt.time(),true); + else { + ret = KGlobal::locale()->formatDateTime( dt,true,true); + } + mail->setDate( ret ); + char tmp[20]; + snprintf( tmp, 20, "%04i-%02i-%02i %02i:%02i:%02i", + dt.date().year(),dt.date().month(), dt.date().day(), dt.time().hour(), dt.time().minute(), dt.time().second() ); + //qDebug(" iso %s ", tmp); mail->setIsoDate( QString( tmp ) ); } // crashes when accessing pop3 account? if (single_fields.fld_message_id) { mail->setMsgid(QString(single_fields.fld_message_id->mid_value)); ; // odebug << "Msgid == " << mail->Msgid().latin1() << "" << oendl; } if (single_fields.fld_reply_to) { QStringList t = parseAddressList(single_fields.fld_reply_to->rt_addr_list); if (t.count()>0) { mail->setReplyto(t[0]); } } #if 0 refs = single_fields.fld_references; if (refs && refs->mid_list && clist_count(refs->mid_list)) { char * text = (char*)refs->mid_list->first->data; mail->setReplyto(QString(text)); } #endif if (single_fields.fld_in_reply_to && single_fields.fld_in_reply_to->mid_list && clist_count(single_fields.fld_in_reply_to->mid_list)) { mail->setInreply(parseInreplies(single_fields.fld_in_reply_to)); } if ( maxSizeInKb == 0 || mail->Msgsize()<=maxSizeInKb*1024 ) target.append(mail); } if (env_list) { mailmessage_list_free(env_list); } } diff --git a/kmicromail/libmailwrapper/genericwrapper.h b/kmicromail/libmailwrapper/genericwrapper.h index 244212f..c35a6da 100644 --- a/kmicromail/libmailwrapper/genericwrapper.h +++ b/kmicromail/libmailwrapper/genericwrapper.h @@ -1,68 +1,68 @@ // CHANGED 2004-09-31 Lutz Rogowski #ifndef __GENERIC_WRAPPER_H #define __GENERIC_WRAPPER_H #include "abstractmail.h" #include <qmap.h> #include <qstring.h> #include <libetpan/clist.h> class RecMail; class RecBody; class encodedString; struct mailpop3; struct mailmessage; struct mailmime; struct mailmime_mechanism; struct mailimf_mailbox_list; struct mailimf_mailbox; struct mailimf_date_time; struct mailimf_group; struct mailimf_address_list; struct mailsession; struct mailstorage; struct mailfolder; struct mailimf_in_reply_to; /* this class hold just the funs shared between * mbox and pop3 (later mh, too) mail access. * it is not desigend to make a instance of it! */ class Genericwrapper : public AbstractMail { Q_OBJECT public: Genericwrapper(); virtual ~Genericwrapper(); virtual encodedString* fetchDecodedPart(const RecMailP&mail,const RecPartP&part); virtual encodedString* fetchRawPart(const RecMailP&mail,const RecPartP&part); virtual QString fetchTextPart(const RecMailP&mail,const RecPartP&part); virtual void cleanMimeCache(); virtual int deleteMbox(const Opie::Core::OSmartPointer<Folder>&){return 1;} virtual void logout(){}; virtual void storeMessage(const char*msg,size_t length, const QString&folder){}; - static QString parseDateTime( mailimf_date_time *date ); + static const QDateTime parseDateTime( mailimf_date_time *date ); protected: RecBodyP parseMail( mailmessage * msg ); QString parseMailboxList( mailimf_mailbox_list *list ); QString parseMailbox( mailimf_mailbox *box ); QString parseGroup( mailimf_group *group ); QString parseAddressList( mailimf_address_list *list ); void traverseBody(RecBodyP&target,mailmessage*message,mailmime*mime,QValueList<int>recList,unsigned int current_rek=0,int current_count=1); static void fillSingleBody(RecPartP&target,mailmessage*message,mailmime*mime); static void fillParameters(RecPartP&target,clist*parameters); static QString getencoding(mailmime_mechanism*aEnc); virtual void parseList(QValueList<Opie::Core::OSmartPointer<RecMail> > &target,mailsession*session,const QString&mailbox,bool mbox_as_to=false, int maxSizeInKb = 0); QStringList parseInreplies(mailimf_in_reply_to * in_replies); QString msgTempName; unsigned int last_msg_id; QMap<QString,encodedString*> bodyCache; mailstorage * m_storage; mailfolder*m_folder; }; #endif diff --git a/kmicromail/libmailwrapper/imapwrapper.cpp b/kmicromail/libmailwrapper/imapwrapper.cpp index d79df4f..b0dd1b8 100644 --- a/kmicromail/libmailwrapper/imapwrapper.cpp +++ b/kmicromail/libmailwrapper/imapwrapper.cpp @@ -1,1310 +1,1319 @@ // CHANGED 2004-09-31 Lutz Rogowski #include <stdlib.h> #include <libetpan/libetpan.h> #include <qpe/global.h> #include <qapplication.h> #include "imapwrapper.h" #include "mailtypes.h" #include "logindialog.h" #include <qprogressbar.h> #include "genericwrapper.h" +#include <kglobal.h> using namespace Opie::Core; int IMAPwrapper::mMax = 0; int IMAPwrapper::mCurrent = 0; IMAPwrapper::IMAPwrapper( IMAPaccount *a ) : AbstractMail() { account = a; m_imap = 0; m_Lastmbox = ""; mCurrent = 0; mMax = 0; } IMAPwrapper::~IMAPwrapper() { logout(); } /* to avoid to often select statements in loops etc. we trust that we are logged in and connection is established!*/ int IMAPwrapper::selectMbox(const QString&mbox) { if (mbox == m_Lastmbox) { return MAILIMAP_NO_ERROR; } int err = mailimap_select( m_imap, (char*)mbox.latin1()); if ( err != MAILIMAP_NO_ERROR ) { m_Lastmbox = ""; return err; } m_Lastmbox = mbox; return err; } void IMAPwrapper::imap_progress( size_t current, size_t maximum ) { //qDebug("imap progress %d of %d ",current,maximum ); //Global::statusMessage(tr("Downloading message %1 of %2").arg( current).arg(maximum)); //qApp->processEvents() static int last = 0; if ( last != current ) IMAPwrapper::progress(); last = current; } void IMAPwrapper::progress( QString m ) { static QString mProgrMess; if ( m != QString::null ) { mProgrMess = m; mCurrent = 0; return; } QString mess; //qDebug("progress "); if ( mMax ) mess = mProgrMess +tr(" message %1 of %2").arg( mCurrent++).arg(mMax); else mess = mProgrMess +tr(" message %1").arg( mCurrent++); Global::statusMessage(mess); qApp->processEvents(); } bool IMAPwrapper::start_tls(bool force_tls) { int err; bool try_tls; mailimap_capability_data * cap_data = 0; err = mailimap_capability(m_imap,&cap_data); if (err != MAILIMAP_NO_ERROR) { Global::statusMessage("error getting capabilities!"); return false; } clistiter * cur; for(cur = clist_begin(cap_data->cap_list) ; cur != NULL;cur = clist_next(cur)) { struct mailimap_capability * cap; cap = (struct mailimap_capability *)clist_content(cur); if (cap->cap_type == MAILIMAP_CAPABILITY_NAME) { if (strcasecmp(cap->cap_data.cap_name, "STARTTLS") == 0) { try_tls = true; break; } } } if (cap_data) { mailimap_capability_data_free(cap_data); } if (try_tls) { err = mailimap_starttls(m_imap); if (err != MAILIMAP_NO_ERROR && force_tls) { Global::statusMessage(tr("Server has no TLS support!")); try_tls = false; } else { mailstream_low * low; mailstream_low * new_low; low = mailstream_get_low(m_imap->imap_stream); if (!low) { try_tls = false; } else { int fd = mailstream_low_get_fd(low); if (fd > -1 && (new_low = mailstream_low_ssl_open(fd))!=0) { mailstream_low_free(low); mailstream_set_low(m_imap->imap_stream, new_low); } else { try_tls = false; } } } } return try_tls; } void IMAPwrapper::login() { QString server, user, pass; uint16_t port; int err = MAILIMAP_NO_ERROR; if (account->getOffline()) return; /* we are connected this moment */ /* TODO: setup a timer holding the line or if connection closed - delete the value */ if (m_imap) { err = mailimap_noop(m_imap); if (err!=MAILIMAP_NO_ERROR) { logout(); } else { mailstream_flush(m_imap->imap_stream); return; } } server = account->getServer(); port = account->getPort().toUInt(); if ( account->getUser().isEmpty() || account->getPassword().isEmpty() ) { LoginDialog login( account->getUser(), account->getPassword(), NULL, 0, true ); login.show(); if ( QDialog::Accepted == login.exec() ) { // ok user = login.getUser(); pass = login.getPassword(); } else { // cancel return; } } else { user = account->getUser(); pass = account->getPassword(); } m_imap = mailimap_new( 20, &imap_progress ); /* connect */ bool ssl = false; bool try_tls = false; bool force_tls = false; if ( account->ConnectionType() == 2 ) { ssl = true; } if (account->ConnectionType()==1) { force_tls = true; } if ( ssl ) { //qDebug("using ssl "); err = mailimap_ssl_connect( m_imap, (char*)server.latin1(), port ); } else { err = mailimap_socket_connect( m_imap, (char*)server.latin1(), port ); } if ( err != MAILIMAP_NO_ERROR && err != MAILIMAP_NO_ERROR_AUTHENTICATED && err != MAILIMAP_NO_ERROR_NON_AUTHENTICATED ) { QString failure = ""; if (err == MAILIMAP_ERROR_CONNECTION_REFUSED) { failure="Connection refused"; } else { failure="Unknown failure"; } Global::statusMessage(tr("error connecting imap server: %1").arg(failure)); mailimap_free( m_imap ); m_imap = 0; return; } if (!ssl) { try_tls = start_tls(force_tls); } bool ok = true; if (force_tls && !try_tls) { Global::statusMessage(tr("Server has no TLS support!")); ok = false; } /* login */ if (ok) { err = mailimap_login_simple( m_imap, (char*)user.latin1(), (char*)pass.latin1() ); if ( err != MAILIMAP_NO_ERROR ) { Global::statusMessage(tr("error logging in imap server: %1").arg(m_imap->imap_response)); ok = false; } } if (!ok) { err = mailimap_close( m_imap ); mailimap_free( m_imap ); m_imap = 0; } } void IMAPwrapper::logout() { int err = MAILIMAP_NO_ERROR; if (!m_imap) return; err = mailimap_logout( m_imap ); err = mailimap_close( m_imap ); mailimap_free( m_imap ); m_imap = 0; m_Lastmbox = ""; } void IMAPwrapper::listMessages(const QString&mailbox,QValueList<Opie::Core::OSmartPointer<RecMail> > &target , int maxSizeInKb) { int err = MAILIMAP_NO_ERROR; clist *result = 0; clistcell *current; mailimap_fetch_type *fetchType = 0; mailimap_set *set = 0; login(); if (!m_imap) { return; } /* select mailbox READONLY for operations */ err = selectMbox(mailbox); if ( err != MAILIMAP_NO_ERROR ) { return; } int last = m_imap->imap_selection_info->sel_exists; if (last == 0) { Global::statusMessage(tr("Mailbox has no mails")); return; } else { } Global::statusMessage(tr("Fetching header list")); qApp->processEvents(); /* the range has to start at 1!!! not with 0!!!! */ set = mailimap_set_new_interval( 1, last ); fetchType = mailimap_fetch_type_new_fetch_att_list_empty(); mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_envelope()); mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_flags()); mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_internaldate()); mailimap_fetch_type_new_fetch_att_list_add(fetchType,mailimap_fetch_att_new_rfc822_size()); err = mailimap_fetch( m_imap, set, fetchType, &result ); mailimap_set_free( set ); mailimap_fetch_type_free( fetchType ); QString date,subject,from; if ( err == MAILIMAP_NO_ERROR ) { mailimap_msg_att * msg_att; int i = 0; for (current = clist_begin(result); current != 0; current=clist_next(current)) { ++i; msg_att = (mailimap_msg_att*)current->data; RecMail*m = parse_list_result(msg_att); if (m) { if ( maxSizeInKb == 0 || m->Msgsize()<=maxSizeInKb*1024 ) { m->setNumber(i); m->setMbox(mailbox); m->setWrapper(this); target.append(m); } } } Global::statusMessage(tr("Mailbox has %1 mails").arg(target.count())); } else { Global::statusMessage(tr("Error fetching headers: %1").arg(m_imap->imap_response)); } if (result) mailimap_fetch_list_free(result); } QValueList<Opie::Core::OSmartPointer<Folder> >* IMAPwrapper::listFolders() { const char *path, *mask; int err = MAILIMAP_NO_ERROR; clist *result = 0; clistcell *current = 0; clistcell*cur_flag = 0; mailimap_mbx_list_flags*bflags = 0; QValueList<FolderP>* folders = new QValueList<FolderP>(); login(); if (!m_imap) { return folders; } /* * First we have to check for INBOX 'cause it sometimes it's not inside the path. * We must not forget to filter them out in next loop! * it seems like ugly code. and yes - it is ugly code. but the best way. */ Global::statusMessage(tr("Fetching folder list")); qApp->processEvents(); QString temp; mask = "INBOX" ; mailimap_mailbox_list *list; err = mailimap_list( m_imap, (char*)"", (char*)mask, &result ); QString del; bool selectable = true; bool no_inferiors = false; if ( err == MAILIMAP_NO_ERROR ) { current = result->first; for ( int i = result->count; i > 0; i-- ) { list = (mailimap_mailbox_list *) current->data; // it is better use the deep copy mechanism of qt itself // instead of using strdup! temp = list->mb_name; del = list->mb_delimiter; current = current->next; if ( (bflags = list->mb_flag) ) { selectable = !(bflags->mbf_type==MAILIMAP_MBX_LIST_FLAGS_SFLAG&& bflags->mbf_sflag==MAILIMAP_MBX_LIST_SFLAG_NOSELECT); for(cur_flag=clist_begin(bflags->mbf_oflags);cur_flag;cur_flag=clist_next(cur_flag)) { if ( ((mailimap_mbx_list_oflag*)cur_flag->data)->of_type==MAILIMAP_MBX_LIST_OFLAG_NOINFERIORS) { no_inferiors = true; } } } folders->append( new IMAPFolder(temp,del,selectable,no_inferiors,account->getPrefix())); } } else { qDebug("error fetching folders: "); } mailimap_list_result_free( result ); /* * second stage - get the other then inbox folders */ mask = "*" ; path = account->getPrefix().latin1(); if (!path) path = ""; err = mailimap_list( m_imap, (char*)path, (char*)mask, &result ); if ( err == MAILIMAP_NO_ERROR ) { current = result->first; for ( current=clist_begin(result);current!=NULL;current=clist_next(current)) { no_inferiors = false; list = (mailimap_mailbox_list *) current->data; // it is better use the deep copy mechanism of qt itself // instead of using strdup! temp = list->mb_name; if (temp.lower()=="inbox") continue; if (temp.lower()==account->getPrefix().lower()) continue; if ( (bflags = list->mb_flag) ) { selectable = !(bflags->mbf_type==MAILIMAP_MBX_LIST_FLAGS_SFLAG&& bflags->mbf_sflag==MAILIMAP_MBX_LIST_SFLAG_NOSELECT); for(cur_flag=clist_begin(bflags->mbf_oflags);cur_flag;cur_flag=clist_next(cur_flag)) { if ( ((mailimap_mbx_list_oflag*)cur_flag->data)->of_type==MAILIMAP_MBX_LIST_OFLAG_NOINFERIORS) { no_inferiors = true; } } } del = list->mb_delimiter; folders->append(new IMAPFolder(temp,del,selectable,no_inferiors,account->getPrefix())); } } else { qDebug("error fetching folders "); } if (result) mailimap_list_result_free( result ); return folders; } RecMail*IMAPwrapper::parse_list_result(mailimap_msg_att* m_att) { RecMail * m = 0; mailimap_msg_att_item *item=0; clistcell *current,*c,*cf; mailimap_msg_att_dynamic*flist; mailimap_flag_fetch*cflag; int size; QBitArray mFlags(7); QStringList addresslist; if (!m_att) { return m; } m = new RecMail(); for (c = clist_begin(m_att->att_list); c!=NULL;c=clist_next(c) ) { current = c; size = 0; item = (mailimap_msg_att_item*)current->data; if ( !item ) continue; if (item->att_type!=MAILIMAP_MSG_ATT_ITEM_STATIC) { flist = (mailimap_msg_att_dynamic*)item->att_data.att_dyn; if (!flist || !flist->att_list) { continue; } cf = flist->att_list->first; if( ! cf ) for (cf = clist_begin(flist->att_list); cf!=NULL; cf = clist_next(cf)) { cflag = (mailimap_flag_fetch*)cf->data; if( ! cflag ) qDebug("imap:not cflag "); if (cflag->fl_type==MAILIMAP_FLAG_FETCH_OTHER && cflag->fl_flag!=0) { switch (cflag->fl_flag->fl_type) { case MAILIMAP_FLAG_ANSWERED: /* \Answered flag */ mFlags.setBit(FLAG_ANSWERED); break; case MAILIMAP_FLAG_FLAGGED: /* \Flagged flag */ mFlags.setBit(FLAG_FLAGGED); break; case MAILIMAP_FLAG_DELETED: /* \Deleted flag */ mFlags.setBit(FLAG_DELETED); break; case MAILIMAP_FLAG_SEEN: /* \Seen flag */ mFlags.setBit(FLAG_SEEN); break; case MAILIMAP_FLAG_DRAFT: /* \Draft flag */ mFlags.setBit(FLAG_DRAFT); break; case MAILIMAP_FLAG_KEYWORD: /* keyword flag */ break; case MAILIMAP_FLAG_EXTENSION: /* \extension flag */ break; default: break; } } else if (cflag->fl_type==MAILIMAP_FLAG_FETCH_RECENT) { mFlags.setBit(FLAG_RECENT); } } continue; } if ( item->att_data.att_static == NULL ) continue; if (item->att_data.att_static->att_type==MAILIMAP_MSG_ATT_ENVELOPE) { mailimap_envelope * head = item->att_data.att_static->att_data.att_env; if ( head == NULL ) continue; if ( head->env_date != NULL ) { m->setDate(head->env_date); struct mailimf_date_time result; struct mailimf_date_time* date = &result; struct mailimf_date_time **re = &date; size_t length = m->getDate().length(); size_t index = 0; if ( mailimf_date_time_parse(head->env_date, length,&index, re ) == MAILIMF_NO_ERROR ) { - m->setDate( Genericwrapper::parseDateTime( date ) ); - char tmp[23]; - snprintf( tmp, 23, "%04i-%02i-%02i %02i:%02i:%02i %05i", - date->dt_year,date->dt_month, date->dt_day, date->dt_hour, date->dt_min, date->dt_sec, date->dt_zone ); + QDateTime dt = Genericwrapper::parseDateTime( date ); + QString ret; + if ( dt.date() == QDate::currentDate () ) + ret = KGlobal::locale()->formatTime( dt.time(),true); + else { + ret = KGlobal::locale()->formatDateTime( dt,true,true); + } + m->setDate( ret ); + char tmp[20]; + snprintf( tmp, 20, "%04i-%02i-%02i %02i:%02i:%02i", + dt.date().year(),dt.date().month(), dt.date().day(), dt.time().hour(), dt.time().minute(), dt.time().second() ); + //qDebug("%d iso %s %s ", date->dt_zone, tmp, head->env_date); m->setIsoDate( QString( tmp ) ); } else { m->setIsoDate(head->env_date); } } if ( head->env_subject != NULL ) m->setSubject(convert_String((const char*)head->env_subject)); //m->setSubject(head->env_subject); if (head->env_from!=NULL) { addresslist = address_list_to_stringlist(head->env_from->frm_list); if (addresslist.count()) { m->setFrom(addresslist.first()); } } if (head->env_to!=NULL) { addresslist = address_list_to_stringlist(head->env_to->to_list); m->setTo(addresslist); } if (head->env_cc!=NULL) { addresslist = address_list_to_stringlist(head->env_cc->cc_list); m->setCC(addresslist); } if (head->env_bcc!=NULL) { addresslist = address_list_to_stringlist(head->env_bcc->bcc_list); m->setBcc(addresslist); } /* reply to address, eg. email. */ if (head->env_reply_to!=NULL) { addresslist = address_list_to_stringlist(head->env_reply_to->rt_list); if (addresslist.count()) { m->setReplyto(addresslist.first()); } } if (head->env_in_reply_to!=NULL) { QString h(head->env_in_reply_to); while (h.length()>0 && h[0]=='<') { h.remove(0,1); } while (h.length()>0 && h[h.length()-1]=='>') { h.remove(h.length()-1,1); } if (h.length()>0) { m->setInreply(QStringList(h)); } } if (head->env_message_id != NULL) { m->setMsgid(QString(head->env_message_id)); } } else if (item->att_data.att_static->att_type==MAILIMAP_MSG_ATT_INTERNALDATE) { #if 0 mailimap_date_time*d = item->att_data.att_static->att_data.att_internal_date; QDateTime da(QDate(d->dt_year,d->dt_month,d->dt_day),QTime(d->dt_hour,d->dt_min,d->dt_sec)); qDebug("time %s ",da.toString().latin1() ); #endif } else if (item->att_data.att_static->att_type==MAILIMAP_MSG_ATT_RFC822_SIZE) { size = item->att_data.att_static->att_data.att_rfc822_size; } } /* msg is already deleted */ if (mFlags.testBit(FLAG_DELETED) && m) { delete m; m = 0; } if (m) { m->setFlags(mFlags); m->setMsgsize(size); } return m; } RecBodyP IMAPwrapper::fetchBody(const RecMailP&mail) { RecBodyP body = new RecBody(); const char *mb; int err = MAILIMAP_NO_ERROR; clist *result = 0; clistcell *current; mailimap_fetch_att *fetchAtt = 0; mailimap_fetch_type *fetchType = 0; mailimap_set *set = 0; mailimap_body*body_desc = 0; mb = mail->getMbox().latin1(); login(); if (!m_imap) { return body; } err = selectMbox(mail->getMbox()); if ( err != MAILIMAP_NO_ERROR ) { return body; } /* the range has to start at 1!!! not with 0!!!! */ set = mailimap_set_new_interval( mail->getNumber(),mail->getNumber() ); fetchAtt = mailimap_fetch_att_new_bodystructure(); fetchType = mailimap_fetch_type_new_fetch_att(fetchAtt); err = mailimap_fetch( m_imap, set, fetchType, &result ); mailimap_set_free( set ); mailimap_fetch_type_free( fetchType ); if (err == MAILIMAP_NO_ERROR && (current=clist_begin(result)) ) { mailimap_msg_att * msg_att; msg_att = (mailimap_msg_att*)current->data; mailimap_msg_att_item*item = (mailimap_msg_att_item*)msg_att->att_list->first->data; QValueList<int> path; body_desc = item->att_data.att_static->att_data.att_body; traverseBody(mail,body_desc,body,0,path); } else { //odebug << "error fetching body: " << m_imap->imap_response << "" << oendl; } if (result) mailimap_fetch_list_free(result); return body; } QStringList IMAPwrapper::address_list_to_stringlist(clist*list) { QStringList l; QString from; bool named_from; clistcell *current = NULL; mailimap_address * current_address=NULL; if (!list) { return l; } unsigned int count = 0; for (current=clist_begin(list);current!= NULL;current=clist_next(current)) { from = ""; named_from = false; current_address=(mailimap_address*)current->data; if (current_address->ad_personal_name){ from+=convert_String((const char*)current_address->ad_personal_name); from+=" "; named_from = true; } if (named_from && (current_address->ad_mailbox_name || current_address->ad_host_name)) { from+="<"; } if (current_address->ad_mailbox_name) { from+=QString(current_address->ad_mailbox_name); from+="@"; } if (current_address->ad_host_name) { from+=QString(current_address->ad_host_name); } if (named_from && (current_address->ad_mailbox_name || current_address->ad_host_name)) { from+=">"; } l.append(QString(from)); if (++count > 99) { break; } } return l; } encodedString*IMAPwrapper::fetchRawPart(const RecMailP&mail,const QValueList<int>&path,bool internal_call) { encodedString*res=new encodedString; int err; mailimap_fetch_type *fetchType; mailimap_set *set; clistcell*current,*cur; mailimap_section_part * section_part = 0; mailimap_section_spec * section_spec = 0; mailimap_section * section = 0; mailimap_fetch_att * fetch_att = 0; login(); if (!m_imap) { return res; } if (!internal_call) { err = selectMbox(mail->getMbox()); if ( err != MAILIMAP_NO_ERROR ) { return res; } } set = mailimap_set_new_single(mail->getNumber()); clist*id_list = 0; /* if path == empty then its a request for the whole rfc822 mail and generates a "fetch <id> (body[])" statement on imap server */ if (path.count()>0 ) { id_list = clist_new(); for (unsigned j=0; j < path.count();++j) { uint32_t * p_id = (uint32_t *)malloc(sizeof(*p_id)); *p_id = path[j]; clist_append(id_list,p_id); } section_part = mailimap_section_part_new(id_list); section_spec = mailimap_section_spec_new(MAILIMAP_SECTION_SPEC_SECTION_PART, NULL, section_part, NULL); } section = mailimap_section_new(section_spec); fetch_att = mailimap_fetch_att_new_body_section(section); fetchType = mailimap_fetch_type_new_fetch_att(fetch_att); clist*result = 0; err = mailimap_fetch( m_imap, set, fetchType, &result ); mailimap_set_free( set ); mailimap_fetch_type_free( fetchType ); if (err == MAILIMAP_NO_ERROR && (current=clist_begin(result)) ) { mailimap_msg_att * msg_att; msg_att = (mailimap_msg_att*)current->data; mailimap_msg_att_item*msg_att_item; for(cur = clist_begin(msg_att->att_list) ; cur != NULL ; cur = clist_next(cur)) { msg_att_item = (mailimap_msg_att_item*)clist_content(cur); if (msg_att_item->att_type == MAILIMAP_MSG_ATT_ITEM_STATIC) { if (msg_att_item->att_data.att_static->att_type == MAILIMAP_MSG_ATT_BODY_SECTION) { char*text = msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part; /* detach - we take over the content */ msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part = 0L; res->setContent(text,msg_att_item->att_data.att_static->att_data.att_body_section->sec_length); } } } } else { ;//odebug << "error fetching text: " << m_imap->imap_response << "" << oendl; } if (result) mailimap_fetch_list_free(result); return res; } /* current_recursion is for recursive calls. current_count means the position inside the internal loop! */ void IMAPwrapper::traverseBody(const RecMailP&mail,mailimap_body*body,RecBodyP&target_body, int current_recursion,QValueList<int>recList,int current_count) { if (!body || current_recursion>=10) { return; } switch (body->bd_type) { case MAILIMAP_BODY_1PART: { QValueList<int>countlist = recList; countlist.append(current_count); RecPartP currentPart = new RecPart(); mailimap_body_type_1part*part1 = body->bd_data.bd_body_1part; QString id(""); currentPart->setPositionlist(countlist); for (unsigned int j = 0; j < countlist.count();++j) { id+=(j>0?" ":""); id+=QString("%1").arg(countlist[j]); } //odebug << "ID = " << id.latin1() << "" << oendl; currentPart->setIdentifier(id); fillSinglePart(currentPart,part1); /* important: Check for is NULL 'cause a body can be empty! And we put it only into the mail if it is the FIRST part */ if (part1->bd_type==MAILIMAP_BODY_TYPE_1PART_TEXT && target_body->Bodytext().isNull() && countlist[0]==1) { QString body_text = fetchTextPart(mail,countlist,true,currentPart->Encoding()); target_body->setDescription(currentPart); target_body->setBodytext(body_text); if (countlist.count()>1) { target_body->addPart(currentPart); } } else { target_body->addPart(currentPart); } if (part1->bd_type==MAILIMAP_BODY_TYPE_1PART_MSG) { traverseBody(mail,part1->bd_data.bd_type_msg->bd_body,target_body,current_recursion+1,countlist); } } break; case MAILIMAP_BODY_MPART: { QValueList<int>countlist = recList; clistcell*current=0; mailimap_body*current_body=0; unsigned int ccount = 1; mailimap_body_type_mpart*mailDescription = body->bd_data.bd_body_mpart; for (current=clist_begin(mailDescription->bd_list);current!=0;current=clist_next(current)) { current_body = (mailimap_body*)current->data; if (current_body->bd_type==MAILIMAP_BODY_MPART) { RecPartP targetPart = new RecPart(); targetPart->setType("multipart"); fillMultiPart(targetPart,mailDescription); countlist.append(current_count); targetPart->setPositionlist(countlist); target_body->addPart(targetPart); QString id(""); for (unsigned int j = 0; j < countlist.count();++j) { id+=(j>0?" ":""); id+=QString("%1").arg(countlist[j]); } // odebug << "ID(mpart) = " << id.latin1() << "" << oendl; } traverseBody(mail,current_body,target_body,current_recursion+1,countlist,ccount); if (current_body->bd_type==MAILIMAP_BODY_MPART) { countlist = recList; } ++ccount; } } break; default: break; } } void IMAPwrapper::fillSinglePart(RecPartP&target_part,mailimap_body_type_1part*Description) { if (!Description) { return; } switch (Description->bd_type) { case MAILIMAP_BODY_TYPE_1PART_TEXT: target_part->setType("text"); fillSingleTextPart(target_part,Description->bd_data.bd_type_text); break; case MAILIMAP_BODY_TYPE_1PART_BASIC: fillSingleBasicPart(target_part,Description->bd_data.bd_type_basic); break; case MAILIMAP_BODY_TYPE_1PART_MSG: target_part->setType("message"); fillSingleMsgPart(target_part,Description->bd_data.bd_type_msg); break; default: break; } } void IMAPwrapper::fillSingleTextPart(RecPartP&target_part,mailimap_body_type_text*which) { if (!which) { return; } QString sub; sub = which->bd_media_text; //odebug << "Type= text/" << which->bd_media_text << "" << oendl; target_part->setSubtype(sub.lower()); target_part->setLines(which->bd_lines); fillBodyFields(target_part,which->bd_fields); } void IMAPwrapper::fillSingleMsgPart(RecPartP&target_part,mailimap_body_type_msg*which) { if (!which) { return; } target_part->setSubtype("rfc822"); //odebug << "Message part" << oendl; /* we set this type to text/plain */ target_part->setLines(which->bd_lines); fillBodyFields(target_part,which->bd_fields); } void IMAPwrapper::fillMultiPart(RecPartP&target_part,mailimap_body_type_mpart*which) { if (!which) return; QString sub = which->bd_media_subtype; target_part->setSubtype(sub.lower()); if (which->bd_ext_mpart && which->bd_ext_mpart->bd_parameter && which->bd_ext_mpart->bd_parameter->pa_list) { clistcell*cur = 0; mailimap_single_body_fld_param*param=0; for (cur = clist_begin(which->bd_ext_mpart->bd_parameter->pa_list);cur!=NULL;cur=clist_next(cur)) { param = (mailimap_single_body_fld_param*)cur->data; if (param) { target_part->addParameter(QString(param->pa_name).lower(),QString(param->pa_value)); } } } } void IMAPwrapper::fillSingleBasicPart(RecPartP&target_part,mailimap_body_type_basic*which) { if (!which) { return; } QString type,sub; switch (which->bd_media_basic->med_type) { case MAILIMAP_MEDIA_BASIC_APPLICATION: type = "application"; break; case MAILIMAP_MEDIA_BASIC_AUDIO: type = "audio"; break; case MAILIMAP_MEDIA_BASIC_IMAGE: type = "image"; break; case MAILIMAP_MEDIA_BASIC_MESSAGE: type = "message"; break; case MAILIMAP_MEDIA_BASIC_VIDEO: type = "video"; break; case MAILIMAP_MEDIA_BASIC_OTHER: default: if (which->bd_media_basic->med_basic_type) { type = which->bd_media_basic->med_basic_type; } else { type = ""; } break; } if (which->bd_media_basic->med_subtype) { sub = which->bd_media_basic->med_subtype; } else { sub = ""; } // odebug << "Type = " << type.latin1() << "/" << sub.latin1() << "" << oendl; target_part->setType(type.lower()); target_part->setSubtype(sub.lower()); fillBodyFields(target_part,which->bd_fields); } void IMAPwrapper::fillBodyFields(RecPartP&target_part,mailimap_body_fields*which) { if (!which) return; if (which->bd_parameter && which->bd_parameter->pa_list && which->bd_parameter->pa_list->count>0) { clistcell*cur; mailimap_single_body_fld_param*param=0; for (cur = clist_begin(which->bd_parameter->pa_list);cur!=NULL;cur=clist_next(cur)) { param = (mailimap_single_body_fld_param*)cur->data; if (param) { target_part->addParameter(QString(param->pa_name).lower(),QString(param->pa_value)); } } } mailimap_body_fld_enc*enc = which->bd_encoding; QString encoding(""); switch (enc->enc_type) { case MAILIMAP_BODY_FLD_ENC_7BIT: encoding = "7bit"; break; case MAILIMAP_BODY_FLD_ENC_8BIT: encoding = "8bit"; break; case MAILIMAP_BODY_FLD_ENC_BINARY: encoding="binary"; break; case MAILIMAP_BODY_FLD_ENC_BASE64: encoding="base64"; break; case MAILIMAP_BODY_FLD_ENC_QUOTED_PRINTABLE: encoding="quoted-printable"; break; case MAILIMAP_BODY_FLD_ENC_OTHER: default: if (enc->enc_value) { char*t=enc->enc_value; encoding=QString(enc->enc_value); enc->enc_value=0L; free(t); } } if (which->bd_description) { target_part->setDescription(QString(which->bd_description)); } target_part->setEncoding(encoding); target_part->setSize(which->bd_size); } void IMAPwrapper::deleteMailList(const QValueList<RecMailP>&target) { //#if 0 mailimap_flag_list*flist; mailimap_set *set; mailimap_store_att_flags * store_flags; int err; login(); //#endif if (!m_imap) { return; } int iii = 0; int count = target.count(); // qDebug("imap remove count %d ", count); mMax = count; //progress( tr("Delete")); QProgressBar wid ( count ); wid.setCaption( tr("Deleting ...")); wid.show(); while (iii < count ) { Global::statusMessage(tr("Delete message %1 of %2").arg(iii).arg(count)); wid.setProgress( iii ); wid.raise(); qApp->processEvents(); RecMailP mail = (*target.at( iii )); //#if 0 //qDebug("IMAP remove %d %d ", iii, mail->getNumber() ); err = selectMbox(mail->getMbox()); if ( err != MAILIMAP_NO_ERROR ) { return; } flist = mailimap_flag_list_new_empty(); mailimap_flag_list_add(flist,mailimap_flag_new_deleted()); store_flags = mailimap_store_att_flags_new_set_flags(flist); set = mailimap_set_new_single(mail->getNumber()); err = mailimap_store(m_imap,set,store_flags); mailimap_set_free( set ); mailimap_store_att_flags_free(store_flags); if (err != MAILIMAP_NO_ERROR) { // odebug << "error deleting mail: " << m_imap->imap_response << "" << oendl; return; } // odebug << "deleting mail: " << m_imap->imap_response << "" << oendl; /* should we realy do that at this moment? */ // err = mailimap_expunge(m_imap); //if (err != MAILIMAP_NO_ERROR) { // Global::statusMessage(tr("Error deleting mails: %s").arg(m_imap->imap_response)); // } //#endif //deleteMail( mail); ++iii; } //qDebug("Deleting imap mails... "); err = mailimap_expunge(m_imap); if (err != MAILIMAP_NO_ERROR) { Global::statusMessage(tr("Error deleting mails: %s").arg(m_imap->imap_response)); } } void IMAPwrapper::deleteMail(const RecMailP&mail) { mailimap_flag_list*flist; mailimap_set *set; mailimap_store_att_flags * store_flags; int err; login(); if (!m_imap) { return; } err = selectMbox(mail->getMbox()); if ( err != MAILIMAP_NO_ERROR ) { return; } flist = mailimap_flag_list_new_empty(); mailimap_flag_list_add(flist,mailimap_flag_new_deleted()); store_flags = mailimap_store_att_flags_new_set_flags(flist); set = mailimap_set_new_single(mail->getNumber()); err = mailimap_store(m_imap,set,store_flags); mailimap_set_free( set ); mailimap_store_att_flags_free(store_flags); if (err != MAILIMAP_NO_ERROR) { // odebug << "error deleting mail: " << m_imap->imap_response << "" << oendl; return; } // odebug << "deleting mail: " << m_imap->imap_response << "" << oendl; /* should we realy do that at this moment? */ err = mailimap_expunge(m_imap); if (err != MAILIMAP_NO_ERROR) { Global::statusMessage(tr("error deleting mail: %s").arg(m_imap->imap_response)); } //qDebug("IMAPwrapper::deleteMail 2"); } void IMAPwrapper::answeredMail(const RecMailP&mail) { mailimap_flag_list*flist; mailimap_set *set; mailimap_store_att_flags * store_flags; int err; login(); if (!m_imap) { return; } err = selectMbox(mail->getMbox()); if ( err != MAILIMAP_NO_ERROR ) { return; } flist = mailimap_flag_list_new_empty(); mailimap_flag_list_add(flist,mailimap_flag_new_answered()); store_flags = mailimap_store_att_flags_new_add_flags(flist); set = mailimap_set_new_single(mail->getNumber()); err = mailimap_store(m_imap,set,store_flags); mailimap_set_free( set ); mailimap_store_att_flags_free(store_flags); if (err != MAILIMAP_NO_ERROR) { // odebug << "error marking mail: " << m_imap->imap_response << "" << oendl; return; } } QString IMAPwrapper::fetchTextPart(const RecMailP&mail,const QValueList<int>&path,bool internal_call,const QString&enc) { QString body(""); encodedString*res = fetchRawPart(mail,path,internal_call); encodedString*r = decode_String(res,enc); delete res; if (r) { if (r->Length()>0) { body = r->Content(); } delete r; } return body; } QString IMAPwrapper::fetchTextPart(const RecMailP&mail,const RecPartP&part) { return fetchTextPart(mail,part->Positionlist(),false,part->Encoding()); } encodedString* IMAPwrapper::fetchDecodedPart(const RecMailP&mail,const RecPartP&part) { encodedString*res = fetchRawPart(mail,part->Positionlist(),false); encodedString*r = decode_String(res,part->Encoding()); delete res; return r; } encodedString* IMAPwrapper::fetchRawPart(const RecMailP&mail,const RecPartP&part) { return fetchRawPart(mail,part->Positionlist(),false); } int IMAPwrapper::deleteAllMail(const FolderP&folder) { login(); if (!m_imap) { return 0; } mailimap_flag_list*flist; mailimap_set *set; mailimap_store_att_flags * store_flags; int err = selectMbox(folder->getName()); if ( err != MAILIMAP_NO_ERROR ) { return 0; } int last = m_imap->imap_selection_info->sel_exists; if (last == 0) { Global::statusMessage(tr("Mailbox has no mails!")); return 0; } flist = mailimap_flag_list_new_empty(); mailimap_flag_list_add(flist,mailimap_flag_new_deleted()); store_flags = mailimap_store_att_flags_new_set_flags(flist); set = mailimap_set_new_interval( 1, last ); err = mailimap_store(m_imap,set,store_flags); mailimap_set_free( set ); mailimap_store_att_flags_free(store_flags); if (err != MAILIMAP_NO_ERROR) { Global::statusMessage(tr("error deleting mail: %s").arg(m_imap->imap_response)); return 0; } // odebug << "deleting mail: " << m_imap->imap_response << "" << oendl; /* should we realy do that at this moment? */ err = mailimap_expunge(m_imap); if (err != MAILIMAP_NO_ERROR) { Global::statusMessage(tr("error deleting mail: %s").arg(m_imap->imap_response)); return 0; } // odebug << "Delete successfull " << m_imap->imap_response << "" << oendl; return 1; } int IMAPwrapper::createMbox(const QString&folder,const FolderP&parentfolder,const QString& delemiter,bool getsubfolder) { if (folder.length()==0) return 0; login(); if (!m_imap) {return 0;} QString pre = account->getPrefix(); if (delemiter.length()>0 && pre.findRev(delemiter)!=pre.length()-1) { pre+=delemiter; } if (parentfolder) { pre += parentfolder->getDisplayName()+delemiter; } pre+=folder; if (getsubfolder) { if (delemiter.length()>0) { pre+=delemiter; } else { Global::statusMessage(tr("Cannot create folder %1 for holding subfolders").arg(pre)); return 0; } } // odebug << "Creating " << pre.latin1() << "" << oendl; int res = mailimap_create(m_imap,pre.latin1()); if (res != MAILIMAP_NO_ERROR) { Global::statusMessage(tr("%1").arg(m_imap->imap_response)); return 0; } return 1; } int IMAPwrapper::deleteMbox(const FolderP&folder) { if (!folder) return 0; login(); if (!m_imap) {return 0;} int res = mailimap_delete(m_imap,folder->getName()); if (res != MAILIMAP_NO_ERROR) { Global::statusMessage(tr("%1").arg(m_imap->imap_response)); return 0; } return 1; } void IMAPwrapper::statusFolder(folderStat&target_stat,const QString & mailbox) { mailimap_status_att_list * att_list =0; mailimap_mailbox_data_status * status=0; clistiter * cur = 0; int r = 0; target_stat.message_count = 0; target_stat.message_unseen = 0; target_stat.message_recent = 0; login(); if (!m_imap) { return; } att_list = mailimap_status_att_list_new_empty(); if (!att_list) return; r = mailimap_status_att_list_add(att_list, MAILIMAP_STATUS_ATT_MESSAGES); r = mailimap_status_att_list_add(att_list, MAILIMAP_STATUS_ATT_RECENT); r = mailimap_status_att_list_add(att_list, MAILIMAP_STATUS_ATT_UNSEEN); r = mailimap_status(m_imap, mailbox.latin1(), att_list, &status); if (r==MAILIMAP_NO_ERROR&&status->st_info_list!=0) { for (cur = clist_begin(status->st_info_list); cur != NULL ; cur = clist_next(cur)) { mailimap_status_info * status_info; status_info = (mailimap_status_info *)clist_content(cur); switch (status_info->st_att) { case MAILIMAP_STATUS_ATT_MESSAGES: target_stat.message_count = status_info->st_value; break; case MAILIMAP_STATUS_ATT_RECENT: target_stat.message_recent = status_info->st_value; break; case MAILIMAP_STATUS_ATT_UNSEEN: target_stat.message_unseen = status_info->st_value; break; } } } else { // odebug << "Error retrieving status" << oendl; } if (status) mailimap_mailbox_data_status_free(status); if (att_list) mailimap_status_att_list_free(att_list); } void IMAPwrapper::storeMessage(const char*msg,size_t length, const QString&folder) { login(); if (!m_imap) return; if (!msg) return; int r = mailimap_append(m_imap,(char*)folder.latin1(),0,0,msg,length); if (r != MAILIMAP_NO_ERROR) { Global::statusMessage("Error storing mail!"); } } MAILLIB::ATYPE IMAPwrapper::getType()const { return account->getType(); } const QString&IMAPwrapper::getName()const { // odebug << "Get name: " << account->getAccountName().latin1() << "" << oendl; return account->getAccountName(); } encodedString* IMAPwrapper::fetchRawBody(const RecMailP&mail) { // dummy QValueList<int> path; return fetchRawPart(mail,path,false); } void IMAPwrapper::mvcpAllMails(const FolderP&fromFolder, const QString&targetFolder,AbstractMail*targetWrapper,bool moveit, int maxSizeInKb) { if (targetWrapper != this || maxSizeInKb > 0 ) { mMax = 0; progress( tr("Copy")); AbstractMail::mvcpAllMails(fromFolder,targetFolder,targetWrapper,moveit, maxSizeInKb); //qDebug("IMAPwrapper::mvcpAllMails::Using generic"); // odebug << "Using generic" << oendl; return; } mailimap_set *set = 0; login(); if (!m_imap) { return; } int err = selectMbox(fromFolder->getName()); if ( err != MAILIMAP_NO_ERROR ) { return; } Global::statusMessage( tr("Copying mails on server...") ); int last = m_imap->imap_selection_info->sel_exists; set = mailimap_set_new_interval( 1, last ); err = mailimap_copy(m_imap,set,targetFolder.latin1()); mailimap_set_free( set ); if ( err != MAILIMAP_NO_ERROR ) { QString error_msg = tr("Error copy mails: %1").arg(m_imap->imap_response); Global::statusMessage(error_msg); // odebug << error_msg << oendl; return; } if (moveit) { deleteAllMail(fromFolder); } } void IMAPwrapper::mvcpMail(const RecMailP&mail,const QString&targetFolder,AbstractMail*targetWrapper,bool moveit) { if (targetWrapper != this) { // odebug << "Using generic" << oendl; AbstractMail::mvcpMail(mail,targetFolder,targetWrapper,moveit); return; } mailimap_set *set = 0; login(); if (!m_imap) { return; } int err = selectMbox(mail->getMbox()); if ( err != MAILIMAP_NO_ERROR ) { return; } set = mailimap_set_new_single(mail->getNumber()); err = mailimap_copy(m_imap,set,targetFolder.latin1()); mailimap_set_free( set ); if ( err != MAILIMAP_NO_ERROR ) { QString error_msg = tr("error copy mail: %1").arg(m_imap->imap_response); Global::statusMessage(error_msg); // odebug << error_msg << oendl; return; } if (moveit) { deleteMail(mail); } } diff --git a/kmicromail/libmailwrapper/mailtypes.cpp b/kmicromail/libmailwrapper/mailtypes.cpp index 1a4ffd1..af3b9d0 100644 --- a/kmicromail/libmailwrapper/mailtypes.cpp +++ b/kmicromail/libmailwrapper/mailtypes.cpp @@ -1,422 +1,428 @@ #include "mailtypes.h" //#include <opie2/odebug.h> #include <stdlib.h> using namespace Opie::Core; RecMail::RecMail() :Opie::Core::ORefCount(),subject(""),date(""),from(""),mbox(""),msg_id(""),msg_number(0),msg_size(0),msg_flags(7) { init(); } RecMail::RecMail(const RecMail&old) :Opie::Core::ORefCount(),subject(""),date(""),from(""),mbox(""),msg_id(""),msg_number(0),msg_flags(7) { init(); copy_old(old); // odebug << "Copy constructor RecMail" << oendl; } RecMail::~RecMail() { wrapper = 0; } static bool stringCompareRec( const QString& s1, const QString& s2 ) { if ( s1.isEmpty() && s2.isEmpty() ) return true; return s1 == s2; } bool RecMail::isEqual( RecMail* r1 ) { if ( !stringCompareRec( isodate, r1->isodate ) ) { - // qDebug("date *%s* *%s* ", isodate.latin1(), r1->isodate.latin1()); + //qDebug("date *%s* *%s* ", isodate.latin1(), r1->isodate.latin1()); return false; - } - if ( !stringCompareRec( from, r1->from ) ) { - //qDebug("from *%s* *%s* ", from.latin1(), r1->from.latin1()); + } + if ( !stringCompareRec( subject.left(40), r1->subject.left(40) ) ) { + //qDebug("sub *%s* *%s*", subject.latin1(), r1->subject.latin1()); return false; } - if ( !stringCompareRec( subject, r1->subject ) ) { - //qDebug("sub "); - return false; + + //qDebug("date *%s* *%s* ", isodate.latin1(), r1->isodate.latin1()); + if ( !stringCompareRec( from.left(40), r1->from.left(40)) ) { + if ( r1->from.find ( from ) < 0 ) { + if ( !stringCompareRec( from.simplifyWhiteSpace ().left(40), r1->from.simplifyWhiteSpace ().left(40)) ) { + //qDebug("from *%s* *%s* ", from.left(40).latin1(), r1->from.left(20).latin1()); + return false; + } + } } return true; } void RecMail::copy_old(const RecMail&old) { subject = old.subject; date = old.date; mbox = old.mbox; msg_id = old.msg_id; msg_size = old.msg_size; msg_number = old.msg_number; from = old.from; msg_flags = old.msg_flags; to = old.to; cc = old.cc; bcc = old.bcc; wrapper = old.wrapper; in_reply_to = old.in_reply_to; references = old.references; replyto = old.replyto; } void RecMail::init() { to.clear(); cc.clear(); bcc.clear(); in_reply_to.clear(); references.clear(); wrapper = 0; } void RecMail::setWrapper(AbstractMail*awrapper) { wrapper = awrapper; } AbstractMail* RecMail::Wrapper() { return wrapper; } void RecMail::setTo(const QStringList&list) { to = list; } const QStringList&RecMail::To()const { return to; } void RecMail::setCC(const QStringList&list) { cc = list; } const QStringList&RecMail::CC()const { return cc; } void RecMail::setBcc(const QStringList&list) { bcc = list; } const QStringList& RecMail::Bcc()const { return bcc; } void RecMail::setInreply(const QStringList&list) { in_reply_to = list; } const QStringList& RecMail::Inreply()const { return in_reply_to; } void RecMail::setReferences(const QStringList&list) { references = list; } const QStringList& RecMail::References()const { return references; } RecPart::RecPart() : Opie::Core::ORefCount(), m_type(""),m_subtype(""),m_identifier(""),m_encoding(""),m_description(""),m_lines(0),m_size(0) { m_Parameters.clear(); m_poslist.clear(); } RecPart::RecPart(const RecPart&old) : Opie::Core::ORefCount(), m_type(""),m_subtype(""),m_identifier(""),m_encoding(""),m_description(""),m_lines(0),m_size(0) { m_type = old.m_type; m_subtype = old.m_subtype; m_identifier = old.m_identifier; m_encoding = old.m_encoding; m_description = old.m_description; m_lines = old.m_lines; m_size = old.m_size; m_Parameters = old.m_Parameters; m_poslist = old.m_poslist; // odebug << "RecPart copy constructor" << oendl; } RecPart::~RecPart() { } void RecPart::setSize(unsigned int size) { m_size = size; } const unsigned int RecPart::Size()const { return m_size; } void RecPart::setLines(unsigned int lines) { m_lines = lines; } const unsigned int RecPart::Lines()const { return m_lines; } const QString& RecPart::Type()const { return m_type; } void RecPart::setType(const QString&type) { m_type = type; } const QString& RecPart::Subtype()const { return m_subtype; } void RecPart::setSubtype(const QString&subtype) { m_subtype = subtype; } const QString& RecPart::Identifier()const { return m_identifier; } void RecPart::setIdentifier(const QString&identifier) { m_identifier = identifier; } const QString& RecPart::Encoding()const { return m_encoding; } void RecPart::setEncoding(const QString&encoding) { m_encoding = encoding; } const QString& RecPart::Description()const { return m_description; } void RecPart::setDescription(const QString&desc) { m_description = desc; } void RecPart::setParameters(const part_plist_t&list) { m_Parameters = list; } const part_plist_t& RecPart::Parameters()const { return m_Parameters; } void RecPart::addParameter(const QString&key,const QString&value) { m_Parameters[key]=value; } const QString RecPart::searchParamter(const QString&key)const { QString value(""); part_plist_t::ConstIterator it = m_Parameters.find(key); if (it != m_Parameters.end()) { value = it.data(); } return value; } void RecPart::setPositionlist(const QValueList<int>&poslist) { m_poslist = poslist; } const QValueList<int>& RecPart::Positionlist()const { return m_poslist; } RecBody::RecBody() : Opie::Core::ORefCount(),m_BodyText(),m_description(new RecPart()) { m_PartsList.clear(); } RecBody::RecBody(const RecBody&old) :Opie::Core::ORefCount(),m_BodyText(),m_PartsList(),m_description(new RecPart()) { m_BodyText = old.m_BodyText; m_PartsList = old.m_PartsList; m_description = old.m_description; // odebug << "Recbody copy constructor" << oendl; } RecBody::~RecBody() { } void RecBody::setBodytext(const QString&bodyText) { m_BodyText = bodyText; } const QString& RecBody::Bodytext()const { return m_BodyText; } void RecBody::setParts(const QValueList<RecPartP>&parts) { m_PartsList.clear(); m_PartsList = parts; } const QValueList<RecPartP>& RecBody::Parts()const { return m_PartsList; } void RecBody::addPart(const RecPartP& part) { m_PartsList.append(part); } void RecBody::setDescription(const RecPartP&des) { m_description = des; } const RecPartP& RecBody::Description()const { return m_description; } /* handling encoded content */ encodedString::encodedString() { init(); } encodedString::encodedString(const char*nContent,unsigned int nSize) { init(); setContent(nContent,nSize); } encodedString::encodedString(char*nContent,unsigned int nSize) { init(); setContent(nContent,nSize); } encodedString::encodedString(const encodedString&old) { init(); copy_old(old); // odebug << "encodedeString: copy constructor!" << oendl; } encodedString& encodedString::operator=(const encodedString&old) { init(); copy_old(old); // odebug << "encodedString: assign operator!" << oendl; return *this; } encodedString::~encodedString() { clean(); } void encodedString::init() { content = 0; size = 0; } void encodedString::clean() { if (content) { free(content); } content = 0; size = 0; } void encodedString::copy_old(const encodedString&old) { clean(); if (old.size>0 && old.content) { content = (char*)malloc(old.size*sizeof(char)); memcpy(content,old.content,size); size = old.size; } } const char*encodedString::Content()const { return content; } const int encodedString::Length()const { return size; } void encodedString::setContent(const char*nContent,int nSize) { if (nSize>0 && nContent) { content = (char*)malloc(nSize*sizeof(char)); memcpy(content,nContent,nSize); size = nSize; } } void encodedString::setContent(char*nContent,int nSize) { content = nContent; size = nSize; } folderStat&folderStat::operator=(const folderStat&old) { message_count = old.message_count; message_unseen = old.message_unseen; message_recent = old.message_recent; return *this; } diff --git a/kmicromail/libmailwrapper/mailtypes.h b/kmicromail/libmailwrapper/mailtypes.h index 020278d..c1c1a74 100644 --- a/kmicromail/libmailwrapper/mailtypes.h +++ b/kmicromail/libmailwrapper/mailtypes.h @@ -1,209 +1,211 @@ #ifndef __MAIL_TYPES_H #define __MAIL_TYPES_H #define FLAG_ANSWERED 0 #define FLAG_FLAGGED 1 #define FLAG_DELETED 2 #define FLAG_SEEN 3 #define FLAG_DRAFT 4 #define FLAG_RECENT 5 #include <opie2/osmartpointer.h> #include <qbitarray.h> #include <qstring.h> #include <qstringlist.h> #include <qmap.h> #include <qvaluelist.h> class AbstractMail; /* a class to describe mails in a mailbox */ /* Attention! From programmers point of view it would make sense to store the mail body into this class, too. But: not from the point of view of the device. Mailbodies can be real large. So we request them when needed from the mail-wrapper class direct from the server itself (imap) or from a file-based cache (pop3?) So there is no interface "const QString&body()" but you should make a request to the mailwrapper with this class as parameter to get the body. Same words for the attachments. */ class RecMail:public Opie::Core::ORefCount { public: RecMail(); RecMail(const RecMail&old); virtual ~RecMail(); bool isEqual( RecMail* r1 ); const unsigned int getNumber()const{return msg_number;} void setNumber(unsigned int number){msg_number=number;} const QString&getDate()const{ return date; } void setDate( const QString&a ) { date = a; } const QString&getIsoDate()const{ return isodate; } void setIsoDate( const QString&a ) { isodate = a; } const QString&getFrom()const{ return from; } void setFrom( const QString&a ) { from = a; } const QString&getSubject()const { return subject; } void setSubject( const QString&s ) { subject = s; } const QString&getMbox()const{return mbox;} void setMbox(const QString&box){mbox = box;} void setMsgid(const QString&id){msg_id=id;} const QString&Msgid()const{return msg_id;} void setReplyto(const QString&reply){replyto=reply;} const QString&Replyto()const{return replyto;} void setMsgsize(unsigned int size){msg_size = size;} const unsigned int Msgsize()const{return msg_size;} void setTo(const QStringList&list); const QStringList&To()const; void setCC(const QStringList&list); const QStringList&CC()const; void setBcc(const QStringList&list); const QStringList&Bcc()const; void setInreply(const QStringList&list); const QStringList&Inreply()const; void setReferences(const QStringList&list); const QStringList&References()const; const QBitArray&getFlags()const{return msg_flags;} void setFlags(const QBitArray&flags){msg_flags = flags;} void setWrapper(AbstractMail*wrapper); AbstractMail* Wrapper(); + // public for debugging + QString subject,date,isodate,from,mbox,msg_id,replyto; protected: - QString subject,date,isodate,from,mbox,msg_id,replyto; + //QString subject,date,isodate,from,mbox,msg_id,replyto; unsigned int msg_number,msg_size; QBitArray msg_flags; QStringList to,cc,bcc,in_reply_to,references; AbstractMail*wrapper; void init(); void copy_old(const RecMail&old); }; typedef Opie::Core::OSmartPointer<RecMail> RecMailP; typedef QMap<QString,QString> part_plist_t; class RecPart:public Opie::Core::ORefCount { protected: QString m_type,m_subtype,m_identifier,m_encoding,m_description; unsigned int m_lines,m_size; part_plist_t m_Parameters; /* describes the position in the mail */ QValueList<int> m_poslist; public: RecPart(); RecPart(const RecPart&); virtual ~RecPart(); const QString&Type()const; void setType(const QString&type); const QString&Subtype()const; void setSubtype(const QString&subtype); const QString&Identifier()const; void setIdentifier(const QString&identifier); const QString&Encoding()const; void setEncoding(const QString&encoding); const QString&Description()const; void setDescription(const QString&desc); void setLines(unsigned int lines); const unsigned int Lines()const; void setSize(unsigned int size); const unsigned int Size()const; void setParameters(const part_plist_t&list); const part_plist_t&Parameters()const; void addParameter(const QString&key,const QString&value); const QString searchParamter(const QString&key)const; void setPositionlist(const QValueList<int>&poslist); const QValueList<int>& Positionlist()const; }; typedef Opie::Core::OSmartPointer<RecPart> RecPartP; class RecBody:public Opie::Core::ORefCount { protected: QString m_BodyText; QValueList<RecPartP> m_PartsList; RecPartP m_description; public: RecBody(); RecBody(const RecBody&old); virtual ~RecBody(); void setBodytext(const QString&); const QString& Bodytext()const; void setDescription(const RecPartP&des); const RecPartP& Description()const; void setParts(const QValueList<RecPartP>&parts); const QValueList<RecPartP>& Parts()const; void addPart(const RecPartP&part); }; typedef Opie::Core::OSmartPointer<RecBody> RecBodyP; class encodedString { public: encodedString(); /* creates an new content string. it makes a deep copy of it! */ encodedString(const char*nContent,unsigned int length); /* Take over the nContent. Means: it will just copy the pointer, not the content. so make sure: No one else frees the string, the string has allocated with malloc for compatibility with c-based libs */ encodedString(char*nContent,unsigned int nSize); /* copy construkor - makes ALWAYS a deep copy!!!! */ encodedString(const encodedString&old); /* assign operator - makes ALWAYS a deep copy!!!! */ encodedString& operator=(const encodedString&old); /* destructor - cleans the content */ virtual ~encodedString(); /* returns a pointer to the content - do not delete yoursel! */ const char*Content()const; /* returns the lengths of the content 'cause it must not be a null-terminated string! */ const int Length()const; /* makes a deep copy of nContent! */ void setContent(const char*nContent,int nSize); /* Take over the nContent. Means: it will just copy the pointer, not the content. so make sure: No one else frees the string, the string has allocated with malloc for compatibility with c-based libs */ void setContent(char*nContent,int nSize); protected: char * content; unsigned int size; void init(); void copy_old(const encodedString&old); void clean(); }; struct folderStat { unsigned int message_count; unsigned int message_unseen; unsigned int message_recent; folderStat&operator=(const folderStat&old); }; #endif |