qtmobility/src/messaging/qmessage_qmf.cpp
changeset 1 2b40d63a9c3d
child 4 90517678cc4f
equal deleted inserted replaced
0:cfcbf08528c4 1:2b40d63a9c3d
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Mobility Components.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 #include "qmessage.h"
       
    42 #include "qmessagecontentcontainer_p.h"
       
    43 #include "qmfhelpers_p.h"
       
    44 #include "qmessage_p.h"
       
    45 
       
    46 #include <qmailnamespace.h>
       
    47 
       
    48 #include <QCoreApplication>
       
    49 #include <QFileInfo>
       
    50 #include <QRegExp>
       
    51 
       
    52 using namespace QTM_PREPEND_NAMESPACE(QmfHelpers);
       
    53 
       
    54 // This class has friend access to QMailMessage
       
    55 // and hsould not be within QTM_NAMESPACE
       
    56 struct QMailStorePrivate
       
    57 {
       
    58     static inline void setUnmodified(QMailMessage *msg)
       
    59     {
       
    60         msg->setUnmodified();
       
    61     }
       
    62 };
       
    63 
       
    64 
       
    65 
       
    66 QTM_BEGIN_NAMESPACE
       
    67 
       
    68 Q_SCOPED_STATIC_DEFINE(QMessagePrivate::StandardFolderMap,QMessagePrivate,standardFolderMap);
       
    69 
       
    70 QMessageFolderId QMessagePrivate::standardFolderId(QMessage::StandardFolder folder)
       
    71 {
       
    72     StandardFolderMap::const_iterator it = standardFolderMap()->find(folder);
       
    73     if (it == standardFolderMap()->end()) {
       
    74         const char *path((folder == QMessage::InboxFolder ? "Inbox" : 
       
    75                          (folder == QMessage::OutboxFolder ? "Outbox" : 
       
    76                          (folder == QMessage::DraftsFolder ? "Drafts" : 
       
    77                          (folder == QMessage::SentFolder ? "Sent" : 
       
    78                          (folder == QMessage::TrashFolder ? "Trash" : ""))))));
       
    79 
       
    80         // Find the ID for this standard folder
       
    81         QMessageFolderFilter pathFilter(QMessageFolderFilter::byPath(path));
       
    82         QMessageFolderFilter accountFilter(QMessageFolderFilter::byParentAccountId(QMessageAccountId()));
       
    83 
       
    84         QMessageFolderId folderId(QMessageManager().queryFolders(pathFilter & accountFilter).first());
       
    85         it = standardFolderMap()->insert(folder, folderId);
       
    86     }
       
    87 
       
    88     return *it;
       
    89 }
       
    90 
       
    91 QMessage::StandardFolder QMessagePrivate::standardFolder(QMessageFolderId folderId)
       
    92 {
       
    93     StandardFolderMap::const_iterator it = standardFolderMap()->begin(), end = standardFolderMap()->end();
       
    94     for ( ; it != end; ++it) {
       
    95         if (it.value() == folderId) {
       
    96             return it.key();
       
    97         }
       
    98     }
       
    99 
       
   100     return QMessage::InboxFolder;
       
   101 }
       
   102 
       
   103 QMessage QMessagePrivate::convert(const QMailMessage &message)
       
   104 {
       
   105     QMessage result;
       
   106     result.d_ptr->_message = message;
       
   107     return result;
       
   108 }
       
   109 
       
   110 QMailMessage QMessagePrivate::convert(const QMessage &message)
       
   111 {
       
   112     return message.d_ptr->_message;
       
   113 }
       
   114 
       
   115 QMailMessage *QMessagePrivate::convert(QMessage *message)
       
   116 {
       
   117     return &message->d_ptr->_message;
       
   118 }
       
   119 
       
   120 /*
       
   121 const QMailMessage *QMessagePrivate::convert(const QMessage *message)
       
   122 {
       
   123     return &message->d_ptr->_message;
       
   124 }
       
   125 */
       
   126 
       
   127 void QMessagePrivate::setStandardFolder(QMessage& message, QMessage::StandardFolder sf)
       
   128 {
       
   129     QMessageFolderId folderId(standardFolderId(sf));
       
   130     message.d_ptr->_message.setParentFolderId(QmfHelpers::convert(folderId));
       
   131 }
       
   132 
       
   133 namespace QmfHelpers {
       
   134 
       
   135 QMessage convert(const QMailMessage &message)
       
   136 {
       
   137     return QMessagePrivate::convert(message);
       
   138 }
       
   139 
       
   140 QMailMessage convert(const QMessage &message)
       
   141 {
       
   142     return QMessagePrivate::convert(message);
       
   143 }
       
   144 
       
   145 QMailMessage *convert(QMessage *message)
       
   146 {
       
   147     return QMessagePrivate::convert(message);
       
   148 }
       
   149 
       
   150 /*
       
   151 const QMailMessage *convert(const QMessage *message)
       
   152 {
       
   153     return QMessagePrivate::convert(message);
       
   154 }
       
   155 */
       
   156 
       
   157 }
       
   158 
       
   159 namespace {
       
   160 
       
   161 struct TextPartLocator
       
   162 {
       
   163     QMailMessagePart::Location _location;
       
   164 
       
   165     bool operator()(const QMailMessagePart &part)
       
   166     {
       
   167         if (part.contentType().type().toLower() == "text") {
       
   168             _location = part.location();
       
   169             return false;
       
   170         }
       
   171 
       
   172         return true;
       
   173     }
       
   174 };
       
   175 
       
   176 struct PartLocator
       
   177 {
       
   178     QMailMessagePart::Location _location;
       
   179     const QMailMessagePart *_part;
       
   180 
       
   181     PartLocator(const QMailMessagePart::Location &location) : _location(location), _part(0) {}
       
   182 
       
   183     bool operator()(const QMailMessagePart &part)
       
   184     {
       
   185         if (part.location() == _location) {
       
   186             _part = &part;
       
   187             return false;
       
   188         }
       
   189 
       
   190         return true;
       
   191     }
       
   192 };
       
   193 
       
   194 struct AttachmentLocator
       
   195 {
       
   196     QList<QMailMessagePart::Location> _locations;
       
   197     bool _foundText;
       
   198 
       
   199     AttachmentLocator() : _foundText(false) {}
       
   200 
       
   201     bool operator()(const QMailMessagePart &part)
       
   202     {
       
   203         if (!_foundText && part.contentType().type().toLower() == "text") {
       
   204             _foundText = true;
       
   205         } else if (part.multipartType() == QMailMessagePart::MultipartNone) {
       
   206             _locations.append(part.location());
       
   207         }
       
   208 
       
   209         return true;
       
   210     }
       
   211 };
       
   212 
       
   213 QByteArray charsetFor(const QString &input)
       
   214 {
       
   215     QByteArray result(QMessage::preferredCharsetFor(input));
       
   216     if (result.isEmpty()) {
       
   217         result = "UTF-8";
       
   218     }
       
   219 
       
   220     return result;
       
   221 }
       
   222 
       
   223 }
       
   224 
       
   225 QMessage::QMessage()
       
   226     : d_ptr(new QMessagePrivate)
       
   227 {
       
   228     setDerivedMessage(this);
       
   229     QMailStorePrivate::setUnmodified(&d_ptr->_message);
       
   230 }
       
   231 
       
   232 QMessage::QMessage(const QMessageId& id)
       
   233     : d_ptr(new QMessagePrivate)
       
   234 {
       
   235     *this = QMessageManager().message(id);
       
   236     setDerivedMessage(this);
       
   237     QMailStorePrivate::setUnmodified(&d_ptr->_message);
       
   238 }
       
   239 
       
   240 QMessage::QMessage(const QMessage &other)
       
   241     : QMessageContentContainer(),
       
   242       d_ptr(new QMessagePrivate)
       
   243 {
       
   244     this->operator=(other);
       
   245     setDerivedMessage(this);
       
   246     QMailStorePrivate::setUnmodified(&d_ptr->_message);
       
   247 }
       
   248 
       
   249 QMessage& QMessage::operator=(const QMessage& other)
       
   250 {
       
   251     if (&other != this) {
       
   252         QMessageContentContainer::operator=(other);
       
   253         d_ptr->_message = other.d_ptr->_message;
       
   254         setDerivedMessage(this);
       
   255     }
       
   256 
       
   257     return *this;
       
   258 }
       
   259 
       
   260 QMessage::~QMessage()
       
   261 {
       
   262     delete d_ptr;
       
   263 }
       
   264 
       
   265 QMessageId QMessage::id() const
       
   266 {
       
   267     return convert(d_ptr->_message.id());
       
   268 }
       
   269 
       
   270 QMessage::Type QMessage::type() const
       
   271 {
       
   272     return convert(d_ptr->_message.messageType());
       
   273 }
       
   274 
       
   275 void QMessage::setType(Type t)
       
   276 {
       
   277     d_ptr->_message.setMessageType(convert(t));
       
   278 }
       
   279 
       
   280 QMessageAccountId QMessage::parentAccountId() const
       
   281 {
       
   282     return convert(d_ptr->_message.parentAccountId());
       
   283 }
       
   284 
       
   285 void QMessage::setParentAccountId(const QMessageAccountId &accountId)
       
   286 {
       
   287     d_ptr->_message.setParentAccountId(convert(accountId));    
       
   288 }
       
   289 
       
   290 QMessageFolderId QMessage::parentFolderId() const
       
   291 {
       
   292     return convert(d_ptr->_message.parentFolderId());
       
   293 }
       
   294 
       
   295 QMessage::StandardFolder QMessage::standardFolder() const
       
   296 {
       
   297     return QMessagePrivate::standardFolder(convert(d_ptr->_message.parentFolderId()));
       
   298 }
       
   299 
       
   300 QMessageAddress QMessage::from() const
       
   301 {
       
   302     return convert(d_ptr->_message.from());
       
   303 }
       
   304 
       
   305 void QMessage::setFrom(const QMessageAddress &address)
       
   306 {
       
   307     d_ptr->_message.setFrom(convert(address));
       
   308 }
       
   309 
       
   310 QString QMessage::subject() const
       
   311 {
       
   312     return d_ptr->_message.subject();
       
   313 }
       
   314 
       
   315 void QMessage::setSubject(const QString &s)
       
   316 {
       
   317     d_ptr->_message.setSubject(s);
       
   318 }
       
   319 
       
   320 QDateTime QMessage::date() const
       
   321 {
       
   322     return d_ptr->_message.date().toLocalTime();
       
   323 }
       
   324 
       
   325 void QMessage::setDate(const QDateTime &d)
       
   326 {
       
   327     d_ptr->_message.setDate(QMailTimeStamp(d));
       
   328 }
       
   329 
       
   330 QDateTime QMessage::receivedDate() const
       
   331 {
       
   332     return d_ptr->_message.receivedDate().toLocalTime();
       
   333 }
       
   334 
       
   335 void QMessage::setReceivedDate(const QDateTime &d)
       
   336 {
       
   337     d_ptr->_message.setReceivedDate(QMailTimeStamp(d));
       
   338 }
       
   339 
       
   340 QMessageAddressList QMessage::to() const
       
   341 {
       
   342     return convert(d_ptr->_message.to());
       
   343 }
       
   344 
       
   345 void QMessage::setTo(const QMessageAddressList& toList)
       
   346 {
       
   347     d_ptr->_message.setTo(convert(toList));
       
   348 }
       
   349 
       
   350 void QMessage::setTo(const QMessageAddress& address)
       
   351 {
       
   352     d_ptr->_message.setTo(convert(address));
       
   353 }
       
   354 
       
   355 QMessageAddressList QMessage::cc() const
       
   356 {
       
   357     return convert(d_ptr->_message.cc());
       
   358 }
       
   359 
       
   360 void QMessage::setCc(const QMessageAddressList& ccList)
       
   361 {
       
   362     d_ptr->_message.setCc(convert(ccList));
       
   363 }
       
   364 
       
   365 QMessageAddressList QMessage::bcc() const
       
   366 {
       
   367     return convert(d_ptr->_message.bcc());
       
   368 }
       
   369 
       
   370 void QMessage::setBcc(const QMessageAddressList& bccList)
       
   371 {
       
   372     d_ptr->_message.setBcc(convert(bccList));
       
   373 }
       
   374 
       
   375 QMessage::StatusFlags QMessage::status() const
       
   376 {
       
   377     return convert(d_ptr->_message.status());
       
   378 }
       
   379 
       
   380 void QMessage::setStatus(QMessage::StatusFlags newStatus)
       
   381 {
       
   382     d_ptr->_message.setStatus(convert(newStatus));
       
   383 }
       
   384 
       
   385 void QMessage::setStatus(QMessage::Status flag, bool set)
       
   386 {
       
   387     d_ptr->_message.setStatus(convert(flag), set);
       
   388 }
       
   389 
       
   390 QMessage::Priority QMessage::priority() const
       
   391 {
       
   392     quint64 status(d_ptr->_message.status());
       
   393 
       
   394     if (status & highPriorityMask()) {
       
   395         return QMessage::HighPriority;
       
   396     } else if (status & lowPriorityMask()) {
       
   397         return QMessage::LowPriority;
       
   398     }
       
   399 
       
   400     return QMessage::NormalPriority;
       
   401 }
       
   402 
       
   403 void QMessage::setPriority(Priority newPriority)
       
   404 {
       
   405     quint64 setMask(0);
       
   406     quint64 unsetMask(0);
       
   407 
       
   408     if (newPriority == QMessage::HighPriority) {
       
   409         setMask = highPriorityMask();
       
   410         unsetMask = lowPriorityMask();
       
   411     } else if (newPriority == QMessage::LowPriority) {
       
   412         unsetMask = highPriorityMask();
       
   413         setMask = lowPriorityMask();
       
   414     } else {
       
   415         unsetMask = (highPriorityMask() | lowPriorityMask());
       
   416     }
       
   417 
       
   418     if (setMask) {
       
   419         d_ptr->_message.setStatus(setMask, true);
       
   420     }
       
   421     if (unsetMask) {
       
   422         d_ptr->_message.setStatus(unsetMask, false);
       
   423     }
       
   424 }
       
   425 
       
   426 int QMessage::size() const
       
   427 {
       
   428     if ((d_ptr->_message.status() & QMailMessage::LocalOnly) && 
       
   429         (d_ptr->_message.dataModified() ||
       
   430          d_ptr->_message.contentModified())) {
       
   431         // We need to update the size estimate for this message
       
   432         d_ptr->_message.setSize(static_cast<int>(d_ptr->_message.indicativeSize()) * 1024);
       
   433     }
       
   434 
       
   435     return static_cast<int>(d_ptr->_message.size());
       
   436 }
       
   437 
       
   438 QMessageContentContainerId QMessage::bodyId() const
       
   439 {
       
   440     if (d_ptr->_message.hasBody()) {
       
   441         return QmfHelpers::bodyId(d_ptr->_message.id());
       
   442     }
       
   443 
       
   444     // Return the first text part
       
   445     TextPartLocator locator;
       
   446     d_ptr->_message.foreachPart<TextPartLocator&>(locator);
       
   447 
       
   448     return convert(locator._location);
       
   449 }
       
   450 
       
   451 void QMessage::setBody(const QString &bodyText, const QByteArray &mimeType)
       
   452 {
       
   453     QByteArray mainType("text");
       
   454     QByteArray subType("plain");
       
   455     QByteArray charset;
       
   456 
       
   457     int index = mimeType.indexOf("/");
       
   458     if (index != -1) {
       
   459         mainType = mimeType.left(index).trimmed();
       
   460 
       
   461         subType = mimeType.mid(index + 1).trimmed();
       
   462         index = subType.indexOf(";");
       
   463         if (index != -1) {
       
   464             QString remainder = subType.mid(index + 1);
       
   465             subType = subType.left(index).trimmed();
       
   466 
       
   467             QRegExp charsetPattern("charset=(\\S+)");
       
   468             index = charsetPattern.indexIn(remainder);
       
   469             if (index != -1) {
       
   470                 charset = charsetPattern.cap(1).toLatin1();
       
   471             }
       
   472         }
       
   473     }
       
   474 
       
   475     if (charset.isEmpty()) {
       
   476         charset = charsetFor(bodyText);
       
   477     }
       
   478 
       
   479     QMailMessageContentType ct;
       
   480     ct.setType(mainType);
       
   481     ct.setSubType(subType);
       
   482     ct.setCharset(charset);
       
   483 
       
   484     QMailMessageBody textBody(QMailMessageBody::fromData(bodyText, ct, QMailMessageBody::Base64));
       
   485 
       
   486     if (d_ptr->_message.multipartType() == QMailMessage::MultipartNone) {
       
   487         // Replace the body with this data
       
   488         d_ptr->_message.setBody(textBody);
       
   489     } else {
       
   490         // Replace any existing text with this part
       
   491         TextPartLocator locator;
       
   492         d_ptr->_message.foreachPart<TextPartLocator&>(locator);
       
   493         if (locator._location.isValid()) {
       
   494             // Update the existing body text part to contain the new text
       
   495             QMailMessagePart &bodyPart = d_ptr->_message.partAt(locator._location);
       
   496             bodyPart.setBody(textBody);
       
   497         } else {
       
   498             // Insert the text as the new first part
       
   499             QMailMessageContentDisposition cd(QMailMessageContentDisposition::Inline);
       
   500             QMailMessagePart part(QMailMessagePart::fromData(bodyText, ct, cd, QMailMessageBody::Base64));
       
   501             d_ptr->_message.prependPart(part);
       
   502         }
       
   503     }
       
   504 }
       
   505 
       
   506 void QMessage::setBody(QTextStream &in, const QByteArray &mimeType)
       
   507 {
       
   508     // Note we have to read the data from the stream, in order to determine the relevant charset
       
   509     setBody(in.readAll(), mimeType);
       
   510 }
       
   511 
       
   512 QMessageContentContainerIdList QMessage::attachmentIds() const
       
   513 {
       
   514     // Return any non-multipart parts excluding the first text part
       
   515     AttachmentLocator locator;
       
   516     d_ptr->_message.foreachPart<AttachmentLocator&>(locator);
       
   517 
       
   518     return convert(locator._locations);
       
   519 }
       
   520 
       
   521 void QMessage::appendAttachments(const QStringList &fileNames)
       
   522 {
       
   523     if (d_ptr->_message.multipartType() == QMailMessage::MultipartNone) {
       
   524         if (d_ptr->_message.hasBody()) {
       
   525             // Move the existing body to become the first part
       
   526             QMailMessageContentType ct(d_ptr->_message.contentType());
       
   527             QString bodyText(d_ptr->_message.body().data());
       
   528 
       
   529             QMailMessageContentDisposition cd(QMailMessageContentDisposition::Inline);
       
   530             cd.setSize(bodyText.length());
       
   531 
       
   532             QMailMessagePart textPart(QMailMessagePart::fromData(bodyText, cd, ct, QMailMessageBody::Base64));
       
   533 
       
   534             d_ptr->_message.setMultipartType(QMailMessage::MultipartMixed);
       
   535             d_ptr->_message.appendPart(textPart);
       
   536         } else {
       
   537             // Just set this message to be multipart
       
   538             d_ptr->_message.setMultipartType(QMailMessage::MultipartMixed);
       
   539         }
       
   540     }
       
   541 
       
   542     foreach (const QString &filename, fileNames) {
       
   543         QString mimeType(QMail::mimeTypeFromFileName(filename));
       
   544         if (!mimeType.isEmpty()) {
       
   545             QFileInfo fi(filename);
       
   546 
       
   547             QMailMessageContentDisposition cd(QMailMessageContentDisposition::Attachment);
       
   548             cd.setFilename(fi.fileName().toAscii());
       
   549             cd.setSize(fi.size());
       
   550 
       
   551             QMailMessageContentType ct(mimeType.toAscii());
       
   552 
       
   553             QMailMessagePart part(QMailMessagePart::fromFile(filename, cd, ct, QMailMessageBody::Base64, QMailMessageBody::RequiresEncoding));
       
   554             d_ptr->_message.appendPart(part);
       
   555         }
       
   556     }
       
   557 }
       
   558 
       
   559 void QMessage::clearAttachments()
       
   560 {
       
   561     QMessageContentContainerId textId(bodyId());
       
   562     QMailMessagePart::Location textLocation(convert(textId));
       
   563 
       
   564     for (uint i = d_ptr->_message.partCount(); i > 0; --i) {
       
   565         QMailMessagePart &part = d_ptr->_message.partAt(i - 1);
       
   566         if (!(part.location() == textLocation)) {
       
   567             // Ensure that this part does not contain the text part
       
   568             PartLocator locator(textLocation);
       
   569             part.foreachPart<PartLocator&>(locator);
       
   570             if (locator._part == 0) {
       
   571                 d_ptr->_message.removePartAt(i - 1);
       
   572             }
       
   573         }
       
   574     }
       
   575 }
       
   576 
       
   577 bool QMessage::isModified() const
       
   578 {
       
   579     return (d_ptr->_message.dataModified() || d_ptr->_message.contentModified());
       
   580 }
       
   581 
       
   582 QMessage QMessage::createResponseMessage(ResponseType type) const
       
   583 {
       
   584     QMessage response;
       
   585 
       
   586     if (type == Forward) {
       
   587         QString subject(d_ptr->_message.subject());
       
   588         response.setSubject("Fwd:" + subject);
       
   589 
       
   590         if (d_ptr->_message.contentType().type().toLower() == "text") {
       
   591             // Forward the text content inline
       
   592             QString existingText = d_ptr->_message.body().data();
       
   593 
       
   594             QString prefix("\r\n----- Forwarded Message -----\r\n\r\n");
       
   595             prefix.append(QString("%1: %2\r\n").arg(qApp->translate("QMessage", "Subject")).arg(subject));
       
   596             prefix.append(QString("%1: %2\r\n").arg(qApp->translate("QMessage", "Date")).arg(date().toString()));
       
   597             prefix.append(QString("%1: %2\r\n").arg(qApp->translate("QMessage", "From")).arg(d_ptr->_message.from().toString()));
       
   598 
       
   599             QStringList addresses;
       
   600             foreach (const QMailAddress &address, d_ptr->_message.to()) {
       
   601                 addresses.append(address.toString());
       
   602             }
       
   603 
       
   604             prefix.append(QString("%1: %2\r\n").arg(qApp->translate("QMessage", "To")).arg(addresses.join(",")));
       
   605 
       
   606             QString postfix("\r\n\r\n-----------------------------\r\n");
       
   607 
       
   608             response.setBody(prefix + existingText + postfix);
       
   609         } else {
       
   610             if (QMailMessage *msg = convert(&response)) {
       
   611                 msg->setMultipartType(QMailMessage::MultipartMixed);
       
   612 
       
   613                 QMailMessageContentDisposition cd(QMailMessageContentDisposition::Inline);
       
   614 
       
   615                 {
       
   616                     // Add an empty text body to be composed into
       
   617                     QMailMessageContentType ct("text/plain");
       
   618                     QMailMessagePart part(QMailMessagePart::fromData(QString(), cd, ct, QMailMessageBody::Base64));
       
   619                     msg->appendPart(part);
       
   620                 }
       
   621 
       
   622                 {
       
   623                     // Include the entirety of this message as a nested part
       
   624                     QMailMessageContentType ct("message/rfc822");
       
   625                     QByteArray responseData(d_ptr->_message.toRfc2822(QMailMessage::TransmissionFormat));
       
   626                     QMailMessagePart part(QMailMessagePart::fromData(responseData, cd, ct, QMailMessageBody::Base64));
       
   627                     msg->appendPart(part);
       
   628                 }
       
   629             }
       
   630         }
       
   631     } else {
       
   632         if (QMailMessage *msg = convert(&response)) {
       
   633             QMailAddress to(d_ptr->_message.replyTo());
       
   634             if (to.address().isEmpty()) {
       
   635                 to = d_ptr->_message.from();
       
   636             }
       
   637             response.setTo(convert(to));
       
   638 
       
   639             if (type == ReplyToAll) {
       
   640                 QList<QMessageAddress> cc;
       
   641                 foreach (const QMailAddress &address, d_ptr->_message.to() + d_ptr->_message.cc()) {
       
   642                     cc.append(convert(address));
       
   643                 }
       
   644 
       
   645                 response.setCc(cc);
       
   646             }
       
   647 
       
   648             QString subject(d_ptr->_message.subject());
       
   649             response.setSubject("Re:" + subject);
       
   650 
       
   651             QString messageId(d_ptr->_message.headerFieldText("Message-Id"));
       
   652             QString references(d_ptr->_message.headerFieldText("References"));
       
   653 
       
   654             if (!messageId.isEmpty()) {
       
   655                 if (!references.isEmpty()) {
       
   656                     references.append(' ');
       
   657                 }
       
   658                 references.append(messageId);
       
   659 
       
   660                 msg->setHeaderField("In-Reply-To", messageId);
       
   661             }
       
   662             if (!references.isEmpty()) {
       
   663                 msg->setHeaderField("References", references);
       
   664             }
       
   665 
       
   666             QString existingText;
       
   667             QMessageContentContainerIdList attachments;
       
   668 
       
   669             if (d_ptr->_message.contentType().type().toLower() == "text") {
       
   670                 existingText = d_ptr->_message.body().data();
       
   671             } else {
       
   672                 // Is there any text in this message?
       
   673                 QMessageContentContainerId textId(bodyId());
       
   674                 if (textId.isValid()) {
       
   675                     QMessageContentContainer textPart(find(textId));
       
   676                     existingText = textPart.textContent();
       
   677                 }
       
   678 
       
   679                 // Find the remaining parts of the message
       
   680                 attachments = attachmentIds();
       
   681             }
       
   682 
       
   683             if (!existingText.isEmpty()) {
       
   684                 existingText = existingText.replace("\n", "\n> ");
       
   685 
       
   686                 QString prefix(qApp->translate("QMessage", "On %1 you wrote:\n> "));
       
   687                 prefix = prefix.arg(d_ptr->_message.date().toLocalTime().toString());
       
   688                 response.setBody(prefix + existingText);
       
   689             }
       
   690 
       
   691             foreach (const QMessageContentContainerId &attachmentId, attachments) {
       
   692                 QMessageContentContainer attachment(find(attachmentId));
       
   693                 msg->appendPart(attachment.d_ptr->_part);
       
   694             }
       
   695         }
       
   696     }
       
   697 
       
   698     return response;
       
   699 }
       
   700 
       
   701 
       
   702 QTM_END_NAMESPACE