void WriteMail::modify(const QMailMessage& previousMessage) { QString recipients = ""; prepareComposer(previousMessage.messageType(), previousMessage.parentAccountId()); if (composer().isEmpty()) return; // Record any message properties we should retain mail.setId(previousMessage.id()); mail.setParentFolderId(previousMessage.parentFolderId()); mail.setContentScheme(previousMessage.contentScheme()); mail.setContentIdentifier(previousMessage.contentIdentifier()); mail.setTo(previousMessage.to()); mail.setFrom(previousMessage.from()); mail.setCustomFields(previousMessage.customFields()); mail.setServerUid(previousMessage.serverUid()); m_composerInterface->compose(QMailMessage::NoResponse, previousMessage); // ugh. we need to do this everywhere m_hasMessageChanged = false; m_precursorId = mail.inResponseTo(); m_replyAction = mail.responseType(); }
// organized after lest expensive search bool Search::matches(const QMailMessage& in) const { if ( !matchesStatus(in) ) return false; if ( !matchesAccount(in) ) return false; if ( !matchesFolder(in) ) return false; if ( !match(fromMail, in.from().toString() ) ) return false; if ( !matchesTo(in) ) return false; if ( !match(subject, in.subject() ) ) return false; if ( !matchesBeforeDate(in) ) return false; if ( !matchesAfterDate(in) ) return false; if ( !matchesBody(in) ) return false; return true; }
void WriteMail::create(const QMailMessage& initMessage) { prepareComposer(initMessage.messageType(), initMessage.parentAccountId()); if (composer().isEmpty()) return; m_composerInterface->compose(QMailMessage::NoResponse, initMessage); m_hasMessageChanged = true; }
bool MessageFolder::insertMessage(QMailMessage &message) { message.setParentFolderId(mFolder.id()); if (message.id().isValid()) { return QMailStore::instance()->updateMessage(&message); } else { return QMailStore::instance()->addMessage(&message); } }
void WriteMail::respond(const QMailMessage& source, QMailMessage::ResponseType type) { prepareComposer(source.messageType(), source.parentAccountId()); if (composer().isEmpty()) return; m_composerInterface->compose(type, source); m_hasMessageChanged = true; m_precursorId = source.id(); m_replyAction = type; }
bool Search::matchesStatus(const QMailMessage& mail) const { switch( _status ) { case Any: return true; case Read: return ( mail.status() & (QMailMessage::Read | QMailMessage::ReadElsewhere) ); case Unread: return ( !(mail.status() & (QMailMessage::Read | QMailMessage::ReadElsewhere)) ); case Replied: return ( (mail.status() & QMailMessage::Replied) || (mail.status() & QMailMessage::RepliedAll) ); } return false; }
bool Search::matchesFolder(const QMailMessage& mail) const { if ( folder.isEmpty() ) return true; return ( folder == mail.fromMailbox() ); }
/* Reading entire mailbox is very slow on a large mailbox */ bool Search::matchesBody(const QMailMessage& mail) const { if ( body.isEmpty() ) return true; return match(body, mail.body().data()); }
QString EmailMessageListModel::bodyPlainText(const QMailMessage &mailMsg) const { if (QMailMessagePartContainer *container = mailMsg.findPlainTextContainer()) { return container->body().data(); } return QString(); }
void ConversationPage::processAttachments(const QMailMessage &message) { if (!message.status() & QMailMessageMetaData::HasAttachments) return; connect(this, SIGNAL(downloadCompleted()), this, SLOT(saveAttachment())); bool oneTimeFlag = true; for (uint i = 1; i < message.partCount(); ++i) { QMailMessagePart sourcePart = message.partAt(i); if (!(sourcePart.multipartType() == QMailMessagePartContainer::MultipartNone)) continue; if (oneTimeFlag) { MSeparator *separator = new MSeparator(); separator->setObjectName("Separator"); m_policy->addItem(separator); oneTimeFlag = false; } MStylableWidget *w = new MStylableWidget(this); QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Horizontal); w->setLayout(layout); //% "Attached: " MLabel *label = new MLabel(qtTrId("xx_attached")); label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); label->setObjectName ("AttachmentText"); layout->addItem(label); MButton *button = new MButton(sourcePart.displayName()); button->setObjectName ("AttachmentButton"); button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); layout->addItem(button); //% "Download..." AttachmentAction *action = new AttachmentAction(qtTrId("xx_download_context_menu"), button, sourcePart); connect(action, SIGNAL(triggered()), this, SLOT(openAttachmentDownloadDialog())); //% "Open..." action = new AttachmentAction(qtTrId("xx_open_context_menu"), button, sourcePart); connect(action, SIGNAL(triggered()), this, SLOT(openAttachmentOpenDialog())); m_policy->addItem (w); } }
bool Search::matchesAccount(const QMailMessage& mail) const { if ( fromAccount.isEmpty() ) return true; if (fromAccount == mail.fromAccount() ) return true; return false; }
/* TODO: We should swap the mail in to get the full to, cc and bcc lists. Only to.first() are currently cached. Reading all the mails from disk are currently to slow a process though */ bool Search::matchesTo(const QMailMessage& mail) const { if ( recipient.isEmpty() ) return true; foreach (const QMailAddress& address, mail.to()) if ( match( recipient, address.toString() ) ) return true; return false; }
void EmailComposerInterface::setMessage( const QMailMessage &mail ) { if (mail.multipartType() == QMailMessagePartContainer::MultipartNone) { if (mail.hasBody()) setText( mail.body().data(), mail.contentType().content() ); } else { // The only type of multipart message we currently compose is Mixed, with // all but the first part as out-of-line attachments int textPart = -1; for ( uint i = 0; i < mail.partCount(); ++i ) { QMailMessagePart &part = const_cast<QMailMessagePart&>(mail.partAt(i)); if (textPart == -1 && part.contentType().type().toLower() == "text") { // This is the first text part, we will use as the forwarded text body textPart = i; } else { QString attPath = part.attachmentPath(); QMailMessage::AttachmentsAction action = QMailMessage::LinkToAttachments; // Detach the part data to a temporary file if necessary if (attPath.isEmpty()) { if (part.detachAttachment(Qtopia::tempDir())) { attPath = part.attachmentPath(); action = QMailMessage::CopyAttachments; // Create a content object for the file QContent doc(attPath); if (part.hasBody()) { QMailMessageContentType type(part.contentType()); if (doc.drmState() == QContent::Unprotected) doc.setType(type.content()); } doc.setName(part.displayName()); doc.setRole(QContent::Data); doc.commit(); // This needs to be removed after composition m_temporaries.append(doc); } } if (!attPath.isEmpty()) attach(attPath, action); } } if (textPart != -1) { const QMailMessagePart& part = mail.partAt(textPart); setText( part.body().data(), part.contentType().content() ); } } }
QString AttachmentListModel::attachmentUrl(const QMailMessage message, const QString &attachmentLocation) { QString attachmentDownloadFolder = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + "/mail_attachments/" + attachmentLocation; for (uint i = 0; i < message.partCount(); i++) { QMailMessagePart sourcePart = message.partAt(i); if (attachmentLocation == sourcePart.location().toString(true)) { QString attachmentPath = attachmentDownloadFolder + "/" + sourcePart.displayName(); QFile f(attachmentPath); if (f.exists()) { return attachmentPath; } else { // we have the part downloaded locally but not in a file type yet if (sourcePart.hasBody()) { QString path = sourcePart.writeBodyTo(attachmentDownloadFolder); return path; } return QString(); } } } return QString(); }
// match against date, if the mails date is not parsed, always return true bool Search::matchesAfterDate(const QMailMessage& mail) const { if ( afterDate.isNull() ) return true; QDateTime dateTime = mail.date().toLocalTime(); if ( dateTime.isNull() ) return true; if ( afterDate < dateTime.date() ) return true; return false; }
QString EmailMessageListModel::bodyHtmlText(const QMailMessage &mailMsg) const { // TODO: This function assumes that at least the structure has been retrieved already if (const QMailMessagePartContainer *container = mailMsg.findHtmlContainer()) { if (!container->contentAvailable()) { // Retrieve the data for this part connect (m_retrievalAction, SIGNAL(activityChanged(QMailServiceAction::Activity)), this, SLOT(downloadActivityChanged(QMailServiceAction::Activity))); QMailMessagePart::Location location = static_cast<const QMailMessagePart *>(container)->location(); m_retrievalAction->retrieveMessagePart(location); return " "; // Put a space here as a place holder to notify UI that we do have html body. } return container->body().data(); } return QString(); }
bool SmsClient::addMail(const QMailMessage& mail) { QList<QMailAddress> smsRecipients = separateSmsAddresses(mail.recipients()); Q_ASSERT(smsRecipients.count() > 0); QString smsBody = formatOutgoing(mail.subject(),mail.body().data()); foreach (const QMailAddress& recipient, smsRecipients) { if(smsAddress(recipient)) { if(!validSmsAddress(recipient)) { QString temp = "<qt>" + tr("Invalid SMS recipient specified for\n " "mail with subject:\n%1\n" "NO mail has been sent.") .arg( mail.subject() ) + "</qt>"; emit errorOccurred(0,temp); return false; } else { //address is valid, queue for sending // Extract the phone number from the e-mail address. RawSms msg; msg.msgId = mail.id(); msg.number = QPhoneNumber::resolveLetters( recipient.address() ); msg.body = smsBody; if (mail.contentType().content().toLower() == "text/x-vcard") msg.mimetype = QLatin1String("text/x-vCard"); else msg.mimetype = QLatin1String("text/plain"); smsList.append( msg ); } } } return true; }
bool WriteMail::buildMail(bool includeSignature) { QMailAccountId accountId(m_accountSelection->itemData(m_accountSelection->currentIndex()).value<QMailAccountId>()); // Ensure the signature of the selected account is used if (accountId.isValid() && includeSignature) { m_composerInterface->setSignature(signature(accountId)); } // Extract the message from the composer QMailMessage newMail = m_composerInterface->message(); // Retain the old mail properties if they're configured newMail.setId(mail.id()); newMail.setParentFolderId(mail.parentFolderId()); newMail.setContentScheme(mail.contentScheme()); newMail.setContentIdentifier(mail.contentIdentifier()); newMail.setServerUid(mail.serverUid()); newMail.setCustomFields(mail.customFields()); newMail.setDate(QMailTimeStamp::currentDateTime()); newMail.setStatus(QMailMessage::Outgoing, true); newMail.setStatus(QMailMessage::ContentAvailable, true); newMail.setStatus(QMailMessage::PartialContentAvailable, true); newMail.setStatus(QMailMessage::Read, true); if (accountId.isValid()) { newMail.setParentAccountId(accountId); newMail.setFrom(QMailAccount(accountId).fromAddress()); } if (!newMail.parentFolderId().isValid()) { newMail.setParentFolderId(QMailFolder::LocalStorageFolderId); } if (m_precursorId.isValid()) { newMail.setInResponseTo(m_precursorId); newMail.setResponseType(m_replyAction); QMailMessage precursor(m_precursorId); // Set the In-Reply-To and References headers in our outgoing message QString references(precursor.headerFieldText("References")); if (references.isEmpty()) { references = precursor.headerFieldText("In-Reply-To"); } QString precursorId(precursor.headerFieldText("Message-ID")); if (!precursorId.isEmpty()) { newMail.setHeaderField("In-Reply-To", precursorId); if (!references.isEmpty()) { references.append(' '); } references.append(precursorId); } if (!references.isEmpty()) { // TODO: Truncate references if they're too long newMail.setHeaderField("References", references); } } mail = newMail; return true; }
void SmsClient::fetched( const QString& id, const QSMSMessage& message ) { if (!id.isEmpty()) { QMailMessage mail; QString subject; QString body; int part; // Construct a full identity for the message. This should be // unique enough to identify messages on different SIM's. QDateTime dt = message.timestamp(); QString identity = QString("sms:%1:%2%3%4%5%6%7:>%8") .arg( simIdentity ) .arg( dt.date().year(), 4 ) .arg( dt.date().month(), 2 ) .arg( dt.date().day(), 2 ) .arg( dt.time().hour(), 2 ) .arg( dt.time().minute(), 2 ) .arg( dt.time().second(), 2 ) .arg( id ); // Add it to the active list, so that we know what's on the // inserted SIM right now, as opposed to the cached copy in // the mailbox folder. activeIds += identity; timeStamps += dt; // If we already have this message in the mailbox, then ignore it. if ( account ) { QStringList list = account->getUidlList(); if ( list.contains( identity ) ) { if ( account->deleteMail() ) deleteImmediately( id ); req->nextMessage(); return; } list += identity; account->setUidlList( list ); } mail.setServerUid( identity ); // If the sender is not set, but the recipient is, then this // is probably an outgoing message that was reflected back // by the phone simulator. if( !message.sender().isEmpty() ) mail.setHeaderField( "From", message.sender() ); else if( !message.recipient().isEmpty() ) mail.setHeaderField( "From", message.recipient() ); // Extract the subject and body. extractSubjectAndBody( message.text(), subject, body ); // Set the subject from the first few words of the text. mail.setSubject( subject ); // Determine if the entire body is text, or if it contains attachments. bool hasAttachments = false; QList<QSMSMessagePart> parts = message.parts(); for ( part = 0; part < parts.count(); ++part ) { if ( !(parts[part].isText()) ) { hasAttachments = true; break; } } if( !hasAttachments ) { QMailMessageContentType type("text/plain; charset=UTF-8"); mail.setBody( QMailMessageBody::fromData( body, type, QMailMessageBody::Base64 ) ); } else { SMSDecoder::formatMessage( mail, message ); } // Set the reception date. QDateTime date = message.timestamp(); if (!date.isValid()) date = QDateTime::currentDateTime(); mail.setDate( QMailTimeStamp( date ) ); // Synthesize some other headers QString smsType; switch(message.messageType()) { case QSMSMessage::Normal: smsType = "normal"; break; case QSMSMessage::CellBroadCast: smsType = "broadcast"; break; case QSMSMessage::StatusReport: smsType = "status-report"; break; default: smsType = "unknown"; break; } mail.setHeaderField( "X-Sms-Type", smsType ); QMailId id; mail.setId( id ); mail.setStatus( QMailMessage::Incoming, true); mail.setStatus( QMailMessage::Downloaded, true); mail.setFromAccount( account->id() ); mail.setFromMailbox( "" ); mail.setMessageType( QMailMessage::Sms ); // Is this necessary? QByteArray mailStr = mail.toRfc2822(); mail.setSize( mailStr.length() ); emit newMessage(mail); // If the "deleteMail" flag is set, then delete the message // from the SIM immediately, rather than waiting for later. if ( account && account->deleteMail() ) deleteImmediately( QString::number(id.toULongLong()) ); req->nextMessage(); sawNewMessage = true; } else { smsFetching = false; if ( sawNewMessage ) { // Check again, just in case another new message arrived // while we were performing the fetch. req->check(); return; } emit allMessagesReceived(); // Make sure there are always 5 free slots on the SIM card // so there is enough space for the reception of new messages. if ( account && !account->deleteMail() && (req->totalMessages() - req->usedMessages()) < 5 && req->totalMessages() >= 5 && !timeStamps.isEmpty() ) { int toBeDeleted = 5 - (req->totalMessages() - req->usedMessages()); while ( toBeDeleted-- > 0 && activeIds.size() > 0 ) { QDateTime dt = timeStamps[0]; int index = 0; for (int i = 1; i < timeStamps.size(); ++i) { if (timeStamps[i] < dt) { dt = timeStamps[i]; index = i; } } deleteImmediately( activeIds[index] ); activeIds.removeAt( index ); timeStamps.removeAt( index ); } } } }
void tst_QMailMessagePart::testSerialization() { QByteArray data; QByteArray type; type = "text/plain; charset=us-ascii"; data = "P1: This is a plain text part."; QMailMessagePart p1; p1.setBody(QMailMessageBody::fromData(data, QMailMessageContentType(type), QMailMessageBody::SevenBit, QMailMessageBody::RequiresEncoding)); p1.setContentID("P1"); p1.setContentLocation("After the header"); p1.setContentDescription("The first part"); QCOMPARE( p1.contentType().toString().toLower(), QByteArray("Content-Type: text/plain; charset=us-ascii").toLower() ); QCOMPARE( p1.transferEncoding(), QMailMessageBody::SevenBit ); type = "text/html; charset=UTF-8"; data = "<html>P2: This is a HTML part</html>"; QMailMessageContentType ct(type); ct.setName("P2"); QMailMessageContentDisposition cd(QMailMessageContentDisposition::Inline); cd.setFilename("p2.html"); QMailMessagePart p2; p2.setBody(QMailMessageBody::fromData(data, ct, QMailMessageBody::EightBit, QMailMessageBody::RequiresEncoding)); p2.setContentDisposition(cd); QCOMPARE( p2.contentType().toString().toLower(), QByteArray("Content-Type: text/html; charset=UTF-8; name=P2").toLower() ); QCOMPARE( p2.transferEncoding(), QMailMessageBody::EightBit ); QMailMessage m; m.setTo(QMailAddress("*****@*****.**")); m.setFrom(QMailAddress("*****@*****.**")); m.setDate(QMailTimeStamp("Fri, 22 Jun 2007 11:34:47 +1000")); m.setMultipartType(QMailMessagePartContainer::MultipartAlternative); m.appendPart(p1); m.appendPart(p2); QCOMPARE( m.contentType().toString().toLower(), QByteArray("Content-Type: multipart/alternative").toLower() ); QCOMPARE( m.transferEncoding(), QMailMessageBody::NoEncoding ); const QByteArray expected( "To: [email protected]" CRLF "From: [email protected]" CRLF "Date: Fri, 22 Jun 2007 11:34:47 +1000" CRLF "Content-Type: multipart/alternative; boundary=\"" BOUNDARY "\"" CRLF "MIME-Version: 1.0" CRLF CRLF "This is a multipart message in Mime 1.0 format" CRLF CRLF "--" BOUNDARY CRLF "Content-Type: text/plain; charset=us-ascii" CRLF "Content-Transfer-Encoding: 7bit" CRLF "Content-ID: <P1>" CRLF "Content-Location: After the header" CRLF "Content-Description: The first part" CRLF CRLF "P1: This is a plain text part." CRLF "--" BOUNDARY CRLF "Content-Type: text/html; charset=utf-8; name=P2" CRLF "Content-Transfer-Encoding: 8bit" CRLF "Content-Disposition: inline; filename=p2.html" CRLF CRLF "<html>P2: This is a HTML part</html>" CRLF "--" BOUNDARY "--" CRLF ); QByteArray serialized = m.toRfc2822(); QCOMPARE( serialized, expected ); QMailMessage m2 = QMailMessage::fromRfc2822(serialized); QByteArray repeat = m.toRfc2822(); QCOMPARE( serialized, repeat ); }
void tst_QMailMessagePart::removeHeaderField() { QString addr1("*****@*****.**"); QString addr2("*****@*****.**"); QMailMessage m; QCOMPARE(m.headerFieldText("Resent-From"), QString()); QCOMPARE(m.headerField("Resent-From"), QMailMessageHeaderField()); QCOMPARE(m.headerFieldsText("Resent-From"), QStringList()); QCOMPARE(m.headerFields("Resent-From"), QList<QMailMessageHeaderField>()); m.appendHeaderField("Resent-From", addr1); m.appendHeaderField("Resent-From", addr2); QCOMPARE(m.headerFieldText("Resent-From"), addr1); QCOMPARE(m.headerField("Resent-From").content(), addr1.toLatin1()); QCOMPARE(m.headerFieldsText("Resent-From"), (QStringList() << addr1 << addr2)); QCOMPARE(m.headerFields("Resent-From"), ( QList<QMailMessageHeaderField>() << QMailMessageHeaderField("Resent-From", addr1.toLatin1()) << QMailMessageHeaderField("Resent-From", addr2.toLatin1()) ) ); m.removeHeaderField("X-Unused-Header"); QCOMPARE(m.headerFieldText("Resent-From"), addr1); QCOMPARE(m.headerField("Resent-From").content(), addr1.toLatin1()); QCOMPARE(m.headerFieldsText("Resent-From"), (QStringList() << addr1 << addr2)); QCOMPARE(m.headerFields("Resent-From"), ( QList<QMailMessageHeaderField>() << QMailMessageHeaderField("Resent-From", addr1.toLatin1()) << QMailMessageHeaderField("Resent-From", addr2.toLatin1()) ) ); m.removeHeaderField("Resent-From"); QCOMPARE(m.headerFieldText("Resent-From"), QString()); QCOMPARE(m.headerField("Resent-From"), QMailMessageHeaderField()); QCOMPARE(m.headerFieldsText("Resent-From"), QStringList()); QCOMPARE(m.headerFields("Resent-From"), QList<QMailMessageHeaderField>()); }
QString EmailMessageListModel::bodyHtmlText(QMailMessagePartContainer *container) const { QMailMessageContentType contentType = container->contentType(); if (container->multipartType() == QMailMessagePartContainerFwd::MultipartNone) { if (contentType.subType().toLower() == "html") { if (container->hasBody() && container->body().data().size() > 1) return container->body().data(); else { connect (m_retrievalAction, SIGNAL(activityChanged(QMailServiceAction::Activity)), this, SLOT(downloadActivityChanged(QMailServiceAction::Activity))); QMailMessage *msg = (QMailMessage *)container; QMailMessageIdList ids; ids << msg->id(); m_retrievalAction->retrieveMessages(ids, QMailRetrievalAction::Content); return " "; // Put a space here as a place holder to notify UI that we do have html body. // Should find a better way. } } return ""; } if (!container->contentAvailable()) { // if content is not available, attempts to downlaod from the server. connect (m_retrievalAction, SIGNAL(activityChanged(QMailServiceAction::Activity)), this, SLOT(downloadActivityChanged(QMailServiceAction::Activity))); QMailMessage *msg = (QMailMessage *)container; QMailMessageIdList ids; ids << msg->id(); m_retrievalAction->retrieveMessages(ids, QMailRetrievalAction::Content); return " "; // Put a space here as a place holder to notify UI that we do have html body. } QString text(""); for ( uint i = 0; i < container->partCount(); i++ ) { QMailMessagePart messagePart = container->partAt(i); contentType = messagePart.contentType(); if (contentType.type().toLower() == "text" && contentType.subType().toLower() == "html") { if (messagePart.hasBody()) { text += messagePart.body().data(); } else { connect (m_retrievalAction, SIGNAL(activityChanged(QMailServiceAction::Activity)), this, SLOT(downloadActivityChanged(QMailServiceAction::Activity))); QMailMessagePart::Location location = messagePart.location(); m_retrievalAction->retrieveMessagePart(location); text = " "; break; } } QMailMessagePart subPart; for (uint j = 0; j < messagePart.partCount(); j++) { subPart = messagePart.partAt(j); contentType = subPart.contentType(); if (contentType.type().toLower() == "text" && contentType.subType().toLower() == "html") { if (subPart.hasBody()) { text += subPart.body().data(); } else { connect (m_retrievalAction, SIGNAL(activityChanged(QMailServiceAction::Activity)), this, SLOT(downloadActivityChanged(QMailServiceAction::Activity))); QMailMessagePart::Location location = subPart.location(); m_retrievalAction->retrieveMessagePart(location); text = " "; break; } } } } return text; }
QVariant EmailMessageListModel::data(const QModelIndex & index, int role) const { if (!index.isValid() || index.row() > rowCount(parent(index))) return QVariant(); if (role == QMailMessageModelBase::MessageTimeStampTextRole) { QMailMessageId msgId = idFromIndex(index); QMailMessageMetaData message(msgId); QDateTime timeStamp = message.date().toLocalTime(); return (timeStamp.toString("hh:mm MM/dd/yyyy")); } else if (role == MessageAttachmentCountRole) { // return number of attachments QMailMessage messageMetaData(idFromIndex(index)); if (!messageMetaData.status() & QMailMessageMetaData::HasAttachments) return 0; // TODO: can we satisfy this from metadata too? QMailMessage message(idFromIndex(index)); int numberOfAttachments = 0; for (uint i = 1; i < message.partCount(); i++) { QMailMessagePart sourcePart = message.partAt(i); if (!(sourcePart.multipartType() == QMailMessagePartContainer::MultipartNone)) continue; QMailMessageContentType contentType = sourcePart.contentType(); if (sourcePart.hasBody() && contentType.type().toLower() == "text" && contentType.subType().toLower() == "plain") continue; if (i == 1 && contentType.type().toLower() == "text" && contentType.subType().toLower() == "html") continue; numberOfAttachments += 1; } return numberOfAttachments; } else if (role == MessageAttachmentsRole) { // return a stringlist of attachments QMailMessage messageMetaData(idFromIndex(index)); if (!messageMetaData.status() & QMailMessageMetaData::HasAttachments) return QStringList(); QMailMessage message(idFromIndex(index)); QStringList attachments; for (uint i = 1; i < message.partCount(); i++) { QMailMessagePart sourcePart = message.partAt(i); if (!(sourcePart.multipartType() == QMailMessagePartContainer::MultipartNone)) continue; QMailMessageContentType contentType = sourcePart.contentType(); if (sourcePart.hasBody() && contentType.type().toLower() == "text" && contentType.subType().toLower() == "plain") continue; if (i == 1 && contentType.type().toLower() == "text" && contentType.subType().toLower() == "html") continue; attachments << sourcePart.displayName(); } return attachments; } else if (role == MessageRecipientsRole) { // TODO: metadata? QMailMessage message (idFromIndex(index)); QStringList recipients; QList<QMailAddress> addresses = message.to(); foreach (const QMailAddress &address, addresses) { recipients << address.address(); } return recipients; }
QVariant EmailMessageListModel::data(const QModelIndex & index, int role) const { if (!index.isValid() || index.row() > rowCount(parent(index))) { qWarning() << Q_FUNC_INFO << "Invalid Index"; return QVariant(); } if (role == MessageSortByRole) { return m_sortBy; } QMailMessageId msgId = idFromIndex(index); if (role == QMailMessageModelBase::MessageBodyTextRole) { QMailMessage message (msgId); return EmailAgent::instance()->bodyPlainText(message); } else if (role == MessageHtmlBodyRole) { QMailMessage message (msgId); return bodyHtmlText(message); } else if (role == MessageQuotedBodyRole) { QMailMessage message (msgId); QString body = EmailAgent::instance()->bodyPlainText(message); body.prepend('\n'); body.replace('\n', "\n>"); body.truncate(body.size() - 1); // remove the extra ">" put there by QString.replace return body; } else if (role == MessageIdRole) { return msgId.toULongLong(); } else if (role == MessageToRole) { QMailMessage message (msgId); return QMailAddress::toStringList(message.to()); } else if (role == MessageCcRole) { QMailMessage message (msgId); return QMailAddress::toStringList(message.cc()); } else if (role == MessageBccRole) { QMailMessage message (msgId); return QMailAddress::toStringList(message.bcc()); } else if (role == MessageSelectModeRole) { int selected = 0; if (m_selectedMsgIds.contains(msgId) == true) selected = 1; return (selected); } QMailMessageMetaData messageMetaData(msgId); if (role == QMailMessageModelBase::MessageTimeStampTextRole) { QDateTime timeStamp = messageMetaData.date().toLocalTime(); return (timeStamp.toString("hh:mm MM/dd/yyyy")); } else if (role == MessageAttachmentCountRole) { // return number of attachments if (!messageMetaData.status() & QMailMessageMetaData::HasAttachments) return 0; QMailMessage message(msgId); const QList<QMailMessagePart::Location> &attachmentLocations = message.findAttachmentLocations(); return attachmentLocations.count(); } else if (role == MessageAttachmentsRole) { // return a stringlist of attachments if (!messageMetaData.status() & QMailMessageMetaData::HasAttachments) return QStringList(); QMailMessage message(msgId); QStringList attachments; foreach (const QMailMessagePart::Location &location, message.findAttachmentLocations()) { const QMailMessagePart &attachmentPart = message.partAt(location); attachments << attachmentPart.displayName(); } return attachments; } else if (role == MessageRecipientsRole) {
void tst_QMailMessagePart::setHeaderField() { QString addr1("*****@*****.**"); QString addr2("*****@*****.**"); QString ownHdr("hello"); QMailMessage m; m.setHeaderField("To", addr2); QCOMPARE(m.headerFieldText("to"), addr2); QCOMPARE(m.headerField("to").content(), addr2.toLatin1()); // Ensure overwrite m.setHeaderField("To", addr1); m.setHeaderField("X-My-Own-Header", ownHdr); QCOMPARE(m.headerFieldText("to"), addr1); QCOMPARE(m.headerField("to").content(), addr1.toLatin1()); QCOMPARE(m.headerFieldText("X-My-Own-Header"), ownHdr); QCOMPARE(m.headerField("X-My-Own-Header").content(), ownHdr.toLatin1()); QCOMPARE(m.to(), (QList<QMailAddress>() << QMailAddress(addr1))); QCOMPARE(m.recipients(), (QList<QMailAddress>() << QMailAddress(addr1))); QMailMessageMetaData mtdata = *static_cast<QMailMessageMetaData*>(&m); QCOMPARE(mtdata.recipients(), (QList<QMailAddress>() << QMailAddress(addr1))); m.setHeaderField("Cc", addr2); QCOMPARE(m.recipients(), (QList<QMailAddress>() << QMailAddress(addr1) << QMailAddress(addr2))); mtdata = *static_cast<QMailMessageMetaData*>(&m); QCOMPARE(mtdata.recipients(), (QList<QMailAddress>() << QMailAddress(addr1) << QMailAddress(addr2))); QCOMPARE(m.cc(), (QList<QMailAddress>() << QMailAddress(addr2))); QString addr3("*****@*****.**"); m.setHeaderField("Bcc", addr3); QCOMPARE(m.recipients(), (QList<QMailAddress>() << QMailAddress(addr1) << QMailAddress(addr2) << QMailAddress(addr3))); mtdata = *static_cast<QMailMessageMetaData*>(&m); QCOMPARE(mtdata.recipients(), (QList<QMailAddress>() << QMailAddress(addr1) << QMailAddress(addr2) << QMailAddress(addr3))); QCOMPARE(m.bcc(), (QList<QMailAddress>() << QMailAddress(addr3))); QString rfc822 = m.toRfc2822(); QMailMessage m2 = QMailMessage::fromRfc2822(rfc822.toLatin1()); QCOMPARE(m2.headerFieldText("to"), addr1); QCOMPARE(m2.headerField("to").content(), addr1.toLatin1()); QCOMPARE(m2.headerFieldText("X-My-Own-Header"), ownHdr); QCOMPARE(m2.headerField("X-My-Own-Header").content(), ownHdr.toLatin1()); QCOMPARE(m2.to(), (QList<QMailAddress>() << QMailAddress(addr1))); m2.setTo(QList<QMailAddress>() << QMailAddress(addr2)); QCOMPARE(m2.headerFieldText("to"), addr2); QCOMPARE(m2.headerField("to").content(), addr2.toLatin1()); QCOMPARE(m2.to(), (QList<QMailAddress>() << QMailAddress(addr2))); }
QMailMessage EmailComposerInterface::message() const { QMailMessage mail; if( isEmpty() ) return mail; QList<AttachmentItem*> attachments = m_composer->addAttDialog()->attachedFiles(); QString messageText( m_composer->toPlainText() ); QMailMessageContentType type("text/plain; charset=UTF-8"); if(attachments.isEmpty()) { mail.setBody( QMailMessageBody::fromData( messageText, type, QMailMessageBody::Base64 ) ); } else { QMailMessagePart textPart; textPart.setBody(QMailMessageBody::fromData(messageText.toUtf8(), type, QMailMessageBody::Base64)); mail.setMultipartType(QMailMessagePartContainer::MultipartMixed); mail.appendPart(textPart); foreach (AttachmentItem* current, attachments) { const QContent& doc( current->document() ); QString fileName( doc.fileName() ); QFileInfo fi( fileName ); QString partName( fi.fileName() ); fileName = fi.absoluteFilePath(); QString content( doc.type() ); if (content.isEmpty()) content = QMimeType( fileName ).id(); QMailMessageContentType type( content.toLatin1() ); type.setName( partName.toLatin1() ); QMailMessageContentDisposition disposition( QMailMessageContentDisposition::Attachment ); disposition.setFilename( partName.toLatin1() ); QMailMessagePart part; if ((current->action() != QMailMessage::LinkToAttachments) || (fileName.startsWith(Qtopia::tempDir()))) { // This file is temporary - extract the data and create a part from that QFile dataFile(fileName); if (dataFile.open(QIODevice::ReadOnly)) { QDataStream in(&dataFile); part = QMailMessagePart::fromStream(in, disposition, type, QMailMessageBody::Base64, QMailMessageBody::RequiresEncoding); } else { qWarning() << "Unable to open temporary file:" << fileName; } } else { part = QMailMessagePart::fromFile(fileName, disposition, type, QMailMessageBody::Base64, QMailMessageBody::RequiresEncoding); } mail.appendPart(part); } } mail.setMessageType( QMailMessage::Email ); return mail; }