I have made the following changes intended for : CE:MW:Shared / nemo-qml-plugins
Please review and accept or decline. BOSS has already run some checks on this request. See the "Messages from BOSS" section below. https://build.pub.meego.com//request/show/7369 Thank You, Marko Saukko [This message was auto-generated] --- Request # 7369: Messages from BOSS: State: review at 2012-11-12T13:18:38 by bossbot Reviews: accepted by bossbot : Prechecks succeeded. new for CE-maintainers : Please replace this text with a review and approve/reject the review (not the SR). BOSS will take care of the rest Changes: submit: Project:MTF:MW / nemo-qml-plugins -> CE:MW:Shared / nemo-qml-plugins changes files: -------------- --- nemo-qml-plugins.changes +++ nemo-qml-plugins.changes @@ -0,0 +1,4 @@ +* Mon Nov 12 2012 Johan Paul <[email protected]> - 0.1.4 +- Improvements to email. (by Matt Vogt) +- Added support for saving addresses and their types in SeasidePerson. (by Chris Adams) + old: ---- nemo-qml-plugins-0.1.3.tar.bz2 new: ---- nemo-qml-plugins-0.1.4.tar.bz2 spec files: ----------- --- nemo-qml-plugins.spec +++ nemo-qml-plugins.spec @@ -9,7 +9,7 @@ # << macros Summary: Nemo QML plugins source package. -Version: 0.1.3 +Version: 0.1.4 Release: 1 Group: System/Libraries License: BSD other changes: -------------- ++++++ nemo-qml-plugins-0.1.3.tar.bz2 -> nemo-qml-plugins-0.1.4.tar.bz2 --- contacts/src/seasideperson.cpp +++ contacts/src/seasideperson.cpp @@ -38,6 +38,7 @@ #include <QContactFavorite> #include <QContactPhoneNumber> #include <QContactEmailAddress> +#include <QContactAddress> #include <QContactOnlineAccount> #include <QContactOrganization> #include <QContactUrl> @@ -232,19 +233,43 @@ LIST_PROPERTY_FROM_DETAIL_FIELD(QContactPhoneNumber, number); } -// this could probably be optimised, but it's easiest: we just remove -// all the old phone number details, and add new ones #define SET_PROPERTY_FIELD_FROM_LIST(detailType, fieldNameGet, fieldNameSet, newValueList) \ const QList<detailType> &oldDetailList = mContact.details<detailType>(); \ \ if (oldDetailList.count() != newValueList.count()) { \ - foreach (detailType detail, oldDetailList) \ - mContact.removeDetail(&detail); \ + bool removeAndReadd = true; \ + if (oldDetailList.count() < newValueList.count()) { \ + /* Check to see if existing details were modified at all */ \ + bool modification = false; \ + for (int i = 0; i < oldDetailList.count(); ++i) { \ + if (oldDetailList.at(i).fieldNameGet() != newValueList.at(i)) { \ + modification = true; \ + break; \ + } \ + } \ \ - foreach (const QString &value, newValueList) { \ - detailType detail; \ - detail.fieldNameSet(value); \ - mContact.saveDetail(&detail); \ + if (!modification) { \ + /* If the only changes are new additions, just add them. */ \ + for (int i = oldDetailList.count(); i < newValueList.count(); ++i) { \ + detailType detail; \ + detail.fieldNameSet(newValueList.at(i)); \ + mContact.saveDetail(&detail); \ + } \ + removeAndReadd = false; \ + } else { \ + removeAndReadd = true; \ + } \ + } \ + \ + if (removeAndReadd) { \ + foreach (detailType detail, oldDetailList) \ + mContact.removeDetail(&detail); \ + \ + foreach (const QString &value, newValueList) { \ + detailType detail; \ + detail.fieldNameSet(value); \ + mContact.saveDetail(&detail); \ + } \ } \ } else { \ /* assign new numbers to the existing details. */ \ @@ -379,6 +404,120 @@ emit emailAddressTypesChanged(); } +// Fields are separated by \n characters +QStringList SeasidePerson::addresses() const +{ + QStringList retn; + const QList<QContactAddress> &addresses = mContact.details<QContactAddress>(); + foreach (const QContactAddress &address, addresses) { + QString currAddressStr; + currAddressStr.append(address.street()); + currAddressStr.append("\n"); + currAddressStr.append(address.locality()); + currAddressStr.append("\n"); + currAddressStr.append(address.region()); + currAddressStr.append("\n"); + currAddressStr.append(address.postcode()); + currAddressStr.append("\n"); + currAddressStr.append(address.country()); + currAddressStr.append("\n"); + currAddressStr.append(address.postOfficeBox()); + retn.append(currAddressStr); + } + return retn; +} + +void SeasidePerson::setAddresses(const QStringList &addresses) +{ + QList<QStringList> splitStrings; + foreach (const QString &currAddressStr, addresses) { + QStringList split = currAddressStr.split("\n"); + if (split.count() != 6) { + qWarning() << "Warning: Could not save addresses - invalid format for address:" << currAddressStr; + return; + } else { + splitStrings.append(split); + } + } + + const QList<QContactAddress> &oldDetailList = mContact.details<QContactAddress>(); + if (oldDetailList.count() != splitStrings.count()) { + /* remove all current details, recreate new ones */ + foreach (QContactAddress oldAddress, oldDetailList) + mContact.removeDetail(&oldAddress); + foreach (const QStringList &split, splitStrings) { + QContactAddress newAddress; + newAddress.setStreet(split.at(0)); + newAddress.setLocality(split.at(1)); + newAddress.setRegion(split.at(2)); + newAddress.setPostcode(split.at(3)); + newAddress.setCountry(split.at(4)); + newAddress.setPostOfficeBox(split.at(5)); + mContact.saveDetail(&newAddress); + } + } else { + /* overwrite existing details */ + for (int i = 0; i < splitStrings.count(); ++i) { + const QStringList &split = splitStrings.at(i); + QContactAddress oldAddress = oldDetailList.at(i); + oldAddress.setStreet(split.at(0)); + oldAddress.setLocality(split.at(1)); + oldAddress.setRegion(split.at(2)); + oldAddress.setPostcode(split.at(3)); + oldAddress.setCountry(split.at(4)); + oldAddress.setPostOfficeBox(split.at(5)); + mContact.saveDetail(&oldAddress); + } + } + + emit addressesChanged(); +} + +QList<int> SeasidePerson::addressTypes() const +{ + const QList<QContactAddress> &addresses = mContact.details<QContactAddress>(); + QList<int> types; + types.reserve((addresses.length())); + + foreach(const QContactAddress &address, addresses) { + if (address.contexts().contains(QContactDetail::ContextHome)) { + types.push_back(SeasidePerson::AddressHomeType); + } else if (address.contexts().contains(QContactDetail::ContextWork)) { + types.push_back(SeasidePerson::AddressWorkType); + } else if (address.contexts().contains(QContactDetail::ContextOther)) { + types.push_back(SeasidePerson::AddressOtherType); + } else { + qWarning() << "Warning: Could not get address type '" << address.contexts() << "'"; + } + } + + return types; +} + +void SeasidePerson::setAddressType(int which, SeasidePerson::DetailTypes type) +{ + const QList<QContactAddress> &addresses = mContact.details<QContactAddress>(); + + if (which >= addresses.length()) { + qWarning() << "Unable to set type for address: invalid index specified. Aborting."; + return; + } + + QContactAddress address = addresses.at(which); + if (type == SeasidePerson::AddressHomeType) { + address.setContexts(QContactDetail::ContextHome); + } else if (type == SeasidePerson::AddressWorkType) { + address.setContexts(QContactDetail::ContextWork); + } else if (type == SeasidePerson::AddressOtherType) { + address.setContexts(QContactDetail::ContextOther); + } else { + qWarning() << "Warning: Could not save address type '" << type << "'"; + } + + mContact.saveDetail(&address); + emit addressTypesChanged(); +} + QStringList SeasidePerson::websites() const { LIST_PROPERTY_FROM_DETAIL_FIELD(QContactUrl, url); --- contacts/src/seasideperson.h +++ contacts/src/seasideperson.h @@ -41,6 +41,8 @@ QTM_USE_NAMESPACE +Q_DECLARE_METATYPE(QContact) + class SeasidePerson : public QObject { Q_OBJECT @@ -68,6 +70,10 @@ EmailHomeType, EmailWorkType, EmailOtherType, + // Address + AddressHomeType, + AddressWorkType, + AddressOtherType, // Website WebsiteHomeType, WebsiteWorkType, @@ -121,13 +127,21 @@ QList<int> emailAddressTypes() const; Q_INVOKABLE void setEmailAddressType(int which, DetailTypes type); + Q_PROPERTY(QStringList addresses READ addresses WRITE setAddresses NOTIFY addressesChanged) + QStringList addresses() const; + void setAddresses(const QStringList &addresses); + + Q_PROPERTY(QList<int> addressTypes READ addressTypes NOTIFY addressTypesChanged) + QList<int> addressTypes() const; + Q_INVOKABLE void setAddressType(int which, DetailTypes type); + Q_PROPERTY(QStringList websites READ websites WRITE setWebsites NOTIFY websitesChanged) QStringList websites() const; - Q_INVOKABLE void setWebsites(const QStringList &sites); + void setWebsites(const QStringList &sites); Q_PROPERTY(QList<int> websiteTypes READ websiteTypes NOTIFY websiteTypesChanged) QList<int> websiteTypes() const; - void setWebsiteType(int which, DetailTypes type); + Q_INVOKABLE void setWebsiteType(int which, DetailTypes type); Q_PROPERTY(QDateTime birthday READ birthday WRITE setBirthday NOTIFY birthdayChanged) QDateTime birthday() const; @@ -146,6 +160,9 @@ QContact contact() const; void setContact(const QContact &contact); + Q_INVOKABLE QVariant contactData() const { return QVariant::fromValue(contact()); } + Q_INVOKABLE void setContactData(const QVariant &data) { setContact(data.value<QContact>()); } + void recalculateDisplayLabel(); signals: @@ -160,6 +177,8 @@ void phoneNumberTypesChanged(); void emailAddressesChanged(); void emailAddressTypesChanged(); + void addressesChanged(); + void addressTypesChanged(); void websitesChanged(); void websiteTypesChanged(); void birthdayChanged(); --- contacts/tests/tst_seasideperson/tst_seasideperson.cpp +++ contacts/tests/tst_seasideperson/tst_seasideperson.cpp @@ -59,6 +59,7 @@ void websiteTypes(); void birthday(); void anniversary(); + void address(); void marshalling(); void setContact(); }; @@ -307,6 +308,37 @@ QCOMPARE(person->anniversary(), QDateTime::fromString("05/01/1980 15:00:00.000", "dd/MM/yyyy hh:mm:ss.zzz")); } +void tst_SeasidePerson::address() +{ + QScopedPointer<SeasidePerson> person(new SeasidePerson); + QCOMPARE(person->addresses(), QStringList()); + QCOMPARE(person->addressTypes(), QList<int>()); + QSignalSpy spy(person.data(), SIGNAL(addressesChanged())); + + QString address1 = "Street 1\nLocality 1\nRegion 1\nPostcode 1\nCountry 1\nPoBox 1"; + QString address2 = "Street 2\nLocality 2\nRegion 2\nPostcode 2\nCountry 2\nPoBox 2"; + + QStringList addresses; + addresses.append(address1); + addresses.append(address2); + person->setAddresses(addresses); + QCOMPARE(spy.count(), 1); + + addresses = person->addresses(); + QCOMPARE(addresses.count(), 2); + QCOMPARE(addresses.at(0), QString("Street 1\nLocality 1\nRegion 1\nPostcode 1\nCountry 1\nPoBox 1")); + QCOMPARE(addresses.at(1), QString("Street 2\nLocality 2\nRegion 2\nPostcode 2\nCountry 2\nPoBox 2")); + + person->setAddressType(0, SeasidePerson::AddressHomeType); + person->setAddressType(1, SeasidePerson::AddressWorkType); + person->setAddressType(2, SeasidePerson::AddressWorkType); // Invalid, should not crash. + + QCOMPARE(person->addressTypes().count(), 2); + QCOMPARE(person->addressTypes().at(0), (int)SeasidePerson::AddressHomeType); + QCOMPARE(person->addressTypes().at(1), (int)SeasidePerson::AddressWorkType); +} + + void tst_SeasidePerson::marshalling() { QContact contact; --- email/src/emailaccount.cpp +++ email/src/emailaccount.cpp @@ -186,8 +186,16 @@ void EmailAccount::activityChanged(QMailServiceAction::Activity activity) { + static const int AccountUpdatedByOther = 1040; + if (sender() == static_cast<QObject*>(mRetrievalAction)) { const QMailServiceAction::Status status(mRetrievalAction->status()); + + if ((activity == QMailServiceAction::Failed) && (status.errorCode == AccountUpdatedByOther)) { + // ignore error 1040/"Account updated by other process" + activity = QMailServiceAction::Successful; + } + if (activity == QMailServiceAction::Successful) { if (mAccount->status() & QMailAccount::MessageSink) { mTransmitAction->transmitMessages(mAccount->id()); @@ -197,27 +205,76 @@ } else if (activity == QMailServiceAction::Failed) { mErrorMessage = status.text; mErrorCode = status.errorCode; - if (status.errorCode == 1040) { - // ignore error 1040/"Account updated by other process" - mTransmitAction->transmitMessages(mAccount->id()); - } else { - emit testFailed(); - } + emit testFailed(); } } else if (sender() == static_cast<QObject*>(mTransmitAction)) { const QMailServiceAction::Status status(mTransmitAction->status()); + + if ((activity == QMailServiceAction::Failed) && (status.errorCode == AccountUpdatedByOther)) { + // ignore error 1040/"Account updated by other process" + activity = QMailServiceAction::Successful; + } + if (activity == QMailServiceAction::Successful) { emit testSucceeded(); } else if (activity == QMailServiceAction::Failed) { mErrorMessage = status.text; mErrorCode = status.errorCode; - if (status.errorCode == 1040) { - // ignore error 1040/"Account updated by other process" - emit testSucceeded(); - } else { - emit testFailed(); - } + emit testFailed(); + } + } +} + +namespace { + + // The only supported types here ('external' type) are: '0':pop3 '1':imap4 + QString externalRecvType(const QString &internal) { + if (internal == QLatin1String("pop3")) { + return QLatin1String("0"); + } else if (internal == QLatin1String("imap4")) { + return QLatin1String("1"); + } + qWarning() << "Unknown internal receive type:" << internal; + return QString(); + } + + // Internal type is the stored value + QString internalRecvType(const QString &external) { + if (external == QLatin1String("0")) { + return QLatin1String("pop3"); + } else if (external == QLatin1String("1")) { + return QLatin1String("imap4"); + } + qWarning() << "Unknown external receive type:" << external; + return QString(); + } + + // Equivalent to QMailTransport::EncryptType? + QString securityType(const QString &securityType) { + if (securityType == QLatin1String("SSL")) { + return QLatin1String("1"); + } else if (securityType == QLatin1String("TLS")) { + return QLatin1String("2"); + } + + if (securityType != QLatin1String("none")) + qWarning() << "Unknown security type:" << securityType; + return QLatin1String("0"); + } + + // Equivalent to QMail::SaslMechanism? + QString authorizationType(const QString &authType) { + if (authType == QLatin1String("Login")) { + return QLatin1String("1"); + } else if (authType == QLatin1String("Plain")) { + return QLatin1String("2"); + } else if (authType == QLatin1String("CRAM-MD5")) { + return QLatin1String("3"); } + + if (authType != QLatin1String("none")) + qWarning() << "Unknown authorization type:" << authType; + return QLatin1String("0"); } } @@ -225,84 +282,84 @@ { switch(preset()) { case mobilemePreset: - setRecvType("1"); // imap + setRecvType(externalRecvType("imap4")); setRecvServer("mail.me.com"); setRecvPort("993"); - setRecvSecurity("1"); // SSL + setRecvSecurity(securityType("SSL")); setRecvUsername(username()); // username only setRecvPassword(password()); setSendServer("smtp.me.com"); setSendPort("587"); - setSendSecurity("1"); // SSL - setSendAuth("1"); // Login + setSendSecurity(securityType("SSL")); + setSendAuth(authorizationType("Login")); setSendUsername(username()); // username only setSendPassword(password()); break; case gmailPreset: - setRecvType("1"); // imap + setRecvType(externalRecvType("imap4")); setRecvServer("imap.gmail.com"); setRecvPort("993"); - setRecvSecurity("1"); // SSL + setRecvSecurity(securityType("SSL")); setRecvUsername(address()); // full email address setRecvPassword(password()); setSendServer("smtp.gmail.com"); setSendPort("465"); - setSendSecurity("1"); // SSL - setSendAuth("1"); // Login + setSendSecurity(securityType("SSL")); + setSendAuth(authorizationType("Login")); setSendUsername(address()); // full email address setSendPassword(password()); break; case yahooPreset: - setRecvType("1"); // imap + setRecvType(externalRecvType("imap4")); setRecvServer("imap.mail.yahoo.com"); setRecvPort("993"); - setRecvSecurity("1"); // SSL + setRecvSecurity(securityType("SSL")); setRecvUsername(address()); // full email address setRecvPassword(password()); setSendServer("smtp.mail.yahoo.com"); setSendPort("465"); - setSendSecurity("1"); // SSL - setSendAuth("1"); // Login + setSendSecurity(securityType("SSL")); + setSendAuth(authorizationType("Login")); setSendUsername(address()); // full email address setSendPassword(password()); break; case aolPreset: - setRecvType("1"); // imap + setRecvType(externalRecvType("imap4")); setRecvServer("imap.aol.com"); setRecvPort("143"); - setRecvSecurity("0"); // none + setRecvSecurity(securityType("none")); setRecvUsername(username()); // username only setRecvPassword(password()); setSendServer("smtp.aol.com"); setSendPort("587"); - setSendSecurity("0"); // none - setSendAuth("1"); // Login + setSendSecurity(securityType("none")); + setSendAuth(authorizationType("Login")); setSendUsername(username()); // username only setSendPassword(password()); break; case mslivePreset: - setRecvType("0"); // pop + setRecvType(externalRecvType("pop3")); setRecvServer("pop3.live.com"); setRecvPort("995"); - setRecvSecurity("1"); // SSL + setRecvSecurity(securityType("SSL")); setRecvUsername(address()); // full email address setRecvPassword(password()); setSendServer("smtp.live.com"); setSendPort("587"); - setSendSecurity("2"); // TLS - setSendAuth("1"); // Login + setSendSecurity(securityType("TLS")); + setSendAuth(authorizationType("Login")); setSendUsername(address()); // full email address setSendPassword(password()); break; case noPreset: - setRecvType("1"); // imap + setRecvType(externalRecvType("imap4")); setRecvPort("993"); - setRecvSecurity("1"); // SSL + setRecvSecurity(securityType("SSL")); setRecvUsername(username()); // username only setRecvPassword(password()); setSendPort("587"); - setSendSecurity("1"); // SSL - setSendAuth("1"); // Login + setSendSecurity(securityType("SSL")); + setSendAuth(authorizationType("Login")); setSendUsername(username()); // username only setSendPassword(password()); break; @@ -375,23 +432,14 @@ QString EmailAccount::recvType() const { - if (mRecvType == "pop3") - return "0"; - else if (mRecvType == "imap4") - return "1"; - else - return QString(); + return externalRecvType(mRecvType); } void EmailAccount::setRecvType(QString val) { // prevent bug where recv type gets reset // when loading the first time - QString newRecvType; - if (val == "0") - newRecvType = "pop3"; - else if (val == "1") - newRecvType = "imap4"; + QString newRecvType = internalRecvType(val); if (newRecvType != mRecvType) { mAccountConfig->removeServiceConfiguration(mRecvType); mAccountConfig->addServiceConfiguration(newRecvType); --- email/src/emailagent.cpp +++ email/src/emailagent.cpp @@ -19,7 +19,17 @@ #include "emailagent.h" -static int sRetrievedMinimum = 0; +namespace { + +int sRetrievedMinimum = 0; + +QMailAccountId accountForMessageId(const QMailMessageId &msgId) +{ + QMailMessageMetaData metaData(msgId); + return metaData.parentAccountId(); +} + +} EmailAgent *EmailAgent::m_instance = 0; @@ -121,8 +131,7 @@ QMailMessageId msgId = id.value<QMailMessageId>(); QMailMessageIdList msgIdList; msgIdList << msgId; - QMailMessage msg(msgId); - exportAccountChanges(msg.parentAccountId()); + exportAccountChanges(accountForMessageId(msgId)); return deleteMessages (msgIdList); } @@ -286,8 +295,7 @@ QMailMessageId id = msgId.value<QMailMessageId>(); quint64 status(QMailMessage::Read); QMailStore::instance()->updateMessagesMetaData(QMailMessageKey::id(id), status, true); - QMailMessage msg (id); - exportAccountChanges(msg.parentAccountId()); + exportAccountChanges(accountForMessageId(id)); } void EmailAgent::markMessageAsUnread(QVariant msgId) @@ -295,8 +303,7 @@ QMailMessageId id = msgId.value<QMailMessageId>(); quint64 status(QMailMessage::Read); QMailStore::instance()->updateMessagesMetaData(QMailMessageKey::id(id), status, false); - QMailMessage msg (id); - exportAccountChanges(msg.parentAccountId()); + exportAccountChanges(accountForMessageId(id)); } QString EmailAgent::getSignatureForAccount(QVariant vMailAccountId) --- email/src/emailmessage.cpp +++ email/src/emailmessage.cpp @@ -19,11 +19,9 @@ EmailMessage::EmailMessage (QDeclarativeItem *parent) : QDeclarativeItem(parent) + , m_textOnly(true) { - // set the default priority to normal - m_msg.appendHeaderField("X-Priority", "3"); - m_msg.appendHeaderField("X-MSMail-Priority", "Normal"); - m_textOnly = true; // body type is text by default + setPriority(NormalPriority); } EmailMessage::~EmailMessage () @@ -98,36 +96,7 @@ void EmailMessage::send() { - QMailMessageContentType type; - if (m_textOnly) - type.setType("text/plain; charset=UTF-8"); - else - type.setType("text/html; charset=UTF-8"); - - if (m_attachments.size() == 0) - m_msg.setBody(QMailMessageBody::fromData(m_bodyText, type, QMailMessageBody::Base64)); - else { - QMailMessagePart body; - body.setBody(QMailMessageBody::fromData(m_bodyText.toUtf8(), type, QMailMessageBody::Base64)); - m_msg.setMultipartType(QMailMessagePartContainer::MultipartMixed); - m_msg.appendPart(body); - } - - // Include attachments into the message before sending - processAttachments(); - - // set message basic attributes - m_msg.setDate(QMailTimeStamp::currentDateTime()); - m_msg.setStatus(QMailMessage::Outgoing, true); - m_msg.setStatus(QMailMessage::ContentAvailable, true); - m_msg.setStatus(QMailMessage::PartialContentAvailable, true); - m_msg.setStatus(QMailMessage::Read, true); - m_msg.setStatus((QMailMessage::Outbox | QMailMessage::Draft), true); - - m_msg.setParentFolderId(QMailFolder::LocalStorageFolderId); - - m_msg.setMessageType(QMailMessage::Email); - m_msg.setSize(m_msg.indicativeSize() * 1024); + buildMessage(); bool stored = false; @@ -148,37 +117,7 @@ void EmailMessage::saveDraft() { - QMailMessageContentType type; - if (m_textOnly) - type.setType("text/plain; charset=UTF-8"); - else - type.setType("text/html; charset=UTF-8"); - - if (m_attachments.size() == 0) { - m_msg.setBody(QMailMessageBody::fromData(m_bodyText, type, QMailMessageBody::Base64)); - } - else { - QMailMessagePart body; - body.setBody(QMailMessageBody::fromData(m_bodyText.toUtf8(), type, QMailMessageBody::Base64)); - m_msg.setMultipartType(QMailMessagePartContainer::MultipartMixed); - m_msg.appendPart(body); - } - - // Include attachments into the message before sending - processAttachments(); - - // set message basic attributes - m_msg.setDate(QMailTimeStamp::currentDateTime()); - m_msg.setStatus(QMailMessage::Outgoing, true); - m_msg.setStatus(QMailMessage::ContentAvailable, true); - m_msg.setStatus(QMailMessage::PartialContentAvailable, true); - m_msg.setStatus(QMailMessage::Read, true); - m_msg.setStatus((QMailMessage::Outbox | QMailMessage::Draft), true); - - m_msg.setParentFolderId(QMailFolder::LocalStorageFolderId); - - m_msg.setMessageType(QMailMessage::Email); - m_msg.setSize(m_msg.indicativeSize() * 1024); + buildMessage(); QMailFolderKey nameKey(QMailFolderKey::displayName("Drafts", QMailDataComparator::Includes)); QMailFolderKey accountKey(QMailFolderKey::parentAccountId(m_msg.parentAccountId())); @@ -212,6 +151,40 @@ emit sendCompleted(); } +void EmailMessage::buildMessage() +{ + QMailMessageContentType type; + if (m_textOnly) + type.setType("text/plain; charset=UTF-8"); + else + type.setType("text/html; charset=UTF-8"); + + if (m_attachments.size() == 0) + m_msg.setBody(QMailMessageBody::fromData(m_bodyText, type, QMailMessageBody::Base64)); + else { + QMailMessagePart body; + body.setBody(QMailMessageBody::fromData(m_bodyText.toUtf8(), type, QMailMessageBody::Base64)); + m_msg.setMultipartType(QMailMessagePartContainer::MultipartMixed); + m_msg.appendPart(body); + } + + // Include attachments into the message + processAttachments(); + + // set message basic attributes + m_msg.setDate(QMailTimeStamp::currentDateTime()); + m_msg.setStatus(QMailMessage::Outgoing, true); + m_msg.setStatus(QMailMessage::ContentAvailable, true); + m_msg.setStatus(QMailMessage::PartialContentAvailable, true); + m_msg.setStatus(QMailMessage::Read, true); + m_msg.setStatus((QMailMessage::Outbox | QMailMessage::Draft), true); + + m_msg.setParentFolderId(QMailFolder::LocalStorageFolderId); + + m_msg.setMessageType(QMailMessage::Email); + m_msg.setSize(m_msg.indicativeSize() * 1024); +} + void EmailMessage::processAttachments () { QMailMessagePart attachmentPart; --- email/src/emailmessage.h +++ email/src/emailmessage.h @@ -43,6 +43,7 @@ void onSendCompleted(); private: + void buildMessage(); void processAttachments(); QMailMessage m_msg; --- email/src/emailmessagelistmodel.cpp +++ email/src/emailmessagelistmodel.cpp @@ -19,109 +19,32 @@ #include "emailmessagelistmodel.h" -QString EmailMessageListModel::bodyHtmlText(QMailMessagePartContainer *container) const +QString EmailMessageListModel::bodyHtmlText(const QMailMessage &mailMsg) 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. - } + // 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 ""; - } - 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 container->body().data(); } - return text; + + return QString(); } QString EmailMessageListModel::bodyPlainText(const QMailMessage &mailMsg) const { - QMailMessagePartContainer *container = (QMailMessagePartContainer *)&mailMsg; - QMailMessageContentType contentType = container->contentType(); - if (container->hasBody() && contentType.type().toLower() == "text" && - contentType.subType().toLower() == "plain") { + if (QMailMessagePartContainer *container = mailMsg.findPlainTextContainer()) { return container->body().data(); } - QString text(""); - for ( uint i = 0; i < container->partCount(); i++ ) { - QMailMessagePart messagePart = container->partAt(i); - - contentType = messagePart.contentType(); - if (messagePart.hasBody() && contentType.type().toLower() == "text" && - contentType.subType().toLower() == "plain") { - text += messagePart.body().data() + "\n"; - } - QMailMessagePart subPart; - for (uint j = 0; j < messagePart.partCount(); j++) { - subPart = messagePart.partAt(j); - contentType = subPart.contentType(); - if (subPart.hasBody() && contentType.type().toLower() == "text" && - contentType.subType().toLower() == "plain") { - text += subPart.body().data() + "\n"; - } - } - } - return text; + return QString(); } //![0] @@ -185,103 +108,73 @@ if (!index.isValid() || index.row() > rowCount(parent(index))) return QVariant(); + QMailMessageId msgId = idFromIndex(index); + 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)); + QMailMessageMetaData messageMetaData(msgId); 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; + QMailMessage message(msgId); + const QList<QMailMessagePart::Location> &attachmentLocations = message.findAttachmentLocations(); + return attachmentLocations.count(); } else if (role == MessageAttachmentsRole) { // return a stringlist of attachments - QMailMessage messageMetaData(idFromIndex(index)); + QMailMessageMetaData messageMetaData(msgId); if (!messageMetaData.status() & QMailMessageMetaData::HasAttachments) return QStringList(); - QMailMessage message(idFromIndex(index)); + QMailMessage message(msgId); 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(); + foreach (const QMailMessagePart::Location &location, message.findAttachmentLocations()) { + const QMailMessagePart &attachmentPart = message.partAt(location); + attachments << attachmentPart.displayName(); } - return attachments; } else if (role == MessageRecipientsRole) { - // TODO: metadata? - QMailMessage message (idFromIndex(index)); + QMailMessageMetaData messageMetaData(msgId); QStringList recipients; - QList<QMailAddress> addresses = message.to(); + QList<QMailAddress> addresses = messageMetaData.recipients(); foreach (const QMailAddress &address, addresses) { recipients << address.address(); } return recipients; } else if (role == MessageRecipientsDisplayNameRole) { - // TODO: metadata? - QMailMessage message (idFromIndex(index)); + QMailMessageMetaData messageMetaData(msgId); QStringList recipients; - QList<QMailAddress> addresses = message.to(); + QList<QMailAddress> addresses = messageMetaData.recipients(); foreach (const QMailAddress &address, addresses) { recipients << address.name(); } return recipients; } else if (role == MessageReadStatusRole) { - QMailMessageMetaData message (idFromIndex(index)); + QMailMessageMetaData messageMetaData(msgId); - if (message.status() & QMailMessage::Read) + if (messageMetaData.status() & QMailMessage::Read) return 1; // 1 for read else return 0; // 0 for unread } else if (role == QMailMessageModelBase::MessageBodyTextRole) { - QMailMessage message (idFromIndex(index)); - return (bodyPlainText(message)); + QMailMessage message (msgId); + return bodyPlainText(message); } else if (role == MessageHtmlBodyRole) { - QMailMessage message (idFromIndex(index)); - return (bodyHtmlText(&message)); + QMailMessage message (msgId); + return bodyHtmlText(message); } else if (role == MessageQuotedBodyRole) { - QMailMessage message (idFromIndex(index)); + QMailMessage message (msgId); QString body = bodyPlainText(message); body.prepend('\n'); body.replace('\n', "\n>"); @@ -289,36 +182,31 @@ return body; } else if (role == MessageUuidRole) { - QMailMessageId messageId = idFromIndex(index); - QString uuid = QString::number(messageId.toULongLong()); - QMailMessage newId = QMailMessageId (uuid.toULongLong()); - QMailMessage message (newId); - QString body = message.body().data(); + QString uuid = QString::number(msgId.toULongLong()); return uuid; } else if (role == MessageSenderDisplayNameRole) { - QMailMessageMetaData message(idFromIndex(index)); - return message.from().name(); + QMailMessageMetaData messageMetaData(msgId); + return messageMetaData.from().name(); } else if (role == MessageSenderEmailAddressRole) { - QMailMessageMetaData message(idFromIndex(index)); - return message.from().address(); + QMailMessageMetaData messageMetaData(msgId); + return messageMetaData.from().address(); } else if (role == MessageCcRole) { - QMailMessage message (idFromIndex(index)); + QMailMessage message (msgId); return QMailAddress::toStringList (message.cc()); } else if (role == MessageBccRole) { - QMailMessage message (idFromIndex(index)); + QMailMessage message (msgId); return QMailAddress::toStringList (message.bcc()); } else if (role == MessageTimeStampRole) { - QMailMessage message (idFromIndex(index)); - return (message.date().toLocalTime()); + QMailMessageMetaData messageMetaData(msgId); + return (messageMetaData.date().toLocalTime()); } else if (role == MessageSelectModeRole) { int selected = 0; - QMailMessageId msgId = idFromIndex(index); if (m_selectedMsgIds.contains(msgId) == true) selected = 1; return (selected); @@ -373,7 +261,7 @@ for (int i = 0; i < ids.size(); i++) { QMailFolderKey key = QMailFolderKey::parentAccountId(accountId); QMailFolderIdList mailFolderIds = QMailStore::instance()->queryFolders(key); - foreach (QMailFolderId folderId, mailFolderIds) { + foreach (const QMailFolderId &folderId, mailFolderIds) { QMailFolder folder(folderId); if (QString::compare(folder.displayName(), "INBOX", Qt::CaseInsensitive) == 0) { folderIdList << folderId; @@ -404,7 +292,7 @@ void EmailMessageListModel::foldersAdded(const QMailFolderIdList &folderIds) { QMailFolderIdList folderIdList; - foreach (QMailFolderId folderId, folderIds) { + foreach (const QMailFolderId &folderId, folderIds) { QMailFolder folder(folderId); if (QString::compare(folder.displayName(), "INBOX", Qt::CaseInsensitive) == 0) { folderIdList << folderId; @@ -497,9 +385,7 @@ QVariant EmailMessageListModel::subject (int idx) { - QMailMessageId id = idFromIndex (index(idx)); - QMailMessageMetaData msg(id); - return msg.subject(); + return data(index(idx), QMailMessageModelBase::MessageSubjectTextRole); } QVariant EmailMessageListModel::mailSender (int idx) @@ -545,15 +431,14 @@ QVariant EmailMessageListModel::recipients (int idx) { QMailMessageId msgId = idFromIndex(index(idx)); - QMailMessage message(msgId); + QMailMessageMetaData messageMetaData(msgId); QStringList recipients; - QMailAccount mailAccount (message.parentAccountId()); + QMailAccount mailAccount (messageMetaData.parentAccountId()); QString myEmailAddress = mailAccount.fromAddress().address(); - QList<QMailAddress> addresses; - addresses = message.to() + message.cc() + message.bcc(); - foreach (QMailAddress address, addresses) { + // Since 1468833f, QMMMD::recipients() returns To: CC: and BCC: recipients + foreach (const QMailAddress &address, messageMetaData.recipients()) { QString emailAddress = address.address(); if (QString::compare(myEmailAddress, emailAddress, Qt::CaseInsensitive) != 0) recipients << address.toString(); @@ -588,7 +473,7 @@ QMailMessageIdList msgIds = m_selectedMsgIds; m_selectedMsgIds.clear(); - foreach (QMailMessageId msgId, msgIds) { + foreach (const QMailMessageId &msgId, msgIds) { for (int row = 0; row < rowCount(); row++) { QVariant vMsgId = data(index(row), QMailMessageModelBase::MessageIdRole); --- email/src/emailmessagelistmodel.h +++ email/src/emailmessagelistmodel.h @@ -46,7 +46,7 @@ ~EmailMessageListModel(); int rowCount (const QModelIndex & parent = QModelIndex()) const; QVariant data (const QModelIndex & index, int role = Qt::DisplayRole) const; - QString bodyHtmlText(QMailMessagePartContainer *container) const; + QString bodyHtmlText(const QMailMessage &) const; QString bodyPlainText(const QMailMessage &) const; signals: ++++++ nemo-qml-plugins.yaml --- nemo-qml-plugins.yaml +++ nemo-qml-plugins.yaml @@ -2,7 +2,7 @@ Summary: Nemo QML plugins source package. Group: System/Libraries Description: Do not install this, install the subpackaged plugins. -Version: 0.1.3 +Version: 0.1.4 Release: 1 Sources: - "%{name}-%{version}.tar.bz2"
