-rw-r--r-- | noncore/net/mail/imapwrapper.cpp | 143 | ||||
-rw-r--r-- | noncore/net/mail/imapwrapper.h | 6 | ||||
-rw-r--r-- | noncore/net/mail/libmailwrapper/imapwrapper.cpp | 143 | ||||
-rw-r--r-- | noncore/net/mail/libmailwrapper/imapwrapper.h | 6 | ||||
-rw-r--r-- | noncore/net/mail/libmailwrapper/mailtypes.cpp | 62 | ||||
-rw-r--r-- | noncore/net/mail/libmailwrapper/mailtypes.h | 25 | ||||
-rw-r--r-- | noncore/net/mail/mailtypes.cpp | 62 | ||||
-rw-r--r-- | noncore/net/mail/mailtypes.h | 25 |
8 files changed, 282 insertions, 190 deletions
diff --git a/noncore/net/mail/imapwrapper.cpp b/noncore/net/mail/imapwrapper.cpp index fa967da..da5974c 100644 --- a/noncore/net/mail/imapwrapper.cpp +++ b/noncore/net/mail/imapwrapper.cpp @@ -328,357 +328,366 @@ RecBody IMAPwrapper::fetchBody(const RecMail&mail) mb = mail.getMbox().latin1(); login(); if (!m_imap) { return body; } /* select mailbox READONLY for operations */ err = mailimap_examine( m_imap, (char*)mb); if ( err != MAILIMAP_NO_ERROR ) { qDebug("error selecting mailbox: %s",m_imap->imap_response); return body; } result = clist_new(); /* 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; body_desc = item->att_data.att_static->att_data.att_body; if (body_desc->bd_type==MAILIMAP_BODY_1PART) { searchBodyText(mail,body_desc->bd_data.bd_body_1part,body); } else if (body_desc->bd_type==MAILIMAP_BODY_MPART) { qDebug("Mulitpart mail"); searchBodyText(mail,body_desc->bd_data.bd_body_mpart,body); } } else { qDebug("error fetching body: %s",m_imap->imap_response); } mailimap_fetch_list_free(result); return body; } /* this routine is just called when the mail has only ONE part. for filling the parts of a multi-part-message there are other routines 'cause we can not simply fetch the whole body. */ void IMAPwrapper::searchBodyText(const RecMail&mail,mailimap_body_type_1part*mailDescription,RecBody&target_body) { if (!mailDescription) { return; } - QString sub; + QString sub,body_text; + RecPart singlePart; + QValueList<int> path; + fillSinglePart(singlePart,mailDescription); switch (mailDescription->bd_type) { case MAILIMAP_BODY_TYPE_1PART_MSG: - target_body.setType("text"); - sub = mailDescription->bd_data.bd_type_text->bd_media_text; - target_body.setSubtype(sub.lower()); - fillPlainBody(mail,target_body); + path.append(1); + body_text = fetchPart(mail,path,true); + target_body.setBodytext(body_text); + target_body.setDescription(singlePart); break; case MAILIMAP_BODY_TYPE_1PART_TEXT: qDebug("Mediatype single: %s",mailDescription->bd_data.bd_type_text->bd_media_text); - target_body.setType("text"); - sub = mailDescription->bd_data.bd_type_text->bd_media_text; - target_body.setSubtype(sub.lower()); - fillPlainBody(mail,target_body); + path.append(1); + body_text = fetchPart(mail,path,true); + target_body.setBodytext(body_text); + target_body.setDescription(singlePart); + break; + case MAILIMAP_BODY_TYPE_1PART_BASIC: + qDebug("Single attachment"); + target_body.setBodytext(""); + target_body.addPart(singlePart); break; default: break; } - return; -} - -void IMAPwrapper::fillPlainBody(const RecMail&mail,RecBody&target_body) -{ - const char *mb; - QString body=""; - int err = MAILIMAP_NO_ERROR; - clist *result; - clistcell *current,*cur; - mailimap_fetch_att *fetchAtt; - mailimap_fetch_type *fetchType; - mailimap_set *set; - - mb = mail.getMbox().latin1(); - - if (!m_imap) { - return; - } - - result = clist_new(); - set = set = mailimap_set_new_single(mail.getNumber()); - mailimap_section * section = mailimap_section_new_text(); - fetchAtt = mailimap_fetch_att_new_body_peek_section(section); - 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*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; - msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part = 0L; - if (text) { - body = QString(text); - free(text); - } else { - body = ""; - } - } - } - } - } else { - qDebug("error fetching text: %s",m_imap->imap_response); - } - mailimap_fetch_list_free(result); - target_body.setBodytext(body); return; } 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+=QString(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; } -QString IMAPwrapper::fetchPart(const RecMail&mail,QValueList<int>&path,bool internal_call) +QString IMAPwrapper::fetchPart(const RecMail&mail,const QValueList<int>&path,bool internal_call) { QString body(""); const char*mb; int err; mailimap_fetch_type *fetchType; mailimap_set *set; clistcell*current,*cur; login(); if (!m_imap) { return body; } if (!internal_call) { mb = mail.getMbox().latin1(); /* select mailbox READONLY for operations */ err = mailimap_examine( m_imap, (char*)mb); if ( err != MAILIMAP_NO_ERROR ) { qDebug("error selecting mailbox: %s",m_imap->imap_response); return body; } } set = mailimap_set_new_single(mail.getNumber()); clist*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); } mailimap_section_part * section_part = mailimap_section_part_new(id_list); mailimap_section_spec * section_spec = mailimap_section_spec_new(MAILIMAP_SECTION_SPEC_SECTION_PART, NULL, section_part, NULL); mailimap_section * section = mailimap_section_new(section_spec); mailimap_fetch_att * fetch_att = mailimap_fetch_att_new_body_section(section); fetchType = mailimap_fetch_type_new_fetch_att(fetch_att); clist*result = clist_new(); 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; msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part = 0L; if (text) { body = QString(text); free(text); } else { body = ""; } } } } } else { qDebug("error fetching text: %s",m_imap->imap_response); } mailimap_fetch_list_free(result); return body; } void IMAPwrapper::searchBodyText(const RecMail&mail,mailimap_body_type_mpart*mailDescription,RecBody&target_body,int current_recursion,QValueList<int>recList) { /* current_recursion is for avoiding ugly mails which has a to deep body-structure */ if (!mailDescription||current_recursion==10) { return; } clistcell*current; mailimap_body*current_body; unsigned int count = 0; for (current=clist_begin(mailDescription->bd_list);current!=0;current=clist_next(current)) { /* the point in the message */ ++count; current_body = (mailimap_body*)current->data; if (current_body->bd_type==MAILIMAP_BODY_MPART) { QValueList<int>clist = recList; clist.append(count); searchBodyText(mail,current_body->bd_data.bd_body_mpart,target_body,current_recursion+1,clist); } else if (current_body->bd_type==MAILIMAP_BODY_1PART){ RecPart currentPart; fillSinglePart(currentPart,current_body->bd_data.bd_body_1part); QValueList<int>clist = recList; clist.append(count); /* important: Check for is NULL 'cause a body can be empty! */ if (currentPart.Type()=="text" && target_body.Bodytext().isNull() ) { QString body_text = fetchPart(mail,clist,true); + target_body.setDescription(currentPart); target_body.setBodytext(body_text); - target_body.setType(currentPart.Type()); - target_body.setSubtype(currentPart.Subtype()); } else { QString id(""); for (unsigned int j = 0; j < clist.count();++j) { - id+=(j>0?".":""); + id+=(j>0?" ":""); id+=QString("%1").arg(clist[j]); } qDebug("ID= %s",id.latin1()); currentPart.setIdentifier(id); + currentPart.setPositionlist(clist); target_body.addPart(currentPart); } } } } void IMAPwrapper::fillSinglePart(RecPart&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: + fillSingleMsgPart(target_part,Description->bd_data.bd_type_msg); + break; default: break; } } void IMAPwrapper::fillSingleTextPart(RecPart&target_part,mailimap_body_type_text*which) { if (!which) { return; } QString sub; sub = which->bd_media_text; target_part.setSubtype(sub.lower()); target_part.setLines(which->bd_lines); fillBodyFields(target_part,which->bd_fields); } +void IMAPwrapper::fillSingleMsgPart(RecPart&target_part,mailimap_body_type_msg*which) +{ + if (!which) { + return; + } +// QString sub; +// sub = which->bd_media_text; +// target_part.setSubtype(sub.lower()); + qDebug("Message part"); + /* we set this type to text/plain */ + target_part.setType("text"); + target_part.setSubtype("plain"); + target_part.setLines(which->bd_lines); + fillBodyFields(target_part,which->bd_fields); +} + void IMAPwrapper::fillSingleBasicPart(RecPart&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 = ""; } qDebug("Type = %s/%s",type.latin1(),sub.latin1()); target_part.setType(type.lower()); target_part.setSubtype(sub.lower()); fillBodyFields(target_part,which->bd_fields); } void IMAPwrapper::fillBodyFields(RecPart&target_part,mailimap_body_fields*which) { if (!which) return; clistcell*cur; mailimap_single_body_fld_param*param; 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); + } + } + target_part.setEncoding(encoding); +} + +QString IMAPwrapper::fetchPart(const RecMail&mail,const RecPart&part) +{ + return fetchPart(mail,part.Positionlist(),false); } diff --git a/noncore/net/mail/imapwrapper.h b/noncore/net/mail/imapwrapper.h index 5ea45f3..95de215 100644 --- a/noncore/net/mail/imapwrapper.h +++ b/noncore/net/mail/imapwrapper.h @@ -1,53 +1,55 @@ #ifndef __IMAPWRAPPER #define __IMAPWRAPPER #include <qlist.h> #include "mailwrapper.h" struct mailimap; struct mailimap_body_type_1part; struct mailimap_body_type_text; struct mailimap_body_type_basic; +struct mailimap_body_type_msg; struct mailimap_body_type_mpart; struct mailimap_body_fields; struct mailimap_msg_att; class RecMail; class RecBody; class RecPart; class IMAPwrapper : public QObject { Q_OBJECT public: IMAPwrapper( IMAPaccount *a ); virtual ~IMAPwrapper(); QList<IMAPFolder>* listFolders(); void listMessages(const QString & mailbox,QList<RecMail>&target ); RecBody fetchBody(const RecMail&mail); - QString fetchPart(const RecMail&mail,QValueList<int>&path,bool internal_call=false); + QString fetchPart(const RecMail&mail,const QValueList<int>&path,bool internal_call=false); + QString fetchPart(const RecMail&mail,const RecPart&part); static void imap_progress( size_t current, size_t maximum ); protected: RecMail*parse_list_result(mailimap_msg_att*); void login(); void logout(); void searchBodyText(const RecMail&mail,mailimap_body_type_1part*mailDescription,RecBody&target_body); void searchBodyText(const RecMail&mail,mailimap_body_type_mpart*mailDescription,RecBody&target_body,int current_recursion=0,QValueList<int>recList=QValueList<int>()); - void fillPlainBody(const RecMail&mail,RecBody&target_body); void fillSinglePart(RecPart&target_part,mailimap_body_type_1part*Description); void fillSingleTextPart(RecPart&target_part,mailimap_body_type_text*which); void fillSingleBasicPart(RecPart&target_part,mailimap_body_type_basic*which); + void fillSingleMsgPart(RecPart&target_part,mailimap_body_type_msg*which); /* just helpers */ static void fillBodyFields(RecPart&target_part,mailimap_body_fields*which); static QStringList address_list_to_stringlist(clist*list); private: IMAPaccount *account; mailimap *m_imap; }; #endif diff --git a/noncore/net/mail/libmailwrapper/imapwrapper.cpp b/noncore/net/mail/libmailwrapper/imapwrapper.cpp index fa967da..da5974c 100644 --- a/noncore/net/mail/libmailwrapper/imapwrapper.cpp +++ b/noncore/net/mail/libmailwrapper/imapwrapper.cpp @@ -328,357 +328,366 @@ RecBody IMAPwrapper::fetchBody(const RecMail&mail) mb = mail.getMbox().latin1(); login(); if (!m_imap) { return body; } /* select mailbox READONLY for operations */ err = mailimap_examine( m_imap, (char*)mb); if ( err != MAILIMAP_NO_ERROR ) { qDebug("error selecting mailbox: %s",m_imap->imap_response); return body; } result = clist_new(); /* 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; body_desc = item->att_data.att_static->att_data.att_body; if (body_desc->bd_type==MAILIMAP_BODY_1PART) { searchBodyText(mail,body_desc->bd_data.bd_body_1part,body); } else if (body_desc->bd_type==MAILIMAP_BODY_MPART) { qDebug("Mulitpart mail"); searchBodyText(mail,body_desc->bd_data.bd_body_mpart,body); } } else { qDebug("error fetching body: %s",m_imap->imap_response); } mailimap_fetch_list_free(result); return body; } /* this routine is just called when the mail has only ONE part. for filling the parts of a multi-part-message there are other routines 'cause we can not simply fetch the whole body. */ void IMAPwrapper::searchBodyText(const RecMail&mail,mailimap_body_type_1part*mailDescription,RecBody&target_body) { if (!mailDescription) { return; } - QString sub; + QString sub,body_text; + RecPart singlePart; + QValueList<int> path; + fillSinglePart(singlePart,mailDescription); switch (mailDescription->bd_type) { case MAILIMAP_BODY_TYPE_1PART_MSG: - target_body.setType("text"); - sub = mailDescription->bd_data.bd_type_text->bd_media_text; - target_body.setSubtype(sub.lower()); - fillPlainBody(mail,target_body); + path.append(1); + body_text = fetchPart(mail,path,true); + target_body.setBodytext(body_text); + target_body.setDescription(singlePart); break; case MAILIMAP_BODY_TYPE_1PART_TEXT: qDebug("Mediatype single: %s",mailDescription->bd_data.bd_type_text->bd_media_text); - target_body.setType("text"); - sub = mailDescription->bd_data.bd_type_text->bd_media_text; - target_body.setSubtype(sub.lower()); - fillPlainBody(mail,target_body); + path.append(1); + body_text = fetchPart(mail,path,true); + target_body.setBodytext(body_text); + target_body.setDescription(singlePart); + break; + case MAILIMAP_BODY_TYPE_1PART_BASIC: + qDebug("Single attachment"); + target_body.setBodytext(""); + target_body.addPart(singlePart); break; default: break; } - return; -} - -void IMAPwrapper::fillPlainBody(const RecMail&mail,RecBody&target_body) -{ - const char *mb; - QString body=""; - int err = MAILIMAP_NO_ERROR; - clist *result; - clistcell *current,*cur; - mailimap_fetch_att *fetchAtt; - mailimap_fetch_type *fetchType; - mailimap_set *set; - - mb = mail.getMbox().latin1(); - - if (!m_imap) { - return; - } - - result = clist_new(); - set = set = mailimap_set_new_single(mail.getNumber()); - mailimap_section * section = mailimap_section_new_text(); - fetchAtt = mailimap_fetch_att_new_body_peek_section(section); - 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*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; - msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part = 0L; - if (text) { - body = QString(text); - free(text); - } else { - body = ""; - } - } - } - } - } else { - qDebug("error fetching text: %s",m_imap->imap_response); - } - mailimap_fetch_list_free(result); - target_body.setBodytext(body); return; } 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+=QString(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; } -QString IMAPwrapper::fetchPart(const RecMail&mail,QValueList<int>&path,bool internal_call) +QString IMAPwrapper::fetchPart(const RecMail&mail,const QValueList<int>&path,bool internal_call) { QString body(""); const char*mb; int err; mailimap_fetch_type *fetchType; mailimap_set *set; clistcell*current,*cur; login(); if (!m_imap) { return body; } if (!internal_call) { mb = mail.getMbox().latin1(); /* select mailbox READONLY for operations */ err = mailimap_examine( m_imap, (char*)mb); if ( err != MAILIMAP_NO_ERROR ) { qDebug("error selecting mailbox: %s",m_imap->imap_response); return body; } } set = mailimap_set_new_single(mail.getNumber()); clist*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); } mailimap_section_part * section_part = mailimap_section_part_new(id_list); mailimap_section_spec * section_spec = mailimap_section_spec_new(MAILIMAP_SECTION_SPEC_SECTION_PART, NULL, section_part, NULL); mailimap_section * section = mailimap_section_new(section_spec); mailimap_fetch_att * fetch_att = mailimap_fetch_att_new_body_section(section); fetchType = mailimap_fetch_type_new_fetch_att(fetch_att); clist*result = clist_new(); 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; msg_att_item->att_data.att_static->att_data.att_body_section->sec_body_part = 0L; if (text) { body = QString(text); free(text); } else { body = ""; } } } } } else { qDebug("error fetching text: %s",m_imap->imap_response); } mailimap_fetch_list_free(result); return body; } void IMAPwrapper::searchBodyText(const RecMail&mail,mailimap_body_type_mpart*mailDescription,RecBody&target_body,int current_recursion,QValueList<int>recList) { /* current_recursion is for avoiding ugly mails which has a to deep body-structure */ if (!mailDescription||current_recursion==10) { return; } clistcell*current; mailimap_body*current_body; unsigned int count = 0; for (current=clist_begin(mailDescription->bd_list);current!=0;current=clist_next(current)) { /* the point in the message */ ++count; current_body = (mailimap_body*)current->data; if (current_body->bd_type==MAILIMAP_BODY_MPART) { QValueList<int>clist = recList; clist.append(count); searchBodyText(mail,current_body->bd_data.bd_body_mpart,target_body,current_recursion+1,clist); } else if (current_body->bd_type==MAILIMAP_BODY_1PART){ RecPart currentPart; fillSinglePart(currentPart,current_body->bd_data.bd_body_1part); QValueList<int>clist = recList; clist.append(count); /* important: Check for is NULL 'cause a body can be empty! */ if (currentPart.Type()=="text" && target_body.Bodytext().isNull() ) { QString body_text = fetchPart(mail,clist,true); + target_body.setDescription(currentPart); target_body.setBodytext(body_text); - target_body.setType(currentPart.Type()); - target_body.setSubtype(currentPart.Subtype()); } else { QString id(""); for (unsigned int j = 0; j < clist.count();++j) { - id+=(j>0?".":""); + id+=(j>0?" ":""); id+=QString("%1").arg(clist[j]); } qDebug("ID= %s",id.latin1()); currentPart.setIdentifier(id); + currentPart.setPositionlist(clist); target_body.addPart(currentPart); } } } } void IMAPwrapper::fillSinglePart(RecPart&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: + fillSingleMsgPart(target_part,Description->bd_data.bd_type_msg); + break; default: break; } } void IMAPwrapper::fillSingleTextPart(RecPart&target_part,mailimap_body_type_text*which) { if (!which) { return; } QString sub; sub = which->bd_media_text; target_part.setSubtype(sub.lower()); target_part.setLines(which->bd_lines); fillBodyFields(target_part,which->bd_fields); } +void IMAPwrapper::fillSingleMsgPart(RecPart&target_part,mailimap_body_type_msg*which) +{ + if (!which) { + return; + } +// QString sub; +// sub = which->bd_media_text; +// target_part.setSubtype(sub.lower()); + qDebug("Message part"); + /* we set this type to text/plain */ + target_part.setType("text"); + target_part.setSubtype("plain"); + target_part.setLines(which->bd_lines); + fillBodyFields(target_part,which->bd_fields); +} + void IMAPwrapper::fillSingleBasicPart(RecPart&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 = ""; } qDebug("Type = %s/%s",type.latin1(),sub.latin1()); target_part.setType(type.lower()); target_part.setSubtype(sub.lower()); fillBodyFields(target_part,which->bd_fields); } void IMAPwrapper::fillBodyFields(RecPart&target_part,mailimap_body_fields*which) { if (!which) return; clistcell*cur; mailimap_single_body_fld_param*param; 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); + } + } + target_part.setEncoding(encoding); +} + +QString IMAPwrapper::fetchPart(const RecMail&mail,const RecPart&part) +{ + return fetchPart(mail,part.Positionlist(),false); } diff --git a/noncore/net/mail/libmailwrapper/imapwrapper.h b/noncore/net/mail/libmailwrapper/imapwrapper.h index 5ea45f3..95de215 100644 --- a/noncore/net/mail/libmailwrapper/imapwrapper.h +++ b/noncore/net/mail/libmailwrapper/imapwrapper.h @@ -1,53 +1,55 @@ #ifndef __IMAPWRAPPER #define __IMAPWRAPPER #include <qlist.h> #include "mailwrapper.h" struct mailimap; struct mailimap_body_type_1part; struct mailimap_body_type_text; struct mailimap_body_type_basic; +struct mailimap_body_type_msg; struct mailimap_body_type_mpart; struct mailimap_body_fields; struct mailimap_msg_att; class RecMail; class RecBody; class RecPart; class IMAPwrapper : public QObject { Q_OBJECT public: IMAPwrapper( IMAPaccount *a ); virtual ~IMAPwrapper(); QList<IMAPFolder>* listFolders(); void listMessages(const QString & mailbox,QList<RecMail>&target ); RecBody fetchBody(const RecMail&mail); - QString fetchPart(const RecMail&mail,QValueList<int>&path,bool internal_call=false); + QString fetchPart(const RecMail&mail,const QValueList<int>&path,bool internal_call=false); + QString fetchPart(const RecMail&mail,const RecPart&part); static void imap_progress( size_t current, size_t maximum ); protected: RecMail*parse_list_result(mailimap_msg_att*); void login(); void logout(); void searchBodyText(const RecMail&mail,mailimap_body_type_1part*mailDescription,RecBody&target_body); void searchBodyText(const RecMail&mail,mailimap_body_type_mpart*mailDescription,RecBody&target_body,int current_recursion=0,QValueList<int>recList=QValueList<int>()); - void fillPlainBody(const RecMail&mail,RecBody&target_body); void fillSinglePart(RecPart&target_part,mailimap_body_type_1part*Description); void fillSingleTextPart(RecPart&target_part,mailimap_body_type_text*which); void fillSingleBasicPart(RecPart&target_part,mailimap_body_type_basic*which); + void fillSingleMsgPart(RecPart&target_part,mailimap_body_type_msg*which); /* just helpers */ static void fillBodyFields(RecPart&target_part,mailimap_body_fields*which); static QStringList address_list_to_stringlist(clist*list); private: IMAPaccount *account; mailimap *m_imap; }; #endif diff --git a/noncore/net/mail/libmailwrapper/mailtypes.cpp b/noncore/net/mail/libmailwrapper/mailtypes.cpp index 6a66113..f56bb63 100644 --- a/noncore/net/mail/libmailwrapper/mailtypes.cpp +++ b/noncore/net/mail/libmailwrapper/mailtypes.cpp @@ -25,165 +25,187 @@ void RecMail::copy_old(const RecMail&old) msg_number = old.msg_number; from = old.from; msg_flags = old.msg_flags; to = old.to; cc = old.cc; bcc = old.bcc; } void RecMail::init() { to.clear(); cc.clear(); bcc.clear(); } 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; } RecPart::RecPart() : m_type(""),m_subtype(""),m_identifier(""),m_encoding(""),m_lines(0) { -} - -RecPart::RecPart(const QString&identifier,const QString&type,const QString&subtype,const QString&encoding,unsigned int lines) - : m_type(type),m_subtype(subtype),m_identifier(identifier),m_encoding(encoding),m_lines(lines) -{ + m_Parameters.clear(); + m_poslist.clear(); } RecPart::~RecPart() { } 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; } +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() - : m_BodyText(),m_PartsList() + : m_BodyText(),m_PartsList(),m_description() { m_PartsList.setAutoDelete(true); } RecBody::~RecBody() { } void RecBody::setBodytext(const QString&bodyText) { m_BodyText = bodyText; } const QString& RecBody::Bodytext()const { return m_BodyText; } void RecBody::setParts(const QList<RecPart>&parts) { m_PartsList = parts; m_PartsList.setAutoDelete(true); } const QList<RecPart>& RecBody::Parts()const { return m_PartsList; } void RecBody::addPart(const RecPart& part) { RecPart*p = new RecPart(part); m_PartsList.append(p); } -void RecBody::setType(const QString&type) +void RecBody::setDescription(const RecPart&des) { - m_type = type; + m_description = des; } -const QString& RecBody::Type()const +const RecPart& RecBody::Description()const { - return m_type; -} - -void RecBody::setSubtype(const QString&type) -{ - m_subtype = type; -} - -const QString& RecBody::Subtype()const -{ - return m_subtype; + return m_description; } diff --git a/noncore/net/mail/libmailwrapper/mailtypes.h b/noncore/net/mail/libmailwrapper/mailtypes.h index 900f10a..60db527 100644 --- a/noncore/net/mail/libmailwrapper/mailtypes.h +++ b/noncore/net/mail/libmailwrapper/mailtypes.h @@ -1,115 +1,128 @@ #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 <qlist.h> #include <qbitarray.h> #include <qstring.h> #include <qstringlist.h> +#include <qmap.h> +#include <qvaluelist.h> /* 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: RecMail(); RecMail(const RecMail&old); virtual ~RecMail(){} const int getNumber()const{return msg_number;} void setNumber(int number){msg_number=number;} const QString&getDate()const{ return date; } void setDate( const QString&a ) { date = 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(int size){msg_size = size;} const 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; const QBitArray&getFlags()const{return msg_flags;} void setFlags(const QBitArray&flags){msg_flags = flags;} protected: QString subject,date,from,mbox,msg_id,replyto; int msg_number,msg_size; QBitArray msg_flags; QStringList to,cc,bcc; void init(); void copy_old(const RecMail&old); }; +typedef QMap<QString,QString> part_plist_t; + class RecPart { protected: QString m_type,m_subtype,m_identifier,m_encoding; unsigned int m_lines; + part_plist_t m_Parameters; + /* describes the position in the mail */ + QValueList<int> m_poslist; + public: RecPart(); - RecPart(const QString&identifier,const QString&type="",const QString&subtype="",const QString&encoding="BASE64",unsigned int lines=0); 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); void setLines(unsigned int lines); const unsigned int Lines()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; }; class RecBody { protected: - QString m_BodyText,m_type,m_subtype; + QString m_BodyText; QList<RecPart> m_PartsList; + RecPart m_description; public: RecBody(); virtual ~RecBody(); void setBodytext(const QString&); const QString& Bodytext()const; - void setType(const QString&); - const QString&Type()const; - void setSubtype(const QString&); - const QString&Subtype()const; + void setDescription(const RecPart&des); + const RecPart& Description()const; void setParts(const QList<RecPart>&parts); const QList<RecPart>& Parts()const; void addPart(const RecPart&part); }; #endif diff --git a/noncore/net/mail/mailtypes.cpp b/noncore/net/mail/mailtypes.cpp index 6a66113..f56bb63 100644 --- a/noncore/net/mail/mailtypes.cpp +++ b/noncore/net/mail/mailtypes.cpp @@ -25,165 +25,187 @@ void RecMail::copy_old(const RecMail&old) msg_number = old.msg_number; from = old.from; msg_flags = old.msg_flags; to = old.to; cc = old.cc; bcc = old.bcc; } void RecMail::init() { to.clear(); cc.clear(); bcc.clear(); } 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; } RecPart::RecPart() : m_type(""),m_subtype(""),m_identifier(""),m_encoding(""),m_lines(0) { -} - -RecPart::RecPart(const QString&identifier,const QString&type,const QString&subtype,const QString&encoding,unsigned int lines) - : m_type(type),m_subtype(subtype),m_identifier(identifier),m_encoding(encoding),m_lines(lines) -{ + m_Parameters.clear(); + m_poslist.clear(); } RecPart::~RecPart() { } 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; } +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() - : m_BodyText(),m_PartsList() + : m_BodyText(),m_PartsList(),m_description() { m_PartsList.setAutoDelete(true); } RecBody::~RecBody() { } void RecBody::setBodytext(const QString&bodyText) { m_BodyText = bodyText; } const QString& RecBody::Bodytext()const { return m_BodyText; } void RecBody::setParts(const QList<RecPart>&parts) { m_PartsList = parts; m_PartsList.setAutoDelete(true); } const QList<RecPart>& RecBody::Parts()const { return m_PartsList; } void RecBody::addPart(const RecPart& part) { RecPart*p = new RecPart(part); m_PartsList.append(p); } -void RecBody::setType(const QString&type) +void RecBody::setDescription(const RecPart&des) { - m_type = type; + m_description = des; } -const QString& RecBody::Type()const +const RecPart& RecBody::Description()const { - return m_type; -} - -void RecBody::setSubtype(const QString&type) -{ - m_subtype = type; -} - -const QString& RecBody::Subtype()const -{ - return m_subtype; + return m_description; } diff --git a/noncore/net/mail/mailtypes.h b/noncore/net/mail/mailtypes.h index 900f10a..60db527 100644 --- a/noncore/net/mail/mailtypes.h +++ b/noncore/net/mail/mailtypes.h @@ -1,115 +1,128 @@ #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 <qlist.h> #include <qbitarray.h> #include <qstring.h> #include <qstringlist.h> +#include <qmap.h> +#include <qvaluelist.h> /* 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: RecMail(); RecMail(const RecMail&old); virtual ~RecMail(){} const int getNumber()const{return msg_number;} void setNumber(int number){msg_number=number;} const QString&getDate()const{ return date; } void setDate( const QString&a ) { date = 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(int size){msg_size = size;} const 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; const QBitArray&getFlags()const{return msg_flags;} void setFlags(const QBitArray&flags){msg_flags = flags;} protected: QString subject,date,from,mbox,msg_id,replyto; int msg_number,msg_size; QBitArray msg_flags; QStringList to,cc,bcc; void init(); void copy_old(const RecMail&old); }; +typedef QMap<QString,QString> part_plist_t; + class RecPart { protected: QString m_type,m_subtype,m_identifier,m_encoding; unsigned int m_lines; + part_plist_t m_Parameters; + /* describes the position in the mail */ + QValueList<int> m_poslist; + public: RecPart(); - RecPart(const QString&identifier,const QString&type="",const QString&subtype="",const QString&encoding="BASE64",unsigned int lines=0); 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); void setLines(unsigned int lines); const unsigned int Lines()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; }; class RecBody { protected: - QString m_BodyText,m_type,m_subtype; + QString m_BodyText; QList<RecPart> m_PartsList; + RecPart m_description; public: RecBody(); virtual ~RecBody(); void setBodytext(const QString&); const QString& Bodytext()const; - void setType(const QString&); - const QString&Type()const; - void setSubtype(const QString&); - const QString&Subtype()const; + void setDescription(const RecPart&des); + const RecPart& Description()const; void setParts(const QList<RecPart>&parts); const QList<RecPart>& Parts()const; void addPart(const RecPart&part); }; #endif |